feat(evaluation): Added results and modified scripts and execution for a test evaluation
Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
This commit is contained in:
@@ -6,12 +6,17 @@ from scapy.all import Ether, IP, UDP, send, sendp, Raw, sniff
|
||||
global initial_timestamp
|
||||
initial_timestamp = int(time.time() * 1000)
|
||||
|
||||
|
||||
# Simulated ACK sending function
|
||||
def send_ack(destination_IP, my_port, sender_port):
|
||||
ack_data = ""
|
||||
###################
|
||||
# With localhost:
|
||||
ack_packet = IP(dst=destination_IP) / UDP(dport=sender_port, sport=my_port) / Raw(load=str(ack_data))
|
||||
ack_packet = (
|
||||
IP(dst=destination_IP)
|
||||
/ UDP(dport=sender_port, sport=my_port)
|
||||
/ Raw(load=str(ack_data))
|
||||
)
|
||||
send(ack_packet, verbose=False)
|
||||
###################
|
||||
# With netns:
|
||||
@@ -20,18 +25,25 @@ def send_ack(destination_IP, my_port, sender_port):
|
||||
###################
|
||||
print(f"Sent ACK: {ack_data}")
|
||||
|
||||
|
||||
# Process incoming packets
|
||||
def process_packet(pkt):
|
||||
################### Save timestamps ###################
|
||||
if Raw in pkt:
|
||||
with open(save_file, "a") as f: # open as "a" for append
|
||||
global initial_timestamp
|
||||
receival_time = str(int(time.time() * 1000) - initial_timestamp) # time of arrival at receiver
|
||||
receival_time = str(
|
||||
int(time.time() * 1000) - initial_timestamp
|
||||
) # time of arrival at receiver
|
||||
send_time = pkt[Raw].load # time it was sent from the sender
|
||||
################### Conversion & error handling ###################
|
||||
try:
|
||||
send_time = int(send_time.decode("utf-8").split("X")[0]) # decode the payload and stop at "X"
|
||||
except ValueError: # For the last packet without a timestamp but "END" as payload
|
||||
send_time = int(
|
||||
send_time.decode("utf-8").split("X")[0]
|
||||
) # decode the payload and stop at "X"
|
||||
except (
|
||||
ValueError
|
||||
): # For the last packet without a timestamp but "END" as payload
|
||||
print(f"END for {my_port}")
|
||||
send_ack(destination_IP, my_port, sender_port)
|
||||
return
|
||||
@@ -45,19 +57,28 @@ def process_packet(pkt):
|
||||
|
||||
send_ack(destination_IP, my_port, sender_port)
|
||||
|
||||
|
||||
# Main loop
|
||||
def main(destination_IP, my_port, sender_port):
|
||||
###################
|
||||
# With localhost:
|
||||
sniff(iface="lo", filter=f"udp and dst port {my_port}", prn=process_packet, store=False)
|
||||
sniff(
|
||||
iface="lo",
|
||||
filter=f"udp and dst port {my_port}",
|
||||
prn=process_packet,
|
||||
store=False,
|
||||
)
|
||||
###################
|
||||
# With netns:
|
||||
# sniff(iface="ns-g", filter=f"udp and dst port {my_port}", prn=process_packet, store=False)
|
||||
###################
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python receive_and_ack.py <destination_IP> <my_port> <sender_port>")
|
||||
print(
|
||||
"Usage: python receive_and_ack.py <destination_IP> <my_port> <sender_port>"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
destination_IP = sys.argv[1] # Clear
|
||||
|
||||
67
sender-receiver-scripts/results/receiver.py
Normal file
67
sender-receiver-scripts/results/receiver.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
from scapy.all import Ether, IP, UDP, send, sendp, Raw, sniff
|
||||
|
||||
global initial_timestamp
|
||||
initial_timestamp = int(time.time() * 1000)
|
||||
|
||||
# Simulated ACK sending function
|
||||
def send_ack(destination_IP, my_port, sender_port):
|
||||
ack_data = ""
|
||||
###################
|
||||
# With localhost:
|
||||
# ack_packet = IP(dst=destination_IP) / UDP(dport=sender_port, sport=my_port) / Raw(load=str(ack_data))
|
||||
# send(ack_packet, verbose=False)
|
||||
###################
|
||||
# With netns:
|
||||
ack_packet = Ether(dst="64:9d:99:b1:0a:a4", src="64:9d:99:b1:0a:88") / IP(dst=destination_IP) / UDP(sport=my_port,dport=sender_port) / Raw(load=str(ack_data))
|
||||
sendp(ack_packet, verbose=False)
|
||||
###################
|
||||
print(f"Sent ACK: {ack_data}")
|
||||
|
||||
# Process incoming packets
|
||||
def process_packet(pkt):
|
||||
################### Save timestamps ###################
|
||||
if Raw in pkt:
|
||||
with open(save_file, "a") as f: # open as "a" for append
|
||||
global initial_timestamp
|
||||
receival_time = str(int(time.time() * 1000) - initial_timestamp) # time of arrival at receiver
|
||||
send_time = pkt[Raw].load # time it was sent from the sender
|
||||
################### Conversion & error handling ###################
|
||||
try:
|
||||
send_time = int(send_time.decode("utf-8").split("X")[0]) # decode the payload and stop at "X"
|
||||
except ValueError: # For the last packet without a timestamp but "END" as payload
|
||||
print(f"END for {my_port}")
|
||||
send_ack(destination_IP, my_port, sender_port)
|
||||
return
|
||||
except Exception as e:
|
||||
print(f"Decoding error at {my_port}")
|
||||
send_ack(destination_IP, my_port, sender_port)
|
||||
return
|
||||
################### Write data ###################
|
||||
aoi = int(receival_time) - send_time
|
||||
f.write(f"{send_time},{receival_time},{aoi}\n")
|
||||
|
||||
send_ack(destination_IP, my_port, sender_port)
|
||||
|
||||
# Main loop
|
||||
def main(destination_IP, my_port, sender_port):
|
||||
###################
|
||||
# With localhost:
|
||||
# sniff(iface="lo", filter=f"udp and dst port {my_port}", prn=process_packet, store=False)
|
||||
###################
|
||||
# With netns:
|
||||
sniff(iface="enp6s0f0np0", filter=f"udp and dst port {my_port}", prn=process_packet, store=False)
|
||||
###################
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: python receive_and_ack.py <destination_IP> <my_port> <sender_port>")
|
||||
sys.exit(1)
|
||||
|
||||
destination_IP = sys.argv[1] # Clear
|
||||
my_port = int(sys.argv[2]) # Port to listen on
|
||||
sender_port = int(sys.argv[3]) # Port to send acks to
|
||||
save_file = f"timestamps_{my_port}"
|
||||
main(destination_IP, my_port, sender_port)
|
||||
3
sender-receiver-scripts/results/receiver.sh
Executable file
3
sender-receiver-scripts/results/receiver.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo ip netns exec tb_node1_if0 python3 receiver.py 10.0.2.1 30123 30123
|
||||
135
sender-receiver-scripts/results/sender.py
Normal file
135
sender-receiver-scripts/results/sender.py
Normal file
@@ -0,0 +1,135 @@
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
import threading
|
||||
from scapy.all import Ether, IP, UDP, sendp, Raw, sniff, send
|
||||
|
||||
global initial_timestamp
|
||||
initial_timestamp = int(time.time() * 1000)
|
||||
|
||||
|
||||
# Parameters
|
||||
Q_max = 10 # Maximum queue size
|
||||
age_threshold = 1.0 # Delta_T in seconds
|
||||
|
||||
# Sender's state
|
||||
last_update_time = None # Last time an ACK was received
|
||||
N = 1 # Active senders (received from ACK)
|
||||
queue_utilization = 0 # Received as Q_i/Q_max
|
||||
delta_c = 0 # Time since the last ACK (calculated using T_ACK)
|
||||
|
||||
# Function to calculate P_s
|
||||
def calculate_probability(N, queue_utilization, delta_c):
|
||||
if queue_utilization < 1:
|
||||
return 1.0 # Full probability if the queue is underutilized
|
||||
elif queue_utilization == 1:
|
||||
# Calculate f(Delta_i)
|
||||
f_delta = max((delta_c - age_threshold) / age_threshold, 0)
|
||||
return (Q_max / N) + f_delta # Combine probabilities
|
||||
|
||||
# Function to send a packet
|
||||
def send_packet(target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_flag):
|
||||
|
||||
ether_layer = Ether(dst="64:9d:99:b1:0a:88", src="64:9d:99:b1:0a:a4")
|
||||
ip_layer = IP(dst=target_ip, tos=dscp_value << 2)
|
||||
udp_layer = UDP(dport=receiver_port, sport=my_port)
|
||||
|
||||
|
||||
# # Socket to listen for the ACKs
|
||||
# ack_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
# ack_socket.settimeout(2) # 2 seconds timer to receive the ack. Otherwise considered lost
|
||||
# ack_socket.bind(("", my_port))
|
||||
|
||||
# timestamp = str(int(time.time())) # Convert to a string for embedding
|
||||
|
||||
global initial_timestamp
|
||||
timestamp = str(int(time.time() * 1000) - initial_timestamp)
|
||||
|
||||
if (not FIN_flag):
|
||||
payload = timestamp + "X" * max((packet_size - len(timestamp)), 0) # max to prevent possible errors when choosing too small packet size
|
||||
else:
|
||||
payload = "END" + "X" * max((packet_size - len(timestamp)), 0)
|
||||
|
||||
packet = ether_layer / ip_layer / udp_layer / Raw(load=payload)
|
||||
# packet = ip_layer / udp_layer / Raw(load=payload)
|
||||
sendp(packet, verbose=False)
|
||||
# send(packet, verbose=False)
|
||||
print(".", end='', flush=True)
|
||||
|
||||
# Listen for ACKs
|
||||
def process_ack(pkt):
|
||||
global last_update_time, N, queue_utilization, delta_c
|
||||
|
||||
if Raw in pkt:
|
||||
ack_data = pkt[Raw].load.decode('utf-8')
|
||||
print(ack_data)
|
||||
# N, queue_utilization, T_ACK = eval(ack_data)
|
||||
# last_update_time = T_ACK
|
||||
# print(f"Received ACK: N={N}, Utilization={queue_utilization}, T_ACK={T_ACK}")
|
||||
|
||||
# Main loop
|
||||
def main(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size):
|
||||
global delta_c
|
||||
packets_sent = 0
|
||||
|
||||
while packets_sent < nb_packets:
|
||||
# Update delta_c (time since the last ACK)
|
||||
if last_update_time:
|
||||
delta_c = time.time() - last_update_time
|
||||
else:
|
||||
delta_c = float('inf') # No ACK received yet
|
||||
|
||||
# Calculate sending probability
|
||||
P_s = calculate_probability(N, queue_utilization, delta_c)
|
||||
|
||||
# Decide whether to send a packet
|
||||
if random.random() < P_s:
|
||||
|
||||
FIN_flag = False
|
||||
if packets_sent == nb_packets - 1:
|
||||
FIN_flag = True
|
||||
|
||||
send_packet(target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_flag)
|
||||
packets_sent += 1
|
||||
print(f"Packet sent with probability P_s={P_s:.2f}")
|
||||
else:
|
||||
print(f"Packet skipped with probability P_s={P_s:.2f}")
|
||||
|
||||
# Wait for a short interval before the next attempt
|
||||
time.sleep(0.1)
|
||||
|
||||
print(f"Finished sending {nb_packets} packets to {target_ip}:{receiver_port}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 6:
|
||||
print("Usage: python send_dscp_packets.py <target_ip> <my_port> <receiver_port> <nb_packets> <packet_size(in Bytes)>")
|
||||
sys.exit(1)
|
||||
|
||||
target_ip = sys.argv[1] # IP of the receiver
|
||||
my_port = int(sys.argv[2]) # Sender port
|
||||
receiver_port = int(sys.argv[3]) # Receiver port
|
||||
nb_packets = int(sys.argv[4]) # Total number of packets to send
|
||||
packet_size = int(sys.argv[5]) - 42 # Packet size in Bytes - 42 (previous headers)
|
||||
dscp_value = 0 # Hardcoded DSCP value for now
|
||||
|
||||
# main(target_ip, receiver_port, my_port, dscp_value, nb_packets)
|
||||
|
||||
threading.Thread(target=main, args=(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size), daemon=True).start()
|
||||
###################
|
||||
# With localhost:
|
||||
# sniff(iface="lo", filter=f"udp and dst port {my_port}", prn=process_ack, store=False)#, timeout=0.1)
|
||||
###################
|
||||
# With netns:
|
||||
sniff(iface="enp6s0f0np0", filter=f"udp and dst port {my_port}", prn=process_ack, store=False)
|
||||
###################
|
||||
|
||||
''' Archive:
|
||||
|
||||
# Add padding:
|
||||
payload = timestamp + "X" * (packet_size - len(timestamp))
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
3
sender-receiver-scripts/results/sender.sh
Executable file
3
sender-receiver-scripts/results/sender.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo ip netns exec tb_node2_if0 python3 sender.py 10.0.1.1 30123 30123 100 128
|
||||
99
sender-receiver-scripts/results/timestamps_30123
Normal file
99
sender-receiver-scripts/results/timestamps_30123
Normal file
@@ -0,0 +1,99 @@
|
||||
1,8490,8489
|
||||
136,8618,8482
|
||||
252,8750,8498
|
||||
368,8886,8518
|
||||
484,9022,8538
|
||||
604,9158,8554
|
||||
720,9298,8578
|
||||
843,9438,8595
|
||||
962,9578,8616
|
||||
1077,9706,8629
|
||||
1192,9846,8654
|
||||
1311,9962,8651
|
||||
1426,10106,8680
|
||||
1545,10255,8710
|
||||
1660,10391,8731
|
||||
1776,10547,8771
|
||||
1891,10681,8790
|
||||
2007,10816,8809
|
||||
2123,10947,8824
|
||||
2239,11082,8843
|
||||
2358,11221,8863
|
||||
2474,11356,8882
|
||||
2593,11495,8902
|
||||
2709,11626,8917
|
||||
2825,11761,8936
|
||||
2940,11896,8956
|
||||
3056,12044,8988
|
||||
3171,12174,9003
|
||||
3286,12310,9024
|
||||
3402,12442,9040
|
||||
3517,12557,9040
|
||||
3632,12692,9060
|
||||
3747,12823,9076
|
||||
3863,12958,9095
|
||||
3978,13097,9119
|
||||
4093,13236,9143
|
||||
4212,13393,9181
|
||||
4331,13524,9193
|
||||
4447,13659,9212
|
||||
4562,13794,9232
|
||||
4679,13929,9250
|
||||
4795,14067,9272
|
||||
4910,14185,9275
|
||||
5026,14341,9315
|
||||
5145,14477,9332
|
||||
5260,14612,9352
|
||||
5376,14748,9372
|
||||
5492,14887,9395
|
||||
5608,15022,9414
|
||||
5723,15153,9430
|
||||
5838,15267,9429
|
||||
5953,15402,9449
|
||||
6068,15537,9469
|
||||
6184,15672,9488
|
||||
6303,15804,9501
|
||||
6418,15943,9525
|
||||
6533,16078,9545
|
||||
6649,16221,9572
|
||||
6765,16360,9595
|
||||
6880,16499,9619
|
||||
6995,16631,9636
|
||||
7110,16766,9656
|
||||
7225,16901,9676
|
||||
7341,17061,9720
|
||||
7470,17196,9726
|
||||
7587,17339,9752
|
||||
7703,17478,9775
|
||||
7818,17596,9778
|
||||
7933,17739,9806
|
||||
8050,17874,9824
|
||||
8169,18009,9840
|
||||
8288,18158,9870
|
||||
8404,18289,9885
|
||||
8523,18424,9901
|
||||
8638,18555,9917
|
||||
8754,18670,9916
|
||||
8874,18805,9931
|
||||
8989,18936,9947
|
||||
9105,19075,9970
|
||||
9220,19206,9986
|
||||
9335,19341,10006
|
||||
9454,19472,10018
|
||||
9577,19615,10038
|
||||
9693,19742,10049
|
||||
9808,19898,10090
|
||||
9924,20029,10105
|
||||
10039,20168,10129
|
||||
10159,20299,10140
|
||||
10274,20434,10160
|
||||
10389,20565,10176
|
||||
10512,20693,10181
|
||||
10627,20820,10193
|
||||
10742,20951,10209
|
||||
10857,21086,10229
|
||||
10977,21238,10261
|
||||
11092,21359,10267
|
||||
11207,21515,10308
|
||||
11331,21646,10315
|
||||
11453,21781,10328
|
||||
@@ -18,6 +18,7 @@ N = 1 # Active senders (received from
|
||||
queue_utilization = 0 # Received as Q_i/Q_max
|
||||
delta_c = 0 # Time since the last ACK (calculated using T_ACK)
|
||||
|
||||
|
||||
# Function to calculate P_s
|
||||
def calculate_probability(N, queue_utilization, delta_c):
|
||||
if queue_utilization < 1:
|
||||
@@ -27,14 +28,13 @@ def calculate_probability(N, queue_utilization, delta_c):
|
||||
f_delta = max((delta_c - age_threshold) / age_threshold, 0)
|
||||
return (Q_max / N) + f_delta # Combine probabilities
|
||||
|
||||
|
||||
# Function to send a packet
|
||||
def send_packet(target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_flag):
|
||||
|
||||
ether_layer = Ether(dst="00:00:00:00:00:04", src="00:00:00:00:00:01")
|
||||
ip_layer = IP(dst=target_ip, tos=dscp_value << 2)
|
||||
udp_layer = UDP(dport=receiver_port, sport=my_port)
|
||||
|
||||
|
||||
# # Socket to listen for the ACKs
|
||||
# ack_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
# ack_socket.settimeout(2) # 2 seconds timer to receive the ack. Otherwise considered lost
|
||||
@@ -45,8 +45,10 @@ def send_packet(target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_
|
||||
global initial_timestamp
|
||||
timestamp = str(int(time.time() * 1000) - initial_timestamp)
|
||||
|
||||
if (not FIN_flag):
|
||||
payload = timestamp + "X" * max((packet_size - len(timestamp)), 0) # max to prevent possible errors when choosing too small packet size
|
||||
if not FIN_flag:
|
||||
payload = timestamp + "X" * max(
|
||||
(packet_size - len(timestamp)), 0
|
||||
) # max to prevent possible errors when choosing too small packet size
|
||||
else:
|
||||
payload = "END" + "X" * max((packet_size - len(timestamp)), 0)
|
||||
|
||||
@@ -54,18 +56,20 @@ def send_packet(target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_
|
||||
packet = ip_layer / udp_layer / Raw(load=payload)
|
||||
# sendp(packet, verbose=False)
|
||||
send(packet, verbose=False)
|
||||
print(".", end='', flush=True)
|
||||
print(".", end="", flush=True)
|
||||
|
||||
|
||||
# Listen for ACKs
|
||||
def process_ack(pkt):
|
||||
global last_update_time, N, queue_utilization, delta_c
|
||||
|
||||
if Raw in pkt:
|
||||
ack_data = pkt[Raw].load.decode('utf-8')
|
||||
ack_data = pkt[Raw].load.decode("utf-8")
|
||||
N, queue_utilization, T_ACK = eval(ack_data)
|
||||
last_update_time = T_ACK
|
||||
print(f"Received ACK: N={N}, Utilization={queue_utilization}, T_ACK={T_ACK}")
|
||||
|
||||
|
||||
# Main loop
|
||||
def main(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size):
|
||||
global delta_c
|
||||
@@ -76,19 +80,20 @@ def main(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size)
|
||||
if last_update_time:
|
||||
delta_c = time.time() - last_update_time
|
||||
else:
|
||||
delta_c = float('inf') # No ACK received yet
|
||||
delta_c = float("inf") # No ACK received yet
|
||||
|
||||
# Calculate sending probability
|
||||
P_s = calculate_probability(N, queue_utilization, delta_c)
|
||||
|
||||
# Decide whether to send a packet
|
||||
if random.random() < P_s:
|
||||
|
||||
FIN_flag = False
|
||||
if packets_sent == nb_packets - 1:
|
||||
FIN_flag = True
|
||||
|
||||
send_packet(target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_flag)
|
||||
send_packet(
|
||||
target_ip, receiver_port, my_port, dscp_value, packet_size, FIN_flag
|
||||
)
|
||||
packets_sent += 1
|
||||
print(f"Packet sent with probability P_s={P_s:.2f}")
|
||||
else:
|
||||
@@ -102,7 +107,9 @@ def main(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 6:
|
||||
print("Usage: python send_dscp_packets.py <target_ip> <my_port> <receiver_port> <nb_packets> <packet_size(in Bytes)>")
|
||||
print(
|
||||
"Usage: python send_dscp_packets.py <target_ip> <my_port> <receiver_port> <nb_packets> <packet_size(in Bytes)>"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
target_ip = sys.argv[1] # IP of the receiver
|
||||
@@ -114,16 +121,22 @@ if __name__ == "__main__":
|
||||
|
||||
# main(target_ip, receiver_port, my_port, dscp_value, nb_packets)
|
||||
|
||||
threading.Thread(target=main, args=(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size), daemon=True).start()
|
||||
threading.Thread(
|
||||
target=main,
|
||||
args=(target_ip, receiver_port, my_port, dscp_value, nb_packets, packet_size),
|
||||
daemon=True,
|
||||
).start()
|
||||
###################
|
||||
# With localhost:
|
||||
sniff(iface="lo", filter=f"udp and dst port {my_port}", prn=process_ack, store=False)#, timeout=0.1)
|
||||
###################
|
||||
# With netns:
|
||||
# sniff(iface="ns-r", filter=f"udp and dst port {my_port}", prn=process_ack, store=False)
|
||||
sniff(
|
||||
iface="lo", filter=f"udp and dst port {my_port}", prn=process_ack, store=False
|
||||
) # , timeout=0.1)
|
||||
###################
|
||||
# With netns:
|
||||
# sniff(iface="ns-r", filter=f"udp and dst port {my_port}", prn=process_ack, store=False)
|
||||
###################
|
||||
|
||||
''' Archive:
|
||||
""" Archive:
|
||||
|
||||
# Add padding:
|
||||
payload = timestamp + "X" * (packet_size - len(timestamp))
|
||||
@@ -131,4 +144,4 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
|
||||
'''
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user