mirror of
https://github.com/markqvist/Reticulum.git
synced 2025-06-08 23:13:17 -04:00
Added IPv6 support to BackboneInterface
This commit is contained in:
parent
b58cb3c0ed
commit
628c4984a3
3 changed files with 49 additions and 18 deletions
|
@ -64,9 +64,9 @@ class BackboneInterface(Interface):
|
||||||
bind_ip = ifaddr[netinfo.AF_INET6][0]["addr"]
|
bind_ip = ifaddr[netinfo.AF_INET6][0]["addr"]
|
||||||
if bind_ip.lower().startswith("fe80::"):
|
if bind_ip.lower().startswith("fe80::"):
|
||||||
# We'll need to add the interface as scope for link-local addresses
|
# We'll need to add the interface as scope for link-local addresses
|
||||||
return self.get_address_for_host(f"{bind_ip}%{name}", bind_port)
|
return BackboneInterface.get_address_for_host(f"{bind_ip}%{name}", bind_port, prefer_ipv6)
|
||||||
else:
|
else:
|
||||||
return self.get_address_for_host(bind_ip, bind_port)
|
return BackboneInterface.get_address_for_host(bind_ip, bind_port, prefer_ipv6)
|
||||||
elif netinfo.AF_INET in ifaddr:
|
elif netinfo.AF_INET in ifaddr:
|
||||||
bind_ip = ifaddr[netinfo.AF_INET][0]["addr"]
|
bind_ip = ifaddr[netinfo.AF_INET][0]["addr"]
|
||||||
return (bind_ip, bind_port)
|
return (bind_ip, bind_port)
|
||||||
|
@ -74,8 +74,15 @@ class BackboneInterface(Interface):
|
||||||
raise SystemError(f"No addresses available on specified kernel interface \"{name}\" for BackboneInterface to bind to")
|
raise SystemError(f"No addresses available on specified kernel interface \"{name}\" for BackboneInterface to bind to")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_address_for_host(name, bind_port):
|
def get_address_for_host(name, bind_port, prefer_ipv6=False):
|
||||||
address_info = socket.getaddrinfo(name, bind_port, proto=socket.IPPROTO_TCP)[0]
|
address_infos = socket.getaddrinfo(name, bind_port, proto=socket.IPPROTO_TCP)
|
||||||
|
address_info = address_infos[0]
|
||||||
|
for entry in address_infos:
|
||||||
|
if prefer_ipv6 and entry[0] == socket.AF_INET6:
|
||||||
|
address_info = entry; break
|
||||||
|
elif not prefer_ipv6 and entry[0] == socket.AF_INET:
|
||||||
|
address_info = entry; break
|
||||||
|
|
||||||
if address_info[0] == socket.AF_INET6:
|
if address_info[0] == socket.AF_INET6:
|
||||||
return (name, bind_port, address_info[4][2], address_info[4][3])
|
return (name, bind_port, address_info[4][2], address_info[4][3])
|
||||||
elif address_info[0] == socket.AF_INET:
|
elif address_info[0] == socket.AF_INET:
|
||||||
|
@ -124,14 +131,16 @@ class BackboneInterface(Interface):
|
||||||
else:
|
else:
|
||||||
if bindip == None:
|
if bindip == None:
|
||||||
raise SystemError(f"No TCP bind IP configured for interface \"{name}\"")
|
raise SystemError(f"No TCP bind IP configured for interface \"{name}\"")
|
||||||
bind_address = self.get_address_for_host(bindip, self.bind_port)
|
bind_address = self.get_address_for_host(bindip, self.bind_port, prefer_ipv6)
|
||||||
|
|
||||||
if bind_address != None:
|
if bind_address != None:
|
||||||
self.receives = True
|
self.receives = True
|
||||||
self.bind_ip = bind_address[0]
|
self.bind_ip = bind_address[0]
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
|
|
||||||
BackboneInterface.add_listener(self, bind_address)
|
if len(bind_address) == 2 : BackboneInterface.add_listener(self, bind_address, socket_type=socket.AF_INET)
|
||||||
|
elif len(bind_address) == 4: BackboneInterface.add_listener(self, bind_address, socket_type=socket.AF_INET6)
|
||||||
|
|
||||||
self.bitrate = self.BITRATE_GUESS
|
self.bitrate = self.BITRATE_GUESS
|
||||||
self.online = True
|
self.online = True
|
||||||
|
|
||||||
|
@ -153,6 +162,10 @@ class BackboneInterface(Interface):
|
||||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
server_socket.bind(bind_address)
|
server_socket.bind(bind_address)
|
||||||
|
elif socket_type == socket.AF_INET6:
|
||||||
|
server_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||||
|
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
server_socket.bind(bind_address)
|
||||||
elif socket_type == socket.AF_UNIX:
|
elif socket_type == socket.AF_UNIX:
|
||||||
server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
server_socket.bind(bind_address)
|
server_socket.bind(bind_address)
|
||||||
|
@ -216,7 +229,6 @@ class BackboneInterface(Interface):
|
||||||
with BackboneInterface._job_lock:
|
with BackboneInterface._job_lock:
|
||||||
if BackboneInterface._job_active: return
|
if BackboneInterface._job_active: return
|
||||||
else:
|
else:
|
||||||
RNS.log(f"Starting BackboneInterface I/O handler", RNS.LOG_DEBUG) # TODO: Remove debug
|
|
||||||
BackboneInterface._job_active = True
|
BackboneInterface._job_active = True
|
||||||
BackboneInterface.ensure_epoll()
|
BackboneInterface.ensure_epoll()
|
||||||
try:
|
try:
|
||||||
|
@ -419,6 +431,7 @@ class BackboneClientInterface(Interface):
|
||||||
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
|
||||||
connect_timeout = c.as_int("connect_timeout") if "connect_timeout" in c else None
|
connect_timeout = c.as_int("connect_timeout") if "connect_timeout" in c else None
|
||||||
max_reconnect_tries = c.as_int("max_reconnect_tries") if "max_reconnect_tries" in c else None
|
max_reconnect_tries = c.as_int("max_reconnect_tries") if "max_reconnect_tries" in c else None
|
||||||
|
prefer_ipv6 = c.as_bool("prefer_ipv6") if "prefer_ipv6" in c else False
|
||||||
|
|
||||||
self.HW_MTU = BackboneInterface.HW_MTU
|
self.HW_MTU = BackboneInterface.HW_MTU
|
||||||
self.IN = True
|
self.IN = True
|
||||||
|
@ -432,6 +445,7 @@ class BackboneClientInterface(Interface):
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.online = False
|
self.online = False
|
||||||
self.detached = False
|
self.detached = False
|
||||||
|
self.prefer_ipv6 = prefer_ipv6
|
||||||
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
|
||||||
self.bitrate = BackboneClientInterface.BITRATE_GUESS
|
self.bitrate = BackboneClientInterface.BITRATE_GUESS
|
||||||
|
@ -507,7 +521,14 @@ class BackboneClientInterface(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)
|
||||||
|
|
||||||
address_info = socket.getaddrinfo(self.target_ip, self.target_port, proto=socket.IPPROTO_TCP)[0]
|
address_infos = socket.getaddrinfo(self.target_ip, self.target_port, proto=socket.IPPROTO_TCP)
|
||||||
|
address_info = address_infos[0]
|
||||||
|
for entry in address_infos:
|
||||||
|
if self.prefer_ipv6 and entry[0] == socket.AF_INET6:
|
||||||
|
address_info = entry; break
|
||||||
|
elif not self.prefer_ipv6 and entry[0] == socket.AF_INET:
|
||||||
|
address_info = entry; break
|
||||||
|
|
||||||
address_family = address_info[0]
|
address_family = address_info[0]
|
||||||
target_address = address_info[4]
|
target_address = address_info[4]
|
||||||
|
|
||||||
|
|
|
@ -454,9 +454,9 @@ class TCPServerInterface(Interface):
|
||||||
bind_ip = ifaddr[netinfo.AF_INET6][0]["addr"]
|
bind_ip = ifaddr[netinfo.AF_INET6][0]["addr"]
|
||||||
if bind_ip.lower().startswith("fe80::"):
|
if bind_ip.lower().startswith("fe80::"):
|
||||||
# We'll need to add the interface as scope for link-local addresses
|
# 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)
|
return TCPServerInterface.get_address_for_host(f"{bind_ip}%{name}", bind_port, prefer_ipv6)
|
||||||
else:
|
else:
|
||||||
return TCPServerInterface.get_address_for_host(bind_ip, bind_port)
|
return TCPServerInterface.get_address_for_host(bind_ip, bind_port, prefer_ipv6)
|
||||||
elif netinfo.AF_INET in ifaddr:
|
elif netinfo.AF_INET in ifaddr:
|
||||||
bind_ip = ifaddr[netinfo.AF_INET][0]["addr"]
|
bind_ip = ifaddr[netinfo.AF_INET][0]["addr"]
|
||||||
return (bind_ip, bind_port)
|
return (bind_ip, bind_port)
|
||||||
|
@ -464,8 +464,15 @@ class TCPServerInterface(Interface):
|
||||||
raise SystemError(f"No addresses available on specified kernel interface \"{name}\" for TCPServerInterface to bind to")
|
raise SystemError(f"No addresses available on specified kernel interface \"{name}\" for TCPServerInterface to bind to")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_address_for_host(name, bind_port):
|
def get_address_for_host(name, bind_port, prefer_ipv6=False):
|
||||||
address_info = socket.getaddrinfo(name, bind_port, proto=socket.IPPROTO_TCP)[0]
|
address_infos = socket.getaddrinfo(name, bind_port, proto=socket.IPPROTO_TCP)
|
||||||
|
address_info = address_infos[0]
|
||||||
|
for entry in address_infos:
|
||||||
|
if prefer_ipv6 and entry[0] == socket.AF_INET6:
|
||||||
|
address_info = entry; break
|
||||||
|
elif not prefer_ipv6 and entry[0] == socket.AF_INET:
|
||||||
|
address_info = entry; break
|
||||||
|
|
||||||
if address_info[0] == socket.AF_INET6:
|
if address_info[0] == socket.AF_INET6:
|
||||||
return (name, bind_port, address_info[4][2], address_info[4][3])
|
return (name, bind_port, address_info[4][2], address_info[4][3])
|
||||||
elif address_info[0] == socket.AF_INET:
|
elif address_info[0] == socket.AF_INET:
|
||||||
|
@ -517,7 +524,7 @@ class TCPServerInterface(Interface):
|
||||||
else:
|
else:
|
||||||
if bindip == None:
|
if bindip == None:
|
||||||
raise SystemError(f"No TCP bind IP configured for interface \"{name}\"")
|
raise SystemError(f"No TCP bind IP configured for interface \"{name}\"")
|
||||||
bind_address = TCPServerInterface.get_address_for_host(bindip, self.bind_port)
|
bind_address = TCPServerInterface.get_address_for_host(bindip, self.bind_port, prefer_ipv6)
|
||||||
|
|
||||||
if bind_address != None:
|
if bind_address != None:
|
||||||
self.receives = True
|
self.receives = True
|
||||||
|
|
|
@ -672,8 +672,15 @@ class Reticulum:
|
||||||
interface = AutoInterface.AutoInterface(RNS.Transport, interface_config)
|
interface = AutoInterface.AutoInterface(RNS.Transport, interface_config)
|
||||||
interface_post_init(interface)
|
interface_post_init(interface)
|
||||||
|
|
||||||
|
if c["type"] == "BackboneInterface" or c["type"] == "BackboneClientInterface":
|
||||||
|
if "port" in c: c["listen_port"] = c["port"]
|
||||||
|
if "port" in c: c["target_port"] = c["port"]
|
||||||
|
if "remote" in c: c["target_host"] = c["remote"]
|
||||||
|
if "listen_on" in c: c["listen_ip"] = c["listen_on"]
|
||||||
|
|
||||||
if c["type"] == "BackboneInterface":
|
if c["type"] == "BackboneInterface":
|
||||||
interface = BackboneInterface.BackboneInterface(RNS.Transport, interface_config)
|
if "target_host" in c: interface = BackboneInterface.BackboneClientInterface(RNS.Transport, interface_config)
|
||||||
|
else: interface = BackboneInterface.BackboneInterface(RNS.Transport, interface_config)
|
||||||
interface_post_init(interface)
|
interface_post_init(interface)
|
||||||
|
|
||||||
if c["type"] == "BackboneClientInterface":
|
if c["type"] == "BackboneClientInterface":
|
||||||
|
@ -1195,10 +1202,6 @@ class Reticulum:
|
||||||
rpc_connection.send({"get": "next_hop", "destination_hash": destination})
|
rpc_connection.send({"get": "next_hop", "destination_hash": destination})
|
||||||
response = rpc_connection.recv()
|
response = rpc_connection.recv()
|
||||||
|
|
||||||
# TODO: Remove this debugging function
|
|
||||||
# if not response:
|
|
||||||
# response = RNS.Transport.next_hop(destination)
|
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue