Last active
February 28, 2018 00:10
-
-
Save Fahrradkette/3678faa152b5d6258cf7 to your computer and use it in GitHub Desktop.
UDP lag-inducing proxy server using python asyncio
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
import sys | |
class FakeServerProtocol(asyncio.DatagramProtocol): | |
def __init__(self, target_addr, stc_delay, cts_delay, loop=None): | |
self.loop = loop | |
if self.loop is None: | |
self.loop = asyncio.get_event_loop() | |
self.transport = None | |
self.target_addr = target_addr | |
self.client_addr = None | |
self.stc_delay = stc_delay | |
self.cts_delay = cts_delay | |
self.loop.call_later(2, self.update_delay, self.loop) | |
def connection_made(self, transport): | |
self.transport = transport | |
def datagram_received(self, data, addr): | |
if addr != self.target_addr: | |
if self.client_addr == None: | |
self.client_addr = addr | |
elif addr != self.client_addr: | |
self.client_addr = addr | |
self.loop.call_later(self.cts_delay, lambda: self.transport.sendto(data, self.target_addr)) | |
else: | |
if self.client_addr != None: | |
self.loop.call_later(self.stc_delay, lambda: self.transport.sendto(data, self.client_addr)) | |
def update_delay(self, loop): | |
self.stc_delay = stc_delay | |
self.cts_delay = cts_delay | |
self.loop.call_later(1, self.update_delay, self.loop) | |
def handle_stdin(): | |
data = sys.stdin.readline() | |
delays = data.split(' ') | |
stc = "" | |
cts = "" | |
if len(delays) > 1: | |
cts = delays[1] | |
else: | |
cts = delays[0] | |
try: | |
stc_ = float(delays[0]) | |
cts_ = float(cts) | |
except ValueError: | |
print("Please enter numbers only") | |
return | |
print("new server to client delay: {}ms".format(stc_)) | |
print("new client to server delay: {}ms".format(cts_)) | |
global stc_delay | |
global cts_delay | |
stc_delay = stc_/1000 | |
cts_delay = cts_/1000 | |
# access the proxy on this address | |
proxy_address = ('192.168.0.6', 12345) | |
# the udp server it's being proxied to | |
target_addr = ('192.168.0.6', 34197) | |
# server to client delay in seconds | |
stc_delay = 0.6 | |
# client to server delay in seconds | |
cts_delay = 0.7 | |
loop = asyncio.get_event_loop() | |
print("Starting UDP proxy server on {}:{}, target: {}:{}".format( | |
proxy_address[0], | |
proxy_address[1], | |
target_addr[0], | |
target_addr[1])) | |
print("server to client delay: {}ms, client to server delay: {}ms".format( | |
int(stc_delay*1000), int(cts_delay*1000))) | |
listen = loop.create_datagram_endpoint( | |
lambda: FakeServerProtocol(target_addr, stc_delay, cts_delay), | |
local_addr=proxy_address | |
) | |
serve_transport, protocol = loop.run_until_complete(listen) | |
loop.add_reader(sys.stdin, handle_stdin) | |
print() | |
print("Enter one or two numbers, seperated by a space, to adjust the simulated lag.") | |
print("The first number will be server to client, the second client to server delay.") | |
print("If you ommit the second number, both delays will have the same value.") | |
print() | |
print("Hit Ctrl+C to abort") | |
try: | |
loop.run_forever() | |
except KeyboardInterrupt: | |
pass | |
serve_transport.close() | |
loop.remove_reader(sys.stdin) | |
loop.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment