diff --git a/.gitignore b/.gitignore index c354214..d83d3e1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ *.img *.bin +test.sh + ~$* # Created by https://www.toptal.com/developers/gitignore/api/python,macos,windows,git diff --git a/Makefile b/Makefile index e7d44ac..e51a3f4 100644 --- a/Makefile +++ b/Makefile @@ -21,16 +21,37 @@ all: client.img server.img tracker.img alt-tracker.img client.img: client/client.sh client/client-base.sh client/workload.csv client/ultra_ping - @docker run --rm -v $(PWD)/client/client.sh:/app.sh -v $(PWD)/client/client-base.sh:/base.sh -v $(PWD)/client/workload.csv:/files/workload.csv -v $(PWD)/client/ultra_ping:/files/ultra_ping -v $(PWD)/client:/opt/code --privileged rootfsbuilder $@ + @docker run --rm \ + -v $(PWD)/client/client.sh:/app.sh \ + -v $(PWD)/client/client-base.sh:/base.sh \ + -v $(PWD)/client/workload.csv:/files/workload.csv \ + -v $(PWD)/client/ultra_ping:/files/ultra_ping \ + -v $(PWD)/client:/opt/code \ + --privileged rootfsbuilder $@ alt-tracker.img: tracker/tracker.bin tracker/alt-tracker.sh - @docker run --rm -v $(PWD)/tracker/alt-tracker.sh:/app.sh -v $(PWD)/tracker/tracker-base.sh:/base.sh -v $(PWD)/tracker/tracker.bin:/files/tracker.bin -v $(PWD)/tracker:/opt/code --privileged rootfsbuilder $@ + @docker run --rm \ + -v $(PWD)/tracker/alt-tracker.sh:/app.sh \ + -v $(PWD)/tracker/tracker-base.sh:/base.sh \ + -v $(PWD)/tracker/tracker.bin:/files/tracker.bin \ + -v $(PWD)/tracker:/opt/code \ + --privileged rootfsbuilder $@ tracker.img: tracker/tracker.bin tracker/tracker.sh - @docker run --rm -v $(PWD)/tracker/tracker.sh:/app.sh -v $(PWD)/tracker/tracker-base.sh:/base.sh -v $(PWD)/tracker/tracker.bin:/files/tracker.bin -v $(PWD)/tracker:/opt/code --privileged rootfsbuilder $@ + @docker run --rm \ + -v $(PWD)/tracker/tracker.sh:/app.sh \ + -v $(PWD)/tracker/tracker-base.sh:/base.sh \ + -v $(PWD)/tracker/tracker.bin:/files/tracker.bin \ + -v $(PWD)/tracker:/opt/code \ + --privileged rootfsbuilder $@ tracker/tracker.bin: tracker/cmd/tracker tracker/go.mod @cd tracker ; GOOS=linux GOARCH=amd64 go build -o tracker.bin ./cmd/tracker server.img: server/server.sh server/multiply.nft server/server-base.sh - @docker run --rm -v $(PWD)/server/server.sh:/app.sh -v $(PWD)/server/server-base.sh:/base.sh -v $(PWD)/server/multiply.nft:/files/multiply.nft -v $(PWD)/server:/opt/code --privileged rootfsbuilder $@ \ No newline at end of file + @docker run --rm \ + -v $(PWD)/server/server.sh:/app.sh \ + -v $(PWD)/server/server-base.sh:/base.sh \ + -v $(PWD)/server/multiply.nft:/files/multiply.nft + -v $(PWD)/server:/opt/code \ + --privileged rootfsbuilder $@ \ No newline at end of file diff --git a/client/client-base.sh b/client/client-base.sh index 880b726..ba91c35 100644 --- a/client/client-base.sh +++ b/client/client-base.sh @@ -17,8 +17,4 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - -apk update -apk add -u chrony -echo "refclock PHC /dev/ptp0 poll -2 dpoll -2 offset 0 trust prefer" > /etc/chrony/chrony.conf -apk add python3 curl \ No newline at end of file +apk add python3 curl diff --git a/client/client.sh b/client/client.sh index 6d03898..5f470eb 100644 --- a/client/client.sh +++ b/client/client.sh @@ -18,31 +18,9 @@ # along with this program. If not, see . # -rc-service chronyd start - -IP=$(/sbin/ip route | awk '/default/ { print $3 }') - -echo nameserver "$IP" > /etc/resolv.conf - -chronyc tracking - -chronyc -a makestep - -sleep 10 - -chronyc tracking - -chronyc -a makestep - -chronyc tracking - -sleep 10 - -chronyc tracking - echo "STARTING CLIENT" -NAME=$(curl -s "$IP"/self | python3 -c 'import sys, json; print(json.load(sys.stdin)["name"])') +NAME=$(curl -s info.celestial/self | python3 -c 'import sys, json; print(json.load(sys.stdin)["name"])') echo "$NAME" cd ultra_ping || exit diff --git a/client/ultra_ping/onewaymeasurement.py b/client/ultra_ping/onewaymeasurement.py index d13510b..505b845 100755 --- a/client/ultra_ping/onewaymeasurement.py +++ b/client/ultra_ping/onewaymeasurement.py @@ -6,8 +6,6 @@ from __future__ import division import socket import time -import socket -import time import pickle import typing import http.server @@ -19,13 +17,13 @@ target_address_pipe_in, target_address_pipe_out = mp.Pipe() -class Handler(http.server.BaseHTTPRequestHandler): +class Handler(http.server.BaseHTTPRequestHandler): def do_POST(self) -> None: form = cgi.FieldStorage( fp=self.rfile, - headers=self.headers, # type: ignore - environ={"REQUEST_METHOD": "POST"} + headers=self.headers, # type: ignore + environ={"REQUEST_METHOD": "POST"}, ) s = form.getvalue("server") @@ -36,8 +34,8 @@ def do_POST(self) -> None: self.end_headers() self.wfile.write(b"OK\n") -class OneWayMeasurement(): +class OneWayMeasurement: description = """Measure one-way UDP packet latency time. On your server host, run: $ ./quack2.py --server @@ -56,7 +54,10 @@ def update_target(self, target_address_pipe: MultiprocessingConnection) -> None: while True: target_address = target_address_pipe.recv() if self.target_port is not None: - print("Updating target address to %s:%d" % (target_address, self.target_port)) + print( + "Updating target address to %s:%d" + % (target_address, self.target_port) + ) if self.target_address != target_address: self.target_address = None @@ -72,12 +73,12 @@ def send_packets(self, id: int, n_packets: int) -> None: send_rate_kbytes_per_s. """ - #send_rate_bytes_per_s = send_rate_kbytes_per_s * 1000 + # send_rate_bytes_per_s = send_rate_kbytes_per_s * 1000 n_bytes = 0 - #packet_rate = send_rate_bytes_per_s / packet_len - #packet_interval = 1 / packet_rate + # packet_rate = send_rate_bytes_per_s / packet_len + # packet_interval = 1 / packet_rate - #print("Sending %d %d-byte packets at about %d kB/s..." %(n_packets, packet_len, send_rate_kbytes_per_s)) + # print("Sending %d %d-byte packets at about %d kB/s..." %(n_packets, packet_len, send_rate_kbytes_per_s)) print("Waiting for a target address...") @@ -86,12 +87,10 @@ def send_packets(self, id: int, n_packets: int) -> None: print("Got a target address...") - send_start_seconds = time.time() - #inter_packet_sleep_times_ms = [] + # inter_packet_sleep_times_ms = [] for packet_n in range(n_packets): - while self.target_address == None: pass @@ -115,8 +114,10 @@ def send_packets(self, id: int, n_packets: int) -> None: # I don't know why, but this still doesn't yield exactly the desired # send rate. But eh, it's good enough. tx_time_seconds = tx_end_seconds - tx_start_seconds - sleep_time_seconds = self.workload_deltas[packet_n % self.workload_length] - tx_time_seconds - #inter_packet_sleep_times_ms.append("%.3f" % (sleep_time_seconds * 1000)) + sleep_time_seconds = ( + self.workload_deltas[packet_n % self.workload_length] - tx_time_seconds + ) + # inter_packet_sleep_times_ms.append("%.3f" % (sleep_time_seconds * 1000)) if sleep_time_seconds > 0: time.sleep(sleep_time_seconds) send_end_seconds = time.time() @@ -125,30 +126,53 @@ def send_packets(self, id: int, n_packets: int) -> None: total_send_duration_seconds = send_end_seconds - send_start_seconds bytes_per_second = n_bytes / total_send_duration_seconds - print("(Actually sent packets at %d kB/s: %d bytes for %.1f seconds)" % (bytes_per_second / 1e3, n_bytes, total_send_duration_seconds)) + print( + "(Actually sent packets at %d kB/s: %d bytes for %.1f seconds)" + % (bytes_per_second / 1e3, n_bytes, total_send_duration_seconds) + ) self.sock_out.close() @staticmethod - def save_packet_latencies(packetn_latency_tuples: typing.Tuple[typing.List[int],typing.List[int],typing.List[int],typing.List[float],typing.List[float],typing.List[float]], n_packets_expected: int, output_filename: str) -> None: + def save_packet_latencies( + packetn_latency_tuples: typing.Tuple[ + typing.List[int], + typing.List[int], + typing.List[int], + typing.List[float], + typing.List[float], + typing.List[float], + ], + n_packets_expected: int, + output_filename: str, + ) -> None: """ Save latencies of received packets to a file, along with the total number of packets send in the first place. """ with open(output_filename, "w") as out_file: - #out_file.write("%d\n" % n_packets_expected) + # out_file.write("%d\n" % n_packets_expected) out_file.write("id,packet_n,packet_len,latency,send_time,recv_time\n") for i in range(len(packetn_latency_tuples[0])): id = packetn_latency_tuples[0][i] packet_n = packetn_latency_tuples[1][i] packet_len = packetn_latency_tuples[2][i] latency = packetn_latency_tuples[3][i] - send_time = (packetn_latency_tuples[4][i] * 1e9) - recv_time = (packetn_latency_tuples[5][i] * 1e9) - out_file.write("%d,%d,%d,%.2f,%.0f,%.0f\n" % (id, packet_n, packet_len,latency, send_time, recv_time)) - - def run_client(self, id: int, listen_port: int, http_port: int, n_packets: int, workload_file: str) -> None: - + send_time = packetn_latency_tuples[4][i] * 1e9 + recv_time = packetn_latency_tuples[5][i] * 1e9 + out_file.write( + "%d,%d,%d,%.2f,%.0f,%.0f\n" + % (id, packet_n, packet_len, latency, send_time, recv_time) + ) + + def run_client( + self, + id: int, + listen_port: int, + http_port: int, + n_packets: int, + workload_file: str, + ) -> None: total_packet_len = 0 total_workload_duration = 0.0 @@ -186,7 +210,9 @@ def run_client(self, id: int, listen_port: int, http_port: int, n_packets: int, print("Started HTTP server on :%d" % (http_port)) - controlThread = td.Thread(target=self.update_target, args=[target_address_pipe_out]) + controlThread = td.Thread( + target=self.update_target, args=[target_address_pipe_out] + ) controlThread.start() print("Started control thread...") @@ -208,14 +234,19 @@ def get_packet_payload(self, id: int, packet_n: int) -> bytes: payload = pickle.dumps((id, packet_n, send_time_seconds)) return payload - def run_server(self, n_packets_expected: int, server_listen_port: int, payload_len: int, timeout: int=15) -> None: + def run_server( + self, + n_packets_expected: int, + server_listen_port: int, + payload_len: int, + timeout: int = 15, + ) -> None: """ Receive packets sent from the client. Calculate the latency for each packet by comparing the counter value from the packet (the counter value at time of transmission) to the current counter value. """ - sock_in = \ - socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + sock_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock_in.bind(("0.0.0.0", server_listen_port)) print("UDP server running...") @@ -242,13 +273,13 @@ def run_server(self, n_packets_expected: int, server_listen_port: int, payload_l payload = data.rstrip(a) (ids[packet_c], packet_ns[packet_c], send_time) = pickle.loads(payload) latency_mss[packet_c] = (recv_time - send_time) * 1e3 - #packets[packet_c] = (id, packet_n, packet_len, latency_ms, send_time, recv_time) - send_times[packet_c] = send_time - recv_times[packet_c] = recv_time + # packets[packet_c] = (id, packet_n, packet_len, latency_ms, send_time, recv_time) + send_times[packet_c] = send_time + recv_times[packet_c] = recv_time packet_c += 1 - #if packet_c % 2000 == 0: + # if packet_c % 2000 == 0: # print("%d packets received so far" % packet_c) except socket.timeout: @@ -261,4 +292,15 @@ def run_server(self, n_packets_expected: int, server_listen_port: int, payload_l print("Received %d packets" % packet_c) - self.save_packet_latencies((ids[:packet_c], packet_ns[:packet_c], packet_lens[:packet_c], latency_mss[:packet_c], send_times[:packet_c], recv_times[:packet_c]), n_packets_expected, self.test_output_filename) + self.save_packet_latencies( + ( + ids[:packet_c], + packet_ns[:packet_c], + packet_lens[:packet_c], + latency_mss[:packet_c], + send_times[:packet_c], + recv_times[:packet_c], + ), + n_packets_expected, + self.test_output_filename, + ) diff --git a/client/ultra_ping/quack.py b/client/ultra_ping/quack.py index 762958a..0afec5a 100755 --- a/client/ultra_ping/quack.py +++ b/client/ultra_ping/quack.py @@ -13,6 +13,7 @@ SERVER_RECV_BUFFER_SIZE = 2048 + def start(Measurement: typing.Type[OneWayMeasurement]) -> None: """ Process arguments and run the appropriate functions depending on whether @@ -22,15 +23,25 @@ def start(Measurement: typing.Type[OneWayMeasurement]) -> None: args = parse_args(Measurement.description) if args.payload_len > SERVER_RECV_BUFFER_SIZE: - print("Warning: payload_len (%d) is greater than " - "SERVER_RECV_BUFFER_SIZE (%d)" % (args.payload_len, - SERVER_RECV_BUFFER_SIZE)) + print( + "Warning: payload_len (%d) is greater than " + "SERVER_RECV_BUFFER_SIZE (%d)" % (args.payload_len, SERVER_RECV_BUFFER_SIZE) + ) tester = Measurement(args.output_filename) if args.server: - tester.run_server(args.n_packets, args.listen_port, SERVER_RECV_BUFFER_SIZE, args.timeout) + tester.run_server( + args.n_packets, args.listen_port, SERVER_RECV_BUFFER_SIZE, args.timeout + ) elif args.client: - tester.run_client(args.id, args.listen_port, args.http_port, args.n_packets, args.workload_file) + tester.run_client( + args.id, + args.listen_port, + args.http_port, + args.n_packets, + args.workload_file, + ) + def parse_args(description: str) -> argparse.Namespace: """ @@ -38,17 +49,17 @@ def parse_args(description: str) -> argparse.Namespace: """ parser = argparse.ArgumentParser( - description=description, formatter_class=argparse.RawTextHelpFormatter) + description=description, formatter_class=argparse.RawTextHelpFormatter + ) group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('--server', action='store_true') - group.add_argument('--client', action='store_true' ) + group.add_argument("--server", action="store_true") + group.add_argument("--client", action="store_true") parser.add_argument("--n_packets", type=int, default=700000) parser.add_argument("--payload_len", type=int, default=1227) parser.add_argument("--send_rate_kBps", type=int, default=1400) parser.add_argument("--timeout", type=int, default=15) - parser.add_argument("--id", type=int, default=random.randint(0,100)) - parser.add_argument( - "--output_filename", default='udp_packetn_latency_pairs') + parser.add_argument("--id", type=int, default=random.randint(0, 100)) + parser.add_argument("--output_filename", default="udp_packetn_latency_pairs") parser.add_argument("--listen_port", type=int, default=8888) parser.add_argument("--http_port", type=int, default=8000) parser.add_argument("--workload_file", type=str, default="./workload.csv") @@ -56,4 +67,4 @@ def parse_args(description: str) -> argparse.Namespace: return args -start(OneWayMeasurement) \ No newline at end of file +start(OneWayMeasurement) diff --git a/server/server.sh b/server/server.sh index 6a7be70..0e7baab 100644 --- a/server/server.sh +++ b/server/server.sh @@ -19,9 +19,7 @@ # -GATEWAY_IP=$(/sbin/ip route | awk '/default/ { print $3 }') MY_IP=$(/sbin/ip route | sed -n '2 p' | awk '{print $9}') -echo nameserver "$GATEWAY_IP" > /etc/resolv.conf sed -i -e "s/%%%HOST%%%/$MY_IP/g" multiply.nft @@ -39,4 +37,4 @@ sleep 10 while true ; do sleep 10 -done \ No newline at end of file +done diff --git a/tracker/alt-tracker.sh b/tracker/alt-tracker.sh index 540d8c1..704cc19 100644 --- a/tracker/alt-tracker.sh +++ b/tracker/alt-tracker.sh @@ -1,28 +1,4 @@ #!/bin/sh -rc-service chronyd start - -IP=$(/sbin/ip route | awk '/default/ { print $3 }') - -echo nameserver "$IP" > /etc/resolv.conf - -chronyc tracking - -chronyc -a makestep - -sleep 10 - -chronyc tracking - -chronyc -a makestep - -chronyc tracking - -sleep 10 - -chronyc tracking - -sleep 10 - echo "STARTING ALT TRACKER" -/tracker.bin --update-interval=5 --gateway="$IP" --alt \ No newline at end of file +/tracker.bin --update-interval=5 --gateway="info.celestial" --alt diff --git a/tracker/cmd/tracker/tracker.go b/tracker/cmd/tracker/tracker.go index df0b3ce..413fe9f 100644 --- a/tracker/cmd/tracker/tracker.go +++ b/tracker/cmd/tracker/tracker.go @@ -418,17 +418,17 @@ func main() { clients = map[string]client{ "1": { - addr: "10.255.0.6", + addr: "10.0.0.6", udp: 3000, http: 8000, }, "2": { - addr: "10.255.0.10", + addr: "10.0.0.10", udp: 3000, http: 8000, }, "3": { - addr: "10.255.0.14", + addr: "10.0.0.14", udp: 3000, http: 8000, }, diff --git a/tracker/tracker-base.sh b/tracker/tracker-base.sh index 00d05e4..1a24852 100644 --- a/tracker/tracker-base.sh +++ b/tracker/tracker-base.sh @@ -1,5 +1 @@ #!/bin/sh - -apk update -apk add -u chrony -echo "refclock PHC /dev/ptp0 poll -2 dpoll -2 offset 0 trust prefer" > /etc/chrony/chrony.conf \ No newline at end of file diff --git a/tracker/tracker.sh b/tracker/tracker.sh index 1277d9f..87c132b 100644 --- a/tracker/tracker.sh +++ b/tracker/tracker.sh @@ -1,28 +1,4 @@ #!/bin/sh -rc-service chronyd start - -IP=$(/sbin/ip route | awk '/default/ { print $3 }') - -echo nameserver "$IP" > /etc/resolv.conf - -chronyc tracking - -chronyc -a makestep - -sleep 10 - -chronyc tracking - -chronyc -a makestep - -chronyc tracking - -sleep 10 - -chronyc tracking - -sleep 10 - echo "STARTING TRACKER" -/tracker.bin --update-interval=5 --gateway="$IP" \ No newline at end of file +/tracker.bin --update-interval=5 --gateway="info.celestial" diff --git a/videoconference-cloud.toml b/videoconference-cloud.toml index ba6203e..7823b42 100644 --- a/videoconference-cloud.toml +++ b/videoconference-cloud.toml @@ -1,15 +1,7 @@ -model = "SGP4" - bbox = [-6.8596, -11.0020, 19.7872, 22.2767] -interval = 5 -animation = false -hosts = ["192.168.0.11:1969", "192.168.0.12:1969", "192.168.0.13:1969", "192.168.0.14:1969"] -peeringhosts = ["192.168.0.11:1970", "192.168.0.12:1970", "192.168.0.13:1970", "192.168.0.14:1970"] -database = true -dbhost = "192.168.0.10:8000" -[sgp4params] -starttime = 2021-05-01T12:00:00+00:00 +resolution = 5 +duration = 600 [networkparams] islpropagation = 3.336e-6 @@ -137,4 +129,4 @@ vcpu_count = 4 mem_size_mib = 4096 kernel = "server-linux.bin" rootfs = "server.img" -bootparams = "" \ No newline at end of file +bootparams = "" diff --git a/videoconference-satellite.toml b/videoconference-satellite.toml index 95747b8..13891c6 100644 --- a/videoconference-satellite.toml +++ b/videoconference-satellite.toml @@ -1,12 +1,7 @@ -model = "SGP4" - bbox = [-6.8596, -11.0020, 19.7872, 22.2767] -interval = 5 -animation = false -hosts = ["192.168.0.11:1969", "192.168.0.12:1969", "192.168.0.13:1969", "192.168.0.14:1969"] -peeringhosts = ["192.168.0.11:1970", "192.168.0.12:1970", "192.168.0.13:1970", "192.168.0.14:1970"] -database = true -dbhost = "192.168.0.10:8000" + +resolution = 5 +duration = 600 [sgp4params] starttime = 2021-05-01T12:00:00+00:00 @@ -124,4 +119,4 @@ kernel = "client-linux.bin" rootfs = "client.img" disk_size_mib = 500 bootparams = "" -hostaffinity = [2] \ No newline at end of file +hostaffinity = [2]