Skip to content

Commit

Permalink
Work around an issue where getaddrinfo() returns duplicate entries
Browse files Browse the repository at this point in the history
This commit works around an issue where getaddrinfo() can return
duplicate entries on some systems, causing bind() to fail when it
attempts to listen on the same address/port more than once. Thanks
go to Colin Watson for reporting this issue and suggesting a fix.
  • Loading branch information
ronf committed Aug 18, 2024
1 parent efb837c commit f2912e8
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions asyncssh/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import socket
from types import TracebackType
from typing import TYPE_CHECKING, AnyStr, Callable, Generic, List, Optional
from typing import Sequence, Tuple, Type, Union
from typing import Sequence, Set, Tuple, Type, Union
from typing_extensions import Self

from .forward import SSHForwarderCoro
Expand Down Expand Up @@ -285,9 +285,19 @@ async def create_tcp_local_listener(
if not addrinfo: # pragma: no cover
raise OSError('getaddrinfo() returned empty list')

seen_addrinfo: Set[Tuple] = set()
servers: List[asyncio.AbstractServer] = []

for family, socktype, proto, _, sa in addrinfo:
for addrinfo_entry in addrinfo:
# Work around an issue where getaddrinfo() on some systems may
# return duplicate results, causing bind to fail.
if addrinfo_entry in seen_addrinfo: # pragma: no cover
continue

seen_addrinfo.add(addrinfo_entry)

family, socktype, proto, _, sa = addrinfo_entry

try:
sock = socket.socket(family, socktype, proto)
except OSError: # pragma: no cover
Expand Down

0 comments on commit f2912e8

Please sign in to comment.