aioquic
aioquic copied to clipboard
The handshake time is particularly long in absence of session resumption
It is very strange for aioquic to take at least 500 ms to complete handshake, and the following code to illustrate this issue.
python examples/http3_client.py -v https://doh3.dns.nextdns.io/info
examples/http3_client.py:528: DeprecationWarning: There is no current event loop
loop = asyncio.get_event_loop()
2022-05-02 18:28:08,973 DEBUG asyncio Using proactor: IocpProactor
2022-05-02 18:28:08,989 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_HANDSHAKE_START -> State.CLIENT_EXPECT_SERVER_HELLO
2022-05-02 18:28:09,020 INFO quic [0caf078deba8e240] Retrying with token (98 bytes)
2022-05-02 18:28:09,020 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_HANDSHAKE_START -> State.CLIENT_EXPECT_SERVER_HELLO
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_SERVER_HELLO -> State.CLIENT_EXPECT_ENCRYPTED_EXTENSIONS
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_ENCRYPTED_EXTENSIONS -> State.CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] Discarding epoch Epoch.INITIAL
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE -> State.CLIENT_EXPECT_CERTIFICATE_VERIFY
2022-05-02 18:28:09,528 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_CERTIFICATE_VERIFY -> State.CLIENT_EXPECT_FINISHED
2022-05-02 18:28:09,528 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_FINISHED -> State.CLIENT_POST_HANDSHAKE
2022-05-02 18:28:09,536 INFO quic [0caf078deba8e240] ALPN negotiated protocol h3
The round-trip time of "doh3.dns.nextdns.io" is 30 ms or so, which is seen from
2022-05-02 18:28:08,989 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_HANDSHAKE_START -> State.CLIENT_EXPECT_SERVER_HELLO
2022-05-02 18:28:09,020 INFO quic [0caf078deba8e240] Retrying with token (98 bytes)
and further verified by
2022-05-02 18:28:09,020 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_HANDSHAKE_START -> State.CLIENT_EXPECT_SERVER_HELLO
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
However, in the following two lines, aioquic unexpectedly spends disproportionately approximately 500 ms to verify certificate, compared with 30 ms round-trip time.
2022-05-02 18:28:09,058 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE -> State.CLIENT_EXPECT_CERTIFICATE_VERIFY
2022-05-02 18:28:09,528 DEBUG quic [0caf078deba8e240] TLS State.CLIENT_EXPECT_CERTIFICATE_VERIFY -> State.CLIENT_EXPECT_FINISHED
From my perspective, the connection time is bound by IO, and thus, it should be instant to verify certificate.
500ms sounds suspiciously like a retransmission, so I think to move forward we'd need a client-side QLOG file + a wireshark capture (with SSL keys).
python examples/http3_client.py -v https://doh3.dns.nextdns.io/info
examples/http3_client.py:528: DeprecationWarning: There is no current event loop
loop = asyncio.get_event_loop()
2022-05-10 21:14:17,904 DEBUG asyncio Using proactor: IocpProactor
2022-05-10 21:14:17,919 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_HANDSHAKE_START -> State.CLIENT_EXPECT_SERVER_HELLO
2022-05-10 21:14:17,951 INFO quic [1fcaf3316f954dff] Retrying with token (98 bytes)
2022-05-10 21:14:17,951 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_HANDSHAKE_START -> State.CLIENT_EXPECT_SERVER_HELLO
2022-05-10 21:14:17,982 DEBUG quic [1fcaf3316f954dff] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
2022-05-10 21:14:17,982 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_EXPECT_SERVER_HELLO -> State.CLIENT_EXPECT_ENCRYPTED_EXTENSIONS
2022-05-10 21:14:17,982 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_EXPECT_ENCRYPTED_EXTENSIONS -> State.CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE
2022-05-10 21:14:17,982 DEBUG quic [1fcaf3316f954dff] Discarding epoch Epoch.INITIAL
2022-05-10 21:14:17,982 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_EXPECT_CERTIFICATE_REQUEST_OR_CERTIFICATE -> State.CLIENT_EXPECT_CERTIFICATE_VERIFY
2022-05-10 21:14:18,436 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_EXPECT_CERTIFICATE_VERIFY -> State.CLIENT_EXPECT_FINISHED
2022-05-10 21:14:18,436 DEBUG quic [1fcaf3316f954dff] TLS State.CLIENT_EXPECT_FINISHED -> State.CLIENT_POST_HANDSHAKE
2022-05-10 21:14:18,436 INFO quic [1fcaf3316f954dff] ALPN negotiated protocol h3
2022-05-10 21:14:18,436 DEBUG quic [1fcaf3316f954dff] Stream 3 created by peer
2022-05-10 21:14:18,436 INFO quic [1fcaf3316f954dff] Duplicate CRYPTO data received for epoch Epoch.HANDSHAKE
2022-05-10 21:14:18,436 INFO quic [1fcaf3316f954dff] Duplicate CRYPTO data received for epoch Epoch.HANDSHAKE
2022-05-10 21:14:18,436 INFO quic [1fcaf3316f954dff] Duplicate CRYPTO data received for epoch Epoch.HANDSHAKE
2022-05-10 21:14:18,436 INFO quic [1fcaf3316f954dff] Duplicate CRYPTO data received for epoch Epoch.HANDSHAKE
2022-05-10 21:14:18,468 DEBUG quic [1fcaf3316f954dff] Peer retiring CID 20729bced00ac52b (0)
2022-05-10 21:14:18,468 DEBUG quic [1fcaf3316f954dff] Discarding epoch Epoch.HANDSHAKE
2022-05-10 21:14:18,468 INFO client New session ticket received
2022-05-10 21:14:18,468 DEBUG quic [1fcaf3316f954dff] Stream 0 discarded
2022-05-10 21:14:18,468 INFO client Response received for GET /info : 73 bytes in 0.0 s (0.019 Mbps)
2022-05-10 21:14:18,468 INFO quic [1fcaf3316f954dff] Connection close sent (code 0x0, reason )
2022-05-10 21:14:18,468 DEBUG quic [1fcaf3316f954dff] QuicConnectionState.CONNECTED -> QuicConnectionState.CLOSING
2022-05-10 21:14:18,740 DEBUG quic [1fcaf3316f954dff] Discarding epoch Epoch.ONE_RTT
2022-05-10 21:14:18,740 DEBUG quic [1fcaf3316f954dff] QuicConnectionState.CLOSING -> QuicConnectionState.TERMINATED
QLOG file: qlog.log
Please forgive me not to provide a complete wireshark capture against leaking possible personally identifiable information.
No. Time Source Destination Protocol Length Info
1 2022-05-10 21:14:17.924601 local remote QUIC 1322 Initial, DCID=1fcaf3316f954dff, SCID=20729bced00ac52b, PKN: 0, CRYPTO, PADDING
2 2022-05-10 21:14:17.953940 remote local QUIC 175 Retry, DCID=20729bced00ac52b, SCID=eee5aad4
3 2022-05-10 21:14:17.960158 local remote QUIC 1322 Initial, DCID=eee5aad4, SCID=20729bced00ac52b, PKN: 1, CRYPTO, PADDING
4 2022-05-10 21:14:17.990826 remote local QUIC 1294 Handshake, DCID=20729bced00ac52b, SCID=33a22577
5 2022-05-10 21:14:17.990826 remote local QUIC 1294 Handshake, DCID=20729bced00ac52b, SCID=33a22577
6 2022-05-10 21:14:17.990826 remote local QUIC 1173 Protected Payload (KP0), DCID=20729bced00ac52b
7 2022-05-10 21:14:17.990826 remote local QUIC 74 Protected Payload (KP0), DCID=20729bced00ac52b
8 2022-05-10 21:14:17.994903 local remote QUIC 232 Handshake, DCID=33a22577, SCID=20729bced00ac52b
9 2022-05-10 21:14:17.995443 local remote QUIC 86 Handshake, DCID=33a22577, SCID=20729bced00ac52b
10 2022-05-10 21:14:18.062945 remote local QUIC 1026 Handshake, DCID=20729bced00ac52b, SCID=33a22577
11 2022-05-10 21:14:18.063355 remote local QUIC 1026 Handshake, DCID=20729bced00ac52b, SCID=33a22577
12 2022-05-10 21:14:18.206917 remote local QUIC 1026 Handshake, DCID=20729bced00ac52b, SCID=33a22577
13 2022-05-10 21:14:18.206917 remote local QUIC 1026 Handshake, DCID=20729bced00ac52b, SCID=33a22577
14 2022-05-10 21:14:18.441259 local remote QUIC 273 Protected Payload (KP0), DCID=33a22577
15 2022-05-10 21:14:18.442315 local remote QUIC 86 Handshake, DCID=33a22577, SCID=20729bced00ac52b
16 2022-05-10 21:14:18.443105 local remote QUIC 115 Protected Payload (KP0), DCID=33a22577
17 2022-05-10 21:14:18.444177 local remote QUIC 97 Protected Payload (KP0), DCID=33a22577
18 2022-05-10 21:14:18.445045 local remote QUIC 86 Handshake, DCID=33a22577, SCID=20729bced00ac52b
19 2022-05-10 21:14:18.445163 local remote QUIC 86 Handshake, DCID=33a22577, SCID=20729bced00ac52b
20 2022-05-10 21:14:18.470597 remote local QUIC 86 Handshake, DCID=20729bced00ac52b, SCID=33a22577
21 2022-05-10 21:14:18.470597 remote local QUIC 74 Protected Payload (KP0), DCID=20729bced00ac52b
22 2022-05-10 21:14:18.470597 remote local QUIC 353 Protected Payload (KP0)
23 2022-05-10 21:14:18.473422 remote local QUIC 198 Protected Payload (KP0)
24 2022-05-10 21:14:18.474769 local remote QUIC 99 Protected Payload (KP0), DCID=33a22577
25 2022-05-10 21:14:18.477514 local remote QUIC 71 Protected Payload (KP0), DCID=33a22577
26 2022-05-10 21:14:18.479070 local remote QUIC 68 Protected Payload (KP0), DCID=33a22577
27 2022-05-10 21:14:18.503927 remote local QUIC 78 Protected Payload (KP0)
28 2022-05-10 21:14:18.506841 remote local QUIC 72 Protected Payload (KP0)
Moreover, the same issue occurs when connecting "https://cloudflare-dns.com/" and "https://dns.google/".
As far as I know, https://github.com/pyca/cryptography/issues/7236 is responsible for this issue. Even though cryptography is downgraded to 36.0.2, it still takes about 30 ms to verify certificate.
Moreover, I prefer system CA certificates to "certifi".
import ssl
context = ssl.create_default_context()
system_certs = context.get_ca_certs(binary_form=True)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.