Skip to content

Commit 0da6cf8

Browse files
committed
python 3.13: be compatible with socket ipv6 changes.
1 parent d51681b commit 0da6cf8

2 files changed

Lines changed: 25 additions & 4 deletions

File tree

src/remote_registration.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@
1414
import prefs
1515
import config
1616

17+
def get_ipv6_addr_tuple(addr, port):
18+
"""
19+
Returns appropriate tuple for IPv6 socket bind/connect/sendto.
20+
Python 3.13+ requires 4-tuple (host, port, flowinfo, scope_id) for
21+
link-local addresses. This format is backward compatible with older Python.
22+
"""
23+
if '%' in addr:
24+
ip_part, scope_name = addr.split('%', 1)
25+
scope_id = socket.if_nametoindex(scope_name)
26+
else:
27+
ip_part = addr
28+
scope_id = 0
29+
return (ip_part, port, 0, scope_id)
30+
1731
class RegRequest():
1832
def __init__(self, ident, hostname, ip_info, port, auth_port, api_version):
1933
self.api_version = api_version
@@ -142,10 +156,12 @@ def request(self):
142156
remote_ip, _, ip_version = self.ip_info.get_usable_ip()
143157

144158
try:
145-
ip = remote_ip if ip_version == socket.AF_INET else "[%s]" % (remote_ip,)
146159
server_sock = socket.socket(ip_version, socket.SOCK_DGRAM)
147160
server_sock.settimeout(5.0)
148-
server_sock.sendto(REQUEST, (ip, self.port))
161+
if ip_version == socket.AF_INET6:
162+
server_sock.sendto(REQUEST, get_ipv6_addr_tuple(remote_ip, self.port))
163+
else:
164+
server_sock.sendto(REQUEST, (remote_ip, self.port))
149165

150166
reply, addr = server_sock.recvfrom(2000)
151167

@@ -182,7 +198,10 @@ def serve_cert_thread(self, ip_version):
182198
try:
183199
server_sock = socket.socket(ip_version, socket.SOCK_DGRAM)
184200
server_sock.settimeout(1.0)
185-
server_sock.bind((local_ip, self.port))
201+
if ip_version == socket.AF_INET6:
202+
server_sock.bind(get_ipv6_addr_tuple(local_ip, self.port))
203+
else:
204+
server_sock.bind((local_ip, self.port))
186205
except socket.error as e:
187206
logging.critical("Could not create udp socket for cert requests: %s" % str(e))
188207
return

src/util.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,9 @@ def as_binary_list(self):
243243
pass
244244
if self.ip6:
245245
try:
246-
blist.append(socket.inet_pton(GLib.SYSDEF_AF_INET6, self.ip6_address))
246+
# Strip scope ID suffix if present (e.g., %eth0)
247+
ip6_clean = self.ip6_address.split('%')[0] if '%' in self.ip6_address else self.ip6_address
248+
blist.append(socket.inet_pton(GLib.SYSDEF_AF_INET6, ip6_clean))
247249
except:
248250
pass
249251

0 commit comments

Comments
 (0)