From e273900e87bdb03e1a91c75ebf9578301f5a35da Mon Sep 17 00:00:00 2001 From: Greg Troxel Date: Tue, 28 Feb 2023 09:47:09 -0500 Subject: [PATCH] AutoInterface: Drop embedded scope identifier on fe80:: The code previously dropped scope identifiers expressed as a trailing "%ifname", which happens on macOS. On NetBSD and OpenBSD (and likely FreeBSD, not tested), the scope identifier is embedded. Drop that form of identifier as well, because we keep address and ifname separate, and because the scope identifier must not be part of computing the hash of the address. Resolves #240, failure to peer on NetBSD and OpenBSD. --- RNS/Interfaces/AutoInterface.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/RNS/Interfaces/AutoInterface.py b/RNS/Interfaces/AutoInterface.py index 8dde98b..ed76304 100644 --- a/RNS/Interfaces/AutoInterface.py +++ b/RNS/Interfaces/AutoInterface.py @@ -23,6 +23,7 @@ from .Interface import Interface import socketserver import threading +import re import socket import struct import time @@ -53,6 +54,13 @@ class AutoInterface(Interface): return AutoInterfaceHandler(callback, *args, **keys) return create_handler + def descope_linklocal(self, link_local_addr): + # Drop scope specifier expressd as %ifname (macOS) + link_local_addr = link_local_addr.split("%")[0] + # Drop embedded scope specifier (NetBSD, OpenBSD) + link_local_addr = re.sub(r"fe80:[0-9a-f]*::","fe80::", link_local_addr) + return link_local_addr + def __init__(self, owner, name, group_id=None, discovery_scope=None, discovery_port=None, data_port=None, allowed_interfaces=None, ignored_interfaces=None, configured_bitrate=None): import importlib if importlib.util.find_spec('netifaces') != None: @@ -158,9 +166,9 @@ class AutoInterface(Interface): for address in addresses[self.netifaces.AF_INET6]: if "addr" in address: if address["addr"].startswith("fe80:"): - link_local_addr = address["addr"] - self.link_local_addresses.append(link_local_addr.split("%")[0]) - self.adopted_interfaces[ifname] = link_local_addr.split("%")[0] + link_local_addr = self.descope_linklocal(address["addr"]) + self.link_local_addresses.append(link_local_addr) + self.adopted_interfaces[ifname] = link_local_addr self.multicast_echoes[ifname] = time.time() RNS.log(str(self)+" Selecting link-local address "+str(link_local_addr)+" for interface "+str(ifname), RNS.LOG_EXTREME) @@ -278,7 +286,7 @@ class AutoInterface(Interface): for address in addresses[self.netifaces.AF_INET6]: if "addr" in address: if address["addr"].startswith("fe80:"): - link_local_addr = address["addr"].split("%")[0] + link_local_addr = self.descope_linklocal(address["addr"]) if link_local_addr != self.adopted_interfaces[ifname]: old_link_local_address = self.adopted_interfaces[ifname] RNS.log("Replacing link-local address "+str(old_link_local_address)+" for "+str(ifname)+" with "+str(link_local_addr), RNS.LOG_DEBUG)