feat(dscp): initial commit
This commit is contained in:
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM martenseemann/quic-network-simulator-endpoint:latest
|
||||
|
||||
# download and build your QUIC implementation
|
||||
# [ DO WORK HERE ]
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y python3 python3-loguru
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
# copy run script and run it
|
||||
COPY run_endpoint.sh .
|
||||
RUN chmod +x run_endpoint.sh
|
||||
COPY sender.py .
|
||||
COPY server.py .
|
||||
ENTRYPOINT [ "./run_endpoint.sh" ]
|
||||
6
compose.yml
Normal file
6
compose.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
services:
|
||||
dscp-toy:
|
||||
image: git.rust.cloud/dscp/toy:latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
9
pyproject.toml
Normal file
9
pyproject.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "test"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"loguru>=0.7.2",
|
||||
]
|
||||
17
run_endpoint.sh
Normal file
17
run_endpoint.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set up the routing needed for the simulation
|
||||
/setup.sh
|
||||
|
||||
# The following variables are available for use:
|
||||
# - ROLE contains the role of this execution context, client or server
|
||||
# - SERVER_PARAMS contains user-supplied command line parameters
|
||||
# - CLIENT_PARAMS contains user-supplied command line parameters
|
||||
|
||||
if [ "$ROLE" == "client" ]; then
|
||||
# Wait for the simulator to start up.
|
||||
/wait-for-it.sh sim:57832 -s -t 30
|
||||
python sender.py $CLIENT_PARAMS
|
||||
elif [ "$ROLE" == "server" ]; then
|
||||
python server.py $SERVER_PARAMS
|
||||
fi
|
||||
68
sender.py
Normal file
68
sender.py
Normal file
@@ -0,0 +1,68 @@
|
||||
from argparse import ArgumentParser
|
||||
from socket import socket, AF_INET, SOCK_DGRAM, IPPROTO_IP, IP_TOS
|
||||
from time import sleep
|
||||
import re
|
||||
import time
|
||||
import sys
|
||||
from loguru import logger
|
||||
|
||||
|
||||
def parse_bandwidth(input_str):
|
||||
pattern = r'^(\d+(?:\.\d+)?)\s*([kKmMgGtT])bps$'
|
||||
match = re.match(pattern, input_str)
|
||||
|
||||
if match:
|
||||
value = float(match.group(1))
|
||||
unit = match.group(2).lower()
|
||||
|
||||
multipliers = {
|
||||
'k': 1e3,
|
||||
'm': 1e6,
|
||||
'g': 1e9,
|
||||
't': 1e12
|
||||
}
|
||||
|
||||
multiplier = multipliers.get(unit, 1.0)
|
||||
return value * multiplier
|
||||
else:
|
||||
raise ValueError(f"Invalid bandwidth: {input_str}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('--host', type=str, default='localhost')
|
||||
parser.add_argument('--port', type=int, default=12345)
|
||||
parser.add_argument("--log-level", type=str, default="INFO")
|
||||
parser.add_argument("--bandwidth", type=str, default="1Mbps")
|
||||
parser.add_argument("--duration", type=int, default=10)
|
||||
parser.add_argument("--dscp", type=str, default="")
|
||||
args = parser.parse_args()
|
||||
logger.remove()
|
||||
logger.add(sys.stderr, level=args.log_level)
|
||||
PACKET_SIZE = 1280
|
||||
bandwidth = parse_bandwidth(args.bandwidth)
|
||||
time_between_packets = PACKET_SIZE / bandwidth
|
||||
packet_cnt = 0
|
||||
logger.info(f"Connecting to {args.host}:{args.port}")
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
dscp = int(args.dscp) if args.dscp else 0
|
||||
if dscp:
|
||||
sock.setsockopt(IPPROTO_IP, IP_TOS, dscp << 2)
|
||||
CODE_WORD = "CAFEABBA"
|
||||
payload = (CODE_WORD + "A" * (PACKET_SIZE - len(CODE_WORD))).encode()
|
||||
t0 = time.time()
|
||||
while True:
|
||||
logger.debug("Sending message:")
|
||||
sock.sendto(payload, (args.host, args.port))
|
||||
packet_cnt += 1
|
||||
t1 = time.time() - t0
|
||||
if t1 > args.duration:
|
||||
break
|
||||
time_to_sleep = time_between_packets * packet_cnt - t1
|
||||
if time_to_sleep > 0:
|
||||
sleep(time_between_packets * packet_cnt - t1)
|
||||
else:
|
||||
logger.warning("We are too slow: {}s", -time_to_sleep)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
37
server.py
Normal file
37
server.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import socket
|
||||
import argparse
|
||||
import time
|
||||
import sys
|
||||
|
||||
def main():
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="UDP Packet Receiver with Timeout")
|
||||
parser.add_argument('--port', type=int, required=True, help="Port to listen for UDP packets.")
|
||||
parser.add_argument('--timeout', type=int, required=True, help="Timeout in seconds to shut down if no packets are received.")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Create a UDP socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock.bind(("", args.port))
|
||||
print(f"Listening for UDP packets on port {args.port}...")
|
||||
|
||||
# Set the timeout for the socket
|
||||
sock.settimeout(args.timeout)
|
||||
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
# Wait for a UDP packet
|
||||
data, addr = sock.recvfrom(1024) # Buffer size is 1024 bytes
|
||||
except socket.timeout:
|
||||
print(f"No packets received for {args.timeout} seconds. Shutting down.")
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
print("\nShutting down due to user interrupt.")
|
||||
finally:
|
||||
sock.close()
|
||||
print("Socket closed.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
44
uv.lock
generated
Normal file
44
uv.lock
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "loguru"
|
||||
version = "0.7.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "win32-setctime", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9e/30/d87a423766b24db416a46e9335b9602b054a72b96a88a241f2b09b560fa8/loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac", size = 145103 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/03/0a/4f6fed21aa246c6b49b561ca55facacc2a44b87d65b8b92362a8e99ba202/loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb", size = 62549 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "loguru" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "loguru", specifier = ">=0.7.2" }]
|
||||
|
||||
[[package]]
|
||||
name = "win32-setctime"
|
||||
version = "1.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6b/dd/f95a13d2b235a28d613ba23ebad55191514550debb968b46aab99f2e3a30/win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2", size = 3676 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/e6/a7d828fef907843b2a5773ebff47fb79ac0c1c88d60c0ca9530ee941e248/win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad", size = 3604 },
|
||||
]
|
||||
Reference in New Issue
Block a user