3proxy/tests/cases/portmap.py

65 lines
2.0 KiB
Python

"""The port mappers: tcppm forwards a TCP port, udppm a UDP one."""
def run(t):
# --- tcppm ---------------------------------------------------------
origin = t.free_port()
mapped = t.free_port()
refused = t.free_port()
t.start("portmap_tcp", f"""
log
auth iponly
allow *
http echo * /echo**
http data * /data
httpsrv -p{origin}
flush
auth iponly
allow *
tcppm {mapped} 127.0.0.1 {origin}
flush
auth iponly
deny *
tcppm {refused} 127.0.0.1 {origin}
""", ports=[origin, mapped, refused])
r = t.http(f"http://127.0.0.1:{mapped}/echo")
t.eq(200, r.status, "a mapped TCP port reaches the target")
t.contains(r, "path=/echo", "the target sees the request")
t.contains(r, "peer.addr=127.0.0.1", "the mapper makes the connection")
t.eq(20000, t.http(f"http://127.0.0.1:{mapped}/data?size=20000").length,
"a body passes through the mapper")
# the mapper is a service like any other, so its rules apply
r = t.http(f"http://127.0.0.1:{refused}/echo")
t.ne(200, r.status, "a mapper whose rules deny the client answers nothing")
t.stop_all()
# --- udppm ---------------------------------------------------------
# something has to be listening for the mapped datagrams to go anywhere
echo = t.udp_echo()
mapped = t.free_port()
t.start("portmap_udp", f"""
log
flush
auth iponly
allow *
udppm {mapped} 127.0.0.1 {echo}
""")
# a UDP service has no listening socket to wait for, so ask until it
# answers rather than racing it
t.wait_udp(mapped)
t.eq(b"echo:hello", t.udp_exchange(mapped, b"hello"),
"a datagram is relayed and the reply comes back")
t.eq(b"echo:second", t.udp_exchange(mapped, b"second"),
"a second datagram uses the mapping again")
big = b"x" * 2000
t.eq(b"echo:" + big, t.udp_exchange(mapped, big),
"a larger datagram survives the round trip")