diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/.gitignore b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..232ccd1d8c8fa7bb09c62bfe30ee8baf3ec12f4f --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/.gitignore @@ -0,0 +1,2 @@ +target/ +logs/ diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Cargo.lock b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..7ccc49374a0461302584facf2ad8140f4b19e8b3 --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Cargo.lock @@ -0,0 +1,106 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "netem-evaluator" +version = "0.1.0" +dependencies = [ + "bincode", + "serde", + "serde_json", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Cargo.toml b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..61442fe3afd6b9ae5b339ea0e0c8d55fea00372e --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "netem-evaluator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bincode = "1.3" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Makefile b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..fd61ebc1e1a3438ba7853cc4ba2416e4f903f319 --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/Makefile @@ -0,0 +1,19 @@ + +export NUMBER_OF_NETWORK_NAMESPACES = 1 + +CARGO = $(shell which cargo) + +run_evaluator: teardown setup + cargo build --release + mkdir -p logs + sudo --preserve-env ip netns exec srv_ns_1 ${CARGO} run --release --bin server > logs/netem_data.log & + sudo --preserve-env ip netns exec cli_ns_1 ${CARGO} run --release --bin client + sleep 1 + sudo --preserve-env pkill -f 'cargo run --release --bin server' + $(MAKE) teardown + +setup: + sudo --preserve-env src/scripts/setup_ns.sh + +teardown: + - src/scripts/remove_ns.sh diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/bin/client.rs b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/bin/client.rs new file mode 100644 index 0000000000000000000000000000000000000000..9836553545ebf3d34064706dfb3d24ad151190d1 --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/bin/client.rs @@ -0,0 +1,93 @@ +use std::error::Error; +use std::net::UdpSocket; +use std::time::{SystemTime, UNIX_EPOCH}; + +use netem_evaluator::Message; +use netem_evaluator::NetemParameters; + +const TIME_BETWEEN_MESSAGES_IN_MICRO_SECONDS: u64 = 10000; +const MESSAGES_TO_SEND: u32 = 1000; + +fn main() -> Result<(), Box<dyn Error>> { + let socket = UdpSocket::bind("0.0.0.0:0")?; + let target = "10.0.0.1:6789"; + socket.connect(target)?; + let mut id = 0; + + // TEST GOAL: find out if there is a difference, between no netem, and netem with 0 delay + // There is a very small difference of 0.03ms on average + let mut netem_parameters = NetemParameters::new(); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + + netem_evaluator::remove_qdiscs(); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, None)?; + + netem_evaluator::create_qdiscs(); + send_messages_to_server( + &socket, + &mut id, + MESSAGES_TO_SEND, + Some(NetemParameters::new()), + )?; + + // TEST GOAL: find out how good the delay of netem works + // The delay is pretty accurate + netem_parameters = NetemParameters::new().with_delay(1); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + netem_parameters = NetemParameters::new().with_delay(2); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + netem_parameters = NetemParameters::new().with_delay(4); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + netem_parameters = NetemParameters::new().with_delay(10); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + netem_parameters = NetemParameters::new().with_delay(20); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + netem_parameters = NetemParameters::new().with_delay(50); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + netem_parameters = NetemParameters::new().with_delay(100); + netem_evaluator::set_network_parameters(netem_parameters.clone()); + send_messages_to_server(&socket, &mut id, MESSAGES_TO_SEND, Some(netem_parameters))?; + + Ok(()) +} + +fn send_messages_to_server( + socket: &UdpSocket, + id: &mut u128, + messages_to_send: u32, + netem_parameters: Option<NetemParameters>, +) -> Result<(), Box<dyn Error>> { + let mut buffer = [0u8; 1000]; + for _ in 0..messages_to_send { + *id += 1; + // Get high-precision timestamp + // Using SystemTime for monotonic timestamps that are consistent across processes + let message = Message { + id: *id, + timestamp: SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos(), + netem_parameters: netem_parameters.clone(), + }; + + let mut cursor = std::io::Cursor::new(&mut buffer[..]); + bincode::serialize_into(&mut cursor, &message)?; + + socket.send(&buffer)?; + println!("{message:?}"); + // println!("{:02x?}", &buffer[0..100]); + + buffer.fill(0); + std::thread::sleep(std::time::Duration::from_micros( + TIME_BETWEEN_MESSAGES_IN_MICRO_SECONDS, + )); + } + + std::thread::sleep(std::time::Duration::from_secs(1)); + Ok(()) +} diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/bin/server.rs b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/bin/server.rs new file mode 100644 index 0000000000000000000000000000000000000000..035ea5062429782ffa2449f0fd3bb37b73257e49 --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/bin/server.rs @@ -0,0 +1,36 @@ +use std::error::Error; +use std::net::UdpSocket; +use std::time::{SystemTime, UNIX_EPOCH}; + +use netem_evaluator::Message; + +fn main() -> Result<(), Box<dyn Error>> { + let socket = UdpSocket::bind("0.0.0.0:6789")?; + eprintln!("Listening on :6789"); + + let mut buffer = [0u8; 1000]; + + loop { + match socket.recv(&mut buffer) { + Ok(received) => { + let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos(); + + let mut message: Message = bincode::deserialize(&buffer[..received])?; + message.timestamp = now - message.timestamp; // Abuse timestamp field to store time difference + + // let time_diff_micros = (now - message.timestamp) as f64 / 1000.; + // let id = message.id; + // println!("Received packet #{id} - Time difference: {time_diff_micros:.3} µs"); + println!("{}", serde_json::to_string(&message)?); + let server_time_per_request = + SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos() - now; + // println!( + // "{} ms time needed for server to handle request", + // server_time_per_request as f64 / 1000000. + // ); + assert!(server_time_per_request < 10000000); // if this bites you, you should choose a higher value for TIME_BETWEEN_MESSAGES_IN_MICRO_SECONDS + } + Err(e) => eprintln!("Error receiving: {}", e), + } + } +} diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/lib.rs b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..0ab806c14d2548a473c23dcf7ce1ca9851216615 --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/lib.rs @@ -0,0 +1,245 @@ +use serde::{Deserialize, Serialize}; +use std::process::Command; + +const NETWORK_NAMESPACES: u32 = 1; + +const SRV_NS: &str = "srv_ns"; +const CLI_NS: &str = "cli_ns"; +const SRV_VE: &str = "srv_ve"; +const CLI_VE: &str = "cli_ve"; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Message { + pub id: u128, + pub timestamp: u128, + pub netem_parameters: Option<NetemParameters>, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct NetemParameters { + pub srv_rate: u32, + pub srv_delay: u32, + pub srv_jitter: u32, + pub srv_pkt_loss: u32, + pub srv_duplicate: u32, + pub srv_corrupt: u32, + pub srv_reorder: u32, + pub cli_rate: u32, + pub cli_delay: u32, + pub cli_jitter: u32, + pub cli_pkt_loss: u32, + pub cli_duplicate: u32, + pub cli_corrupt: u32, + pub cli_reorder: u32, +} + +// impl NetemParameters { +// pub fn from_json(json_str: &str) -> Result<NetemParameters, serde_json::Error> { +// serde_json::from_str(json_str) +// } + +// pub fn to_json(&self) -> Result<String, serde_json::Error> { +// serde_json::to_string(self) +// } +// } + +impl NetemParameters { + pub fn new() -> NetemParameters { + NetemParameters { + srv_rate: 1000, + srv_delay: 0, + srv_jitter: 0, + srv_pkt_loss: 0, + srv_duplicate: 0, + srv_corrupt: 0, + srv_reorder: 0, + cli_rate: 1000, + cli_delay: 0, + cli_jitter: 0, + cli_pkt_loss: 0, + cli_duplicate: 0, + cli_corrupt: 0, + cli_reorder: 0, + } + } + + pub fn with_rate(mut self, rate: u32) -> NetemParameters { + self.srv_rate = rate; + self.cli_rate = rate; + self + } + + pub fn with_delay(mut self, delay: u32) -> NetemParameters { + self.srv_delay = delay; + self.cli_delay = delay; + self + } + + pub fn with_jitter(mut self, jitter: u32) -> NetemParameters { + self.srv_jitter = jitter; + self.cli_jitter = jitter; + self + } + + pub fn with_pkt_loss(mut self, pkt_loss: u32) -> NetemParameters { + self.srv_pkt_loss = pkt_loss; + self.cli_pkt_loss = pkt_loss; + self + } + + pub fn with_duplicate(mut self, duplicate: u32) -> NetemParameters { + self.srv_duplicate = duplicate; + self.cli_duplicate = duplicate; + self + } + + pub fn with_corrupt(mut self, corrupt: u32) -> NetemParameters { + self.srv_corrupt = corrupt; + self.cli_corrupt = corrupt; + self + } + + pub fn with_reorder(mut self, reorder: u32) -> NetemParameters { + self.srv_reorder = reorder; + self.cli_reorder = reorder; + self + } +} + +pub fn set_network_parameters(parameters: NetemParameters) { + for i in 1..(NETWORK_NAMESPACES + 1) { + change_qdisc( + format!("{SRV_NS}_{i}"), + format!("{SRV_VE}"), + parameters.srv_rate, + parameters.srv_delay, + parameters.srv_jitter, + parameters.srv_pkt_loss, + parameters.srv_duplicate, + parameters.srv_corrupt, + parameters.srv_reorder, + ); + change_qdisc( + format!("{CLI_NS}_{i}"), + format!("{CLI_VE}"), + parameters.cli_rate, + parameters.cli_delay, + parameters.cli_jitter, + parameters.cli_pkt_loss, + parameters.cli_duplicate, + parameters.cli_corrupt, + parameters.cli_reorder, + ); + } +} + +fn change_qdisc( + ns: String, + dev: String, + rate: u32, + delay: u32, + jitter: u32, + pkt_loss: u32, + duplicate: u32, + corrupt: u32, + reorder: u32, +) { + let rate = format!("{rate}mbit"); + let delay = format!("{delay}ms"); + let jitter = format!("{jitter}ms"); + let pkt_loss = format!("{pkt_loss}%"); + let duplicate = format!("{duplicate}%"); + let corrupt = format!("{corrupt}%"); + let reorder = format!("{reorder}%"); + + let args = [ + "netns", + "exec", + &ns, + "tc", + "qdisc", + "change", + "dev", + &dev, + "root", + "netem", + "limit", + "1000", + "rate", + &rate, + "delay", + &delay, + &jitter, + "loss", + &pkt_loss, + "duplicate", + &duplicate, + "corrupt", + &corrupt, + "reorder", + &reorder, + ]; + println!("> ip {args:?}"); + + let output = Command::new("ip") + .args(&args) + .output() + .expect("failed to execute command"); + println!("{output:?}"); +} + +pub fn create_qdiscs() { + for i in 1..(NETWORK_NAMESPACES + 1) { + create_qdisc(format!("{SRV_NS}_{i}"), format!("{SRV_VE}")); + create_qdisc(format!("{CLI_NS}_{i}"), format!("{CLI_VE}")); + } + set_network_parameters(NetemParameters::new()); +} +fn create_qdisc(ns: String, dev: String) { + let args = [ + "netns", "exec", &ns, "tc", "qdisc", "add", "dev", &dev, "root", "netem", + ]; + println!("> ip {args:?}"); + + let output = Command::new("ip") + .args(&args) + .output() + .expect("failed to execute command"); + println!("{output:?}"); +} + +pub fn remove_qdiscs() { + for i in 1..(NETWORK_NAMESPACES + 1) { + remove_qdisc(format!("{SRV_NS}_{i}"), format!("{SRV_VE}")); + remove_qdisc(format!("{CLI_NS}_{i}"), format!("{CLI_VE}")); + } +} +fn remove_qdisc(ns: String, dev: String) { + let args = [ + "netns", "exec", &ns, "tc", "qdisc", "del", "dev", &dev, "root", + ]; + println!("> ip {args:?}"); + + let output = Command::new("ip") + .args(&args) + .output() + .expect("failed to execute command"); + println!("{output:?}"); +} + +pub fn show_qdiscs() { + for i in 1..(NETWORK_NAMESPACES + 1) { + show_qdisc(format!("{SRV_NS}_{i}"), format!("{SRV_VE}")); + show_qdisc(format!("{CLI_NS}_{i}"), format!("{CLI_VE}")); + } +} +fn show_qdisc(ns: String, dev: String) { + let args = ["netns", "exec", &ns, "tc", "qdisc", "show", "dev", &dev]; + println!("> ip {args:?}"); + + let output = Command::new("ip") + .args(&args) + .output() + .expect("failed to execute command"); + println!("{output:?}"); +} diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/main.rs b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..e7a11a969c037e00a796aafeff6258501ec15e9a --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/analyze.py b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/analyze.py new file mode 100644 index 0000000000000000000000000000000000000000..a93c4d388d13898e47de206087f0362de2215c1a --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/analyze.py @@ -0,0 +1,111 @@ +# format of json is {"id":1,"timestamp":186514,"netem_parameters":{"srv_rate":1000,"srv_delay":0,"srv_jitter":0,"srv_pkt_loss":0,"srv_duplicate":0,"srv_corrupt":0,"srv_reorder":0,"cli_rate":1000,"cli_delay":0,"cli_jitter":0,"cli_pkt_loss":0,"cli_duplicate":0,"cli_corrupt":0,"cli_reorder":0}} + +# write a function that reads the json file into a pandas dataframe +import json +import pandas as pd + + +def main(): + df = read_json_file("logs/netem_data.log") + # print(df) + summarized = summarize_data(df) + summarized = summarized.drop( + columns=["srv_reorder", "srv_corrupt", "srv_duplicate"] + ) + print(summarized) + + +def read_json_file(file_path): + data = [] + with open(file_path, "r") as file: + for line in file: + data.append(json.loads(line)) + + df = pd.json_normalize(data) + df.rename(columns={"timestamp": "time_ns"}, inplace=True) + df["time_ms"] = df["time_ns"] / 1000000 + + # make netem_parameters a boolean + df = df.astype({"netem_parameters": "bool"}) + # set netem_parameters to true if all netem_parameters.* are some value + netem_columns = [col for col in df.columns if col.startswith("netem_parameters.")] + df["netem_parameters"] = df[netem_columns].notnull().all(axis=1) + + df = df[df["time_ms"] < 1e30] # filter out unreasonable large values + + return df + + +def summarize_data(df): + summarized = pd.DataFrame() + + # print the row with index 1001 + # print(df.loc[1]) + # print(df.loc[5]) + + # find out each set of distinct values for all netem_parameters.* + netem_columns = [col for col in df.columns if col.startswith("netem_parameters")] + distinct_rows = df[netem_columns].drop_duplicates() + # print("Distinct rows for netem parameters:") + # print(distinct_rows) + + for row in distinct_rows.iterrows(): + # Extract the current `netem_parameters` values + entry = row[1] + current_netem_params = entry.to_dict() + + if current_netem_params["netem_parameters"] == True: + mask = df[netem_columns] == current_netem_params + # print(mask) + # print(mask.all(axis=1)) + filtered_df = df[mask.all(axis=1)] + else: + mask = df["netem_parameters"] == False + # print(mask) + filtered_df = df[mask] + + # print(filtered_df) + + time_ms_max = filtered_df["time_ms"].max() + time_ms_min = filtered_df["time_ms"].min() + time_ms_avg = filtered_df["time_ms"].mean() + time_ms_std = filtered_df["time_ms"].std() + count = filtered_df["time_ms"].count() + netem_parameters = filtered_df["netem_parameters"].iloc[0] + srv_rate = filtered_df["netem_parameters.srv_rate"].iloc[0] + srv_delay = filtered_df["netem_parameters.srv_delay"].iloc[0] + srv_jitter = filtered_df["netem_parameters.srv_jitter"].iloc[0] + srv_pkt_loss = filtered_df["netem_parameters.srv_pkt_loss"].iloc[0] + srv_duplicate = filtered_df["netem_parameters.srv_duplicate"].iloc[0] + srv_corrupt = filtered_df["netem_parameters.srv_corrupt"].iloc[0] + srv_reorder = filtered_df["netem_parameters.srv_reorder"].iloc[0] + + summarized = pd.concat( + [ + summarized, + pd.DataFrame( + { + "time_ms_min": time_ms_min, + "time_ms_max": time_ms_max, + "time_ms_avg": time_ms_avg, + "time_ms_std": time_ms_std, + "count": count, + "netem_parameters": netem_parameters, + "srv_rate": srv_rate, + "srv_delay": srv_delay, + "srv_jitter": srv_jitter, + "srv_pkt_loss": srv_pkt_loss, + "srv_duplicate": srv_duplicate, + "srv_corrupt": srv_corrupt, + "srv_reorder": srv_reorder, + }, + index=[0], + ), + ], + ignore_index=True, + ) + + return summarized + + +main() diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/remove_ns.sh b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/remove_ns.sh new file mode 100755 index 0000000000000000000000000000000000000000..764842eaf80c1c5f8eaca4778048228e4a14df3c --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/remove_ns.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -x + +########################## +# Remove network namespaces +########################## +for i in $(seq 1 ${NUMBER_OF_NETWORK_NAMESPACES}); do + sudo ip netns del srv_ns_${i} + sudo ip netns del cli_ns_${i} +done diff --git a/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/setup_ns.sh b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/setup_ns.sh new file mode 100755 index 0000000000000000000000000000000000000000..6d2ab507706b23727ad3f9879036f4534e2c69fc --- /dev/null +++ b/pq-tls-benchmark-framework/emulation-exp/code/netem-evaluator/src/scripts/setup_ns.sh @@ -0,0 +1,84 @@ +#!/bin/bash +set -ex + +# Code taken from benchmarking-pqc-in-tls project. + +########################## +# Setup network namespaces +########################## + +# NUMBER_OF_NETWORK_NAMESPACES is set in setup.sh +echo "Setting up ${NUMBER_OF_NETWORK_NAMESPACES} network namespaces" + +# Server +SERVER_VETH=srv_ve +SERVER_VETH_LL_ADDR=00:00:00:00:00:01 + +# Client +CLIENT_VETH=cli_ve +CLIENT_VETH_LL_ADDR=00:00:00:00:00:02 + +for i in $(seq 1 ${NUMBER_OF_NETWORK_NAMESPACES}); do + SERVER_NS=srv_ns_${i} + CLIENT_NS=cli_ns_${i} + + ip netns add ${SERVER_NS} + ip netns add ${CLIENT_NS} + + # Add virtual link of types VETH + ip link add \ + name ${SERVER_VETH} \ + address ${SERVER_VETH_LL_ADDR} \ + netns ${SERVER_NS} type veth \ + peer name ${CLIENT_VETH} \ + address ${CLIENT_VETH_LL_ADDR} \ + netns ${CLIENT_NS} + + ip netns exec ${SERVER_NS} \ + ip link set dev ${SERVER_VETH} up + ip netns exec ${SERVER_NS} \ + ip link set dev lo up + ip netns exec ${SERVER_NS} \ + ip addr add 10.0.0.1/24 dev ${SERVER_VETH} + + ip netns exec ${CLIENT_NS} \ + ip link set dev ${CLIENT_VETH} up + ip netns exec ${CLIENT_NS} \ + ip link set dev lo up + ip netns exec ${CLIENT_NS} \ + ip addr add 10.0.0.2/24 dev ${CLIENT_VETH} + + # Add neighbour objects for IP connection + ip netns exec ${SERVER_NS} \ + ip neigh add 10.0.0.2 \ + lladdr ${CLIENT_VETH_LL_ADDR} \ + dev ${SERVER_VETH} + ip netns exec ${CLIENT_NS} \ + ip neigh add 10.0.0.1 \ + lladdr ${SERVER_VETH_LL_ADDR} \ + dev ${CLIENT_VETH} + + # Turn off optimizations that dent realism. + ip netns exec ${CLIENT_NS} \ + ethtool -K ${CLIENT_VETH} gso off gro off tso off + + ip netns exec ${SERVER_NS} \ + ethtool -K ${SERVER_VETH} gso off gro off tso off + + # Add netem as qdisc for traffic control + ip netns exec ${CLIENT_NS} \ + tc qdisc add \ + dev ${CLIENT_VETH} \ + root netem + ip netns exec ${SERVER_NS} \ + tc qdisc add \ + dev ${SERVER_VETH} \ + root netem +done + +# $DATE and $DEBUG is set by setup.sh +# Only set up tshark for the first network namespace +if [ "$DEBUG" == "true" ]; then + mkdir -p -m 777 captures && touch captures/capture_${DATE}.pcap && chmod a+w captures/capture_${DATE}.pcap + ip netns exec cli_ns_1 tshark -i ${CLIENT_VETH} -w captures/capture_${DATE}.pcap & +fi