Added I2P-tunneled mode to TCP interfaces

This commit is contained in:
Mark Qvist 2022-01-31 23:31:29 +01:00
parent 05288d7c97
commit 3f53c89d32
2 changed files with 36 additions and 13 deletions

View File

@ -46,7 +46,12 @@ class TCPClientInterface(Interface):
TCP_PROBE_INTERVAL = 3 TCP_PROBE_INTERVAL = 3
TCP_PROBES = 5 TCP_PROBES = 5
def __init__(self, owner, name, target_ip=None, target_port=None, connected_socket=None, max_reconnect_tries=None, kiss_framing=False): I2P_USER_TIMEOUT = 40
I2P_PROBE_AFTER = 10
I2P_PROBE_INTERVAL = 5
I2P_PROBES = 6
def __init__(self, owner, name, target_ip=None, target_port=None, connected_socket=None, max_reconnect_tries=None, kiss_framing=False, i2p_tunneled = False):
self.rxb = 0 self.rxb = 0
self.txb = 0 self.txb = 0
@ -63,6 +68,7 @@ class TCPClientInterface(Interface):
self.online = False self.online = False
self.detached = False self.detached = False
self.kiss_framing = kiss_framing self.kiss_framing = kiss_framing
self.i2p_tunneled = i2p_tunneled
if max_reconnect_tries == None: if max_reconnect_tries == None:
self.max_reconnect_tries = TCPClientInterface.RECONNECT_MAX_TRIES self.max_reconnect_tries = TCPClientInterface.RECONNECT_MAX_TRIES
@ -99,12 +105,18 @@ class TCPClientInterface(Interface):
def set_timeouts_linux(self): def set_timeouts_linux(self):
if not self.i2p_tunneled:
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, int(TCPClientInterface.TCP_USER_TIMEOUT * 1000)) self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, int(TCPClientInterface.TCP_USER_TIMEOUT * 1000))
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, int(TCPClientInterface.TCP_PROBE_AFTER)) self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, int(TCPClientInterface.TCP_PROBE_AFTER))
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, int(TCPClientInterface.TCP_PROBE_INTERVAL)) self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, int(TCPClientInterface.TCP_PROBE_INTERVAL))
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, int(TCPClientInterface.TCP_PROBES)) self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, int(TCPClientInterface.TCP_PROBES))
else:
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, int(TCPClientInterface.I2P_USER_TIMEOUT * 1000))
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, int(TCPClientInterface.I2P_PROBE_AFTER))
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, int(TCPClientInterface.I2P_PROBE_INTERVAL))
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, int(TCPClientInterface.I2P_PROBES))
def set_timeouts_osx(self): def set_timeouts_osx(self):
if hasattr(socket, "TCP_KEEPALIVE"): if hasattr(socket, "TCP_KEEPALIVE"):
@ -113,7 +125,11 @@ class TCPClientInterface(Interface):
TCP_KEEPIDLE = 0x10 TCP_KEEPIDLE = 0x10
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if not self.i2p_tunneled:
self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPIDLE, int(TCPClientInterface.TCP_PROBE_AFTER)) self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPIDLE, int(TCPClientInterface.TCP_PROBE_AFTER))
else:
self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPIDLE, int(TCPClientInterface.I2P_PROBE_AFTER))
def detach(self): def detach(self):
if self.socket != None: if self.socket != None:
@ -358,7 +374,7 @@ class TCPServerInterface(Interface):
RNS.log("You can install it with the command: python3 -m pip install netifaces", RNS.LOG_CRITICAL) RNS.log("You can install it with the command: python3 -m pip install netifaces", RNS.LOG_CRITICAL)
RNS.panic() RNS.panic()
def __init__(self, owner, name, device=None, bindip=None, bindport=None): def __init__(self, owner, name, device=None, bindip=None, bindport=None, i2p_tunneled=False):
self.rxb = 0 self.rxb = 0
self.txb = 0 self.txb = 0
self.online = False self.online = False
@ -368,6 +384,8 @@ class TCPServerInterface(Interface):
self.OUT = False self.OUT = False
self.name = name self.name = name
self.i2p_tunneled = i2p_tunneled
if device != None: if device != None:
bindip = TCPServerInterface.get_address_for_if(device) bindip = TCPServerInterface.get_address_for_if(device)
@ -397,7 +415,7 @@ class TCPServerInterface(Interface):
def incoming_connection(self, handler): def incoming_connection(self, handler):
RNS.log("Accepting incoming TCP connection", RNS.LOG_VERBOSE) RNS.log("Accepting incoming TCP connection", RNS.LOG_VERBOSE)
interface_name = "Client on "+self.name interface_name = "Client on "+self.name
spawned_interface = TCPClientInterface(self.owner, interface_name, target_ip=None, target_port=None, connected_socket=handler.request) spawned_interface = TCPClientInterface(self.owner, interface_name, target_ip=None, target_port=None, connected_socket=handler.request, i2p_tunneled=self.i2p_tunneled)
spawned_interface.OUT = self.OUT spawned_interface.OUT = self.OUT
spawned_interface.IN = self.IN spawned_interface.IN = self.IN
spawned_interface.target_ip = handler.client_address[0] spawned_interface.target_ip = handler.client_address[0]

View File

@ -349,6 +349,7 @@ class Reticulum:
port = int(c["port"]) if "port" in c else None port = int(c["port"]) if "port" in c else None
listen_ip = c["listen_ip"] if "listen_ip" in c else None listen_ip = c["listen_ip"] if "listen_ip" in c else None
listen_port = int(c["listen_port"]) if "listen_port" in c else None listen_port = int(c["listen_port"]) if "listen_port" in c else None
i2p_tunneled = c.as_bool("i2p_tunneled") if "i2p_tunneled" in c else False
if port != None: if port != None:
listen_port = port listen_port = port
@ -358,7 +359,8 @@ class Reticulum:
name, name,
device, device,
listen_ip, listen_ip,
listen_port listen_port,
i2p_tunneled
) )
if "outgoing" in c and c.as_bool("outgoing") == True: if "outgoing" in c and c.as_bool("outgoing") == True:
@ -373,13 +375,16 @@ class Reticulum:
kiss_framing = False kiss_framing = False
if "kiss_framing" in c and c.as_bool("kiss_framing") == True: if "kiss_framing" in c and c.as_bool("kiss_framing") == True:
kiss_framing = True kiss_framing = True
i2p_tunneled = c.as_bool("i2p_tunneled") if "i2p_tunneled" in c else False
interface = TCPInterface.TCPClientInterface( interface = TCPInterface.TCPClientInterface(
RNS.Transport, RNS.Transport,
name, name,
c["target_host"], c["target_host"],
int(c["target_port"]), int(c["target_port"]),
kiss_framing = kiss_framing kiss_framing = kiss_framing,
i2p_tunneled
) )
if "outgoing" in c and c.as_bool("outgoing") == True: if "outgoing" in c and c.as_bool("outgoing") == True: