From 1cc0a303f8cf1664a6f857ae400c973c7fd37aa4 Mon Sep 17 00:00:00 2001 From: DerEnderKeks Date: Sat, 24 Feb 2024 18:53:15 +0100 Subject: [PATCH] fix: use dual-stack socket instead of IPv4-only By using an INET6 socket with IPV6_V6ONLY disabled, legacy IPv4 can still be reached. To connect to v4 IPs, the addresses are mapped to IPv6. IPv6 addresses are only used when a hostname resolves to one and the system has a non-local IPv6 available. --- pychromecast/socket_client.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pychromecast/socket_client.py b/pychromecast/socket_client.py index db14e0511..595a71076 100644 --- a/pychromecast/socket_client.py +++ b/pychromecast/socket_client.py @@ -352,7 +352,16 @@ def mdns_backoff( self.host, self.port, ) - self.socket.connect((self.host, self.port)) + + mapped_host = socket.getaddrinfo( + self.host, + self.port, + socket.AF_INET6, + socket.SOCK_STREAM, + flags=(socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) + )[0][4] + + self.socket.connect(mapped_host) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.check_hostname = False context.verify_mode = ssl.CERT_NONE @@ -1135,7 +1144,8 @@ def new_socket() -> socket.socket: Try to set SO_REUSEPORT for BSD-flavored systems if it's an option. Catches errors if not. """ - new_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + new_sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + new_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) new_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: