Skip to content

Commit

Permalink
fix: use dual-stack socket instead of IPv4-only
Browse files Browse the repository at this point in the history
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. For hosts with IPv6 completely disabled for some reason, the socket falls back to v4-only.
  • Loading branch information
DerEnderKeks committed Mar 20, 2024
1 parent b2e3c9d commit 4f06028
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions pychromecast/socket_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,16 @@ def mdns_backoff(
self.host,
self.port,
)
self.socket.connect((self.host, self.port))

mapped_host = socket.getaddrinfo(
self.host,
self.port,
self.socket.family,
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
Expand Down Expand Up @@ -1133,7 +1142,13 @@ 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)
try:
new_sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
new_sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) # ensuring dual-stack
except OSError:
# falling back to IPv4 on systems without IPv6
new_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

new_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

try:
Expand Down

0 comments on commit 4f06028

Please sign in to comment.