diff --git a/.gitignore b/.gitignore index cdc0cb4..736ffad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -netreplay* +netreplay powercap __pycache__ rpxy_* diff --git a/README.md b/README.md index b19bbf6..b27afe7 100644 --- a/README.md +++ b/README.md @@ -204,9 +204,7 @@ sudo make install ### Record -#### Installation - -Authorize netreplay to bind to ports 80 and 443: +Authorize rpxy and netreplay to bind to ports 80 and 443: ```bash sudo setcap CAP_NET_BIND_SERVICE=+eip netreplay ``` @@ -219,7 +217,11 @@ firefox -P tlsbench In settings, disable DNS security. -In `about:config`, set `network.dns.forceResolve` to `127.0.0.1`. +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: Run the shell commands: @@ -230,8 +232,6 @@ 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 5b3d66a..c7aab73 100644 --- a/exp.py +++ b/exp.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -import os, sys, subprocess, socket +import os, sys, subprocess CONFIGS = { "debug": { @@ -9,30 +9,27 @@ CONFIGS = { "impl-kex-ver", "zrtt", ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, + "setups": [ + "none-local", + "client-local", + "server-local", ], "records": [ { "filename": "youtube", "repeat": 1 }, ], - "repo_dir": "/home/tuxmain/reps/tlsbench", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/tuxmain/reps/tlsbench", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/tuxmain/reps/tlsbench", + "p2_hostname": "localhost", + "p2_addr": "127.0.0.1", + "p2_repodir": "/home/tuxmain/reps/tlsbench", "wattmeter": False, "perf": False, "rapl": False, "perf_dir": "/home/tuxmain/.cache/exp", - "listen_port": 8080, - "notify_listen": ("127.0.0.1", 8090), - "notify_addr": "127.0.0.1:8090", + "p3_suffix": ".localhost", + "p3_port_plain": 8080, + "p3_port_tls": 8443, }, # i7-4790 local "local": { @@ -40,67 +37,60 @@ CONFIGS = { "impl-cipher-ver", "impl-cert-ver", "impl-kex-ver", - "zrtt", ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, + "setups": [ + "none-local", + "client-local", + "server-local", ], "records": [ - { "filename": "wikipedia", "repeat": 1 }, + { "filename": "youtube", "repeat": 1 }, ], - "repo_dir": "/home/tuxmain/reps/tlsbench", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/tuxmain/reps/tlsbench", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/tuxmain/reps/tlsbench", + "p2_hostname": "localhost", + "p2_addr": "127.0.0.1", + "p2_repodir": "/home/tuxmain/reps/tlsbench", "wattmeter": False, - "perf": False, + "perf": True, "rapl": False, "perf_dir": "/home/tuxmain/.cache/exp", - "listen_port": 8080, - "notify_listen": ("127.0.0.1", 8090), - "notify_addr": "127.0.0.1:8090", + "p3_suffix": ".localhost", + "p3_port_plain": 8080, + "p3_port_tls": 8443, }, # i7-4790 -> pi3 "pi3": { "experiments": [ - #"impl-cipher-ver", + "impl-cipher-ver", "impl-cert-ver", - #"impl-kex-ver", - #"zrtt" + "impl-kex-ver", + "zrtt" ], - "sides": [ + "setups": [ + "none", "client", - #"server", - ], - "tls": [ - #False, - True, + "server", ], "records": [ { "filename": "wikipedia", "repeat": 400 }, ], - "repo_dir": "/home/tuxmain/reps/tlsbench", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/tuxmain/reps/tlsbench", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "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", + "p2_hostname": "p2", + "p2_addr": "192.168.3.14", + "p2_ssh": "exp@p2", + "p2_psw": "exp", + "p2_repodir": "/home/exp/exp", "wattmeter": True, "perf": False, "rapl": False, - "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", + "p3_suffix": "", + "p3_port_plain": 80, + "p3_port_tls": 443, + "idle": "idle - - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 0 -", }, "pi3-local": { "experiments": [ @@ -108,30 +98,27 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, + "setups": [ + "none-local", + "client-local", + "server-local", ], "records": [ { "filename": "wikipedia", "repeat": 5 }, ], - "repo_dir": "/home/exp/exp", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/exp/exp", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/exp", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/exp/exp", + "p2_hostname": "localhost", + "p2_addr": "127.0.0.1", + "p2_repodir": "/home/exp/exp", "wattmeter": False, "perf": True, "rapl": False, "perf_dir": "/home/exp/.cache/exp", - "listen_port": 8080, - "notify_listen": ("127.0.0.1", 8090), - "notify_addr": "127.0.0.1:8090", + "p3_suffix": ".localhost", + "p3_port_plain": 8080, + "p3_port_tls": 8443, }, # i7-4790 -> core2 "core2": { @@ -140,33 +127,30 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "sides": [ + "setups": [ + "none", "client", "server", ], - "tls": [ - False, - True, - ], "records": [ { "filename": "wikipedia", "repeat": 400 }, { "filename": "youtube", "repeat": 100 }, ], - "repo_dir": "/home/tuxmain/reps/tlsbench", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/tuxmain/reps/tlsbench", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "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", + "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", "wattmeter": True, "perf": False, "rapl": False, - "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", + "p3_suffix": "", + "p3_port_plain": 80, + "p3_port_tls": 443, + "idle": "idle - - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 0 -", }, "core2-local": { "experiments": [ @@ -174,28 +158,27 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, + "setups": [ + "none-local", + "client-local", + "server-local", ], "records": [ { "filename": "wikipedia", "repeat": 10 }, ], - "repo_dir": "/home/exp/exp", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/exp/exp", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/exp", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/exp/exp", + "p2_hostname": "localhost", + "p2_addr": "127.0.0.1", + "p2_repodir": "/home/exp/exp", "wattmeter": False, "perf": True, "rapl": False, "perf_dir": "/home/exp/.cache/exp", - "listen_port": 8080, + "p3_suffix": ".localhost", + "p3_port_plain": 8080, + "p3_port_tls": 8443, }, # i7-4790 -> i5-7300HQ "i5": { @@ -205,32 +188,29 @@ CONFIGS = { "impl-kex-ver", "zrtt", ], - "sides": [ + "setups": [ + "none", "client", "server", ], - "tls": [ - False, - True, - ], "records": [ { "filename": "wikipedia", "repeat": 2000 }, ], - "repo_dir": "/home/tuxmain/reps/tlsbench", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/tuxmain/reps/tlsbench", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/tuxmain", - "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", + "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", "wattmeter": True, "perf": False, "rapl": True, - "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", + "p3_suffix": "", + "p3_port_plain": 80, + "p3_port_tls": 443, + "idle": "idle - - - - - - - 600.000194311142 0.0 1822 6541 1.3880000000000052 304283035 -", }, "i5-local": { "experiments": [ @@ -238,28 +218,27 @@ CONFIGS = { "impl-cert-ver", "impl-kex-ver", ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, + "setups": [ + "none-local", + "client-local", + "server-local", ], "records": [ { "filename": "wikipedia", "repeat": 100 }, ], - "repo_dir": "/home/exp/exp", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/exp/exp", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/exp", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/exp/exp", + "p2_hostname": "localhost", + "p2_addr": "127.0.0.1", + "p2_repodir": "/home/exp/exp", "wattmeter": False, "perf": True, "rapl": False, "perf_dir": "/home/exp/.cache/exp", - "listen_port": 8080, + "p3_suffix": ".localhost", + "p3_port_plain": 8080, + "p3_port_tls": 8443, }, "g5k": { "experiments": [ @@ -268,32 +247,29 @@ CONFIGS = { "impl-kex-ver", "zrtt", ], - "sides": [ + "setups": [ + "none", "client", "server", ], - "tls": [ - False, - True, - ], "records": [ { "filename": "wikipedia", "repeat": 400 }, ], - "repo_dir": "/home/pengelib/tlsbench", - "exp_dir": "/dev/shm/exp", + "repodir": "/home/pengelib/tlsbench", + "expdir": "/dev/shm/exp", "log_backup_dir": "/home/pengelib", - "local_addr": "TODO", - "remote_addr": "172.16.52.6", - "remote_ssh": "pengelib@nova-6", - "remote_psw": None, - "remote_repo_dir": "/home/pengelib/tlsbench", + "p2_hostname": "nova-6", + "p2_addr": "172.16.52.6", + "p2_ssh": "pengelib@nova-6", + "p2_psw": None, + "p2_repodir": "/home/pengelib/tlsbench", "wattmeter": False, "perf": False, "rapl": False, - "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", + "p3_suffix": "", + "p3_port_plain": 8080, + "p3_port_tls": 8443, + "idle": "idle - - - - - - - 600.000194311142 0.0 1822 6541 1.3880000000000052 304283035 -",#TODO }, } @@ -301,6 +277,10 @@ 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", @@ -335,10 +315,14 @@ DOMAINS_ = [ "encrypted-tbn3.gstatic.com", "fonts.googleapis.com", "consent.youtube.com", + # Amazon + "amazon.com", "www.amazon.com", # Wikipedia article - "en.wikipedia.org", "auth.wikimedia.org", "upload.wikimedia.org", "meta.wikimedia.org", "intake-analytics.wikimedia.org", + "fr.wikipedia.org", "upload.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 = [ @@ -348,12 +332,12 @@ CERT_SIGN_ALGS = [ "rsa2048", "rsa3072", "rsa4096", # widely used ] 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 + "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 #"wolfcrypt" # used in embedded (won't build with rpxy for now) ] # Symmetric ciphers @@ -460,7 +444,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 @@ -584,54 +568,176 @@ 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) -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) +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 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) +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_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("/") +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 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) + 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("/") env = {"RUST_LOG": "warning", "SSLKEYLOGFILE": "/dev/shm/netreplay.keys.txt", "EARLYDATA": earlydata} if ciphers: env["CIPHERS"] = ciphers if kexes: env["KEXES"] = kexes - cmd = [repo_dir+"/netreplay"+("" if impl == None else ("-"+impl)), repo_dir+"/records/"+record["filename"], "client", remote_addr, str(remote_port), "-r", str(record["repeat"])] + 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" + ] if debug: cmd.append("-d") - if tls: - cmd.append("--tls") if only_record != None: cmd += ["--record", only_record] - if notify_addr != None: - cmd += ["-n", notify_addr] - cmdline = " ".join(cmd) - print(cmdline) - return ssh_run_bg(ssh, cmdline, env) + print(" ".join(cmd)) + return subprocess.Popen(cmd, env=env) # Run with or without SSH def ssh_run(ssh, cmd, env={}, **kwargs): @@ -673,8 +779,8 @@ def get_net_stat(ssh): bytes_out = int(items[8]) return (bytes_in, bytes_out) -def get_rapl_energy(ssh, repo_dir): - res = ssh_run(ssh, repo_dir+"/powercap", hide=True) +def get_rapl_energy(ssh, repodir): + res = ssh_run(ssh, repodir+"/powercap", hide=True) items = res.split("\n") energy = 0 for item in items: @@ -684,12 +790,12 @@ def get_rapl_energy(ssh, repo_dir): def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): ssh = None - if "remote_ssh" in config: + if "p2_ssh" in config: ssh = connect_ssh(config) - exp_dir = config["exp_dir"] + expdir = config["expdir"] log_backup_dir = config["log_backup_dir"] - remote_path = config["remote_repo_dir"] + p2_path = config["p2_repodir"] config_name = config["name"] wattmeter = None if config["wattmeter"]: @@ -701,21 +807,19 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): print("No YoctoWatt connected") exit(1) - killed = [] + sh("killall netreplay") for expname in config["experiments"]: exp = EXPERIMENTS[expname] for impl in exp["impls"]: - if impl not in killed: - killed.append(impl) - try: - ssh_run(ssh, f"killall netreplay-{impl}") - except invoke.exceptions.UnexpectedExit as e: - pass + try: + ssh_run(ssh, f"killall rpxy_rustls_{impl}") + except invoke.exceptions.UnexpectedExit as e: + pass timestr = str(int(time.time())) logfile_name = "log-"+timestr - logfile_path = exp_dir+"/"+logfile_name + logfile_path = expdir+"/"+logfile_name logfile = open(logfile_path, "w") - logfile.write("exp impl alg kex cipher ed side tls record time cpu bytes_in bytes_out Wh Wh_rapl prof\n") + logfile.write("exp impl alg kex cipher ed setup record time cpu bytes_in bytes_out Wh Wh_rapl prof\n") logfile.close() perf_dir = "" @@ -726,13 +830,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) - remote_bytes_in, remote_bytes_out = get_net_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, remote_path) + energy_rapl = get_rapl_energy(ssh, p2_path) start = time.time() time.sleep(600) @@ -743,19 +847,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, remote_path) - new_remote_bytes_in, new_remote_bytes_out = get_net_stat(ssh) + 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) rpxy_cpu_diff = new_rpxy_cpu - rpxy_cpu - remote_bytes_in_diff = new_remote_bytes_in - remote_bytes_in - remote_bytes_out_diff = new_remote_bytes_out - remote_bytes_out + 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"idle - - - - - - - - {time_diff} {rpxy_cpu_diff} {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") + logfile.write(f"idle - - - - - - - {time_diff} {rpxy_cpu_diff} {p2_bytes_in_diff} {p2_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") logfile.close() break except Exception as e: @@ -773,174 +877,136 @@ 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"]: - certs_dir = exp_dir+"/certs/"+alg + choose_cert_alg(expdir, alg) + ssh_run(ssh, f"python {p2_path}/exp.py cert {config_name} {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 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 + 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) - 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}") + 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 config["wattmeter"]: YAPI.FreeAPI() if shutdown and ssh: - ssh_run(ssh, f"python3 {remote_path}/exp.py --shutdown") + ssh_run(ssh, f"python3 {p2_path}/exp.py --shutdown") def update_certs(config): info = platform.freedesktop_os_release() dist = info.get("ID_LIKE", info["ID"]) - exp_dir = config["exp_dir"] + expdir = config["expdir"] if dist == "debian": for alg in CERT_SIGN_ALGS: sh([ - f"sudo cp {exp_dir}/certs/{alg}/ca.crt /usr/local/share/ca-certificates/ca-{alg}.crt", + f"sudo cp {expdir}/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" ]) @@ -948,7 +1014,7 @@ def update_certs(config): elif dist == "arch": for alg in CERT_SIGN_ALGS: sh([ - f"sudo cp {exp_dir}/certs/{alg}/ca.crt /etc/ca-certificates/trust-source/anchors/ca-{alg}.crt", + f"sudo cp {expdir}/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" ]) @@ -969,15 +1035,16 @@ def connect_ssh(config): if ssh_passphrase: import getpass connect_kwargs["passphrase"] = getpass.getpass("Enter passphrase for SSH key: ") - if "remote_psw" in config: - connect_kwargs["password"] = config["remote_psw"] - ssh = fabric.Connection(config["remote_ssh"], connect_kwargs=connect_kwargs) + if "p2_psw" in config: + connect_kwargs["password"] = config["p2_psw"] + ssh = fabric.Connection(config["p2_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 @@ -987,6 +1054,9 @@ 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} @@ -1009,12 +1079,19 @@ Run options: config = CONFIGS[sys.argv[2]] make_ca = "-c" in sys.argv config_only = "-o" in sys.argv - make_everything(config["exp_dir"], DOMAINS, make_ca) + 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) elif opt == "send": config = CONFIGS[sys.argv[2]] import fabric ssh = connect_ssh(config) - upload_dir(ssh, config["exp_dir"], "/dev/shm") + upload_dir(ssh, config["expdir"], "/dev/shm") elif opt == "update-certs": import platform config = CONFIGS[sys.argv[2]] @@ -1031,7 +1108,7 @@ Run options: import time import re - if "remote_ssh" in config: + if "p2_ssh" in config: import invoke import fabric diff --git a/plots.py b/plots.py index 4c6de16..732d8cf 100644 --- a/plots.py +++ b/plots.py @@ -77,9 +77,6 @@ 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) @@ -91,7 +88,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 -{titleline} +set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})" #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 @@ -106,7 +103,7 @@ plot \ set term cairolatex pdf set output "{plots_dir}/{object}_by_{criterion}_{side}_{record}.tex" replot -""".format(plots_dir=PLOTS_DIR, cluster=cluster, titleline=titleline, **kwargs)) +""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs)) f.close() os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs)) @@ -115,8 +112,6 @@ 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) @@ -128,7 +123,7 @@ set boxwidth 0.9 absolute set style fill solid 1.0 border lt -1 set style histogram rowstacked set style data histograms -{titleline} +set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})" set xtics border in scale 0,0 nomirror noenhanced rotate by 30 right set lmargin 9 set rmargin 1 @@ -145,11 +140,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, titleline=titleline, **kwargs).replace("aws_lc", "aws-lc")) +""".format(plots_dir=PLOTS_DIR, cluster=cluster, **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, maketitle=True): +def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version=None): f = open(f"/dev/shm/plots/{obj}_by_{criterion}_{side}_{record}.dat", "w") ciphers = {} impls = [] @@ -161,14 +156,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["side"] == side and log["tls"] == "0": + if log["setup"] == "none": 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["side"] == side: + if log["exp"] == exp and log["record"] == record and log["setup"] == side: #ver = VER_LABEL[log["cipher"]] #if log[COL[criterion]]+"/"+ver not in ciphers: # ciphers[log[COL[criterion]]+"/"+ver] = {} @@ -213,11 +208,10 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version unit=UNIT[obj], nb_impls=len(impls), record=record, - machine=machine, - maketitle=maketitle + machine=machine ) -def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, machine=None, maketitle=False): +def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, machine=None): f = open(f"/dev/shm/plots/profile_by_{criterion}_{side}_{record}.dat", "w") runs = [] functions = [] @@ -270,8 +264,7 @@ 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, - maketitle=maketitle + machine=machine ) # Are CPU and energy proportional @@ -391,27 +384,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, 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"]) + 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") 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, 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) + 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) elif cmd == "correl": from scipy import stats import matplotlib.pyplot as plt