Skip to content

Commit f2912e8

Browse files
committed
Work around an issue where getaddrinfo() returns duplicate entries
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.
1 parent efb837c commit f2912e8

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

asyncssh/listener.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import socket
2626
from types import TracebackType
2727
from typing import TYPE_CHECKING, AnyStr, Callable, Generic, List, Optional
28-
from typing import Sequence, Tuple, Type, Union
28+
from typing import Sequence, Set, Tuple, Type, Union
2929
from typing_extensions import Self
3030

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

288+
seen_addrinfo: Set[Tuple] = set()
288289
servers: List[asyncio.AbstractServer] = []
289290

290-
for family, socktype, proto, _, sa in addrinfo:
291+
for addrinfo_entry in addrinfo:
292+
# Work around an issue where getaddrinfo() on some systems may
293+
# return duplicate results, causing bind to fail.
294+
if addrinfo_entry in seen_addrinfo: # pragma: no cover
295+
continue
296+
297+
seen_addrinfo.add(addrinfo_entry)
298+
299+
family, socktype, proto, _, sa = addrinfo_entry
300+
291301
try:
292302
sock = socket.socket(family, socktype, proto)
293303
except OSError: # pragma: no cover

0 commit comments

Comments
 (0)