aio-libs / aio-libs/aiohttp

Failure establishing connection when IPv6 network is unreachable while IPv4 works

未关闭
#6,496 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
enhancement
主要语言
Python
星标
16.5k
派生
2.4k
平均合并
17 小时 22 分钟
30 天内合并 PR
212

描述

### Describe the bug

`aiohttp` fails to connect to `pypi.org` which has DNS entries for IPv6 and IPv4 but the host I am using has no IPv6 connectivity.
Looks very similar to https://github.com/aio-libs/aiohttp/issues/5110.

### To Reproduce

Run on a machine with IPv6 enabled but without IPv6 connectivity:
```python
import asyncio
import aiohttp

async def main():
async with aiohttp.ClientSession() as session:
r = await session.get('https://pypi.org/')
print(await r.text())

if __name__ == '__main__':
asyncio.run(main())
```

It fails with:
```
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host pypi.org:443 ssl:default [Network is unreachable]
```

On the same host `curl` works fine:
```
* About to connect() to pypi.org port 443 (#0)
* Trying 151.101.192.223...
* Connected to pypi.org (151.101.192.223) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=pypi.org
* start date: Oct 22 18:55:44 2021 GMT
* expire date: Nov 23 18:55:43 2022 GMT
* common name: pypi.org
* issuer: CN=GlobalSign Atlas R3 DV TLS CA H2 2021,O=GlobalSign nv-sa,C=BE
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: pypi.org
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Length: 28784
```

### Expected behavior

IPv4 should be used and "network unreachable" for IPv6 ignored.

### Logs/tracebacks

```python-traceback
Traceback (most recent call last):
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/connector.py", line 986, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
File "/opt/starfish/python3.7/lib/python3.7/asyncio/base_events.py", line 962, in create_connection
raise exceptions[0]
File "/opt/starfish/python3.7/lib/python3.7/asyncio/base_events.py", line 949, in create_connection
await self.sock_connect(sock, address)
File "/opt/starfish/python3.7/lib/python3.7/asyncio/selector_events.py", line 473, in sock_connect
return await fut
File "/opt/starfish/python3.7/lib/python3.7/asyncio/selector_events.py", line 478, in _sock_connect
sock.connect(address)
OSError: [Errno 101] Network is unreachable

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "bug.py", line 10, in
asyncio.run(main())
File "/opt/starfish/python3.7/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/opt/starfish/python3.7/lib/python3.7/asyncio/base_events.py", line 587, in run_until_complete
return future.result()
File "bug.py", line 6, in main
r = await session.get('https://pypi.org/')
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/client.py", line 536, in _request
req, traces=traces, timeout=real_timeout
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/connector.py", line 542, in connect
proto = await self._create_connection(req, traces, timeout)
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/connector.py", line 907, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/connector.py", line 1206, in _create_direct_connection
raise last_exc
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/connector.py", line 1187, in _create_direct_connection
client_error=client_error,
File "/opt/devpi/venv/lib/python3.7/site-packages/aiohttp/connector.py", line 992, in _wrap_create_connection
raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host pypi.org:443 ssl:default [Network is unreachable]
```

### Python Version

```console
$ python --version
Python 3.7.12
```

### aiohttp Version

```console
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.8.1
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author:
Author-email:
License: Apache 2
Location: /opt/devpi/venv/lib/python3.7/site-packages
Requires: aiosignal, async-timeout, asynctest, attrs, charset-normalizer, frozenlist, multidict, typing-extensions, yarl
Required-by: devpi-server
```

### multidict Version

```console
$ python -m pip show multidict
Name: multidict
Version: 5.2.0
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /opt/devpi/venv/lib/python3.7/site-packages
Requires:
Required-by: aiohttp, yarl
(venv) -bash-4.2$
```

### yarl Version

```console
$ python -m pip show yarl
Name: yarl
Version: 1.7.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /opt/devpi/venv/lib/python3.7/site-packages
Requires: idna, multidict, typing-extensions
Required-by: aiohttp
```

### OS

```CentOS Linux release 7.9.2009 (Core)```

### Related component

Client

### Additional context

_No response_

### Code of Conduct

- [X] I agree to follow the aio-libs Code of Conduct

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。