From b9a57aa2e868190829a6dadfac2dbe7273722d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Eng=C3=A9libert?= Date: Wed, 4 Feb 2026 10:31:50 +0100 Subject: [PATCH 1/2] plot titles --- .gitignore | 2 +- exp.py | 50 +++++++++++++++++++++++++------------------------- plots.py | 49 ++++++++++++++++++++++++++++--------------------- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 736ffad..cdc0cb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -netreplay +netreplay* powercap __pycache__ rpxy_* diff --git a/exp.py b/exp.py index c7aab73..b75935a 100644 --- a/exp.py +++ b/exp.py @@ -35,16 +35,16 @@ CONFIGS = { "local": { "experiments": [ "impl-cipher-ver", - "impl-cert-ver", - "impl-kex-ver", + #"impl-cert-ver", + #"impl-kex-ver", ], "setups": [ - "none-local", + #"none-local", "client-local", - "server-local", + #"server-local", ], "records": [ - { "filename": "youtube", "repeat": 1 }, + { "filename": "wikipedia", "repeat": 50 }, ], "repodir": "/home/tuxmain/reps/tlsbench", "expdir": "/dev/shm/exp", @@ -53,7 +53,7 @@ CONFIGS = { "p2_addr": "127.0.0.1", "p2_repodir": "/home/tuxmain/reps/tlsbench", "wattmeter": False, - "perf": True, + "perf": False, "rapl": False, "perf_dir": "/home/tuxmain/.cache/exp", "p3_suffix": ".localhost", @@ -64,17 +64,17 @@ CONFIGS = { "pi3": { "experiments": [ "impl-cipher-ver", - "impl-cert-ver", - "impl-kex-ver", - "zrtt" + #"impl-cert-ver", + #"impl-kex-ver", + #"zrtt" ], "setups": [ - "none", + #"none", "client", - "server", + #"server", ], "records": [ - { "filename": "wikipedia", "repeat": 400 }, + { "filename": "wikipedia", "repeat": 10 }, ], "repodir": "/home/tuxmain/reps/tlsbench", "expdir": "/dev/shm/exp", @@ -333,11 +333,11 @@ CERT_SIGN_ALGS = [ ] IMPLS = [ "aws_lc", # Amazon's Rust crypto widely used in Rust stuff - "boring", # Google's fork of OpenSSL used in Chrome and Android - "graviola", # New crypto in Rust - "openssl", # widely used - "ring", # used in most Rust stuff - "symcrypt", # Microsoft's crypto + #"boring", # Google's fork of OpenSSL used in Chrome and Android + #"graviola", # New crypto in Rust + #"openssl", # widely used + #"ring", # used in most Rust stuff + #"symcrypt", # Microsoft's crypto #"wolfcrypt" # used in embedded (won't build with rpxy for now) ] # Symmetric ciphers @@ -369,12 +369,12 @@ EXPERIMENTS = { "impl-cipher-ver": { "impls": IMPLS, "ciphers": [ - "AES_128_GCM_SHA256", - "AES_256_GCM_SHA384", - "CHACHA20_POLY1305_SHA256", + #"AES_128_GCM_SHA256", + #"AES_256_GCM_SHA384", + #"CHACHA20_POLY1305_SHA256", "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384", - "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + #"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384", + #"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", ], "kexes": ["X25519"], "cert": ["prime256v1"], @@ -384,7 +384,7 @@ EXPERIMENTS = { "impl-cert-ver": { "impls": IMPLS, "ciphers": [ - "AES_128_GCM_SHA256", + #"AES_128_GCM_SHA256", "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256", ], "kexes": ["X25519"], @@ -690,10 +690,10 @@ def make_rpxy_config(outdir, domains, cryptodir, config_name, p3_suffix, p3_port f.close() def make_everything(expdir, domains, make_ca, config_only, p3_suffix, p3_port_plain, p3_port_tls): + if expdir[-1] != "/": + expdir += "/" if not config_only: os.makedirs(expdir, exist_ok=True) - if expdir[-1] != "/": - expdir += "/" for alg in CERT_SIGN_ALGS: algdir = expdir+"certs/"+alg os.makedirs(algdir, exist_ok=True) diff --git a/plots.py b/plots.py index 732d8cf..05f39a7 100644 --- a/plots.py +++ b/plots.py @@ -77,6 +77,9 @@ def gnuplot_histogram(**kwargs): kwargs["machine"] = ", " + kwargs["machine"] else: kwargs["machine"] = "" + titleline = "" + if kwargs["maketitle"]: + titleline = 'set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})"'.format(**kwargs) cluster = "" for i in range(kwargs["nb_impls"]-1): cluster += """, "" using {}:xticlabels(1) title col""".format(i+4) @@ -88,7 +91,7 @@ set boxwidth 0.9 absolute set style fill solid 1.0 border lt -1 set style histogram clustered gap 1 title textcolor lt -1 set style data histograms -set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})" +{titleline} #set xtics border in scale 0,0 nomirror rotate by -45 autojustify set xtics border in scale 0,0 nomirror autojustify #set key fixed right top vertical Right noreverse noenhanced autotitle nobox @@ -103,7 +106,7 @@ plot \ set term cairolatex pdf set output "{plots_dir}/{object}_by_{criterion}_{side}_{record}.tex" replot -""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs)) +""".format(plots_dir=PLOTS_DIR, cluster=cluster, titleline=titleline, **kwargs)) f.close() os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs)) @@ -112,6 +115,8 @@ def gnuplot_stacked_histogram(**kwargs): kwargs["machine"] = ", " + kwargs["machine"] else: kwargs["machine"] = "" + if kwargs["maketitle"]: + titleline = 'set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})"'.format(**kwargs) cluster = "" #for i in range(kwargs["nb_impls"]-1): # cluster += """, "" using {}:xticlabels(1) title col""".format(i+4) @@ -123,7 +128,7 @@ set boxwidth 0.9 absolute set style fill solid 1.0 border lt -1 set style histogram rowstacked set style data histograms -set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})" +{titleline} set xtics border in scale 0,0 nomirror noenhanced rotate by 30 right set lmargin 9 set rmargin 1 @@ -140,11 +145,11 @@ set term pict2e font ",10" set output "{plots_dir}/{object}_by_{criterion}_{side}_{record}.tex" set key font ",10" spacing 0.8 replot -""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs).replace("aws_lc", "aws-lc")) +""".format(plots_dir=PLOTS_DIR, cluster=cluster, titleline=titleline, **kwargs).replace("aws_lc", "aws-lc")) f.close() os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs)) -def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version=None): +def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version=None, maketitle=True): f = open(f"/dev/shm/plots/{obj}_by_{criterion}_{side}_{record}.dat", "w") ciphers = {} impls = [] @@ -208,10 +213,11 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version unit=UNIT[obj], nb_impls=len(impls), record=record, - machine=machine + machine=machine, + maketitle=maketitle ) -def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, machine=None): +def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, machine=None, maketitle=False): f = open(f"/dev/shm/plots/profile_by_{criterion}_{side}_{record}.dat", "w") runs = [] functions = [] @@ -264,7 +270,8 @@ def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, m unit=UNIT["profile"], record=record, nb_functions=len(functions)+1, - machine=machine + machine=machine, + maketitle=maketitle ) # Are CPU and energy proportional @@ -384,27 +391,27 @@ if __name__ == "__main__": os.makedirs("/dev/shm/plots", exist_ok=True) no_flamegraph = "-f" in sys.argv - machine = getargv("-m", None) + maketitle = "-t" not in sys.argv if cmd == "log": - cmp_versions(logs, ["impl-cipher-ver", "impl-cert-ver", "impl-kex-ver"], ["side", "cipher", "cert", "kex", "record"], ["cpu", "energy"]) for side in ["client", "server"]: for record in records: - make_log_plot(logs, "impl-cipher-ver", "cipher", side, "cpu", record, machine=machine, version="1.3") - make_log_plot(logs, "impl-cipher-ver", "cipher", side, "energy", record, machine=machine, version="1.3") - make_log_plot(logs, "impl-cert-ver", "cert", side, "cpu", record, machine=machine, version="1.3") - make_log_plot(logs, "impl-cert-ver", "cert", side, "energy", record, machine=machine, version="1.3") - make_log_plot(logs, "impl-kex-ver", "kex", side, "cpu", record, machine=machine, version="1.3") - make_log_plot(logs, "impl-kex-ver", "kex", side, "energy", record, machine=machine, version="1.3") - make_log_plot(logs, "zrtt", "ed", side, "cpu", record, machine=machine, version="1.3") - make_log_plot(logs, "zrtt", "ed", side, "energy", record, machine=machine, version="1.3") + make_log_plot(logs, "impl-cipher-ver", "cipher", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "impl-cipher-ver", "cipher", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "impl-cert-ver", "cert", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "impl-cert-ver", "cert", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "impl-kex-ver", "kex", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "impl-kex-ver", "kex", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "zrtt", "ed", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) + make_log_plot(logs, "zrtt", "ed", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) + cmp_versions(logs, ["impl-cipher-ver", "impl-cert-ver", "impl-kex-ver"], ["side", "cipher", "cert", "kex", "record"], ["cpu", "energy"]) elif cmd == "prof": for side in ["client-local", "server-local"]: for record in records: - make_profile_plot(logs, "impl-cipher-ver", "cipher", side, record, no_flamegraph=no_flamegraph, machine=machine) - make_profile_plot(logs, "impl-cert-ver", "cert", side, record, no_flamegraph=no_flamegraph, machine=machine) - make_profile_plot(logs, "impl-kex-ver", "kex", side, record, no_flamegraph=no_flamegraph, machine=machine) + make_profile_plot(logs, "impl-cipher-ver", "cipher", side, record, no_flamegraph=no_flamegraph, machine=machine, maketitle=maketitle) + make_profile_plot(logs, "impl-cert-ver", "cert", side, record, no_flamegraph=no_flamegraph, machine=machine, maketitle=maketitle) + make_profile_plot(logs, "impl-kex-ver", "kex", side, record, no_flamegraph=no_flamegraph, machine=machine, maketitle=maketitle) elif cmd == "correl": from scipy import stats import matplotlib.pyplot as plt From 5d4d3e86720dfb5318bfc5480d7cbea6c185f673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Eng=C3=A9libert?= Date: Fri, 6 Feb 2026 17:27:56 +0100 Subject: [PATCH 2/2] Remove rpxy --- README.md | 12 +- exp.py | 805 ++++++++++++++++++++++++------------------------------ plots.py | 22 +- 3 files changed, 381 insertions(+), 458 deletions(-) diff --git a/README.md b/README.md index b27afe7..b19bbf6 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,9 @@ sudo make install ### Record -Authorize rpxy and netreplay to bind to ports 80 and 443: +#### Installation + +Authorize netreplay to bind to ports 80 and 443: ```bash sudo setcap CAP_NET_BIND_SERVICE=+eip netreplay ``` @@ -217,11 +219,7 @@ firefox -P tlsbench In settings, disable DNS security. -In `about:config`, set: -* `devtools.chrome.enabled` to `true` -* `network.dns.forceResolve` to `127.0.0.1` - -In the `about:config` tab, open the console, execute this script to override DNS for the selected names, and redirect them to localhost: +In `about:config`, set `network.dns.forceResolve` to `127.0.0.1`. Run the shell commands: @@ -232,6 +230,8 @@ python exp.py update-certs debug In Firefox, go to security settings, Certificates, import `/dev/shm/exp/certs/prime256v1/ca.crt` and trust it for identifying websites. +#### After installation + Stop anything running on ports 80 or 443. Start the record proxy: diff --git a/exp.py b/exp.py index b75935a..5b3d66a 100644 --- a/exp.py +++ b/exp.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -import os, sys, subprocess +import os, sys, subprocess, socket CONFIGS = { "debug": { @@ -9,88 +9,98 @@ CONFIGS = { "impl-kex-ver", "zrtt", ], - "setups": [ - "none-local", - "client-local", - "server-local", + "sides": [ + "client", + "server", + ], + "tls": [ + False, + True, ], "records": [ { "filename": "youtube", "repeat": 1 }, ], - "repodir": "/home/tuxmain/reps/tlsbench", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/tuxmain/reps/tlsbench", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "p2_hostname": "localhost", - "p2_addr": "127.0.0.1", - "p2_repodir": "/home/tuxmain/reps/tlsbench", + "local_addr": "127.0.0.1", + "remote_addr": "127.0.0.1", + "remote_repo_dir": "/home/tuxmain/reps/tlsbench", "wattmeter": False, "perf": False, "rapl": False, "perf_dir": "/home/tuxmain/.cache/exp", - "p3_suffix": ".localhost", - "p3_port_plain": 8080, - "p3_port_tls": 8443, + "listen_port": 8080, + "notify_listen": ("127.0.0.1", 8090), + "notify_addr": "127.0.0.1:8090", }, # i7-4790 local "local": { "experiments": [ "impl-cipher-ver", - #"impl-cert-ver", - #"impl-kex-ver", + "impl-cert-ver", + "impl-kex-ver", + "zrtt", ], - "setups": [ - #"none-local", - "client-local", - #"server-local", + "sides": [ + "client", + "server", + ], + "tls": [ + False, + True, ], "records": [ - { "filename": "wikipedia", "repeat": 50 }, + { "filename": "wikipedia", "repeat": 1 }, ], - "repodir": "/home/tuxmain/reps/tlsbench", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/tuxmain/reps/tlsbench", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "p2_hostname": "localhost", - "p2_addr": "127.0.0.1", - "p2_repodir": "/home/tuxmain/reps/tlsbench", + "local_addr": "127.0.0.1", + "remote_addr": "127.0.0.1", + "remote_repo_dir": "/home/tuxmain/reps/tlsbench", "wattmeter": False, "perf": False, "rapl": False, "perf_dir": "/home/tuxmain/.cache/exp", - "p3_suffix": ".localhost", - "p3_port_plain": 8080, - "p3_port_tls": 8443, + "listen_port": 8080, + "notify_listen": ("127.0.0.1", 8090), + "notify_addr": "127.0.0.1:8090", }, # i7-4790 -> pi3 "pi3": { "experiments": [ - "impl-cipher-ver", - #"impl-cert-ver", + #"impl-cipher-ver", + "impl-cert-ver", #"impl-kex-ver", #"zrtt" ], - "setups": [ - #"none", + "sides": [ "client", #"server", ], - "records": [ - { "filename": "wikipedia", "repeat": 10 }, + "tls": [ + #False, + True, ], - "repodir": "/home/tuxmain/reps/tlsbench", - "expdir": "/dev/shm/exp", + "records": [ + { "filename": "wikipedia", "repeat": 400 }, + ], + "repo_dir": "/home/tuxmain/reps/tlsbench", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "p2_hostname": "p2", - "p2_addr": "192.168.3.14", - "p2_ssh": "exp@p2", - "p2_psw": "exp", - "p2_repodir": "/home/exp/exp", + "local_addr": "192.168.3.1", + "remote_addr": "192.168.3.14", + "remote_ssh": "exp@p2", + "remote_psw": "exp", + "remote_repo_dir": "/home/exp/exp", "wattmeter": True, "perf": False, "rapl": False, - "p3_suffix": "", - "p3_port_plain": 80, - "p3_port_tls": 443, - "idle": "idle - - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 0 -", + "listen_port": 8080, + "idle": "idle - - - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 0 -", + "notify_listen": ("0.0.0.0", 8090), + "notify_addr": "192.168.3.1:8090", }, "pi3-local": { "experiments": [ @@ -98,27 +108,30 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "setups": [ - "none-local", - "client-local", - "server-local", + "sides": [ + "client", + "server", + ], + "tls": [ + False, + True, ], "records": [ { "filename": "wikipedia", "repeat": 5 }, ], - "repodir": "/home/exp/exp", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/exp/exp", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/exp", - "p2_hostname": "localhost", - "p2_addr": "127.0.0.1", - "p2_repodir": "/home/exp/exp", + "local_addr": "127.0.0.1", + "remote_addr": "127.0.0.1", + "remote_repo_dir": "/home/exp/exp", "wattmeter": False, "perf": True, "rapl": False, "perf_dir": "/home/exp/.cache/exp", - "p3_suffix": ".localhost", - "p3_port_plain": 8080, - "p3_port_tls": 8443, + "listen_port": 8080, + "notify_listen": ("127.0.0.1", 8090), + "notify_addr": "127.0.0.1:8090", }, # i7-4790 -> core2 "core2": { @@ -127,30 +140,33 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "setups": [ - "none", + "sides": [ "client", "server", ], + "tls": [ + False, + True, + ], "records": [ { "filename": "wikipedia", "repeat": 400 }, { "filename": "youtube", "repeat": 100 }, ], - "repodir": "/home/tuxmain/reps/tlsbench", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/tuxmain/reps/tlsbench", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "p2_hostname": "192.168.3.3", - "p2_addr": "192.168.3.3", - "p2_ssh": "exp@192.168.3.3", - "p2_psw": None, - "p2_repodir": "/home/exp/exp", + "local_addr": "192.168.3.1", + "remote_addr": "192.168.3.3", + "remote_ssh": "exp@192.168.3.3", + "remote_psw": None, + "remote_repo_dir": "/home/exp/exp", "wattmeter": True, "perf": False, "rapl": False, - "p3_suffix": "", - "p3_port_plain": 80, - "p3_port_tls": 443, - "idle": "idle - - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 0 -", + "listen_port": 8080, + "idle": "idle - - - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 0 -", + "notify_listen": ("0.0.0.0", 8090), + "notify_addr": "192.168.3.1:8090", }, "core2-local": { "experiments": [ @@ -158,27 +174,28 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "setups": [ - "none-local", - "client-local", - "server-local", + "sides": [ + "client", + "server", + ], + "tls": [ + False, + True, ], "records": [ { "filename": "wikipedia", "repeat": 10 }, ], - "repodir": "/home/exp/exp", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/exp/exp", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/exp", - "p2_hostname": "localhost", - "p2_addr": "127.0.0.1", - "p2_repodir": "/home/exp/exp", + "local_addr": "127.0.0.1", + "remote_addr": "127.0.0.1", + "remote_repo_dir": "/home/exp/exp", "wattmeter": False, "perf": True, "rapl": False, "perf_dir": "/home/exp/.cache/exp", - "p3_suffix": ".localhost", - "p3_port_plain": 8080, - "p3_port_tls": 8443, + "listen_port": 8080, }, # i7-4790 -> i5-7300HQ "i5": { @@ -188,29 +205,32 @@ CONFIGS = { "impl-kex-ver", "zrtt", ], - "setups": [ - "none", + "sides": [ "client", "server", ], + "tls": [ + False, + True, + ], "records": [ { "filename": "wikipedia", "repeat": 2000 }, ], - "repodir": "/home/tuxmain/reps/tlsbench", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/tuxmain/reps/tlsbench", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "p2_hostname": "192.168.3.42", - "p2_addr": "192.168.3.42", - "p2_ssh": "exp@192.168.3.42", - "p2_psw": None, - "p2_repodir": "/home/exp/exp", + "local_addr": "192.168.3.1", + "remote_addr": "192.168.3.42", + "remote_ssh": "exp@192.168.3.42", + "remote_psw": None, + "remote_repo_dir": "/home/exp/exp", "wattmeter": True, "perf": False, "rapl": True, - "p3_suffix": "", - "p3_port_plain": 80, - "p3_port_tls": 443, - "idle": "idle - - - - - - - 600.000194311142 0.0 1822 6541 1.3880000000000052 304283035 -", + "listen_port": 8080, + "idle": "idle - - - - - - - - 600.000194311142 0.0 1822 6541 1.3880000000000052 304283035 -", + "notify_listen": ("0.0.0.0", 8090), + "notify_addr": "192.168.3.1:8090", }, "i5-local": { "experiments": [ @@ -218,27 +238,28 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "setups": [ - "none-local", - "client-local", - "server-local", + "sides": [ + "client", + "server", + ], + "tls": [ + False, + True, ], "records": [ { "filename": "wikipedia", "repeat": 100 }, ], - "repodir": "/home/exp/exp", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/exp/exp", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/exp", - "p2_hostname": "localhost", - "p2_addr": "127.0.0.1", - "p2_repodir": "/home/exp/exp", + "local_addr": "127.0.0.1", + "remote_addr": "127.0.0.1", + "remote_repo_dir": "/home/exp/exp", "wattmeter": False, "perf": True, "rapl": False, "perf_dir": "/home/exp/.cache/exp", - "p3_suffix": ".localhost", - "p3_port_plain": 8080, - "p3_port_tls": 8443, + "listen_port": 8080, }, "g5k": { "experiments": [ @@ -247,29 +268,32 @@ CONFIGS = { "impl-kex-ver", "zrtt", ], - "setups": [ - "none", + "sides": [ "client", "server", ], + "tls": [ + False, + True, + ], "records": [ { "filename": "wikipedia", "repeat": 400 }, ], - "repodir": "/home/pengelib/tlsbench", - "expdir": "/dev/shm/exp", + "repo_dir": "/home/pengelib/tlsbench", + "exp_dir": "/dev/shm/exp", "log_backup_dir": "/home/pengelib", - "p2_hostname": "nova-6", - "p2_addr": "172.16.52.6", - "p2_ssh": "pengelib@nova-6", - "p2_psw": None, - "p2_repodir": "/home/pengelib/tlsbench", + "local_addr": "TODO", + "remote_addr": "172.16.52.6", + "remote_ssh": "pengelib@nova-6", + "remote_psw": None, + "remote_repo_dir": "/home/pengelib/tlsbench", "wattmeter": False, "perf": False, "rapl": False, - "p3_suffix": "", - "p3_port_plain": 8080, - "p3_port_tls": 8443, - "idle": "idle - - - - - - - 600.000194311142 0.0 1822 6541 1.3880000000000052 304283035 -",#TODO + "listen_port": 8080, + "idle": "idle - - - - - - - - 600.000194311142 0.0 1822 6541 1.3880000000000052 304283035 -",#TODO + "notify_listen": ("0.0.0.0", 8090), + "notify_addr": "TODO:8090", }, } @@ -277,10 +301,6 @@ CONFIGS = { # This is useful for recording, because some domains may be unknown at that time. # Proxy config ignores them so individual subdomains must be added as well for replaying. DOMAINS_ = [ - # Apple - "apple.com", "www.apple.com", "graffiti-tags.apple.com", "securemetrics.apple.com", - "store.storeimages.cdn-apple.com", - "mzstatic.com", "is1-ssl.mzstatic.com", # Youtube video "youtube.com", "www.youtube.com", "*.ytimg.com", @@ -315,14 +335,10 @@ DOMAINS_ = [ "encrypted-tbn3.gstatic.com", "fonts.googleapis.com", "consent.youtube.com", - # Amazon - "amazon.com", "www.amazon.com", # Wikipedia article - "fr.wikipedia.org", "upload.wikimedia.org", + "en.wikipedia.org", "auth.wikimedia.org", "upload.wikimedia.org", "meta.wikimedia.org", "intake-analytics.wikimedia.org", # Google search "www.google.com", "www.googleadservices.com", "www.gstatic.com", "csp.withgoogle.com", "ogads-pa.clients6.google.com", "play.google.com", "ssl.gstatic.com", "fonts.gstatic.com", "ogs.google.com", - # Peertube video - "videos.domainepublic.net", ] CERT_SIGN_ALGS = [ @@ -332,7 +348,7 @@ CERT_SIGN_ALGS = [ "rsa2048", "rsa3072", "rsa4096", # widely used ] IMPLS = [ - "aws_lc", # Amazon's Rust crypto widely used in Rust stuff + "aws-lc", # Amazon's Rust crypto widely used in Rust stuff #"boring", # Google's fork of OpenSSL used in Chrome and Android #"graviola", # New crypto in Rust #"openssl", # widely used @@ -369,12 +385,12 @@ EXPERIMENTS = { "impl-cipher-ver": { "impls": IMPLS, "ciphers": [ - #"AES_128_GCM_SHA256", - #"AES_256_GCM_SHA384", - #"CHACHA20_POLY1305_SHA256", + "AES_128_GCM_SHA256", + "AES_256_GCM_SHA384", + "CHACHA20_POLY1305_SHA256", "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256", - #"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384", - #"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", ], "kexes": ["X25519"], "cert": ["prime256v1"], @@ -384,7 +400,7 @@ EXPERIMENTS = { "impl-cert-ver": { "impls": IMPLS, "ciphers": [ - #"AES_128_GCM_SHA256", + "AES_128_GCM_SHA256", "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256", ], "kexes": ["X25519"], @@ -444,7 +460,7 @@ def alg_filter(kex, cert, cipher, impl): if "MLKEM" in kex and "WITH" in cipher: # WITH means TLS1.2 return False - if "MLKEM" in kex and impl != "openssl" and impl != "aws_lc" and impl != "graviola": + if "MLKEM" in kex and impl != "openssl" and impl != "aws-lc" and impl != "graviola": return False if kex == "SECP256R1MLKEM768" and impl == "openssl": return False @@ -568,176 +584,54 @@ def make_certs(outdir, domains, alg, make_ca): make_sk(outdir+"all.key", alg) make_cert(outdir+"all.crt", outdir+"all.key", outdir+"ca.crt", outdir+"ca.key", "wikipedia.org", domains) -RPXY_CONFIGS = { - "plain": { - "listen_http": 80, - "listen_https": 443, - "app": """[apps.{app}] -server_name = "{domain}" -tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }} -reverse_proxy = [{{ upstream = [{{ location = "{domain}{p3_suffix}:{p3_port_plain}" }}], set_host = "{domain}"}}] -[apps.{app}_localhost] -server_name = "{domain}.localhost" -tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }} -reverse_proxy = [{{ upstream = [{{ location = "{domain}{p3_suffix}:{p3_port_plain}" }}], set_host = "{domain}"}}] -[apps.{app}_p2] -server_name = "{domain}.p2" -tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }} -reverse_proxy = [{{ upstream = [{{ location = "{domain}{p3_suffix}:{p3_port_plain}" }}], set_host = "{domain}"}}] -""" - }, - "tls": { - "listen_http": 80, - "listen_https": 443, - "app": """[apps.{app}] -server_name = "{domain}" -tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }} -reverse_proxy = [{{ upstream = [{{ location = "{domain}{p3_suffix}:{p3_port_tls}", tls = true }}], set_host = "{domain}"}}] -[apps.{app}_localhost] -server_name = "{domain}.localhost" -tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }} -reverse_proxy = [{{ upstream = [{{ location = "{domain}{p3_suffix}:{p3_port_tls}", tls = true }}], set_host = "{domain}"}}] -[apps.{app}_p2] -server_name = "{domain}.p2" -tls = {{ tls_cert_path = "{cert}", tls_cert_key_path = "{key}", https_redirection = false }} -reverse_proxy = [{{ upstream = [{{ location = "{domain}{p3_suffix}:{p3_port_tls}", tls = true }}], set_host = "{domain}"}}] -""" - }, -} +def make_everything(exp_dir, domains, make_ca): + if exp_dir[-1] != "/": + exp_dir += "/" + os.makedirs(exp_dir, exist_ok=True) + for alg in CERT_SIGN_ALGS: + algdir = exp_dir+"certs/"+alg + os.makedirs(algdir, exist_ok=True) + make_certs(algdir, domains, alg, make_ca) -SETUPS = { - "none": { - "rpxy_config": "plain", - "netreplay_tls_mode": "none", - "p2_port": 80, - "listen_port": 80, - "tls_invariant": True, - }, - "client": { - "rpxy_config": "tls", - "netreplay_tls_mode": "server", - "p2_port": 80, - "listen_port": 443, - "tls_invariant": False, - }, - "server": { - "rpxy_config": "plain", - "netreplay_tls_mode": "client", - "p2_port": 443, - "listen_port": 80, - "tls_invariant": False, - }, - "both": { - "rpxy_config": "tls", - "netreplay_tls_mode": "both", - "p2_port": 443, - "listen_port": 443, - "tls_invariant": False, - }, - "none-local": { - "rpxy_config": "plain", - "netreplay_tls_mode": "none", - "p2_port": 80, - "listen_port": 8080, - "tls_invariant": True, - }, - "client-local": { - "rpxy_config": "tls", - "netreplay_tls_mode": "server", - "p2_port": 80, - "listen_port": 8443, - "tls_invariant": False, - }, - "server-local": { - "rpxy_config": "plain", - "netreplay_tls_mode": "client", - "p2_port": 443, - "listen_port": 8080, - "tls_invariant": False, - }, - "both-local": { - "rpxy_config": "tls", - "netreplay_tls_mode": "both", - "p2_port": 443, - "listen_port": 8443, - "tls_invariant": False, - }, -} +def run_netreplay_server(ssh, exp_dir, repo_dir, record, listen_addr, listen_port, tls, impl, certs_dir, only_record=None, ciphers=None, kexes=None, debug=False): + if exp_dir[-1] != "/": + exp_dir += "/" + repo_dir = repo_dir.removesuffix("/") + env = {"RUST_LOG": "warning", "SSLKEYLOGFILE": "/dev/shm/netreplay.keys.txt"} + if ciphers: + env["CIPHERS"] = ciphers + if kexes: + env["KEXES"] = kexes + cmd = [repo_dir+"/netreplay"+("" if impl == None else ("-"+impl)), repo_dir+"/records/"+record["filename"], "server", str(listen_port), certs_dir] + if debug: + cmd.append("-d") + if tls: + cmd.append("--tls") + cmdline = " ".join(cmd) + print(cmdline) + return ssh_run_bg(ssh, cmdline, env) -def make_rpxy_config(outdir, domains, cryptodir, config_name, p3_suffix, p3_port_plain, p3_port_tls): - if outdir[-1] != "/": - outdir += "/" - if cryptodir[-1] != "/": - cryptodir += "/" - - rpxy_config = RPXY_CONFIGS[config_name] - f = open(outdir+config_name+".toml", "w") - f.write("listen_port = {}\nlisten_port_tls = {}\n".format(rpxy_config["listen_http"], rpxy_config["listen_https"])) - for domain in domains: - if "*" in domain: - continue - app = domain.replace(".", "_") - root = get_domain_root(domain) - f.write(rpxy_config["app"].format( - app=app, - domain=domain, - cert=cryptodir+root+".crt", - key=cryptodir+root+".key", - p3_suffix=p3_suffix, - p3_port_plain=p3_port_plain, - p3_port_tls=p3_port_tls, - )) - f.close() - -def make_everything(expdir, domains, make_ca, config_only, p3_suffix, p3_port_plain, p3_port_tls): - if expdir[-1] != "/": - expdir += "/" - if not config_only: - os.makedirs(expdir, exist_ok=True) - for alg in CERT_SIGN_ALGS: - algdir = expdir+"certs/"+alg - os.makedirs(algdir, exist_ok=True) - make_certs(algdir, domains, alg, make_ca) - # this will be a symbolic link to the chosen certs directory - cryptodir = expdir+"current_certs" - configdir = expdir+"configs/" - os.makedirs(configdir, exist_ok=True) - for config_name in RPXY_CONFIGS: - make_rpxy_config(configdir, domains, cryptodir, config_name, p3_suffix, p3_port_plain, p3_port_tls) - -def choose_cert_alg(expdir, alg): - if expdir[-1] != "/": - expdir += "/" - try: - os.unlink(expdir+"current_certs") - except FileNotFoundError as e: - pass - # WHY is dst pointing to src????? - os.symlink(expdir+"certs/"+alg, expdir+"current_certs", True) - -def choose_impl(expdir, p, impl): - if expdir[-1] != "/": - expdir += "/" - os.symlink(os.getcwd()+"/rpxy_rustls_"+impl, expdir+str(p)+"_rpxy", False) - -def run_netreplay(expdir, repodir, record, p2_addr, p2_port, listen_port, tls_mode, only_record=None, ciphers=None, kexes=None, earlydata="0", debug=False): - if expdir[-1] != "/": - expdir += "/" - repodir = repodir.removesuffix("/") +def run_netreplay_client(ssh, exp_dir, repo_dir, record, remote_addr, remote_port, tls, impl, only_record=None, ciphers=None, kexes=None, earlydata="0", debug=False, notify_addr=None): + if exp_dir[-1] != "/": + exp_dir += "/" + repo_dir = repo_dir.removesuffix("/") env = {"RUST_LOG": "warning", "SSLKEYLOGFILE": "/dev/shm/netreplay.keys.txt", "EARLYDATA": earlydata} if ciphers: env["CIPHERS"] = ciphers if kexes: env["KEXES"] = kexes - cmd = [repodir+"/netreplay", repodir+"/records/"+record["filename"], "play", p2_addr, str(p2_port), str(listen_port), expdir+"current_certs", tls_mode, "-r", str(record["repeat"]), - #"--record", "21" - ] + cmd = [repo_dir+"/netreplay"+("" if impl == None else ("-"+impl)), repo_dir+"/records/"+record["filename"], "client", remote_addr, str(remote_port), "-r", str(record["repeat"])] if debug: cmd.append("-d") + if tls: + cmd.append("--tls") if only_record != None: cmd += ["--record", only_record] - print(" ".join(cmd)) - return subprocess.Popen(cmd, env=env) + if notify_addr != None: + cmd += ["-n", notify_addr] + cmdline = " ".join(cmd) + print(cmdline) + return ssh_run_bg(ssh, cmdline, env) # Run with or without SSH def ssh_run(ssh, cmd, env={}, **kwargs): @@ -779,8 +673,8 @@ def get_net_stat(ssh): bytes_out = int(items[8]) return (bytes_in, bytes_out) -def get_rapl_energy(ssh, repodir): - res = ssh_run(ssh, repodir+"/powercap", hide=True) +def get_rapl_energy(ssh, repo_dir): + res = ssh_run(ssh, repo_dir+"/powercap", hide=True) items = res.split("\n") energy = 0 for item in items: @@ -790,12 +684,12 @@ def get_rapl_energy(ssh, repodir): def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): ssh = None - if "p2_ssh" in config: + if "remote_ssh" in config: ssh = connect_ssh(config) - expdir = config["expdir"] + exp_dir = config["exp_dir"] log_backup_dir = config["log_backup_dir"] - p2_path = config["p2_repodir"] + remote_path = config["remote_repo_dir"] config_name = config["name"] wattmeter = None if config["wattmeter"]: @@ -807,19 +701,21 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): print("No YoctoWatt connected") exit(1) - sh("killall netreplay") + killed = [] for expname in config["experiments"]: exp = EXPERIMENTS[expname] for impl in exp["impls"]: - try: - ssh_run(ssh, f"killall rpxy_rustls_{impl}") - except invoke.exceptions.UnexpectedExit as e: - pass + if impl not in killed: + killed.append(impl) + try: + ssh_run(ssh, f"killall netreplay-{impl}") + except invoke.exceptions.UnexpectedExit as e: + pass timestr = str(int(time.time())) logfile_name = "log-"+timestr - logfile_path = expdir+"/"+logfile_name + logfile_path = exp_dir+"/"+logfile_name logfile = open(logfile_path, "w") - logfile.write("exp impl alg kex cipher ed setup record time cpu bytes_in bytes_out Wh Wh_rapl prof\n") + logfile.write("exp impl alg kex cipher ed side tls record time cpu bytes_in bytes_out Wh Wh_rapl prof\n") logfile.close() perf_dir = "" @@ -830,13 +726,13 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): if idle: print("Measuring idle...") rpxy_cpu = get_cpu_stat(ssh) - p2_bytes_in, p2_bytes_out = get_net_stat(ssh) + remote_bytes_in, remote_bytes_out = get_net_stat(ssh) energy = 0 energy_rapl = 0 if config["wattmeter"]: energy = wattmeter.get_meter() if config["rapl"]: - energy_rapl = get_rapl_energy(ssh, p2_path) + energy_rapl = get_rapl_energy(ssh, remote_path) start = time.time() time.sleep(600) @@ -847,19 +743,19 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): if config["wattmeter"]: new_energy = wattmeter.get_meter() if config["rapl"]: - new_energy_rapl = get_rapl_energy(ssh, p2_path) - new_p2_bytes_in, new_p2_bytes_out = get_net_stat(ssh) + new_energy_rapl = get_rapl_energy(ssh, remote_path) + new_remote_bytes_in, new_remote_bytes_out = get_net_stat(ssh) new_rpxy_cpu = get_cpu_stat(ssh) rpxy_cpu_diff = new_rpxy_cpu - rpxy_cpu - p2_bytes_in_diff = new_p2_bytes_in - p2_bytes_in - p2_bytes_out_diff = new_p2_bytes_out - p2_bytes_out + remote_bytes_in_diff = new_remote_bytes_in - remote_bytes_in + remote_bytes_out_diff = new_remote_bytes_out - remote_bytes_out energy_diff = new_energy - energy energy_rapl_diff = new_energy_rapl - energy_rapl time_diff = end - start while True: try: with open(logfile_path, "a") as logfile: - logfile.write(f"idle - - - - - - - {time_diff} {rpxy_cpu_diff} {p2_bytes_in_diff} {p2_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") + logfile.write(f"idle - - - - - - - - {time_diff} {rpxy_cpu_diff} {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") logfile.close() break except Exception as e: @@ -877,136 +773,174 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): time.sleep(1) sh(f"cp {logfile_path} {log_backup_dir}/{logfile_name}") + notify_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + notify_socket.bind(config["notify_listen"]) + notify_socket.setblocking(True) + run_id = 0 for expname in config["experiments"]: exp = EXPERIMENTS[expname] first_set = True for impl in exp["impls"]: for alg in exp["cert"]: - choose_cert_alg(expdir, alg) - ssh_run(ssh, f"python {p2_path}/exp.py cert {config_name} {alg}") + certs_dir = exp_dir+"/certs/"+alg for kex in exp["kexes"]: for cipher in exp["ciphers"]: for earlydata in exp["earlydata"]: if not alg_filter(kex, alg, cipher, impl): continue - for setup in config["setups"]: - if SETUPS[setup]["tls_invariant"] and not first_set: - continue - setupdir = expdir+"setups/"+setup - for record in config["records"]: - print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} ED={earlydata} {setup}") - p2_rpxy_config = SETUPS[setup]["rpxy_config"] - vars = {"CIPHERS": cipher, "KEXES": kex, "RUST_LOG": "warning", "EARLYDATA": earlydata} - cmd = f"{p2_path}/rpxy_rustls_{impl} --config {expdir}/configs/{p2_rpxy_config}.toml --log-dir /dev/shm" - #cmd = f"{p2_path}/rpxy_rustls_{impl} --config {expdir}/configs/{p2_rpxy_config}.toml" - ssh_run_bg(ssh, cmd, env=vars) - time.sleep(1) + for tls in config["tls"]: + tls_int = int(tls) + if not tls: + # Without TLS, TLS parameters don't matter so we skip redundant experiments + if first_set: + first_set = False + else: + continue + for side in config["sides"]: + for record in config["records"]: + print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} ED={earlydata} {side} TLS={tls}") + + run_id += 1 - prof_filename = "-" - if config["perf"]: - prof_filename = f"{perf_dir}/perf-{timestr}-{run_id}.data" - rpxy_pid = ssh_run(ssh, f"pidof rpxy_rustls_{impl}").removesuffix("\n") - ssh_run_bg(ssh, f"perf record -F 997 --call-graph dwarf,64000 -g -o {prof_filename} -p {rpxy_pid}") - - run_id += 1 - - rpxy_cpu = get_cpu_stat(ssh) - p2_bytes_in, p2_bytes_out = get_net_stat(ssh) - energy = 0 - energy_rapl = 0 - if config["wattmeter"]: - energy = wattmeter.get_meter() - if config["rapl"]: - energy_rapl = get_rapl_energy(ssh, p2_path) - - start = time.time() - netreplay = run_netreplay( - config["expdir"], - config["repodir"], - record, - config["p2_addr"], - SETUPS[setup]["p2_port"], - SETUPS[setup]["listen_port"], - SETUPS[setup]["netreplay_tls_mode"], - only_record=only_record, - ciphers=cipher, - kexes=kex, - earlydata=earlydata, - debug=debug, - ) - - # TODO detect when netreplay has finished - try: - netreplay.wait() - except KeyboardInterrupt: - netreplay.kill() - try: - ssh_run(ssh, f"killall rpxy_rustls_{impl}") - except invoke.exceptions.UnexpectedExit as e: - pass - try: - ssh_run(ssh, f"killall dtach") - except invoke.exceptions.UnexpectedExit as e: - pass - exit(0) - - #time.sleep(30) - #sh("killall netreplay") - try: - ssh_run(ssh, f"rm /dev/shm/access.log /dev/shm/rpxy.log") - pass - except invoke.exceptions.UnexpectedExit as e: - pass - try: - ssh_run(ssh, f"killall rpxy_rustls_{impl}") - except invoke.exceptions.UnexpectedExit as e: - pass - try: - ssh_run(ssh, f"killall dtach") - except invoke.exceptions.UnexpectedExit as e: - pass - end = time.time() - - new_energy = 0 - new_energy_rapl = 0 - if config["wattmeter"]: - new_energy = wattmeter.get_meter() - if config["rapl"]: - new_energy_rapl = get_rapl_energy(ssh, p2_path) - new_p2_bytes_in, new_p2_bytes_out = get_net_stat(ssh) - new_rpxy_cpu = get_cpu_stat(ssh) - record_filename = record["filename"] - rpxy_cpu_diff = new_rpxy_cpu - rpxy_cpu - p2_bytes_in_diff = new_p2_bytes_in - p2_bytes_in - p2_bytes_out_diff = new_p2_bytes_out - p2_bytes_out - energy_diff = new_energy - energy - energy_rapl_diff = new_energy_rapl - energy_rapl - time_diff = end - start - while True: - try: - with open(logfile_path, "a") as logfile: - logfile.write(f"{expname} {impl} {alg} {kex} {cipher} {earlydata} {setup} {record_filename} {time_diff} {rpxy_cpu_diff} {p2_bytes_in_diff} {p2_bytes_out_diff} {energy_diff} {energy_rapl_diff} {prof_filename}\n") - logfile.close() - break - except Exception as e: - print("Can't open log file:", e) - time.sleep(1) - sh(f"cp {logfile_path} {log_backup_dir}/{logfile_name}") - first_set = False + if side == "client": + netreplay = run_netreplay_server( + None, + config["exp_dir"], + config["repo_dir"], + record, + "0.0.0.0", + config["listen_port"], + tls, + None, + certs_dir, + only_record=only_record, + ciphers=cipher, + kexes=kex, + debug=debug, + ) + netreplay = run_netreplay_client( + ssh, + config["exp_dir"], + config["remote_repo_dir"], + record, + config["local_addr"], + config["listen_port"], + tls, + impl, + only_record=only_record, + ciphers=cipher, + kexes=kex, + earlydata=earlydata, + debug=debug, + notify_addr=config["notify_addr"], + ) + else: + netreplay = run_netreplay_server( + ssh, + config["exp_dir"], + config["remote_repo_dir"], + record, + "0.0.0.0", + config["listen_port"], + tls, + impl, + certs_dir, + only_record=only_record, + ciphers=cipher, + kexes=kex, + debug=debug, + ) + netreplay = run_netreplay_client( + None, + config["exp_dir"], + config["repo_dir"], + record, + config["remote_addr"], + config["listen_port"], + tls, + None, + only_record=only_record, + ciphers=cipher, + kexes=kex, + earlydata=earlydata, + debug=debug, + notify_addr=config["notify_addr"], + ) + + prof_filename = "-" + if config["perf"]: + prof_filename = f"{perf_dir}/perf-{timestr}-{run_id}.data" + process_pid = ssh_run(ssh, "pidof netreplay"+("" if side == "server" else ("-"+impl))).removesuffix("\n") + ssh_run_bg(ssh, f"perf record -F 997 --call-graph dwarf,64000 -g -o {prof_filename} -p {rpxy_pid}") + + # Measure + cpu = get_cpu_stat(ssh) + remote_bytes_in, remote_bytes_out = get_net_stat(ssh) + energy = 0 + energy_rapl = 0 + if config["wattmeter"]: + energy = wattmeter.get_meter() + if config["rapl"]: + energy_rapl = get_rapl_energy(ssh, remote_path) + start = time.time() + + # Wait for the client to terminate + notify_socket.recv(4) + + # Measure + end = time.time() + new_energy = 0 + new_energy_rapl = 0 + if config["wattmeter"]: + new_energy = wattmeter.get_meter() + if config["rapl"]: + new_energy_rapl = get_rapl_energy(ssh, remote_path) + new_remote_bytes_in, new_remote_bytes_out = get_net_stat(ssh) + new_cpu = get_cpu_stat(ssh) + + # Kill server + if side == "client": + try: + ssh_run(None, "killall netreplay") + except invoke.exceptions.UnexpectedExit as e: + pass + else: + try: + ssh_run(ssh, "killall netreplay-"+impl) + except invoke.exceptions.UnexpectedExit as e: + pass + + record_filename = record["filename"] + cpu_diff = new_cpu - cpu + remote_bytes_in_diff = new_remote_bytes_in - remote_bytes_in + remote_bytes_out_diff = new_remote_bytes_out - remote_bytes_out + energy_diff = new_energy - energy + energy_rapl_diff = new_energy_rapl - energy_rapl + time_diff = end - start + while True: + try: + with open(logfile_path, "a") as logfile: + logfile.write(f"{expname} {impl} {alg} {kex} {cipher} {earlydata} {side} {tls_int} {record_filename} {time_diff} {cpu_diff} {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} {prof_filename}\n") + logfile.close() + break + except Exception as e: + print("Can't open log file:", e) + time.sleep(1) + sh(f"cp {logfile_path} {log_backup_dir}/{logfile_name}") if config["wattmeter"]: YAPI.FreeAPI() if shutdown and ssh: - ssh_run(ssh, f"python3 {p2_path}/exp.py --shutdown") + ssh_run(ssh, f"python3 {remote_path}/exp.py --shutdown") def update_certs(config): info = platform.freedesktop_os_release() dist = info.get("ID_LIKE", info["ID"]) - expdir = config["expdir"] + exp_dir = config["exp_dir"] if dist == "debian": for alg in CERT_SIGN_ALGS: sh([ - f"sudo cp {expdir}/certs/{alg}/ca.crt /usr/local/share/ca-certificates/ca-{alg}.crt", + f"sudo cp {exp_dir}/certs/{alg}/ca.crt /usr/local/share/ca-certificates/ca-{alg}.crt", f"sudo chmod 644 /usr/local/share/ca-certificates/ca-{alg}.crt", f"sudo chown root:root /usr/local/share/ca-certificates/ca-{alg}.crt" ]) @@ -1014,7 +948,7 @@ def update_certs(config): elif dist == "arch": for alg in CERT_SIGN_ALGS: sh([ - f"sudo cp {expdir}/certs/{alg}/ca.crt /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt", + f"sudo cp {exp_dir}/certs/{alg}/ca.crt /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt", f"sudo chmod 644 /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt", f"sudo chown root:root /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt" ]) @@ -1035,16 +969,15 @@ def connect_ssh(config): if ssh_passphrase: import getpass connect_kwargs["passphrase"] = getpass.getpass("Enter passphrase for SSH key: ") - if "p2_psw" in config: - connect_kwargs["password"] = config["p2_psw"] - ssh = fabric.Connection(config["p2_ssh"], connect_kwargs=connect_kwargs) + if "remote_psw" in config: + connect_kwargs["password"] = config["remote_psw"] + ssh = fabric.Connection(config["remote_ssh"], connect_kwargs=connect_kwargs) return ssh if __name__ == "__main__": if len(sys.argv) < 2 or sys.argv[1] in ["h", "help", "?", "-h", "-help", "--help", "/?"]: print("""Options: make [-c] [-o] Create everything - cert Select cert signature algorithm send Send configs and certs to p2 update-certs Update system's certs run Run experiment @@ -1054,9 +987,6 @@ Make options: -c Make CA cert (otherwise use already existing one) -o Make only configs (do not make certs) -Cert options: - One of: {sig_algs} - Send options: One of: {configs} @@ -1079,19 +1009,12 @@ Run options: config = CONFIGS[sys.argv[2]] make_ca = "-c" in sys.argv config_only = "-o" in sys.argv - make_everything(config["expdir"], DOMAINS, make_ca, config_only, config["p3_suffix"], config["p3_port_plain"], config["p3_port_tls"]) - elif opt == "cert": - alg = sys.argv[3] - if not alg in CERT_SIGN_ALGS: - print("Error: alg must be in", CERT_SIGN_ALGS) - exit(1) - config = CONFIGS[sys.argv[2]] - choose_cert_alg(config["expdir"], alg) + make_everything(config["exp_dir"], DOMAINS, make_ca) elif opt == "send": config = CONFIGS[sys.argv[2]] import fabric ssh = connect_ssh(config) - upload_dir(ssh, config["expdir"], "/dev/shm") + upload_dir(ssh, config["exp_dir"], "/dev/shm") elif opt == "update-certs": import platform config = CONFIGS[sys.argv[2]] @@ -1108,7 +1031,7 @@ Run options: import time import re - if "p2_ssh" in config: + if "remote_ssh" in config: import invoke import fabric diff --git a/plots.py b/plots.py index 05f39a7..4c6de16 100644 --- a/plots.py +++ b/plots.py @@ -161,14 +161,14 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version idle_val = float(log[COL[obj]]) / float(log["time"]) if log["exp"] != exp or log["record"] != record: continue - if log["setup"] == "none": + if log["side"] == side and log["tls"] == "0": plain_line = "plain {}".format(float(log[COL[obj]]) - idle_val * float(log["time"])) if plain_line == None: return for log in logs: - if log["exp"] == exp and log["record"] == record and log["setup"] == side: + if log["exp"] == exp and log["record"] == record and log["side"] == side: #ver = VER_LABEL[log["cipher"]] #if log[COL[criterion]]+"/"+ver not in ciphers: # ciphers[log[COL[criterion]]+"/"+ver] = {} @@ -397,15 +397,15 @@ if __name__ == "__main__": if cmd == "log": for side in ["client", "server"]: for record in records: - make_log_plot(logs, "impl-cipher-ver", "cipher", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "impl-cipher-ver", "cipher", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "impl-cert-ver", "cert", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "impl-cert-ver", "cert", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "impl-kex-ver", "kex", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "impl-kex-ver", "kex", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "zrtt", "ed", side, "cpu", record, machine=machine, version="1.3", maketitle=maketitle) - make_log_plot(logs, "zrtt", "ed", side, "energy", record, machine=machine, version="1.3", maketitle=maketitle) - cmp_versions(logs, ["impl-cipher-ver", "impl-cert-ver", "impl-kex-ver"], ["side", "cipher", "cert", "kex", "record"], ["cpu", "energy"]) + make_log_plot(logs, "impl-cipher-ver", "cipher", side, "cpu", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "impl-cipher-ver", "cipher", side, "energy", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "impl-cert-ver", "cert", side, "cpu", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "impl-cert-ver", "cert", side, "energy", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "impl-kex-ver", "kex", side, "cpu", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "impl-kex-ver", "kex", side, "energy", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "zrtt", "ed", side, "cpu", record, machine=machine, maketitle=maketitle, version="1.3") + make_log_plot(logs, "zrtt", "ed", side, "energy", record, machine=machine, maketitle=maketitle, version="1.3") + #cmp_versions(logs, ["impl-cipher-ver", "impl-cert-ver", "impl-kex-ver"], ["side", "cipher", "cert", "kex", "record"], ["cpu", "energy"]) elif cmd == "prof": for side in ["client-local", "server-local"]: for record in records: