Skip to content

Commit

Permalink
Changed getaddrinfo() to filter out invalid IPv6 results when IPv6 is…
Browse files Browse the repository at this point in the history
… disabled (#871)

This also fixes the internal type annotations for AsyncBackend.getaddrinfo().
  • Loading branch information
agronholm authored Feb 22, 2025
1 parent 38885f9 commit fb25da7
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ repos:
- id: mypy
additional_dependencies:
- pytest
- trio >= 0.23
- trio >= 0.26
- packaging

- repo: https://github.com/pre-commit/pygrep-hooks
Expand Down
2 changes: 2 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
``anyio.open_process()``, ``asyncio.create_subprocess_…()``, ``trio.run_process()``,
and ``subprocess.run()`` already accept (PR by @jmehnle)
- Added the ``info`` property to ``anyio.Path`` on Python 3.14
- Changed ``anyio.getaddrinfo()`` to ignore (invalid) IPv6 name resolution results when
IPv6 support is disabled in Python
- Fixed traceback formatting growing quadratically with level of ``TaskGroup``
nesting on asyncio due to exception chaining when raising ``ExceptionGroups``
in ``TaskGroup.__aexit__``
Expand Down
4 changes: 2 additions & 2 deletions src/anyio/_backends/_asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -2674,13 +2674,13 @@ async def getaddrinfo(
type: int | SocketKind = 0,
proto: int = 0,
flags: int = 0,
) -> list[
) -> Sequence[
tuple[
AddressFamily,
SocketKind,
int,
str,
tuple[str, int] | tuple[str, int, int, int],
tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
]
]:
return await get_running_loop().getaddrinfo(
Expand Down
4 changes: 2 additions & 2 deletions src/anyio/_backends/_trio.py
Original file line number Diff line number Diff line change
Expand Up @@ -1246,13 +1246,13 @@ async def getaddrinfo(
type: int | SocketKind = 0,
proto: int = 0,
flags: int = 0,
) -> list[
) -> Sequence[
tuple[
AddressFamily,
SocketKind,
int,
str,
tuple[str, int] | tuple[str, int, int, int],
tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
]
]:
return await trio.socket.getaddrinfo(host, port, family, type, proto, flags)
Expand Down
2 changes: 2 additions & 0 deletions src/anyio/_core/_sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ async def getaddrinfo(
return [
(family, type, proto, canonname, convert_ipv6_sockaddr(sockaddr))
for family, type, proto, canonname, sockaddr in gai_res
# filter out IPv6 results when IPv6 is disabled
if not isinstance(sockaddr[0], int)
]


Expand Down
4 changes: 2 additions & 2 deletions src/anyio/abc/_eventloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,13 @@ async def getaddrinfo(
type: int | SocketKind = 0,
proto: int = 0,
flags: int = 0,
) -> list[
) -> Sequence[
tuple[
AddressFamily,
SocketKind,
int,
str,
tuple[str, int] | tuple[str, int, int, int],
tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
]
]:
pass
Expand Down
10 changes: 10 additions & 0 deletions tests/test_sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from ssl import SSLContext, SSLError
from threading import Thread
from typing import TYPE_CHECKING, Any, Literal, NoReturn, TypeVar, cast
from unittest import mock

import psutil
import pytest
Expand Down Expand Up @@ -52,6 +53,7 @@
wait_socket_writable,
wait_writable,
)
from anyio._core._eventloop import get_async_backend
from anyio.abc import (
IPSockAddrType,
Listener,
Expand Down Expand Up @@ -1846,6 +1848,14 @@ async def test_getaddrinfo_ipv6addr(
]


async def test_getaddrinfo_ipv6_disabled() -> None:
gai_result = [
(AddressFamily.AF_INET6, socket.SocketKind.SOCK_STREAM, 6, "", (1, b""))
]
with mock.patch.object(get_async_backend(), "getaddrinfo", return_value=gai_result):
assert await getaddrinfo("::1", 0) == []


async def test_getnameinfo() -> None:
expected_result = socket.getnameinfo(("127.0.0.1", 6666), 0)
result = await getnameinfo(("127.0.0.1", 6666))
Expand Down

0 comments on commit fb25da7

Please sign in to comment.