mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-22 13:40:19 +00:00
Compare commits
13 Commits
1331cfa239
...
c1bba0030e
Author | SHA1 | Date | |
---|---|---|---|
|
c1bba0030e | ||
|
1282061701 | ||
|
49dba483a9 | ||
|
ebec63487f | ||
|
9373819234 | ||
|
04925d8004 | ||
|
4284084fef | ||
|
63ad2afe3f | ||
|
61712d322a | ||
|
3599066356 | ||
|
18c2a38b97 | ||
|
f55004a574 | ||
|
1768ddc459 |
@ -58,6 +58,9 @@ class KISS():
|
|||||||
class ThreadingTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
class ThreadingTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class ThreadingTCP6Server(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||||
|
address_family = socket.AF_INET6
|
||||||
|
|
||||||
class TCPClientInterface(Interface):
|
class TCPClientInterface(Interface):
|
||||||
BITRATE_GUESS = 10*1000*1000
|
BITRATE_GUESS = 10*1000*1000
|
||||||
|
|
||||||
@ -200,10 +203,14 @@ class TCPClientInterface(Interface):
|
|||||||
if initial:
|
if initial:
|
||||||
RNS.log("Establishing TCP connection for "+str(self)+"...", RNS.LOG_DEBUG)
|
RNS.log("Establishing TCP connection for "+str(self)+"...", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
address_info = socket.getaddrinfo(self.target_ip, self.target_port, proto=socket.IPPROTO_TCP)[0]
|
||||||
|
address_family = address_info[0]
|
||||||
|
target_address = address_info[4]
|
||||||
|
|
||||||
|
self.socket = socket.socket(address_family, socket.SOCK_STREAM)
|
||||||
self.socket.settimeout(TCPClientInterface.INITIAL_CONNECT_TIMEOUT)
|
self.socket.settimeout(TCPClientInterface.INITIAL_CONNECT_TIMEOUT)
|
||||||
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
self.socket.connect((self.target_ip, self.target_port))
|
self.socket.connect(target_address)
|
||||||
self.socket.settimeout(None)
|
self.socket.settimeout(None)
|
||||||
self.online = True
|
self.online = True
|
||||||
|
|
||||||
@ -409,18 +416,37 @@ class TCPServerInterface(Interface):
|
|||||||
BITRATE_GUESS = 10*1000*1000
|
BITRATE_GUESS = 10*1000*1000
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_address_for_if(name):
|
def get_address_for_if(name, bind_port, prefer_ipv6=False):
|
||||||
import RNS.vendor.ifaddr.niwrapper as netinfo
|
import RNS.vendor.ifaddr.niwrapper as netinfo
|
||||||
ifaddr = netinfo.ifaddresses(name)
|
ifaddr = netinfo.ifaddresses(name)
|
||||||
return ifaddr[netinfo.AF_INET][0]["addr"]
|
if len(ifaddr) < 1:
|
||||||
|
raise SystemError(f"No addresses available on specified kernel interface \"{name}\" for TCPServerInterface to bind to")
|
||||||
|
|
||||||
|
if prefer_ipv6 and netinfo.AF_INET6 in ifaddr:
|
||||||
|
bind_ip = ifaddr[netinfo.AF_INET6][0]["addr"]
|
||||||
|
if bind_ip.lower().startswith("fe80::"):
|
||||||
|
# We'll need to add the interface as scope for link-local addresses
|
||||||
|
return TCPServerInterface.get_address_for_host(f"{bind_ip}%{name}", bind_port)
|
||||||
|
else:
|
||||||
|
return TCPServerInterface.get_address_for_host(bind_ip, bind_port)
|
||||||
|
elif netinfo.AF_INET in ifaddr:
|
||||||
|
bind_ip = ifaddr[netinfo.AF_INET][0]["addr"]
|
||||||
|
return (bind_ip, bind_port)
|
||||||
|
else:
|
||||||
|
raise SystemError(f"No addresses available on specified kernel interface \"{name}\" for TCPServerInterface to bind to")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_broadcast_for_if(name):
|
def get_address_for_host(name, bind_port):
|
||||||
import RNS.vendor.ifaddr.niwrapper as netinfo
|
address_info = socket.getaddrinfo(name, bind_port, proto=socket.IPPROTO_TCP)[0]
|
||||||
ifaddr = netinfo.ifaddresses(name)
|
if address_info[0] == socket.AF_INET6:
|
||||||
return ifaddr[netinfo.AF_INET][0]["broadcast"]
|
return (name, bind_port, address_info[4][2], address_info[4][3])
|
||||||
|
elif address_info[0] == socket.AF_INET:
|
||||||
|
return (name, bind_port)
|
||||||
|
else:
|
||||||
|
raise SystemError(f"No suitable kernel interface available for address \"{name}\" for TCPServerInterface to bind to")
|
||||||
|
|
||||||
def __init__(self, owner, name, device=None, bindip=None, bindport=None, i2p_tunneled=False):
|
|
||||||
|
def __init__(self, owner, name, device=None, bindip=None, bindport=None, i2p_tunneled=False, prefer_ipv6=False):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.HW_MTU = 1064
|
self.HW_MTU = 1064
|
||||||
@ -436,24 +462,40 @@ class TCPServerInterface(Interface):
|
|||||||
self.i2p_tunneled = i2p_tunneled
|
self.i2p_tunneled = i2p_tunneled
|
||||||
self.mode = RNS.Interfaces.Interface.Interface.MODE_FULL
|
self.mode = RNS.Interfaces.Interface.Interface.MODE_FULL
|
||||||
|
|
||||||
if device != None:
|
if bindport == None:
|
||||||
bindip = TCPServerInterface.get_address_for_if(device)
|
raise SystemError(f"No TCP port configured for interface \"{name}\"")
|
||||||
|
else:
|
||||||
if (bindip != None and bindport != None):
|
|
||||||
self.receives = True
|
|
||||||
self.bind_ip = bindip
|
|
||||||
self.bind_port = bindport
|
self.bind_port = bindport
|
||||||
|
|
||||||
|
bind_address = None
|
||||||
|
if device != None:
|
||||||
|
bind_address = TCPServerInterface.get_address_for_if(device, self.bind_port, prefer_ipv6)
|
||||||
|
else:
|
||||||
|
if bindip == None:
|
||||||
|
raise SystemError(f"No TCP bind IP configured for interface \"{name}\"")
|
||||||
|
bind_address = TCPServerInterface.get_address_for_host(bindip, self.bind_port)
|
||||||
|
|
||||||
|
if bind_address != None:
|
||||||
|
self.receives = True
|
||||||
|
self.bind_ip = bind_address[0]
|
||||||
|
|
||||||
def handlerFactory(callback):
|
def handlerFactory(callback):
|
||||||
def createHandler(*args, **keys):
|
def createHandler(*args, **keys):
|
||||||
return TCPInterfaceHandler(callback, *args, **keys)
|
return TCPInterfaceHandler(callback, *args, **keys)
|
||||||
return createHandler
|
return createHandler
|
||||||
|
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
address = (self.bind_ip, self.bind_port)
|
|
||||||
|
|
||||||
|
if len(bind_address) == 4:
|
||||||
|
try:
|
||||||
|
ThreadingTCP6Server.allow_reuse_address = True
|
||||||
|
self.server = ThreadingTCP6Server(bind_address, handlerFactory(self.incoming_connection))
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log(f"Error while binding IPv6 socket for interface, the contained exception was: {e}", RNS.LOG_ERROR)
|
||||||
|
raise SystemError("Could not bind IPv6 socket for interface. Please check the specified \"listen_ip\" configuration option")
|
||||||
|
else:
|
||||||
ThreadingTCPServer.allow_reuse_address = True
|
ThreadingTCPServer.allow_reuse_address = True
|
||||||
self.server = ThreadingTCPServer(address, handlerFactory(self.incoming_connection))
|
self.server = ThreadingTCPServer(bind_address, handlerFactory(self.incoming_connection))
|
||||||
|
|
||||||
self.bitrate = TCPServerInterface.BITRATE_GUESS
|
self.bitrate = TCPServerInterface.BITRATE_GUESS
|
||||||
|
|
||||||
@ -463,6 +505,8 @@ class TCPServerInterface(Interface):
|
|||||||
|
|
||||||
self.online = True
|
self.online = True
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise SystemError("Insufficient parameters to create TCP listener")
|
||||||
|
|
||||||
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)
|
||||||
|
@ -640,6 +640,7 @@ class Reticulum:
|
|||||||
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
|
i2p_tunneled = c.as_bool("i2p_tunneled") if "i2p_tunneled" in c else False
|
||||||
|
prefer_ipv6 = c.as_bool("prefer_ipv6") if "prefer_ipv6" in c else False
|
||||||
|
|
||||||
if port != None:
|
if port != None:
|
||||||
listen_port = port
|
listen_port = port
|
||||||
@ -650,7 +651,8 @@ class Reticulum:
|
|||||||
device,
|
device,
|
||||||
listen_ip,
|
listen_ip,
|
||||||
listen_port,
|
listen_port,
|
||||||
i2p_tunneled
|
i2p_tunneled,
|
||||||
|
prefer_ipv6,
|
||||||
)
|
)
|
||||||
|
|
||||||
if "outgoing" in c and c.as_bool("outgoing") == False:
|
if "outgoing" in c and c.as_bool("outgoing") == False:
|
||||||
|
Loading…
Reference in New Issue
Block a user