This commit is contained in:
Pascal Engélibert 2026-01-16 16:55:20 +01:00
commit c9dc2a306e
8 changed files with 230 additions and 134 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
netreplay netreplay
__pycache__ __pycache__
rpxy_* rpxy_*
records/

View file

@ -136,6 +136,7 @@ sudo make install
* OpenSSL * OpenSSL
* ML-KEM * ML-KEM
* https://www.semanticscholar.org/paper/Energy-Profiling-and-Comparison-of-TLS-Protocols-Gatram-Reddy/9c061fe57a0008574b85919bc70fc803c6e66f06 * https://www.semanticscholar.org/paper/Energy-Profiling-and-Comparison-of-TLS-Protocols-Gatram-Reddy/9c061fe57a0008574b85919bc70fc803c6e66f06
* Energy Profiling and Comparison of TLS Protocols for Embedded Devices: Experimental Study
* 2024 * 2024
* RaspberryPi * RaspberryPi
* TLS PQ, TLS KEM, TLS * TLS PQ, TLS KEM, TLS
@ -185,6 +186,15 @@ sudo make install
* https://hal.science/hal-04197885/document * https://hal.science/hal-04197885/document
* Empreinte carbone de la transmission de données sur le backbone RENATER * Empreinte carbone de la transmission de données sur le backbone RENATER
* 2021 * 2021
* https://ieeexplore.ieee.org/document/10971851/
* Optimizing TLS/SSL for IoT Devices: Performance Enhancements and Security Considerations
* 2024
* https://ieeexplore.ieee.org/document/10060762/
* Performance Evaluation of Quantum-Resistant TLS for Consumer IoT Devices
* 2023
*
* Evaluating the Energy Profile of Tasks Managed by Build Automation Tools in Continuous Integration Workflows: The Case of Apache Maven and Gradle
* 2025
## Sources ## Sources
@ -207,29 +217,21 @@ firefox -P tlsbench
In settings, disable DNS security. In settings, disable DNS security.
In `about:config`, set `devtools.chrome.enabled` to `true`. 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 the `about:config` tab, open the console, execute this script to override DNS for the selected names, and redirect them to localhost:
```js Run the shell commands:
const gOverride = Cc["@mozilla.org/network/native-dns-override;1"].getService(Ci.nsINativeDNSResolverOverride);
gOverride.clearOverrides(); ```bash
var names = [ python exp.py make debug -c
"apple.com", "www.apple.com", python exp.py update-certs debug
"yt3.ggpht.com",
"accounts.google.com", "www.google.com",
"fonts.gstatic.com", "www.gstatic.com",
"mzstatic.com",
"wikimedia.org", "intake-analytics.wikimedia.org", "meta.wikimedia.org", "upload.wikimedia.org",
"wikipedia.org", "fr.wikipedia.org",
"youtube.com", "www.youtube.com",
"i.ytimg.com"
];
for(var i in names) {
gOverride.addIPOverride(names[i], "127.0.0.1");
}
``` ```
In Firefox, go to security settings, Certificates, import `/dev/shm/exp/certs/prime256v1/ca.crt` and trust it for identifying websites.
Stop anything running on ports 80 or 443. Stop anything running on ports 80 or 443.
Start the record proxy: Start the record proxy:
@ -325,7 +327,13 @@ Install OpenSSL with debug symbols:
/usr/bin/perl ./Configure --release -g --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/x86_64-linux-gnu shared no-idea no-mdc2 no-rc5 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms no-capieng no-rdrand enable-zlib enable-ec_nistp_64_gcc_128 linux-x86_64 /usr/bin/perl ./Configure --release -g --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/x86_64-linux-gnu shared no-idea no-mdc2 no-rc5 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms no-capieng no-rdrand enable-zlib enable-ec_nistp_64_gcc_128 linux-x86_64
``` ```
Backup your system's `libcrypto.so` and `libssl.so` and replace them with the new ones. To build rpxy with this openssl:
```bash
OPENSSL_LIB_DIR=/home/pi/reps/openssl-openssl-3.6.0/ OPENSSL_DIR=/home/pi/reps/openssl-openssl-3.6.0/ cargo build --release
```
Or: Backup your system's `libcrypto.so` and `libssl.so` and replace them with the new ones.
It would be simpler with `LD_PRELOAD` but Rust loads dynamic libraries in a particuliar way so it doesn't work. It would be simpler with `LD_PRELOAD` but Rust loads dynamic libraries in a particuliar way so it doesn't work.
Authorize non-root users to use perf: Authorize non-root users to use perf:
@ -372,3 +380,14 @@ Get the most used domains here https://www.akamai.com/fr/security-research/akara
python crawler.py crawl /dev/shm/top1K.csv python crawler.py crawl /dev/shm/top1K.csv
python crawler.py stat /dev/shm/crawl.json python crawler.py stat /dev/shm/crawl.json
``` ```
## 0-RTT
```bash
echo "hello world" > /dev/shm/ed
openssl s_server -port 8000 -cert /dev/shm/exp/certs/prime256v1/wikipedia.org.crt -key /dev/shm/exp/certs/prime256v1/wikipedia.org.key -early_data
# First req, without early data
echo | openssl s_client -no-interactive -keylogfile /dev/shm/client.txt -sess_out sessions 127.0.0.1:8000
# Second req, using 0-RTT for early data
echo | openssl s_client -no-interactive -early_data /dev/shm/ed -keylogfile /dev/shm/client.txt -sess_in sessions 127.0.0.1:8000
```

286
exp.py
View file

@ -2,6 +2,31 @@
import os, sys, subprocess import os, sys, subprocess
CONFIGS = { CONFIGS = {
"debug": {
"experiments": [
"zrtt",
],
"setups": [
#"none-local",
"client-local",
#"server-local",
],
"records": [
{ "filename": "youtube", "repeat": 1 },
],
"repodir": "/home/tuxmain/reps/tlsbench",
"expdir": "/dev/shm/exp",
"log_backup_dir": "/home/tuxmain",
"p2_hostname": "localhost",
"p2_addr": "127.0.0.1",
"p2_repodir": "/home/tuxmain/reps/tlsbench",
"wattmeter": False,
"perf": False,
"perf_dir": "/home/tuxmain/.cache/exp",
"p3_suffix": ".localhost",
"p3_port_plain": 8080,
"p3_port_tls": 8443,
},
# i7-4790 local # i7-4790 local
"local": { "local": {
"experiments": [ "experiments": [
@ -33,9 +58,10 @@ CONFIGS = {
# i7-4790 -> pi3 # i7-4790 -> pi3
"pi3": { "pi3": {
"experiments": [ "experiments": [
#"impl-cipher-ver", "impl-cipher-ver",
"impl-cert-ver", "impl-cert-ver",
#"impl-kex-ver", "impl-kex-ver",
"zrtt"
], ],
"setups": [ "setups": [
"none", "none",
@ -43,7 +69,7 @@ CONFIGS = {
"server", "server",
], ],
"records": [ "records": [
{ "filename": "youtube", "repeat": 100 }, { "filename": "youtube", "repeat": 1 },
], ],
"repodir": "/home/tuxmain/reps/tlsbench", "repodir": "/home/tuxmain/reps/tlsbench",
"expdir": "/dev/shm/exp", "expdir": "/dev/shm/exp",
@ -58,7 +84,7 @@ CONFIGS = {
"p3_suffix": "", "p3_suffix": "",
"p3_port_plain": 80, "p3_port_plain": 80,
"p3_port_tls": 443, "p3_port_tls": 443,
"idle": "idle - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 -", "idle": "idle - - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 -",
}, },
"pi3-local": { "pi3-local": {
"experiments": [ "experiments": [
@ -116,7 +142,7 @@ CONFIGS = {
"p3_suffix": "", "p3_suffix": "",
"p3_port_plain": 80, "p3_port_plain": 80,
"p3_port_tls": 443, "p3_port_tls": 443,
"idle": "idle - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 -", "idle": "idle - - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 -",
}, },
"core2-local": { "core2-local": {
"experiments": [ "experiments": [
@ -147,6 +173,9 @@ CONFIGS = {
}, },
} }
# Wildcard subdomains are used only for certificates.
# 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_ = [ DOMAINS_ = [
# Apple # Apple
"apple.com", "www.apple.com", "graffiti-tags.apple.com", "securemetrics.apple.com", "apple.com", "www.apple.com", "graffiti-tags.apple.com", "securemetrics.apple.com",
@ -154,13 +183,38 @@ DOMAINS_ = [
"mzstatic.com", "is1-ssl.mzstatic.com", "mzstatic.com", "is1-ssl.mzstatic.com",
# Youtube video # Youtube video
"youtube.com", "www.youtube.com", "youtube.com", "www.youtube.com",
"*.ytimg.com",
"i.ytimg.com", "i.ytimg.com",
"i1.ytimg.com",
"i9.ytimg.com",
"fonts.gstatic.com", "www.gstatic.com", "fonts.gstatic.com", "www.gstatic.com",
"www.google.com", "accounts.google.com", "www.google.com", "accounts.google.com",
"yt3.ggpht.com", "yt3.ggpht.com",
"rr1---sn-gxo5uxg-jqbl.googlevideo.com", "*.googlevideo.com",
"rr2---sn-gxo5uxg-jqbl.googlevideo.com", "rr3---sn-gx1v2vax-atne.googlevideo.com",
"rr4---sn-q4fl6nds.googlevideo.com", "rr4---sn-hgn7yn7l.googlevideo.com",
"rr3---sn-gx1v2vax-atne.googlevideo.com",
"rr2---sn-gx1v2vax-atne.googlevideo.com",
"rr1---sn-hgn7yn7l.googlevideo.com",
"rr4---sn-hgn7yn76.googlevideo.com",
"rr3---sn-hgn7rn7r.googlevideo.com",
"rr1---sn-hgn7rn7y.googlevideo.com",
"rr1---sn-hgn7rnee.googlevideo.com",
"rr2---sn-aigl6ney.googlevideo.com",
"rr3---sn-q4fzenee.googlevideo.com",
"googleads.g.doubleclick.net",
"static.doubleclick.net",
"ad.doubleclick.net",
"yt3.googleusercontent.com",
"suggestqueries-clients6.youtube.com",
"pagead2.googlesyndication.com",
"tpc.googlesyndication.com",
"encrypted-tbn0.gstatic.com",
"encrypted-tbn1.gstatic.com",
"encrypted-tbn2.gstatic.com",
"encrypted-tbn3.gstatic.com",
"fonts.googleapis.com",
"consent.youtube.com",
# Amazon # Amazon
"amazon.com", "www.amazon.com", "amazon.com", "www.amazon.com",
# Wikipedia article # Wikipedia article
@ -182,7 +236,7 @@ IMPLS = [
"boring", # Google's fork of OpenSSL used in Chrome and Android "boring", # Google's fork of OpenSSL used in Chrome and Android
"openssl", # widely used "openssl", # widely used
"ring", # used in most Rust stuff "ring", # used in most Rust stuff
"symcrypt", # Microsoft's crypto #"symcrypt", # Microsoft's crypto
#"wolfcrypt" # used in embedded (won't build with rpxy for now) #"wolfcrypt" # used in embedded (won't build with rpxy for now)
] ]
# Symmetric ciphers # Symmetric ciphers
@ -223,6 +277,7 @@ EXPERIMENTS = {
], ],
"kexes": ["X25519"], "kexes": ["X25519"],
"cert": ["prime256v1"], "cert": ["prime256v1"],
"earlydata": ["0"],
}, },
# Compare signatures among implementations and TLS versions # Compare signatures among implementations and TLS versions
"impl-cert-ver": { "impl-cert-ver": {
@ -239,6 +294,7 @@ EXPERIMENTS = {
"rsa3072", "rsa3072",
"rsa4096", "rsa4096",
], ],
"earlydata": ["0"],
}, },
# Compare key exchange groups among implementations and TLS versions # Compare key exchange groups among implementations and TLS versions
"impl-kex-ver": { "impl-kex-ver": {
@ -256,6 +312,25 @@ EXPERIMENTS = {
"MLKEM768", "MLKEM768",
], ],
"cert": ["prime256v1"], "cert": ["prime256v1"],
"earlydata": ["0"],
},
# Compare 0-RTT with no early data
"zrtt": {
"impls": [
"aws_lc",
#"ring"
],
"ciphers": [
"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",
],
"kexes": ["X25519"],
"cert": ["prime256v1"],
"earlydata": ["0", "1"],
}, },
"debug": { "debug": {
"impls": IMPLS, "impls": IMPLS,
@ -265,6 +340,7 @@ EXPERIMENTS = {
], ],
"kexes": ["X25519"], "kexes": ["X25519"],
"cert": ["prime256v1"], "cert": ["prime256v1"],
"earlydata": ["0"],
}, },
} }
@ -283,15 +359,6 @@ for domain in DOMAINS_:
if not domain in DOMAINS: if not domain in DOMAINS:
DOMAINS.append(domain) DOMAINS.append(domain)
# JS to redirect the target domains to local (bypass DNS without altering system's config or webpages or packets)
SCRIPT_FIREFOX_HOSTS = """const gOverride = Cc["@mozilla.org/network/native-dns-override;1"].getService(Ci.nsINativeDNSResolverOverride);
gOverride.clearOverrides();
var names = """+str(DOMAINS)+""";
for(var i in names) {
gOverride.addIPOverride(names[i], "127.0.0.1");
}
"""
for config in CONFIGS: for config in CONFIGS:
CONFIGS[config]["name"] = config CONFIGS[config]["name"] = config
@ -502,6 +569,8 @@ def make_rpxy_config(outdir, domains, cryptodir, config_name, p3_suffix, p3_port
f = open(outdir+config_name+".toml", "w") f = open(outdir+config_name+".toml", "w")
f.write("listen_port = {}\nlisten_port_tls = {}\n".format(rpxy_config["listen_http"], rpxy_config["listen_https"])) f.write("listen_port = {}\nlisten_port_tls = {}\n".format(rpxy_config["listen_http"], rpxy_config["listen_https"]))
for domain in domains: for domain in domains:
if "*" in domain:
continue
app = domain.replace(".", "_") app = domain.replace(".", "_")
root = get_domain_root(domain) root = get_domain_root(domain)
f.write(rpxy_config["app"].format( f.write(rpxy_config["app"].format(
@ -545,16 +614,18 @@ def choose_impl(expdir, p, impl):
expdir += "/" expdir += "/"
os.symlink(os.getcwd()+"/rpxy_rustls_"+impl, expdir+str(p)+"_rpxy", False) 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): def run_netreplay(expdir, repodir, record, p2_addr, p2_port, listen_port, tls_mode, only_record=None, ciphers=None, kexes=None, earlydata="0"):
if expdir[-1] != "/": if expdir[-1] != "/":
expdir += "/" expdir += "/"
repodir = repodir.removesuffix("/") repodir = repodir.removesuffix("/")
env = {"RUST_LOG": "warning"} env = {"RUST_LOG": "warning", "EARLYDATA": earlydata}
if ciphers: if ciphers:
env["CIPHERS"] = ciphers env["CIPHERS"] = ciphers
if kexes: if kexes:
env["KEXES"] = 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"])] 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 only_record != None: if only_record != None:
cmd += ["--record", only_record] cmd += ["--record", only_record]
print(" ".join(cmd)) print(" ".join(cmd))
@ -631,7 +702,7 @@ def run_exp(config, only_record=None, idle=False):
logfile_name = "log-"+timestr logfile_name = "log-"+timestr
logfile_path = expdir+"/"+logfile_name logfile_path = expdir+"/"+logfile_name
logfile = open(logfile_path, "w") logfile = open(logfile_path, "w")
logfile.write("exp impl alg kex cipher setup record time cpu bytes_in bytes_out Wh prof\n") logfile.write("exp impl alg kex cipher ed setup record time cpu bytes_in bytes_out Wh prof\n")
logfile.close() logfile.close()
perf_dir = "" perf_dir = ""
@ -664,7 +735,7 @@ def run_exp(config, only_record=None, idle=False):
while True: while True:
try: try:
with open(logfile_path, "a") as logfile: 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} -\n") logfile.write(f"idle - - - - - - - {time_diff} {rpxy_cpu_diff} {p2_bytes_in_diff} {p2_bytes_out_diff} {energy_diff} -\n")
logfile.close() logfile.close()
break break
except Exception as e: except Exception as e:
@ -692,54 +763,73 @@ def run_exp(config, only_record=None, idle=False):
ssh_run(ssh, f"python {p2_path}/exp.py cert {config_name} {alg}") ssh_run(ssh, f"python {p2_path}/exp.py cert {config_name} {alg}")
for kex in exp["kexes"]: for kex in exp["kexes"]:
for cipher in exp["ciphers"]: for cipher in exp["ciphers"]:
if not alg_filter(kex, alg, cipher, impl): for earlydata in exp["earlydata"]:
continue if not alg_filter(kex, alg, cipher, impl):
for setup in config["setups"]:
if SETUPS[setup]["tls_invariant"] and not first_set:
continue continue
setupdir = expdir+"setups/"+setup for setup in config["setups"]:
for record in config["records"]: if SETUPS[setup]["tls_invariant"] and not first_set:
print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} {setup}") continue
p2_rpxy_config = SETUPS[setup]["rpxy_config"] setupdir = expdir+"setups/"+setup
vars = {"CIPHERS": cipher, "KEXES": kex, "RUST_LOG": "warning"} for record in config["records"]:
cmd = f"{p2_path}/rpxy_rustls_{impl} --config {expdir}/configs/{p2_rpxy_config}.toml --log-dir /dev/shm" print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} ED={earlydata} {setup}")
#cmd = f"{p2_path}/rpxy_rustls_{impl} --config {expdir}/configs/{p2_rpxy_config}.toml" p2_rpxy_config = SETUPS[setup]["rpxy_config"]
ssh_run_bg(ssh, cmd, env=vars) vars = {"CIPHERS": cipher, "KEXES": kex, "RUST_LOG": "warning", "EARLYDATA": earlydata}
time.sleep(1) 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)
prof_filename = "-" prof_filename = "-"
if config["perf"]: if config["perf"]:
prof_filename = f"{perf_dir}/perf-{timestr}-{run_id}.data" prof_filename = f"{perf_dir}/perf-{timestr}-{run_id}.data"
rpxy_pid = ssh_run(ssh, f"pidof rpxy_rustls_{impl}").removesuffix("\n") 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}") ssh_run_bg(ssh, f"perf record -F 997 --call-graph dwarf,64000 -g -o {prof_filename} -p {rpxy_pid}")
run_id += 1 run_id += 1
rpxy_cpu = get_cpu_stat(ssh) rpxy_cpu = get_cpu_stat(ssh)
p2_bytes_in, p2_bytes_out = get_net_stat(ssh) p2_bytes_in, p2_bytes_out = get_net_stat(ssh)
energy = 0 energy = 0
if config["wattmeter"]: if config["wattmeter"]:
energy = wattmeter.get_meter() energy = wattmeter.get_meter()
start = time.time() start = time.time()
netreplay = run_netreplay( netreplay = run_netreplay(
config["expdir"], config["expdir"],
config["repodir"], config["repodir"],
record, record,
config["p2_addr"], config["p2_addr"],
SETUPS[setup]["p2_port"], SETUPS[setup]["p2_port"],
SETUPS[setup]["listen_port"], SETUPS[setup]["listen_port"],
SETUPS[setup]["netreplay_tls_mode"], SETUPS[setup]["netreplay_tls_mode"],
only_record=only_record, only_record=only_record,
ciphers=cipher, ciphers=cipher,
kexes=kex kexes=kex,
) earlydata=earlydata,
)
# TODO detect when netreplay has finished # TODO detect when netreplay has finished
try: try:
netreplay.wait() netreplay.wait()
except KeyboardInterrupt: except KeyboardInterrupt:
netreplay.kill() 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: try:
ssh_run(ssh, f"killall rpxy_rustls_{impl}") ssh_run(ssh, f"killall rpxy_rustls_{impl}")
except invoke.exceptions.UnexpectedExit as e: except invoke.exceptions.UnexpectedExit as e:
@ -748,47 +838,30 @@ def run_exp(config, only_record=None, idle=False):
ssh_run(ssh, f"killall dtach") ssh_run(ssh, f"killall dtach")
except invoke.exceptions.UnexpectedExit as e: except invoke.exceptions.UnexpectedExit as e:
pass pass
exit(0) end = time.time()
#time.sleep(30) new_energy = 0
#sh("killall netreplay") if config["wattmeter"]:
try: new_energy = wattmeter.get_meter()
#ssh_run(ssh, f"rm /dev/shm/access.log /dev/shm/rpxy.log") new_p2_bytes_in, new_p2_bytes_out = get_net_stat(ssh)
pass new_rpxy_cpu = get_cpu_stat(ssh)
except invoke.exceptions.UnexpectedExit as e: record_filename = record["filename"]
pass rpxy_cpu_diff = new_rpxy_cpu - rpxy_cpu
try: p2_bytes_in_diff = new_p2_bytes_in - p2_bytes_in
ssh_run(ssh, f"killall rpxy_rustls_{impl}") p2_bytes_out_diff = new_p2_bytes_out - p2_bytes_out
except invoke.exceptions.UnexpectedExit as e: energy_diff = new_energy - energy
pass time_diff = end - start
try: while True:
ssh_run(ssh, f"killall dtach") try:
except invoke.exceptions.UnexpectedExit as e: with open(logfile_path, "a") as logfile:
pass 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} {prof_filename}\n")
end = time.time() logfile.close()
break
new_energy = 0 except Exception as e:
if config["wattmeter"]: print("Can't open log file:", e)
new_energy = wattmeter.get_meter() time.sleep(1)
new_p2_bytes_in, new_p2_bytes_out = get_net_stat(ssh) sh(f"cp {logfile_path} {log_backup_dir}/{logfile_name}")
new_rpxy_cpu = get_cpu_stat(ssh) first_set = False
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
time_diff = end - start
while True:
try:
with open(logfile_path, "a") as logfile:
logfile.write(f"{expname} {impl} {alg} {kex} {cipher} {setup} {record_filename} {time_diff} {rpxy_cpu_diff} {p2_bytes_in_diff} {p2_bytes_out_diff} {energy_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"]: if config["wattmeter"]:
YAPI.FreeAPI() YAPI.FreeAPI()
@ -841,7 +914,6 @@ if __name__ == "__main__":
send <config> Send configs and certs to p2 send <config> Send configs and certs to p2
update-certs <config> Update system's certs update-certs <config> Update system's certs
run <config> Run experiment run <config> Run experiment
script Print Firefox script to override DNS
Make options: Make options:
-c Make CA cert (otherwise use already existing one) -c Make CA cert (otherwise use already existing one)
@ -907,8 +979,6 @@ Run options:
from yoctopuce.yocto_power import * from yoctopuce.yocto_power import *
run_exp(config, only_record=getargv("--record", None), idle="--idle" in sys.argv) run_exp(config, only_record=getargv("--record", None), idle="--idle" in sys.argv)
elif opt == "script":
print(SCRIPT_FIREFOX_HOSTS)
else: else:
print("Unknown command, use help for help") print("Unknown command, use help for help")
exit(1) exit(1)

View file

@ -20,6 +20,8 @@ ALG_LABEL = {
"X25519MLKEM768": "x25519mlkem", "X25519MLKEM768": "x25519mlkem",
"SECP256R1MLKEM768": "p256mlkem", "SECP256R1MLKEM768": "p256mlkem",
"MLKEM768": "mlkem", "MLKEM768": "mlkem",
"0": "Off",
"1": "On",
} }
# Nice labels for TLS versions using ciphers # Nice labels for TLS versions using ciphers
@ -44,7 +46,8 @@ COL = {
"energy": "Wh", "energy": "Wh",
"cipher": "cipher", "cipher": "cipher",
"cert": "alg", "cert": "alg",
"kex": "kex" "kex": "kex",
"ed": "ed",
} }
# Physical units by object # Physical units by object
UNIT = { UNIT = {
@ -56,7 +59,8 @@ UNIT = {
CRITERION_TITLE = { CRITERION_TITLE = {
"cipher": "cipher", "cipher": "cipher",
"cert": "signature algorithm", "cert": "signature algorithm",
"kex": "key exchange" "kex": "key exchange",
"ed": "0-RTT",
} }
def impl_title(impl): def impl_title(impl):
@ -335,6 +339,8 @@ if __name__ == "__main__":
make_log_plot(logs, "impl-cert-ver", "cert", side, "energy", record, machine=machine) make_log_plot(logs, "impl-cert-ver", "cert", side, "energy", record, machine=machine)
make_log_plot(logs, "impl-kex-ver", "kex", side, "cpu", record, machine=machine) make_log_plot(logs, "impl-kex-ver", "kex", side, "cpu", record, machine=machine)
make_log_plot(logs, "impl-kex-ver", "kex", side, "energy", record, machine=machine) make_log_plot(logs, "impl-kex-ver", "kex", side, "energy", record, machine=machine)
make_log_plot(logs, "zrtt", "ed", side, "cpu", record, machine=machine)
make_log_plot(logs, "zrtt", "ed", side, "energy", record, machine=machine)
elif cmd == "prof": elif cmd == "prof":
for side in ["client-local", "server-local"]: for side in ["client-local", "server-local"]:
for record in records: for record in records:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.