puma-plus-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/puma_plus_core/extconf.rb +85 -0
- data/go/cmd/puma-plus/main.go +472 -0
- data/go/go.mod +20 -0
- data/go/go.sum +38 -0
- data/go/internal/control/booted_test.go +97 -0
- data/go/internal/control/decide.go +427 -0
- data/go/internal/control/decide_test.go +526 -0
- data/go/internal/control/loop.go +343 -0
- data/go/internal/control/loop_test.go +228 -0
- data/go/internal/control/replay.go +121 -0
- data/go/internal/control/sim/cooldown_test.go +74 -0
- data/go/internal/control/sim/sim.go +599 -0
- data/go/internal/control/sim/sim_test.go +300 -0
- data/go/internal/frontend/acceptor.go +164 -0
- data/go/internal/frontend/altsvc.go +57 -0
- data/go/internal/frontend/altsvc_test.go +170 -0
- data/go/internal/frontend/bodypump.go +81 -0
- data/go/internal/frontend/env.go +224 -0
- data/go/internal/frontend/env_test.go +64 -0
- data/go/internal/frontend/handler.go +543 -0
- data/go/internal/frontend/handler_test.go +486 -0
- data/go/internal/frontend/hijack.go +108 -0
- data/go/internal/frontend/hijack_test.go +197 -0
- data/go/internal/frontend/hooks_test.go +283 -0
- data/go/internal/frontend/launcher_test.go +289 -0
- data/go/internal/frontend/listeners.go +196 -0
- data/go/internal/frontend/protocol_test.go +391 -0
- data/go/internal/frontend/ractor_shepherd.go +160 -0
- data/go/internal/frontend/ractor_smoke_test.go +168 -0
- data/go/internal/frontend/realcert_test.go +163 -0
- data/go/internal/frontend/rtbridge.go +410 -0
- data/go/internal/frontend/shepherd.go +188 -0
- data/go/internal/frontend/socket.go +37 -0
- data/go/internal/frontend/socketpair_test.go +34 -0
- data/go/internal/frontend/tlscert.go +184 -0
- data/go/internal/frontend/tlscert_test.go +81 -0
- data/go/internal/frontend/wscontrol.go +198 -0
- data/go/internal/metrics/collector.go +207 -0
- data/go/internal/metrics/endpoints.go +244 -0
- data/go/internal/metrics/gvl.go +136 -0
- data/go/internal/metrics/gvl_test.go +122 -0
- data/go/internal/metrics/hist.go +204 -0
- data/go/internal/metrics/hist_test.go +353 -0
- data/go/internal/metrics/window.go +120 -0
- data/go/internal/queue/drain_test.go +141 -0
- data/go/internal/queue/queue.go +297 -0
- data/go/internal/realtime/event.go +53 -0
- data/go/internal/realtime/hub.go +456 -0
- data/go/internal/realtime/hub_test.go +370 -0
- data/go/internal/realtime/id.go +69 -0
- data/go/internal/realtime/id_test.go +64 -0
- data/go/internal/websocket/frame.go +186 -0
- data/go/internal/websocket/serve.go +196 -0
- data/go/internal/websocket/transport.go +101 -0
- data/go/internal/webtransport/serve.go +169 -0
- data/go/internal/webtransport/transport.go +220 -0
- data/go/internal/wire/golden_test.go +250 -0
- data/go/internal/wire/rack_test.go +40 -0
- data/go/internal/wire/ractor_test.go +43 -0
- data/go/internal/wire/wire.go +401 -0
- data/go/vendor/github.com/dunglas/httpsfv/LICENSE +27 -0
- data/go/vendor/github.com/dunglas/httpsfv/README.md +25 -0
- data/go/vendor/github.com/dunglas/httpsfv/bareitem.go +115 -0
- data/go/vendor/github.com/dunglas/httpsfv/binary.go +59 -0
- data/go/vendor/github.com/dunglas/httpsfv/boolean.go +49 -0
- data/go/vendor/github.com/dunglas/httpsfv/date.go +41 -0
- data/go/vendor/github.com/dunglas/httpsfv/decimal.go +64 -0
- data/go/vendor/github.com/dunglas/httpsfv/decode.go +63 -0
- data/go/vendor/github.com/dunglas/httpsfv/dictionary.go +167 -0
- data/go/vendor/github.com/dunglas/httpsfv/displaystring.go +105 -0
- data/go/vendor/github.com/dunglas/httpsfv/encode.go +42 -0
- data/go/vendor/github.com/dunglas/httpsfv/innerlist.go +91 -0
- data/go/vendor/github.com/dunglas/httpsfv/integer.go +120 -0
- data/go/vendor/github.com/dunglas/httpsfv/item.go +73 -0
- data/go/vendor/github.com/dunglas/httpsfv/key.go +81 -0
- data/go/vendor/github.com/dunglas/httpsfv/list.go +99 -0
- data/go/vendor/github.com/dunglas/httpsfv/member.go +9 -0
- data/go/vendor/github.com/dunglas/httpsfv/params.go +143 -0
- data/go/vendor/github.com/dunglas/httpsfv/string.go +88 -0
- data/go/vendor/github.com/dunglas/httpsfv/token.go +71 -0
- data/go/vendor/github.com/dunglas/httpsfv/utils.go +16 -0
- data/go/vendor/github.com/quic-go/qpack/LICENSE.md +7 -0
- data/go/vendor/github.com/quic-go/qpack/README.md +21 -0
- data/go/vendor/github.com/quic-go/qpack/decoder.go +183 -0
- data/go/vendor/github.com/quic-go/qpack/encoder.go +95 -0
- data/go/vendor/github.com/quic-go/qpack/header_field.go +16 -0
- data/go/vendor/github.com/quic-go/qpack/static_table.go +255 -0
- data/go/vendor/github.com/quic-go/qpack/varint.go +69 -0
- data/go/vendor/github.com/quic-go/quic-go/FIPS140.md +37 -0
- data/go/vendor/github.com/quic-go/quic-go/FUZZING.md +59 -0
- data/go/vendor/github.com/quic-go/quic-go/LICENSE +21 -0
- data/go/vendor/github.com/quic-go/quic-go/README.md +65 -0
- data/go/vendor/github.com/quic-go/quic-go/SECURITY.md +14 -0
- data/go/vendor/github.com/quic-go/quic-go/buffer_pool.go +92 -0
- data/go/vendor/github.com/quic-go/quic-go/client.go +109 -0
- data/go/vendor/github.com/quic-go/quic-go/closed_conn.go +58 -0
- data/go/vendor/github.com/quic-go/quic-go/codecov.yml +23 -0
- data/go/vendor/github.com/quic-go/quic-go/config.go +129 -0
- data/go/vendor/github.com/quic-go/quic-go/conn_id_generator.go +212 -0
- data/go/vendor/github.com/quic-go/quic-go/conn_id_manager.go +321 -0
- data/go/vendor/github.com/quic-go/quic-go/connection.go +3150 -0
- data/go/vendor/github.com/quic-go/quic-go/connection_logging.go +315 -0
- data/go/vendor/github.com/quic-go/quic-go/crypto_stream.go +249 -0
- data/go/vendor/github.com/quic-go/quic-go/crypto_stream_manager.go +73 -0
- data/go/vendor/github.com/quic-go/quic-go/datagram_queue.go +137 -0
- data/go/vendor/github.com/quic-go/quic-go/errors.go +105 -0
- data/go/vendor/github.com/quic-go/quic-go/flow_controller_base.go +84 -0
- data/go/vendor/github.com/quic-go/quic-go/flow_controller_connection.go +186 -0
- data/go/vendor/github.com/quic-go/quic-go/flow_controller_stream.go +196 -0
- data/go/vendor/github.com/quic-go/quic-go/frame_sorter.go +274 -0
- data/go/vendor/github.com/quic-go/quic-go/framer.go +295 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/README.md +9 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/body.go +137 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/capsule.go +148 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/client.go +496 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/conn.go +319 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/error.go +63 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/error_codes.go +84 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/frames.go +327 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/gzip_reader.go +39 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/headers.go +429 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/ip_addr.go +48 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/mockgen.go +11 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/qlog/event.go +138 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/qlog/frame.go +220 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/qlog/qlog_dir.go +15 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/qlog.go +56 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/request_writer.go +324 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/response_writer.go +372 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/server.go +738 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/server_conn.go +259 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/state_tracking_stream.go +173 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/stream.go +406 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/trace.go +105 -0
- data/go/vendor/github.com/quic-go/quic-go/http3/transport.go +538 -0
- data/go/vendor/github.com/quic-go/quic-go/interface.go +221 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/ack_eliciting.go +33 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/ecn.go +340 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/frame.go +21 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/interfaces.go +39 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/lost_packet_tracker.go +73 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/mockgen.go +6 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/packet.go +60 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/packet_number_generator.go +84 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_handler.go +119 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_history.go +159 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go +228 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/send_mode.go +46 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go +1143 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_history.go +274 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/bandwidth.go +22 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/clock.go +20 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go +214 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go +330 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/hybrid_slow_start.go +112 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/interface.go +27 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go +110 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/aead.go +91 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go +114 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite_fips140.go +48 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go +718 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/fake_conn.go +21 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/fips140_go126.go +9 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/fips140_legacy.go +7 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/header_protector.go +134 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/hkdf.go +26 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/initial_aead.go +80 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/interface.go +140 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/quic_event_go125.go +11 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/quic_event_go126.go +11 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/retry_go125.go +68 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/retry_go126.go +70 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/session_ticket.go +55 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/tls_config_go126.go +54 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/tls_config_go127.go +24 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/token_generator.go +126 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/token_protector.go +78 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go +372 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/monotime/time.go +90 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/connection_id.go +116 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/encryption_level.go +65 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/key_phase.go +36 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/packet_number.go +57 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/params.go +169 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/perspective.go +26 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go +156 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/stream.go +102 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/protocol/version.go +115 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/qerr/error_codes.go +87 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/qerr/errors.go +134 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/buffered_write_closer.go +26 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/connstats.go +14 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/linkedlist/README.md +6 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/linkedlist/linkedlist.go +264 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/log.go +131 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/rand.go +29 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/ringbuffer/ringbuffer.go +96 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go +159 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go +298 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/ack_frequency_frame.go +65 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/ack_range.go +14 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/connection_close_frame.go +75 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/crypto_frame.go +97 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/data_blocked_frame.go +29 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/datagram_frame.go +85 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/extended_header.go +164 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/frame.go +33 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/frame_parser.go +192 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/frame_type.go +81 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/handshake_done_frame.go +17 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/header.go +302 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/immediate_ack_frame.go +18 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/log.go +74 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/max_data_frame.go +33 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/max_stream_data_frame.go +43 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/max_streams_frame.go +50 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/new_connection_id_frame.go +80 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/new_token_frame.go +43 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/path_challenge_frame.go +32 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/path_response_frame.go +32 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/ping_frame.go +17 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/pool.go +33 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/reset_stream_frame.go +79 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/retire_connection_id_frame.go +30 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/short_header.go +62 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/stop_sending_frame.go +45 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/stream_data_blocked_frame.go +42 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/stream_frame.go +191 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/streams_blocked_frame.go +50 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go +593 -0
- data/go/vendor/github.com/quic-go/quic-go/internal/wire/version_negotiation.go +53 -0
- data/go/vendor/github.com/quic-go/quic-go/mockgen.go +47 -0
- data/go/vendor/github.com/quic-go/quic-go/mtu_discoverer.go +253 -0
- data/go/vendor/github.com/quic-go/quic-go/oss-fuzz.sh +52 -0
- data/go/vendor/github.com/quic-go/quic-go/packet_packer.go +1009 -0
- data/go/vendor/github.com/quic-go/quic-go/packet_unpacker.go +222 -0
- data/go/vendor/github.com/quic-go/quic-go/path_manager.go +206 -0
- data/go/vendor/github.com/quic-go/quic-go/path_manager_outgoing.go +314 -0
- data/go/vendor/github.com/quic-go/quic-go/qlog/event.go +849 -0
- data/go/vendor/github.com/quic-go/quic-go/qlog/frame.go +481 -0
- data/go/vendor/github.com/quic-go/quic-go/qlog/packet_header.go +96 -0
- data/go/vendor/github.com/quic-go/quic-go/qlog/qlog_dir.go +61 -0
- data/go/vendor/github.com/quic-go/quic-go/qlog/types.go +305 -0
- data/go/vendor/github.com/quic-go/quic-go/qlogwriter/jsontext/encoder.go +324 -0
- data/go/vendor/github.com/quic-go/quic-go/qlogwriter/trace.go +124 -0
- data/go/vendor/github.com/quic-go/quic-go/qlogwriter/writer.go +229 -0
- data/go/vendor/github.com/quic-go/quic-go/quicvarint/io.go +98 -0
- data/go/vendor/github.com/quic-go/quic-go/quicvarint/varint.go +180 -0
- data/go/vendor/github.com/quic-go/quic-go/receive_stream.go +578 -0
- data/go/vendor/github.com/quic-go/quic-go/retransmission_queue.go +158 -0
- data/go/vendor/github.com/quic-go/quic-go/send_conn.go +124 -0
- data/go/vendor/github.com/quic-go/quic-go/send_queue.go +112 -0
- data/go/vendor/github.com/quic-go/quic-go/send_stream.go +915 -0
- data/go/vendor/github.com/quic-go/quic-go/server.go +1119 -0
- data/go/vendor/github.com/quic-go/quic-go/sni.go +136 -0
- data/go/vendor/github.com/quic-go/quic-go/stateless_reset.go +42 -0
- data/go/vendor/github.com/quic-go/quic-go/stream.go +253 -0
- data/go/vendor/github.com/quic-go/quic-go/streams_map.go +356 -0
- data/go/vendor/github.com/quic-go/quic-go/streams_map_incoming.go +209 -0
- data/go/vendor/github.com/quic-go/quic-go/streams_map_outgoing.go +253 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn.go +143 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_buffers.go +68 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_buffers_write.go +70 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_df.go +22 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_df_darwin.go +90 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_df_linux.go +42 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_df_windows.go +52 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go +38 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_helper_freebsd.go +33 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go +156 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_helper_nonlinux.go +10 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_no_oob.go +21 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_oob.go +338 -0
- data/go/vendor/github.com/quic-go/quic-go/sys_conn_windows.go +42 -0
- data/go/vendor/github.com/quic-go/quic-go/token_store.go +116 -0
- data/go/vendor/github.com/quic-go/quic-go/transport.go +848 -0
- data/go/vendor/github.com/quic-go/webtransport-go/LICENSE +7 -0
- data/go/vendor/github.com/quic-go/webtransport-go/README.md +31 -0
- data/go/vendor/github.com/quic-go/webtransport-go/SECURITY.md +14 -0
- data/go/vendor/github.com/quic-go/webtransport-go/capsule.go +261 -0
- data/go/vendor/github.com/quic-go/webtransport-go/client_conn.go +289 -0
- data/go/vendor/github.com/quic-go/webtransport-go/codecov.yml +12 -0
- data/go/vendor/github.com/quic-go/webtransport-go/config.go +90 -0
- data/go/vendor/github.com/quic-go/webtransport-go/errors.go +96 -0
- data/go/vendor/github.com/quic-go/webtransport-go/flow_control.go +107 -0
- data/go/vendor/github.com/quic-go/webtransport-go/protocol.go +59 -0
- data/go/vendor/github.com/quic-go/webtransport-go/receive_stream.go +185 -0
- data/go/vendor/github.com/quic-go/webtransport-go/send_stream.go +322 -0
- data/go/vendor/github.com/quic-go/webtransport-go/server.go +533 -0
- data/go/vendor/github.com/quic-go/webtransport-go/session.go +463 -0
- data/go/vendor/github.com/quic-go/webtransport-go/session_manager.go +190 -0
- data/go/vendor/github.com/quic-go/webtransport-go/stream.go +147 -0
- data/go/vendor/github.com/quic-go/webtransport-go/streams_map_incoming.go +179 -0
- data/go/vendor/github.com/quic-go/webtransport-go/streams_map_outgoing.go +357 -0
- data/go/vendor/github.com/quic-go/webtransport-go/transport.go +126 -0
- data/go/vendor/golang.org/x/crypto/LICENSE +27 -0
- data/go/vendor/golang.org/x/crypto/PATENTS +22 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go +16 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s +307 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_generic.go +398 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go +13 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.go +16 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.s +501 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go +27 -0
- data/go/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s +224 -0
- data/go/vendor/golang.org/x/crypto/chacha20/xor.go +42 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go +101 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go +92 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s +5230 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go +87 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go +15 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/fips140only_compat.go +9 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/fips140only_go1.26.go +11 -0
- data/go/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go +89 -0
- data/go/vendor/golang.org/x/crypto/internal/alias/alias.go +31 -0
- data/go/vendor/golang.org/x/crypto/internal/alias/alias_purego.go +34 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go +9 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go +99 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s +93 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go +47 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go +312 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s +123 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64x.s +187 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go +76 -0
- data/go/vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s +503 -0
- data/go/vendor/golang.org/x/net/LICENSE +27 -0
- data/go/vendor/golang.org/x/net/PATENTS +22 -0
- data/go/vendor/golang.org/x/net/bpf/asm.go +41 -0
- data/go/vendor/golang.org/x/net/bpf/constants.go +222 -0
- data/go/vendor/golang.org/x/net/bpf/doc.go +87 -0
- data/go/vendor/golang.org/x/net/bpf/instructions.go +726 -0
- data/go/vendor/golang.org/x/net/bpf/setter.go +10 -0
- data/go/vendor/golang.org/x/net/bpf/vm.go +150 -0
- data/go/vendor/golang.org/x/net/bpf/vm_instructions.go +182 -0
- data/go/vendor/golang.org/x/net/http/httpguts/guts.go +50 -0
- data/go/vendor/golang.org/x/net/http/httpguts/httplex.go +347 -0
- data/go/vendor/golang.org/x/net/http2/README.md +19 -0
- data/go/vendor/golang.org/x/net/http2/ascii.go +53 -0
- data/go/vendor/golang.org/x/net/http2/ciphers.go +641 -0
- data/go/vendor/golang.org/x/net/http2/client_conn_pool.go +301 -0
- data/go/vendor/golang.org/x/net/http2/client_priority_go126.go +20 -0
- data/go/vendor/golang.org/x/net/http2/client_priority_go127.go +13 -0
- data/go/vendor/golang.org/x/net/http2/clientconn.go +57 -0
- data/go/vendor/golang.org/x/net/http2/config.go +171 -0
- data/go/vendor/golang.org/x/net/http2/config_go125.go +15 -0
- data/go/vendor/golang.org/x/net/http2/config_go126.go +15 -0
- data/go/vendor/golang.org/x/net/http2/databuffer.go +149 -0
- data/go/vendor/golang.org/x/net/http2/errors.go +145 -0
- data/go/vendor/golang.org/x/net/http2/flow.go +120 -0
- data/go/vendor/golang.org/x/net/http2/frame.go +1871 -0
- data/go/vendor/golang.org/x/net/http2/gotrack.go +181 -0
- data/go/vendor/golang.org/x/net/http2/h2c/h2c.go +256 -0
- data/go/vendor/golang.org/x/net/http2/hpack/encode.go +245 -0
- data/go/vendor/golang.org/x/net/http2/hpack/hpack.go +523 -0
- data/go/vendor/golang.org/x/net/http2/hpack/huffman.go +226 -0
- data/go/vendor/golang.org/x/net/http2/hpack/static_table.go +188 -0
- data/go/vendor/golang.org/x/net/http2/hpack/tables.go +403 -0
- data/go/vendor/golang.org/x/net/http2/http2.go +415 -0
- data/go/vendor/golang.org/x/net/http2/pipe.go +184 -0
- data/go/vendor/golang.org/x/net/http2/server.go +3217 -0
- data/go/vendor/golang.org/x/net/http2/server_common.go +221 -0
- data/go/vendor/golang.org/x/net/http2/server_wrap.go +217 -0
- data/go/vendor/golang.org/x/net/http2/transport.go +3036 -0
- data/go/vendor/golang.org/x/net/http2/transport_common.go +447 -0
- data/go/vendor/golang.org/x/net/http2/transport_wrap.go +394 -0
- data/go/vendor/golang.org/x/net/http2/unencrypted.go +32 -0
- data/go/vendor/golang.org/x/net/http2/write.go +381 -0
- data/go/vendor/golang.org/x/net/http2/writesched.go +252 -0
- data/go/vendor/golang.org/x/net/http2/writesched_common.go +90 -0
- data/go/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go +420 -0
- data/go/vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go +226 -0
- data/go/vendor/golang.org/x/net/http2/writesched_random.go +81 -0
- data/go/vendor/golang.org/x/net/http2/writesched_roundrobin.go +121 -0
- data/go/vendor/golang.org/x/net/idna/idna.go +884 -0
- data/go/vendor/golang.org/x/net/idna/punycode.go +220 -0
- data/go/vendor/golang.org/x/net/idna/tables15.0.0.go +5144 -0
- data/go/vendor/golang.org/x/net/idna/tables17.0.0.go +5302 -0
- data/go/vendor/golang.org/x/net/idna/trie.go +51 -0
- data/go/vendor/golang.org/x/net/idna/trieval.go +119 -0
- data/go/vendor/golang.org/x/net/internal/httpcommon/ascii.go +53 -0
- data/go/vendor/golang.org/x/net/internal/httpcommon/headermap.go +115 -0
- data/go/vendor/golang.org/x/net/internal/httpcommon/request.go +475 -0
- data/go/vendor/golang.org/x/net/internal/httpsfv/httpsfv.go +665 -0
- data/go/vendor/golang.org/x/net/internal/iana/const.go +223 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr.go +11 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go +13 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go +13 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go +13 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go +13 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go +27 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go +21 -0
- data/go/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go +11 -0
- data/go/vendor/golang.org/x/net/internal/socket/complete_dontwait.go +25 -0
- data/go/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go +21 -0
- data/go/vendor/golang.org/x/net/internal/socket/empty.s +7 -0
- data/go/vendor/golang.org/x/net/internal/socket/error_unix.go +31 -0
- data/go/vendor/golang.org/x/net/internal/socket/error_windows.go +26 -0
- data/go/vendor/golang.org/x/net/internal/socket/iovec_32bit.go +18 -0
- data/go/vendor/golang.org/x/net/internal/socket/iovec_64bit.go +18 -0
- data/go/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go +18 -0
- data/go/vendor/golang.org/x/net/internal/socket/iovec_stub.go +11 -0
- data/go/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go +21 -0
- data/go/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go +195 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go +39 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go +16 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_linux.go +36 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go +23 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go +23 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go +14 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_stub.go +14 -0
- data/go/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/norace.go +12 -0
- data/go/vendor/golang.org/x/net/internal/socket/race.go +37 -0
- data/go/vendor/golang.org/x/net/internal/socket/rawconn.go +91 -0
- data/go/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go +53 -0
- data/go/vendor/golang.org/x/net/internal/socket/rawconn_msg.go +59 -0
- data/go/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go +15 -0
- data/go/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go +15 -0
- data/go/vendor/golang.org/x/net/internal/socket/socket.go +281 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_bsd.go +15 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_const_unix.go +20 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux.go +22 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_386.go +28 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_386.s +11 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_arm.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go +12 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_mips.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go +10 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go +12 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go +28 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s +11 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_netbsd.go +25 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_posix.go +184 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_stub.go +52 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_unix.go +121 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_windows.go +55 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go +66 -0
- data/go/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s +11 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go +39 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go +39 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go +39 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go +35 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go +38 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go +30 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go +32 -0
- data/go/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go +28 -0
- data/go/vendor/golang.org/x/net/ipv4/batch.go +194 -0
- data/go/vendor/golang.org/x/net/ipv4/control.go +144 -0
- data/go/vendor/golang.org/x/net/ipv4/control_bsd.go +43 -0
- data/go/vendor/golang.org/x/net/ipv4/control_pktinfo.go +41 -0
- data/go/vendor/golang.org/x/net/ipv4/control_stub.go +13 -0
- data/go/vendor/golang.org/x/net/ipv4/control_unix.go +75 -0
- data/go/vendor/golang.org/x/net/ipv4/control_windows.go +12 -0
- data/go/vendor/golang.org/x/net/ipv4/control_zos.go +88 -0
- data/go/vendor/golang.org/x/net/ipv4/dgramopt.go +264 -0
- data/go/vendor/golang.org/x/net/ipv4/doc.go +240 -0
- data/go/vendor/golang.org/x/net/ipv4/endpoint.go +186 -0
- data/go/vendor/golang.org/x/net/ipv4/genericopt.go +55 -0
- data/go/vendor/golang.org/x/net/ipv4/header.go +170 -0
- data/go/vendor/golang.org/x/net/ipv4/helper.go +77 -0
- data/go/vendor/golang.org/x/net/ipv4/iana.go +38 -0
- data/go/vendor/golang.org/x/net/ipv4/icmp.go +57 -0
- data/go/vendor/golang.org/x/net/ipv4/icmp_linux.go +25 -0
- data/go/vendor/golang.org/x/net/ipv4/icmp_stub.go +25 -0
- data/go/vendor/golang.org/x/net/ipv4/packet.go +117 -0
- data/go/vendor/golang.org/x/net/ipv4/payload.go +23 -0
- data/go/vendor/golang.org/x/net/ipv4/payload_cmsg.go +84 -0
- data/go/vendor/golang.org/x/net/ipv4/payload_nocmsg.go +39 -0
- data/go/vendor/golang.org/x/net/ipv4/sockopt.go +44 -0
- data/go/vendor/golang.org/x/net/ipv4/sockopt_posix.go +71 -0
- data/go/vendor/golang.org/x/net/ipv4/sockopt_stub.go +42 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_aix.go +43 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_asmreq.go +122 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go +25 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_asmreqn.go +44 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go +21 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_bpf.go +24 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go +16 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_bsd.go +41 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_darwin.go +69 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_dragonfly.go +39 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_freebsd.go +80 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_linux.go +61 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_solaris.go +61 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_ssmreq.go +52 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go +21 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_stub.go +13 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_windows.go +44 -0
- data/go/vendor/golang.org/x/net/ipv4/sys_zos.go +57 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go +16 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_darwin.go +59 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go +13 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go +52 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go +54 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go +54 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go +52 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go +52 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_386.go +72 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go +72 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go +76 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go +72 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go +72 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go +72 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go +76 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go +74 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_netbsd.go +13 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_openbsd.go +13 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_solaris.go +57 -0
- data/go/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go +56 -0
- data/go/vendor/golang.org/x/net/ipv6/batch.go +116 -0
- data/go/vendor/golang.org/x/net/ipv6/control.go +187 -0
- data/go/vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go +51 -0
- data/go/vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go +97 -0
- data/go/vendor/golang.org/x/net/ipv6/control_stub.go +13 -0
- data/go/vendor/golang.org/x/net/ipv6/control_unix.go +55 -0
- data/go/vendor/golang.org/x/net/ipv6/control_windows.go +12 -0
- data/go/vendor/golang.org/x/net/ipv6/dgramopt.go +301 -0
- data/go/vendor/golang.org/x/net/ipv6/doc.go +239 -0
- data/go/vendor/golang.org/x/net/ipv6/endpoint.go +127 -0
- data/go/vendor/golang.org/x/net/ipv6/genericopt.go +56 -0
- data/go/vendor/golang.org/x/net/ipv6/header.go +55 -0
- data/go/vendor/golang.org/x/net/ipv6/helper.go +58 -0
- data/go/vendor/golang.org/x/net/ipv6/iana.go +86 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp.go +60 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp_bsd.go +29 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp_linux.go +27 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp_solaris.go +27 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp_stub.go +23 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp_windows.go +22 -0
- data/go/vendor/golang.org/x/net/ipv6/icmp_zos.go +29 -0
- data/go/vendor/golang.org/x/net/ipv6/payload.go +23 -0
- data/go/vendor/golang.org/x/net/ipv6/payload_cmsg.go +70 -0
- data/go/vendor/golang.org/x/net/ipv6/payload_nocmsg.go +38 -0
- data/go/vendor/golang.org/x/net/ipv6/sockopt.go +43 -0
- data/go/vendor/golang.org/x/net/ipv6/sockopt_posix.go +89 -0
- data/go/vendor/golang.org/x/net/ipv6/sockopt_stub.go +46 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_aix.go +79 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_asmreq.go +24 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go +17 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_bpf.go +24 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_bpf_stub.go +16 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_bsd.go +59 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_darwin.go +80 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_freebsd.go +94 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_linux.go +76 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_solaris.go +76 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_ssmreq.go +54 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go +21 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_stub.go +13 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_windows.go +68 -0
- data/go/vendor/golang.org/x/net/ipv6/sys_zos.go +72 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go +68 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_darwin.go +64 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_dragonfly.go +42 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go +64 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go +66 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go +66 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go +64 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go +64 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_386.go +72 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_arm.go +72 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go +76 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go +72 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go +72 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go +72 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go +76 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go +74 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_netbsd.go +42 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_openbsd.go +42 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_solaris.go +63 -0
- data/go/vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go +62 -0
- data/go/vendor/golang.org/x/sys/LICENSE +27 -0
- data/go/vendor/golang.org/x/sys/PATENTS +22 -0
- data/go/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s +17 -0
- data/go/vendor/golang.org/x/sys/cpu/asm_darwin_arm64_gc.s +12 -0
- data/go/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s +17 -0
- data/go/vendor/golang.org/x/sys/cpu/byteorder.go +66 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu.go +343 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_aix.go +33 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_arm.go +73 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_arm64.go +191 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_arm64.s +35 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_darwin_arm64.go +67 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_darwin_arm64_other.go +31 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go +61 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go +12 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go +21 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go +15 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s +26 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go +12 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go +22 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c +37 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go +25 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux.go +15 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go +39 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go +120 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go +22 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go +22 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go +9 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go +30 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go +162 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go +40 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_loong64.go +62 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_loong64.s +13 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_mips64x.go +15 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_mipsx.go +11 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go +173 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go +65 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s +11 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_other_arm.go +9 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go +11 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go +11 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go +12 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go +11 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_other_x86.go +11 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_ppc64x.go +16 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_riscv64.go +33 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_s390x.go +172 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_s390x.s +57 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_wasm.go +17 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_windows.go +26 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_windows_arm64.go +38 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_x86.go +236 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_zos.go +10 -0
- data/go/vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go +25 -0
- data/go/vendor/golang.org/x/sys/cpu/endian_big.go +10 -0
- data/go/vendor/golang.org/x/sys/cpu/endian_little.go +10 -0
- data/go/vendor/golang.org/x/sys/cpu/hwcap_linux.go +71 -0
- data/go/vendor/golang.org/x/sys/cpu/parse.go +55 -0
- data/go/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go +53 -0
- data/go/vendor/golang.org/x/sys/cpu/runtime_auxv.go +16 -0
- data/go/vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go +18 -0
- data/go/vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go +26 -0
- data/go/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go +35 -0
- data/go/vendor/golang.org/x/sys/cpu/syscall_darwin_arm64_gc.go +54 -0
- data/go/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go +98 -0
- data/go/vendor/golang.org/x/sys/cpu/zcpu_windows.go +48 -0
- data/go/vendor/golang.org/x/sys/unix/README.md +184 -0
- data/go/vendor/golang.org/x/sys/unix/affinity_linux.go +189 -0
- data/go/vendor/golang.org/x/sys/unix/aliases.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/asm_aix_ppc64.s +17 -0
- data/go/vendor/golang.org/x/sys/unix/asm_bsd_386.s +27 -0
- data/go/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s +27 -0
- data/go/vendor/golang.org/x/sys/unix/asm_bsd_arm.s +27 -0
- data/go/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s +27 -0
- data/go/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s +29 -0
- data/go/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s +27 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_386.s +65 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_amd64.s +57 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_arm.s +56 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_arm64.s +50 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_loong64.s +51 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s +54 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s +52 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s +42 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s +47 -0
- data/go/vendor/golang.org/x/sys/unix/asm_linux_s390x.s +54 -0
- data/go/vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s +29 -0
- data/go/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s +17 -0
- data/go/vendor/golang.org/x/sys/unix/asm_zos_s390x.s +382 -0
- data/go/vendor/golang.org/x/sys/unix/auxv.go +36 -0
- data/go/vendor/golang.org/x/sys/unix/auxv_unsupported.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/bluetooth_linux.go +36 -0
- data/go/vendor/golang.org/x/sys/unix/bpxsvc_zos.go +657 -0
- data/go/vendor/golang.org/x/sys/unix/bpxsvc_zos.s +192 -0
- data/go/vendor/golang.org/x/sys/unix/cap_freebsd.go +195 -0
- data/go/vendor/golang.org/x/sys/unix/constants.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/dev_aix_ppc.go +26 -0
- data/go/vendor/golang.org/x/sys/unix/dev_aix_ppc64.go +28 -0
- data/go/vendor/golang.org/x/sys/unix/dev_darwin.go +24 -0
- data/go/vendor/golang.org/x/sys/unix/dev_dragonfly.go +30 -0
- data/go/vendor/golang.org/x/sys/unix/dev_freebsd.go +30 -0
- data/go/vendor/golang.org/x/sys/unix/dev_linux.go +42 -0
- data/go/vendor/golang.org/x/sys/unix/dev_netbsd.go +29 -0
- data/go/vendor/golang.org/x/sys/unix/dev_openbsd.go +29 -0
- data/go/vendor/golang.org/x/sys/unix/dev_zos.go +28 -0
- data/go/vendor/golang.org/x/sys/unix/dirent.go +102 -0
- data/go/vendor/golang.org/x/sys/unix/endian_big.go +9 -0
- data/go/vendor/golang.org/x/sys/unix/endian_little.go +9 -0
- data/go/vendor/golang.org/x/sys/unix/env_unix.go +31 -0
- data/go/vendor/golang.org/x/sys/unix/fcntl.go +36 -0
- data/go/vendor/golang.org/x/sys/unix/fcntl_darwin.go +24 -0
- data/go/vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/fdset.go +27 -0
- data/go/vendor/golang.org/x/sys/unix/gccgo.go +59 -0
- data/go/vendor/golang.org/x/sys/unix/gccgo_c.c +44 -0
- data/go/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go +20 -0
- data/go/vendor/golang.org/x/sys/unix/ifreq_linux.go +139 -0
- data/go/vendor/golang.org/x/sys/unix/ioctl_linux.go +334 -0
- data/go/vendor/golang.org/x/sys/unix/ioctl_signed.go +74 -0
- data/go/vendor/golang.org/x/sys/unix/ioctl_unsigned.go +74 -0
- data/go/vendor/golang.org/x/sys/unix/ioctl_zos.go +71 -0
- data/go/vendor/golang.org/x/sys/unix/mkall.sh +250 -0
- data/go/vendor/golang.org/x/sys/unix/mkerrors.sh +814 -0
- data/go/vendor/golang.org/x/sys/unix/mmap_nomremap.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/mremap.go +57 -0
- data/go/vendor/golang.org/x/sys/unix/pagesize_unix.go +15 -0
- data/go/vendor/golang.org/x/sys/unix/pledge_openbsd.go +111 -0
- data/go/vendor/golang.org/x/sys/unix/ptrace_darwin.go +11 -0
- data/go/vendor/golang.org/x/sys/unix/ptrace_ios.go +11 -0
- data/go/vendor/golang.org/x/sys/unix/race.go +30 -0
- data/go/vendor/golang.org/x/sys/unix/race0.go +25 -0
- data/go/vendor/golang.org/x/sys/unix/readdirent_getdents.go +12 -0
- data/go/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go +19 -0
- data/go/vendor/golang.org/x/sys/unix/readv_unix.go +103 -0
- data/go/vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go +16 -0
- data/go/vendor/golang.org/x/sys/unix/sockcmsg_linux.go +85 -0
- data/go/vendor/golang.org/x/sys/unix/sockcmsg_unix.go +106 -0
- data/go/vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go +46 -0
- data/go/vendor/golang.org/x/sys/unix/sockcmsg_zos.go +58 -0
- data/go/vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s +75 -0
- data/go/vendor/golang.org/x/sys/unix/syscall.go +86 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_aix.go +582 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go +52 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go +83 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_bsd.go +609 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_darwin.go +711 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go +50 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go +50 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go +26 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +359 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go +56 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_freebsd.go +455 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go +64 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go +64 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go +60 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go +60 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go +60 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_hurd.go +30 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_hurd_386.go +28 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_illumos.go +78 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux.go +2574 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_386.go +313 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go +12 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go +144 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go +12 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_arm.go +218 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +188 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_gc.go +14 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go +16 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go +30 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go +20 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go +220 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +187 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go +173 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go +203 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +114 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +193 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go +295 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go +111 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_netbsd.go +388 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go +37 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go +37 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go +37 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_netbsd_arm64.go +37 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd.go +346 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go +41 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go +41 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go +41 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go +41 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go +26 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go +39 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go +41 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go +41 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_solaris.go +1183 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go +27 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_unix.go +619 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_unix_gc.go +14 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_unix_gc_ppc64x.go +22 -0
- data/go/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +3213 -0
- data/go/vendor/golang.org/x/sys/unix/sysvshm_linux.go +20 -0
- data/go/vendor/golang.org/x/sys/unix/sysvshm_unix.go +51 -0
- data/go/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/timestruct.go +76 -0
- data/go/vendor/golang.org/x/sys/unix/unveil_openbsd.go +51 -0
- data/go/vendor/golang.org/x/sys/unix/vgetrandom_linux.go +13 -0
- data/go/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go +11 -0
- data/go/vendor/golang.org/x/sys/unix/xattr_bsd.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_aix_ppc.go +1384 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_aix_ppc64.go +1385 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +1922 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +1922 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go +1737 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go +2042 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go +2039 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go +2033 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go +2033 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go +2147 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux.go +4207 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +883 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +883 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +888 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +885 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +875 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +889 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +889 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +889 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +889 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +941 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +945 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +945 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +885 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +944 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +987 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go +1779 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go +1769 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go +1758 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm64.go +1769 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go +1905 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go +1905 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go +1905 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm64.go +1905 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_mips64.go +1905 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go +1904 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go +1903 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go +1556 -0
- data/go/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go +990 -0
- data/go/vendor/golang.org/x/sys/unix/zptrace_armnn_linux.go +40 -0
- data/go/vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go +17 -0
- data/go/vendor/golang.org/x/sys/unix/zptrace_mipsnn_linux.go +49 -0
- data/go/vendor/golang.org/x/sys/unix/zptrace_mipsnnle_linux.go +49 -0
- data/go/vendor/golang.org/x/sys/unix/zptrace_x86_linux.go +79 -0
- data/go/vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s +364 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go +1461 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go +1420 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go +1188 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go +1069 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +2728 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +799 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +2728 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +799 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +1666 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +1886 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +1886 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +1886 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go +1886 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go +1886 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go +101 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux.go +2267 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +469 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +636 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +584 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +535 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go +469 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go +636 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +630 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +619 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go +636 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go +641 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +687 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +687 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go +531 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go +478 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +631 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +1848 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +1848 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +1848 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go +1848 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s +719 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s +719 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s +719 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s +719 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s +719 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s +862 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +2407 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s +719 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +2217 -0
- data/go/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go +3458 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm64.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_mips64.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go +280 -0
- data/go/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go +281 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go +439 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go +437 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go +316 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go +393 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go +393 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go +393 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go +393 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go +393 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +470 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +394 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +434 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +337 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +334 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +454 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +384 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +384 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +454 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +461 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +433 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +433 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +338 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +399 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +413 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go +274 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go +274 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go +274 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm64.go +274 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go +219 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go +219 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go +219 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go +218 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_mips64.go +221 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go +217 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go +218 -0
- data/go/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go +2852 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_aix_ppc.go +353 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_aix_ppc64.go +357 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +878 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +878 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go +473 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +651 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +656 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +642 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go +636 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go +638 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux.go +6475 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +717 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +731 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +711 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +710 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +711 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +716 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +713 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +713 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +716 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +724 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +719 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +719 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +798 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +733 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +714 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go +585 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go +593 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +590 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm64.go +593 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go +568 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go +568 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go +575 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm64.go +568 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_mips64.go +568 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go +570 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go +570 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +516 -0
- data/go/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go +552 -0
- data/go/vendor/golang.org/x/sys/windows/aliases.go +13 -0
- data/go/vendor/golang.org/x/sys/windows/dll_windows.go +380 -0
- data/go/vendor/golang.org/x/sys/windows/env_windows.go +57 -0
- data/go/vendor/golang.org/x/sys/windows/eventlog.go +20 -0
- data/go/vendor/golang.org/x/sys/windows/exec_windows.go +248 -0
- data/go/vendor/golang.org/x/sys/windows/memory_windows.go +48 -0
- data/go/vendor/golang.org/x/sys/windows/mkerrors.bash +70 -0
- data/go/vendor/golang.org/x/sys/windows/mkknownfolderids.bash +27 -0
- data/go/vendor/golang.org/x/sys/windows/mksyscall.go +9 -0
- data/go/vendor/golang.org/x/sys/windows/race.go +30 -0
- data/go/vendor/golang.org/x/sys/windows/race0.go +25 -0
- data/go/vendor/golang.org/x/sys/windows/security_windows.go +1537 -0
- data/go/vendor/golang.org/x/sys/windows/service.go +257 -0
- data/go/vendor/golang.org/x/sys/windows/setupapi_windows.go +1425 -0
- data/go/vendor/golang.org/x/sys/windows/str.go +22 -0
- data/go/vendor/golang.org/x/sys/windows/syscall.go +104 -0
- data/go/vendor/golang.org/x/sys/windows/syscall_windows.go +1952 -0
- data/go/vendor/golang.org/x/sys/windows/types_windows.go +4057 -0
- data/go/vendor/golang.org/x/sys/windows/types_windows_386.go +35 -0
- data/go/vendor/golang.org/x/sys/windows/types_windows_amd64.go +34 -0
- data/go/vendor/golang.org/x/sys/windows/types_windows_arm.go +35 -0
- data/go/vendor/golang.org/x/sys/windows/types_windows_arm64.go +34 -0
- data/go/vendor/golang.org/x/sys/windows/zerrors_windows.go +9468 -0
- data/go/vendor/golang.org/x/sys/windows/zknownfolderids_windows.go +149 -0
- data/go/vendor/golang.org/x/sys/windows/zsyscall_windows.go +4828 -0
- data/go/vendor/golang.org/x/text/LICENSE +27 -0
- data/go/vendor/golang.org/x/text/PATENTS +22 -0
- data/go/vendor/golang.org/x/text/secure/bidirule/bidirule.go +340 -0
- data/go/vendor/golang.org/x/text/transform/transform.go +709 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/bidi.go +359 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/bracket.go +335 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/core.go +1064 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/prop.go +206 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/tables15.0.0.go +2042 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/tables17.0.0.go +2135 -0
- data/go/vendor/golang.org/x/text/unicode/bidi/trieval.go +48 -0
- data/go/vendor/golang.org/x/text/unicode/norm/composition.go +512 -0
- data/go/vendor/golang.org/x/text/unicode/norm/forminfo.go +296 -0
- data/go/vendor/golang.org/x/text/unicode/norm/input.go +109 -0
- data/go/vendor/golang.org/x/text/unicode/norm/iter.go +454 -0
- data/go/vendor/golang.org/x/text/unicode/norm/normalize.go +610 -0
- data/go/vendor/golang.org/x/text/unicode/norm/readwriter.go +125 -0
- data/go/vendor/golang.org/x/text/unicode/norm/tables15.0.0.go +7907 -0
- data/go/vendor/golang.org/x/text/unicode/norm/tables17.0.0.go +8104 -0
- data/go/vendor/golang.org/x/text/unicode/norm/transform.go +88 -0
- data/go/vendor/golang.org/x/text/unicode/norm/trie.go +54 -0
- data/go/vendor/modules.txt +63 -0
- data/lib/puma_plus/core/version.rb +13 -0
- data/lib/puma_plus/core.rb +60 -0
- metadata +1099 -0
|
@@ -0,0 +1,3150 @@
|
|
|
1
|
+
package quic
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"context"
|
|
6
|
+
"crypto/tls"
|
|
7
|
+
"errors"
|
|
8
|
+
"fmt"
|
|
9
|
+
"io"
|
|
10
|
+
"net"
|
|
11
|
+
"reflect"
|
|
12
|
+
"slices"
|
|
13
|
+
"sync"
|
|
14
|
+
"sync/atomic"
|
|
15
|
+
"time"
|
|
16
|
+
|
|
17
|
+
"github.com/quic-go/quic-go/internal/ackhandler"
|
|
18
|
+
"github.com/quic-go/quic-go/internal/handshake"
|
|
19
|
+
"github.com/quic-go/quic-go/internal/monotime"
|
|
20
|
+
"github.com/quic-go/quic-go/internal/protocol"
|
|
21
|
+
"github.com/quic-go/quic-go/internal/qerr"
|
|
22
|
+
"github.com/quic-go/quic-go/internal/utils"
|
|
23
|
+
"github.com/quic-go/quic-go/internal/utils/ringbuffer"
|
|
24
|
+
"github.com/quic-go/quic-go/internal/wire"
|
|
25
|
+
"github.com/quic-go/quic-go/qlog"
|
|
26
|
+
"github.com/quic-go/quic-go/qlogwriter"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
type unpacker interface {
|
|
30
|
+
UnpackLongHeader(hdr *wire.Header, data []byte) (*unpackedPacket, error)
|
|
31
|
+
UnpackShortHeader(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type cryptoStreamHandler interface {
|
|
35
|
+
StartHandshake(context.Context) error
|
|
36
|
+
ChangeConnectionID(protocol.ConnectionID)
|
|
37
|
+
SetLargest1RTTAcked(protocol.PacketNumber) error
|
|
38
|
+
SetHandshakeConfirmed()
|
|
39
|
+
GetSessionTicket() ([]byte, error)
|
|
40
|
+
NextEvent() handshake.Event
|
|
41
|
+
DiscardInitialKeys()
|
|
42
|
+
HandleMessage([]byte, protocol.EncryptionLevel) error
|
|
43
|
+
io.Closer
|
|
44
|
+
ConnectionState() handshake.ConnectionState
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type receivedPacket struct {
|
|
48
|
+
buffer *packetBuffer
|
|
49
|
+
|
|
50
|
+
remoteAddr net.Addr
|
|
51
|
+
rcvTime monotime.Time
|
|
52
|
+
data []byte
|
|
53
|
+
|
|
54
|
+
ecn protocol.ECN
|
|
55
|
+
|
|
56
|
+
info packetInfo // only valid if the contained IP address is valid
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type receivedPacketWithChecksum struct {
|
|
60
|
+
receivedPacket
|
|
61
|
+
checksum qlog.DatagramPayloadChecksum
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
func (p *receivedPacket) Size() protocol.ByteCount { return protocol.ByteCount(len(p.data)) }
|
|
65
|
+
|
|
66
|
+
func (p *receivedPacket) Clone() *receivedPacket {
|
|
67
|
+
return &receivedPacket{
|
|
68
|
+
remoteAddr: p.remoteAddr,
|
|
69
|
+
rcvTime: p.rcvTime,
|
|
70
|
+
data: p.data,
|
|
71
|
+
buffer: p.buffer,
|
|
72
|
+
ecn: p.ecn,
|
|
73
|
+
info: p.info,
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
type connRunner interface {
|
|
78
|
+
Add(protocol.ConnectionID, packetHandler) bool
|
|
79
|
+
Remove(protocol.ConnectionID)
|
|
80
|
+
ReplaceWithClosed([]protocol.ConnectionID, []byte, time.Duration)
|
|
81
|
+
AddResetToken(protocol.StatelessResetToken, packetHandler)
|
|
82
|
+
RemoveResetToken(protocol.StatelessResetToken)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type closeError struct {
|
|
86
|
+
err error
|
|
87
|
+
immediate bool
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
type errCloseForRecreating struct {
|
|
91
|
+
nextPacketNumber protocol.PacketNumber
|
|
92
|
+
nextVersion protocol.Version
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func (e *errCloseForRecreating) Error() string {
|
|
96
|
+
return "closing connection in order to recreate it"
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
var deadlineSendImmediately = monotime.Time(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine
|
|
100
|
+
|
|
101
|
+
type blockMode uint8
|
|
102
|
+
|
|
103
|
+
const (
|
|
104
|
+
// blockModeNone means that the connection is not blocked.
|
|
105
|
+
blockModeNone blockMode = iota
|
|
106
|
+
// blockModeCongestionLimited means that the connection is congestion limited.
|
|
107
|
+
// In that case, we can still send acknowledgments and PTO probe packets.
|
|
108
|
+
blockModeCongestionLimited
|
|
109
|
+
// blockModeHardBlocked means that no packet can be sent, under no circumstances. This can happen when:
|
|
110
|
+
// * the send queue is full
|
|
111
|
+
// * the SentPacketHandler returns SendNone, e.g. when we are tracking the maximum number of packets
|
|
112
|
+
// In that case, the timer will be set to the idle timeout.
|
|
113
|
+
blockModeHardBlocked
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
// A Conn is a QUIC connection between two peers.
|
|
117
|
+
// Calls to the connection (and to streams) can return the following types of errors:
|
|
118
|
+
// - [ApplicationError]: for errors triggered by the application running on top of QUIC
|
|
119
|
+
// - [TransportError]: for errors triggered by the QUIC transport (in many cases a misbehaving peer)
|
|
120
|
+
// - [IdleTimeoutError]: when the peer goes away unexpectedly (this is a [net.Error] timeout error)
|
|
121
|
+
// - [HandshakeTimeoutError]: when the cryptographic handshake takes too long (this is a [net.Error] timeout error)
|
|
122
|
+
// - [StatelessResetError]: when we receive a stateless reset
|
|
123
|
+
// - [VersionNegotiationError]: returned by the client, when there's no version overlap between the peers
|
|
124
|
+
type Conn struct {
|
|
125
|
+
// Destination connection ID used during the handshake.
|
|
126
|
+
// Used to check source connection ID on incoming packets.
|
|
127
|
+
handshakeDestConnID protocol.ConnectionID
|
|
128
|
+
// Set for the client. Destination connection ID used on the first Initial sent.
|
|
129
|
+
origDestConnID protocol.ConnectionID
|
|
130
|
+
retrySrcConnID *protocol.ConnectionID // only set for the client (and if a Retry was performed)
|
|
131
|
+
|
|
132
|
+
srcConnIDLen int
|
|
133
|
+
|
|
134
|
+
perspective protocol.Perspective
|
|
135
|
+
version protocol.Version
|
|
136
|
+
config *Config
|
|
137
|
+
|
|
138
|
+
conn sendConn
|
|
139
|
+
sendQueue sender
|
|
140
|
+
|
|
141
|
+
// lazily initialzed: most connections never migrate
|
|
142
|
+
pathManager *pathManager
|
|
143
|
+
largestRcvdAppData protocol.PacketNumber
|
|
144
|
+
pathManagerOutgoing atomic.Pointer[pathManagerOutgoing]
|
|
145
|
+
|
|
146
|
+
streamsMap *streamsMap
|
|
147
|
+
connIDManager *connIDManager
|
|
148
|
+
connIDGenerator *connIDGenerator
|
|
149
|
+
|
|
150
|
+
rttStats *utils.RTTStats
|
|
151
|
+
connStats utils.ConnectionStats
|
|
152
|
+
|
|
153
|
+
cryptoStreamManager *cryptoStreamManager
|
|
154
|
+
sentPacketHandler ackhandler.SentPacketHandler
|
|
155
|
+
receivedPacketHandler ackhandler.ReceivedPacketHandler
|
|
156
|
+
retransmissionQueue *retransmissionQueue
|
|
157
|
+
framer *framer
|
|
158
|
+
connFlowController *connectionFlowController
|
|
159
|
+
tokenStoreKey string // only set for the client
|
|
160
|
+
tokenGenerator *handshake.TokenGenerator // only set for the server
|
|
161
|
+
|
|
162
|
+
unpacker unpacker
|
|
163
|
+
frameParser wire.FrameParser
|
|
164
|
+
packer packer
|
|
165
|
+
mtuDiscoverer mtuDiscoverer // initialized when the transport parameters are received
|
|
166
|
+
|
|
167
|
+
maxPayloadSizeEstimate atomic.Uint32
|
|
168
|
+
|
|
169
|
+
initialStream *initialCryptoStream
|
|
170
|
+
handshakeStream *cryptoStream
|
|
171
|
+
oneRTTStream *cryptoStream // only set for the server
|
|
172
|
+
cryptoStreamHandler cryptoStreamHandler
|
|
173
|
+
|
|
174
|
+
notifyReceivedPacket chan struct{}
|
|
175
|
+
sendingScheduled chan struct{}
|
|
176
|
+
receivedPacketMx sync.Mutex
|
|
177
|
+
receivedPackets ringbuffer.RingBuffer[receivedPacket]
|
|
178
|
+
|
|
179
|
+
// closeChan is used to notify the run loop that it should terminate
|
|
180
|
+
closeChan chan struct{}
|
|
181
|
+
closeErr atomic.Pointer[closeError]
|
|
182
|
+
|
|
183
|
+
ctx context.Context
|
|
184
|
+
ctxCancel context.CancelCauseFunc
|
|
185
|
+
handshakeCompleteChan chan struct{}
|
|
186
|
+
|
|
187
|
+
undecryptablePackets []receivedPacketWithChecksum // undecryptable packets, waiting for a change in encryption level
|
|
188
|
+
undecryptablePacketsToProcess []receivedPacketWithChecksum
|
|
189
|
+
|
|
190
|
+
earlyConnReadyChan chan struct{}
|
|
191
|
+
sentFirstPacket bool
|
|
192
|
+
droppedInitialKeys bool
|
|
193
|
+
handshakeComplete bool
|
|
194
|
+
handshakeConfirmed bool
|
|
195
|
+
|
|
196
|
+
receivedRetry bool
|
|
197
|
+
versionNegotiated bool
|
|
198
|
+
receivedFirstPacket bool
|
|
199
|
+
|
|
200
|
+
blocked blockMode
|
|
201
|
+
|
|
202
|
+
// the minimum of the max_idle_timeout values advertised by both endpoints
|
|
203
|
+
idleTimeout time.Duration
|
|
204
|
+
creationTime monotime.Time
|
|
205
|
+
// The idle timeout is set based on the max of the time we received the last packet...
|
|
206
|
+
lastPacketReceivedTime monotime.Time
|
|
207
|
+
// ... and the time we sent a new ack-eliciting packet after receiving a packet.
|
|
208
|
+
firstAckElicitingPacketAfterIdleSentTime monotime.Time
|
|
209
|
+
// pacingDeadline is the time when the next packet should be sent
|
|
210
|
+
pacingDeadline monotime.Time
|
|
211
|
+
|
|
212
|
+
peerParams *wire.TransportParameters
|
|
213
|
+
|
|
214
|
+
timer *time.Timer
|
|
215
|
+
// keepAlivePingSent stores whether a keep alive PING is in flight.
|
|
216
|
+
// It is reset as soon as we receive a packet from the peer.
|
|
217
|
+
keepAlivePingSent bool
|
|
218
|
+
keepAliveInterval time.Duration
|
|
219
|
+
|
|
220
|
+
datagramQueue *datagramQueue
|
|
221
|
+
|
|
222
|
+
connStateMutex sync.Mutex
|
|
223
|
+
connState ConnectionState
|
|
224
|
+
|
|
225
|
+
logID string
|
|
226
|
+
qlogTrace qlogwriter.Trace
|
|
227
|
+
qlogger qlogwriter.Recorder
|
|
228
|
+
logger utils.Logger
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
var _ streamSender = &Conn{}
|
|
232
|
+
|
|
233
|
+
type connTestHooks struct {
|
|
234
|
+
run func() error
|
|
235
|
+
earlyConnReady func() <-chan struct{}
|
|
236
|
+
context func() context.Context
|
|
237
|
+
handshakeComplete func() <-chan struct{}
|
|
238
|
+
closeWithTransportError func(TransportErrorCode)
|
|
239
|
+
destroy func(error)
|
|
240
|
+
handlePacket func(receivedPacket)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
type wrappedConn struct {
|
|
244
|
+
testHooks *connTestHooks
|
|
245
|
+
*Conn
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var newConnection = func(
|
|
249
|
+
ctx context.Context,
|
|
250
|
+
ctxCancel context.CancelCauseFunc,
|
|
251
|
+
conn sendConn,
|
|
252
|
+
runner connRunner,
|
|
253
|
+
origDestConnID protocol.ConnectionID,
|
|
254
|
+
retrySrcConnID *protocol.ConnectionID,
|
|
255
|
+
clientDestConnID protocol.ConnectionID,
|
|
256
|
+
destConnID protocol.ConnectionID,
|
|
257
|
+
srcConnID protocol.ConnectionID,
|
|
258
|
+
connIDGenerator ConnectionIDGenerator,
|
|
259
|
+
statelessResetter *statelessResetter,
|
|
260
|
+
conf *Config,
|
|
261
|
+
tlsConf *tls.Config,
|
|
262
|
+
tokenGenerator *handshake.TokenGenerator,
|
|
263
|
+
clientAddressValidated bool,
|
|
264
|
+
rtt time.Duration,
|
|
265
|
+
qlogTrace qlogwriter.Trace,
|
|
266
|
+
logger utils.Logger,
|
|
267
|
+
v protocol.Version,
|
|
268
|
+
) *wrappedConn {
|
|
269
|
+
s := &Conn{
|
|
270
|
+
ctx: ctx,
|
|
271
|
+
ctxCancel: ctxCancel,
|
|
272
|
+
conn: conn,
|
|
273
|
+
config: conf,
|
|
274
|
+
handshakeDestConnID: destConnID,
|
|
275
|
+
srcConnIDLen: srcConnID.Len(),
|
|
276
|
+
tokenGenerator: tokenGenerator,
|
|
277
|
+
oneRTTStream: newCryptoStream(),
|
|
278
|
+
perspective: protocol.PerspectiveServer,
|
|
279
|
+
qlogTrace: qlogTrace,
|
|
280
|
+
logger: logger,
|
|
281
|
+
version: v,
|
|
282
|
+
}
|
|
283
|
+
if qlogTrace != nil {
|
|
284
|
+
s.qlogger = qlogTrace.AddProducer()
|
|
285
|
+
}
|
|
286
|
+
if origDestConnID.Len() > 0 {
|
|
287
|
+
s.logID = origDestConnID.String()
|
|
288
|
+
} else {
|
|
289
|
+
s.logID = destConnID.String()
|
|
290
|
+
}
|
|
291
|
+
s.connIDManager = newConnIDManager(
|
|
292
|
+
destConnID,
|
|
293
|
+
func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) },
|
|
294
|
+
runner.RemoveResetToken,
|
|
295
|
+
s.queueControlFrame,
|
|
296
|
+
)
|
|
297
|
+
s.connIDGenerator = newConnIDGenerator(
|
|
298
|
+
runner,
|
|
299
|
+
srcConnID,
|
|
300
|
+
&clientDestConnID,
|
|
301
|
+
statelessResetter,
|
|
302
|
+
connRunnerCallbacks{
|
|
303
|
+
AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, s) },
|
|
304
|
+
RemoveConnectionID: runner.Remove,
|
|
305
|
+
ReplaceWithClosed: runner.ReplaceWithClosed,
|
|
306
|
+
},
|
|
307
|
+
s.queueControlFrame,
|
|
308
|
+
connIDGenerator,
|
|
309
|
+
)
|
|
310
|
+
s.preSetup()
|
|
311
|
+
s.rttStats.SetInitialRTT(rtt)
|
|
312
|
+
s.sentPacketHandler = ackhandler.NewSentPacketHandler(
|
|
313
|
+
0,
|
|
314
|
+
protocol.ByteCount(s.config.InitialPacketSize),
|
|
315
|
+
s.rttStats,
|
|
316
|
+
&s.connStats,
|
|
317
|
+
clientAddressValidated,
|
|
318
|
+
s.conn.capabilities().ECN,
|
|
319
|
+
s.receivedPacketHandler.IgnorePacketsBelow,
|
|
320
|
+
s.perspective,
|
|
321
|
+
s.qlogger,
|
|
322
|
+
s.logger,
|
|
323
|
+
)
|
|
324
|
+
s.maxPayloadSizeEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize))))
|
|
325
|
+
statelessResetToken := statelessResetter.GetStatelessResetToken(srcConnID)
|
|
326
|
+
params := &wire.TransportParameters{
|
|
327
|
+
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
|
328
|
+
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
|
329
|
+
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
|
330
|
+
InitialMaxData: protocol.ByteCount(s.config.InitialConnectionReceiveWindow),
|
|
331
|
+
MaxIdleTimeout: s.config.MaxIdleTimeout,
|
|
332
|
+
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
|
|
333
|
+
MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams),
|
|
334
|
+
MaxAckDelay: protocol.MaxAckDelayInclGranularity,
|
|
335
|
+
AckDelayExponent: protocol.AckDelayExponent,
|
|
336
|
+
MaxUDPPayloadSize: protocol.MaxPacketBufferSize,
|
|
337
|
+
StatelessResetToken: &statelessResetToken,
|
|
338
|
+
OriginalDestinationConnectionID: origDestConnID,
|
|
339
|
+
// For interoperability with quic-go versions before May 2023, this value must be set to a value
|
|
340
|
+
// different from protocol.DefaultActiveConnectionIDLimit.
|
|
341
|
+
// If set to the default value, it will be omitted from the transport parameters, which will make
|
|
342
|
+
// old quic-go versions interpret it as 0, instead of the default value of 2.
|
|
343
|
+
// See https://github.com/quic-go/quic-go/pull/3806.
|
|
344
|
+
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
|
|
345
|
+
InitialSourceConnectionID: srcConnID,
|
|
346
|
+
RetrySourceConnectionID: retrySrcConnID,
|
|
347
|
+
EnableResetStreamAt: conf.EnableStreamResetPartialDelivery,
|
|
348
|
+
}
|
|
349
|
+
if s.config.EnableDatagrams {
|
|
350
|
+
params.MaxDatagramFrameSize = wire.MaxDatagramSize
|
|
351
|
+
} else {
|
|
352
|
+
params.MaxDatagramFrameSize = protocol.InvalidByteCount
|
|
353
|
+
}
|
|
354
|
+
if s.qlogger != nil {
|
|
355
|
+
s.qlogTransportParameters(params, protocol.PerspectiveServer, false)
|
|
356
|
+
}
|
|
357
|
+
cs := handshake.NewCryptoSetupServer(
|
|
358
|
+
clientDestConnID,
|
|
359
|
+
conn.LocalAddr(),
|
|
360
|
+
conn.RemoteAddr(),
|
|
361
|
+
params,
|
|
362
|
+
tlsConf,
|
|
363
|
+
conf.Allow0RTT,
|
|
364
|
+
s.rttStats,
|
|
365
|
+
s.qlogger,
|
|
366
|
+
logger,
|
|
367
|
+
s.version,
|
|
368
|
+
)
|
|
369
|
+
s.cryptoStreamHandler = cs
|
|
370
|
+
s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, &s.receivedPacketHandler, s.datagramQueue, s.perspective)
|
|
371
|
+
s.unpacker = newPacketUnpacker(cs, s.srcConnIDLen)
|
|
372
|
+
s.cryptoStreamManager = newCryptoStreamManager(s.initialStream, s.handshakeStream, s.oneRTTStream)
|
|
373
|
+
return &wrappedConn{Conn: s}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// declare this as a variable, such that we can it mock it in the tests
|
|
377
|
+
var newClientConnection = func(
|
|
378
|
+
ctx context.Context,
|
|
379
|
+
conn sendConn,
|
|
380
|
+
runner connRunner,
|
|
381
|
+
destConnID protocol.ConnectionID,
|
|
382
|
+
srcConnID protocol.ConnectionID,
|
|
383
|
+
connIDGenerator ConnectionIDGenerator,
|
|
384
|
+
statelessResetter *statelessResetter,
|
|
385
|
+
conf *Config,
|
|
386
|
+
tlsConf *tls.Config,
|
|
387
|
+
initialPacketNumber protocol.PacketNumber,
|
|
388
|
+
enable0RTT bool,
|
|
389
|
+
hasNegotiatedVersion bool,
|
|
390
|
+
qlogTrace qlogwriter.Trace,
|
|
391
|
+
logger utils.Logger,
|
|
392
|
+
v protocol.Version,
|
|
393
|
+
) *wrappedConn {
|
|
394
|
+
s := &Conn{
|
|
395
|
+
conn: conn,
|
|
396
|
+
config: conf,
|
|
397
|
+
origDestConnID: destConnID,
|
|
398
|
+
handshakeDestConnID: destConnID,
|
|
399
|
+
srcConnIDLen: srcConnID.Len(),
|
|
400
|
+
perspective: protocol.PerspectiveClient,
|
|
401
|
+
logID: destConnID.String(),
|
|
402
|
+
logger: logger,
|
|
403
|
+
qlogTrace: qlogTrace,
|
|
404
|
+
versionNegotiated: hasNegotiatedVersion,
|
|
405
|
+
version: v,
|
|
406
|
+
}
|
|
407
|
+
if qlogTrace != nil {
|
|
408
|
+
s.qlogger = qlogTrace.AddProducer()
|
|
409
|
+
}
|
|
410
|
+
if s.qlogger != nil {
|
|
411
|
+
var srcAddr, destAddr *net.UDPAddr
|
|
412
|
+
if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok {
|
|
413
|
+
srcAddr = addr
|
|
414
|
+
}
|
|
415
|
+
if addr, ok := conn.RemoteAddr().(*net.UDPAddr); ok {
|
|
416
|
+
destAddr = addr
|
|
417
|
+
}
|
|
418
|
+
s.qlogger.RecordEvent(startedConnectionEvent(srcAddr, destAddr))
|
|
419
|
+
}
|
|
420
|
+
s.connIDManager = newConnIDManager(
|
|
421
|
+
destConnID,
|
|
422
|
+
func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) },
|
|
423
|
+
runner.RemoveResetToken,
|
|
424
|
+
s.queueControlFrame,
|
|
425
|
+
)
|
|
426
|
+
s.connIDGenerator = newConnIDGenerator(
|
|
427
|
+
runner,
|
|
428
|
+
srcConnID,
|
|
429
|
+
nil,
|
|
430
|
+
statelessResetter,
|
|
431
|
+
connRunnerCallbacks{
|
|
432
|
+
AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, s) },
|
|
433
|
+
RemoveConnectionID: runner.Remove,
|
|
434
|
+
ReplaceWithClosed: runner.ReplaceWithClosed,
|
|
435
|
+
},
|
|
436
|
+
s.queueControlFrame,
|
|
437
|
+
connIDGenerator,
|
|
438
|
+
)
|
|
439
|
+
s.ctx, s.ctxCancel = context.WithCancelCause(ctx)
|
|
440
|
+
s.preSetup()
|
|
441
|
+
s.sentPacketHandler = ackhandler.NewSentPacketHandler(
|
|
442
|
+
initialPacketNumber,
|
|
443
|
+
protocol.ByteCount(s.config.InitialPacketSize),
|
|
444
|
+
s.rttStats,
|
|
445
|
+
&s.connStats,
|
|
446
|
+
false, // has no effect
|
|
447
|
+
s.conn.capabilities().ECN,
|
|
448
|
+
s.receivedPacketHandler.IgnorePacketsBelow,
|
|
449
|
+
s.perspective,
|
|
450
|
+
s.qlogger,
|
|
451
|
+
s.logger,
|
|
452
|
+
)
|
|
453
|
+
s.maxPayloadSizeEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize))))
|
|
454
|
+
oneRTTStream := newCryptoStream()
|
|
455
|
+
params := &wire.TransportParameters{
|
|
456
|
+
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
|
457
|
+
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
|
458
|
+
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
|
459
|
+
InitialMaxData: protocol.ByteCount(s.config.InitialConnectionReceiveWindow),
|
|
460
|
+
MaxIdleTimeout: s.config.MaxIdleTimeout,
|
|
461
|
+
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
|
|
462
|
+
MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams),
|
|
463
|
+
MaxAckDelay: protocol.MaxAckDelayInclGranularity,
|
|
464
|
+
MaxUDPPayloadSize: protocol.MaxPacketBufferSize,
|
|
465
|
+
AckDelayExponent: protocol.AckDelayExponent,
|
|
466
|
+
// For interoperability with quic-go versions before May 2023, this value must be set to a value
|
|
467
|
+
// different from protocol.DefaultActiveConnectionIDLimit.
|
|
468
|
+
// If set to the default value, it will be omitted from the transport parameters, which will make
|
|
469
|
+
// old quic-go versions interpret it as 0, instead of the default value of 2.
|
|
470
|
+
// See https://github.com/quic-go/quic-go/pull/3806.
|
|
471
|
+
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
|
|
472
|
+
InitialSourceConnectionID: srcConnID,
|
|
473
|
+
EnableResetStreamAt: conf.EnableStreamResetPartialDelivery,
|
|
474
|
+
}
|
|
475
|
+
if s.config.EnableDatagrams {
|
|
476
|
+
params.MaxDatagramFrameSize = wire.MaxDatagramSize
|
|
477
|
+
} else {
|
|
478
|
+
params.MaxDatagramFrameSize = protocol.InvalidByteCount
|
|
479
|
+
}
|
|
480
|
+
if s.qlogger != nil {
|
|
481
|
+
s.qlogTransportParameters(params, protocol.PerspectiveClient, false)
|
|
482
|
+
}
|
|
483
|
+
cs := handshake.NewCryptoSetupClient(
|
|
484
|
+
destConnID,
|
|
485
|
+
params,
|
|
486
|
+
tlsConf,
|
|
487
|
+
enable0RTT,
|
|
488
|
+
s.rttStats,
|
|
489
|
+
s.qlogger,
|
|
490
|
+
logger,
|
|
491
|
+
s.version,
|
|
492
|
+
)
|
|
493
|
+
s.cryptoStreamHandler = cs
|
|
494
|
+
s.cryptoStreamManager = newCryptoStreamManager(s.initialStream, s.handshakeStream, oneRTTStream)
|
|
495
|
+
s.unpacker = newPacketUnpacker(cs, s.srcConnIDLen)
|
|
496
|
+
s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, &s.receivedPacketHandler, s.datagramQueue, s.perspective)
|
|
497
|
+
if len(tlsConf.ServerName) > 0 {
|
|
498
|
+
s.tokenStoreKey = tlsConf.ServerName
|
|
499
|
+
} else {
|
|
500
|
+
s.tokenStoreKey = conn.RemoteAddr().String()
|
|
501
|
+
}
|
|
502
|
+
if s.config.TokenStore != nil {
|
|
503
|
+
if token := s.config.TokenStore.Pop(s.tokenStoreKey); token != nil {
|
|
504
|
+
s.packer.SetToken(token.data)
|
|
505
|
+
s.rttStats.SetInitialRTT(token.rtt)
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return &wrappedConn{Conn: s}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
func (c *Conn) preSetup() {
|
|
512
|
+
c.largestRcvdAppData = protocol.InvalidPacketNumber
|
|
513
|
+
c.initialStream = newInitialCryptoStream(c.perspective == protocol.PerspectiveClient)
|
|
514
|
+
c.handshakeStream = newCryptoStream()
|
|
515
|
+
c.sendQueue = newSendQueue(c.conn)
|
|
516
|
+
c.retransmissionQueue = newRetransmissionQueue()
|
|
517
|
+
c.frameParser = *wire.NewFrameParser(
|
|
518
|
+
c.config.EnableDatagrams,
|
|
519
|
+
c.config.EnableStreamResetPartialDelivery,
|
|
520
|
+
false, // ACK_FREQUENCY is not supported yet
|
|
521
|
+
)
|
|
522
|
+
c.rttStats = utils.NewRTTStats()
|
|
523
|
+
c.connFlowController = newConnectionFlowController(
|
|
524
|
+
protocol.ByteCount(c.config.InitialConnectionReceiveWindow),
|
|
525
|
+
protocol.ByteCount(c.config.MaxConnectionReceiveWindow),
|
|
526
|
+
func(size protocol.ByteCount) bool {
|
|
527
|
+
if c.config.AllowConnectionWindowIncrease == nil {
|
|
528
|
+
return true
|
|
529
|
+
}
|
|
530
|
+
return c.config.AllowConnectionWindowIncrease(c, uint64(size))
|
|
531
|
+
},
|
|
532
|
+
c.rttStats,
|
|
533
|
+
c.logger,
|
|
534
|
+
)
|
|
535
|
+
c.earlyConnReadyChan = make(chan struct{})
|
|
536
|
+
c.streamsMap = newStreamsMap(
|
|
537
|
+
c.ctx,
|
|
538
|
+
c,
|
|
539
|
+
c.queueControlFrame,
|
|
540
|
+
c.newFlowController,
|
|
541
|
+
uint64(c.config.MaxIncomingStreams),
|
|
542
|
+
uint64(c.config.MaxIncomingUniStreams),
|
|
543
|
+
c.perspective,
|
|
544
|
+
)
|
|
545
|
+
c.framer = newFramer(c.connFlowController)
|
|
546
|
+
c.receivedPackets.Init(8)
|
|
547
|
+
c.notifyReceivedPacket = make(chan struct{}, 1)
|
|
548
|
+
c.closeChan = make(chan struct{}, 1)
|
|
549
|
+
c.sendingScheduled = make(chan struct{}, 1)
|
|
550
|
+
c.handshakeCompleteChan = make(chan struct{})
|
|
551
|
+
|
|
552
|
+
now := monotime.Now()
|
|
553
|
+
c.lastPacketReceivedTime = now
|
|
554
|
+
c.creationTime = now
|
|
555
|
+
|
|
556
|
+
c.receivedPacketHandler = *ackhandler.NewReceivedPacketHandler(c.logger)
|
|
557
|
+
|
|
558
|
+
c.datagramQueue = newDatagramQueue(c.scheduleSending, c.logger)
|
|
559
|
+
c.connState.Version = c.version
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// run the connection main loop
|
|
563
|
+
func (c *Conn) run() (err error) {
|
|
564
|
+
defer func() { c.ctxCancel(err) }()
|
|
565
|
+
|
|
566
|
+
defer func() {
|
|
567
|
+
// drain queued packets that will never be processed
|
|
568
|
+
c.receivedPacketMx.Lock()
|
|
569
|
+
defer c.receivedPacketMx.Unlock()
|
|
570
|
+
|
|
571
|
+
for !c.receivedPackets.Empty() {
|
|
572
|
+
p := c.receivedPackets.PopFront()
|
|
573
|
+
p.buffer.Decrement()
|
|
574
|
+
p.buffer.MaybeRelease()
|
|
575
|
+
}
|
|
576
|
+
}()
|
|
577
|
+
|
|
578
|
+
c.timer = time.NewTimer(monotime.Until(c.idleTimeoutStartTime().Add(c.config.HandshakeIdleTimeout)))
|
|
579
|
+
|
|
580
|
+
if err := c.cryptoStreamHandler.StartHandshake(c.ctx); err != nil {
|
|
581
|
+
return err
|
|
582
|
+
}
|
|
583
|
+
if err := c.handleHandshakeEvents(monotime.Now()); err != nil {
|
|
584
|
+
return err
|
|
585
|
+
}
|
|
586
|
+
go func() {
|
|
587
|
+
if err := c.sendQueue.Run(); err != nil {
|
|
588
|
+
c.destroyImpl(err)
|
|
589
|
+
}
|
|
590
|
+
}()
|
|
591
|
+
|
|
592
|
+
if c.perspective == protocol.PerspectiveClient {
|
|
593
|
+
c.scheduleSending() // so the ClientHello actually gets sent
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
var sendQueueAvailable <-chan struct{}
|
|
597
|
+
|
|
598
|
+
runLoop:
|
|
599
|
+
for {
|
|
600
|
+
if c.framer.QueuedTooManyControlFrames() {
|
|
601
|
+
c.setCloseError(&closeError{err: &qerr.TransportError{ErrorCode: InternalError}})
|
|
602
|
+
break runLoop
|
|
603
|
+
}
|
|
604
|
+
// Close immediately if requested
|
|
605
|
+
select {
|
|
606
|
+
case <-c.closeChan:
|
|
607
|
+
break runLoop
|
|
608
|
+
default:
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// no need to set a timer if we can send packets immediately
|
|
612
|
+
if c.pacingDeadline != deadlineSendImmediately {
|
|
613
|
+
c.maybeResetTimer()
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// 1st: handle undecryptable packets, if any.
|
|
617
|
+
// This can only occur before completion of the handshake.
|
|
618
|
+
if len(c.undecryptablePacketsToProcess) > 0 {
|
|
619
|
+
var processedUndecryptablePacket bool
|
|
620
|
+
queue := c.undecryptablePacketsToProcess
|
|
621
|
+
c.undecryptablePacketsToProcess = nil
|
|
622
|
+
for _, p := range queue {
|
|
623
|
+
processed, err := c.handleOnePacket(p.receivedPacket, p.checksum)
|
|
624
|
+
if err != nil {
|
|
625
|
+
c.setCloseError(&closeError{err: err})
|
|
626
|
+
break runLoop
|
|
627
|
+
}
|
|
628
|
+
if processed {
|
|
629
|
+
processedUndecryptablePacket = true
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if processedUndecryptablePacket {
|
|
633
|
+
// if we processed any undecryptable packets, jump to the resetting of the timers directly
|
|
634
|
+
continue
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// 2nd: receive packets.
|
|
639
|
+
processed, err := c.handlePackets() // don't check receivedPackets.Len() in the run loop to avoid locking the mutex
|
|
640
|
+
if err != nil {
|
|
641
|
+
c.setCloseError(&closeError{err: err})
|
|
642
|
+
break runLoop
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// We don't need to wait for new events if:
|
|
646
|
+
// * we processed packets: we probably need to send an ACK, and potentially more data
|
|
647
|
+
// * the pacer allows us to send more packets immediately
|
|
648
|
+
shouldProceedImmediately := sendQueueAvailable == nil && (processed || c.pacingDeadline.Equal(deadlineSendImmediately))
|
|
649
|
+
if !shouldProceedImmediately {
|
|
650
|
+
// 3rd: wait for something to happen:
|
|
651
|
+
// * closing of the connection
|
|
652
|
+
// * timer firing
|
|
653
|
+
// * sending scheduled
|
|
654
|
+
// * send queue available
|
|
655
|
+
// * received packets
|
|
656
|
+
select {
|
|
657
|
+
case <-c.closeChan:
|
|
658
|
+
break runLoop
|
|
659
|
+
case <-c.timer.C:
|
|
660
|
+
case <-c.sendingScheduled:
|
|
661
|
+
case <-sendQueueAvailable:
|
|
662
|
+
case <-c.notifyReceivedPacket:
|
|
663
|
+
wasProcessed, err := c.handlePackets()
|
|
664
|
+
if err != nil {
|
|
665
|
+
c.setCloseError(&closeError{err: err})
|
|
666
|
+
break runLoop
|
|
667
|
+
}
|
|
668
|
+
// if we processed any undecryptable packets, jump to the resetting of the timers directly
|
|
669
|
+
if !wasProcessed {
|
|
670
|
+
continue
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Check for loss detection timeout.
|
|
676
|
+
// This could cause packets to be declared lost, and retransmissions to be enqueued.
|
|
677
|
+
now := monotime.Now()
|
|
678
|
+
if timeout := c.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && !timeout.After(now) {
|
|
679
|
+
if err := c.sentPacketHandler.OnLossDetectionTimeout(now); err != nil {
|
|
680
|
+
c.setCloseError(&closeError{err: err})
|
|
681
|
+
break runLoop
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
if keepAliveTime := c.nextKeepAliveTime(); !keepAliveTime.IsZero() && !now.Before(keepAliveTime) {
|
|
686
|
+
// send a PING frame since there is no activity in the connection
|
|
687
|
+
c.logger.Debugf("Sending a keep-alive PING to keep the connection alive.")
|
|
688
|
+
c.framer.QueueControlFrame(&wire.PingFrame{})
|
|
689
|
+
c.keepAlivePingSent = true
|
|
690
|
+
} else if !c.handshakeComplete && now.Sub(c.creationTime) >= c.config.handshakeTimeout() {
|
|
691
|
+
c.destroyImpl(qerr.ErrHandshakeTimeout)
|
|
692
|
+
break runLoop
|
|
693
|
+
} else {
|
|
694
|
+
idleTimeoutStartTime := c.idleTimeoutStartTime()
|
|
695
|
+
if (!c.handshakeComplete && now.Sub(idleTimeoutStartTime) >= c.config.HandshakeIdleTimeout) ||
|
|
696
|
+
(c.handshakeComplete && !now.Before(c.nextIdleTimeoutTime())) {
|
|
697
|
+
c.destroyImpl(qerr.ErrIdleTimeout)
|
|
698
|
+
break runLoop
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
c.connIDGenerator.RemoveRetiredConnIDs(now)
|
|
703
|
+
|
|
704
|
+
if c.perspective == protocol.PerspectiveClient {
|
|
705
|
+
pm := c.pathManagerOutgoing.Load()
|
|
706
|
+
if pm != nil {
|
|
707
|
+
tr, ok := pm.ShouldSwitchPath()
|
|
708
|
+
if ok {
|
|
709
|
+
c.switchToNewPath(tr, now)
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if c.sendQueue.WouldBlock() {
|
|
715
|
+
// The send queue is still busy sending out packets. Wait until there's space to enqueue new packets.
|
|
716
|
+
sendQueueAvailable = c.sendQueue.Available()
|
|
717
|
+
// Cancel the pacing timer, as we can't send any more packets until the send queue is available again.
|
|
718
|
+
c.pacingDeadline = 0
|
|
719
|
+
c.blocked = blockModeHardBlocked
|
|
720
|
+
continue
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if c.closeErr.Load() != nil {
|
|
724
|
+
break runLoop
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
c.blocked = blockModeNone // sending might set it back to true if we're congestion limited
|
|
728
|
+
if err := c.triggerSending(now); err != nil {
|
|
729
|
+
c.setCloseError(&closeError{err: err})
|
|
730
|
+
break runLoop
|
|
731
|
+
}
|
|
732
|
+
if c.sendQueue.WouldBlock() {
|
|
733
|
+
// The send queue is still busy sending out packets. Wait until there's space to enqueue new packets.
|
|
734
|
+
sendQueueAvailable = c.sendQueue.Available()
|
|
735
|
+
// Cancel the pacing timer, as we can't send any more packets until the send queue is available again.
|
|
736
|
+
c.pacingDeadline = 0
|
|
737
|
+
c.blocked = blockModeHardBlocked
|
|
738
|
+
} else {
|
|
739
|
+
sendQueueAvailable = nil
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
closeErr := c.closeErr.Load()
|
|
744
|
+
c.cryptoStreamHandler.Close()
|
|
745
|
+
c.sendQueue.Close() // close the send queue before sending the CONNECTION_CLOSE
|
|
746
|
+
c.handleCloseError(closeErr)
|
|
747
|
+
if c.qlogger != nil {
|
|
748
|
+
if e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) {
|
|
749
|
+
c.qlogger.Close()
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
c.logger.Infof("Connection %s closed.", c.logID)
|
|
753
|
+
c.timer.Stop()
|
|
754
|
+
return closeErr.err
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// blocks until the early connection can be used
|
|
758
|
+
func (c *Conn) earlyConnReady() <-chan struct{} {
|
|
759
|
+
return c.earlyConnReadyChan
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Context returns a context that is cancelled when the connection is closed.
|
|
763
|
+
// The cancellation cause is set to the error that caused the connection to close.
|
|
764
|
+
func (c *Conn) Context() context.Context {
|
|
765
|
+
return c.ctx
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
func (c *Conn) supportsDatagrams() bool {
|
|
769
|
+
return c.peerParams.MaxDatagramFrameSize > 0
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// ConnectionState returns basic details about the QUIC connection.
|
|
773
|
+
func (c *Conn) ConnectionState() ConnectionState {
|
|
774
|
+
c.connStateMutex.Lock()
|
|
775
|
+
defer c.connStateMutex.Unlock()
|
|
776
|
+
|
|
777
|
+
cs := c.cryptoStreamHandler.ConnectionState()
|
|
778
|
+
c.connState.TLS = cs.ConnectionState
|
|
779
|
+
c.connState.Used0RTT = cs.Used0RTT
|
|
780
|
+
if c.peerParams != nil {
|
|
781
|
+
c.connState.SupportsDatagrams.Remote = c.supportsDatagrams()
|
|
782
|
+
c.connState.SupportsStreamResetPartialDelivery.Remote = c.peerParams.EnableResetStreamAt
|
|
783
|
+
}
|
|
784
|
+
c.connState.SupportsDatagrams.Local = c.config.EnableDatagrams
|
|
785
|
+
c.connState.SupportsStreamResetPartialDelivery.Local = c.config.EnableStreamResetPartialDelivery
|
|
786
|
+
c.connState.GSO = c.conn.capabilities().GSO
|
|
787
|
+
return c.connState
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// ConnectionStats contains statistics about the QUIC connection
|
|
791
|
+
type ConnectionStats struct {
|
|
792
|
+
// MinRTT is the estimate of the minimum RTT observed on the active network
|
|
793
|
+
// path.
|
|
794
|
+
MinRTT time.Duration
|
|
795
|
+
// LatestRTT is the last RTT sample observed on the active network path.
|
|
796
|
+
LatestRTT time.Duration
|
|
797
|
+
// SmoothedRTT is an exponentially weighted moving average of an endpoint's
|
|
798
|
+
// RTT samples. See https://www.rfc-editor.org/rfc/rfc9002#section-5.3
|
|
799
|
+
SmoothedRTT time.Duration
|
|
800
|
+
// MeanDeviation estimates the variation in the RTT samples using a mean
|
|
801
|
+
// variation. See https://www.rfc-editor.org/rfc/rfc9002#section-5.3
|
|
802
|
+
MeanDeviation time.Duration
|
|
803
|
+
|
|
804
|
+
// BytesSent is the number of bytes sent on the underlying connection,
|
|
805
|
+
// including retransmissions. Does not include UDP or any other outer
|
|
806
|
+
// framing.
|
|
807
|
+
BytesSent uint64
|
|
808
|
+
// PacketsSent is the number of packets sent on the underlying connection,
|
|
809
|
+
// including those that are determined to have been lost.
|
|
810
|
+
PacketsSent uint64
|
|
811
|
+
// BytesReceived is the number of total bytes received on the underlying
|
|
812
|
+
// connection, including duplicate data for streams. Does not include UDP or
|
|
813
|
+
// any other outer framing.
|
|
814
|
+
BytesReceived uint64
|
|
815
|
+
// PacketsReceived is the number of total packets received on the underlying
|
|
816
|
+
// connection, including packets that were not processable.
|
|
817
|
+
PacketsReceived uint64
|
|
818
|
+
// BytesLost is the number of bytes lost on the underlying connection (does
|
|
819
|
+
// not monotonically increase, because packets that are declared lost can
|
|
820
|
+
// subsequently be received). Does not include UDP or any other outer
|
|
821
|
+
// framing.
|
|
822
|
+
BytesLost uint64
|
|
823
|
+
// PacketsLost is the number of packets lost on the underlying connection
|
|
824
|
+
// (does not monotonically increase, because packets that are declared lost
|
|
825
|
+
// can subsequently be received).
|
|
826
|
+
PacketsLost uint64
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
func (c *Conn) ConnectionStats() ConnectionStats {
|
|
830
|
+
return ConnectionStats{
|
|
831
|
+
MinRTT: c.rttStats.MinRTT(),
|
|
832
|
+
LatestRTT: c.rttStats.LatestRTT(),
|
|
833
|
+
SmoothedRTT: c.rttStats.SmoothedRTT(),
|
|
834
|
+
MeanDeviation: c.rttStats.MeanDeviation(),
|
|
835
|
+
|
|
836
|
+
BytesSent: c.connStats.BytesSent.Load(),
|
|
837
|
+
PacketsSent: c.connStats.PacketsSent.Load(),
|
|
838
|
+
BytesReceived: c.connStats.BytesReceived.Load(),
|
|
839
|
+
PacketsReceived: c.connStats.PacketsReceived.Load(),
|
|
840
|
+
BytesLost: c.connStats.BytesLost.Load(),
|
|
841
|
+
PacketsLost: c.connStats.PacketsLost.Load(),
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Time when the connection should time out
|
|
846
|
+
func (c *Conn) nextIdleTimeoutTime() monotime.Time {
|
|
847
|
+
idleTimeout := max(c.idleTimeout, c.rttStats.PTO(true)*3)
|
|
848
|
+
return c.idleTimeoutStartTime().Add(idleTimeout)
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Time when the next keep-alive packet should be sent.
|
|
852
|
+
// It returns a zero time if no keep-alive should be sent.
|
|
853
|
+
func (c *Conn) nextKeepAliveTime() monotime.Time {
|
|
854
|
+
if c.config.KeepAlivePeriod == 0 || c.keepAlivePingSent {
|
|
855
|
+
return 0
|
|
856
|
+
}
|
|
857
|
+
keepAliveInterval := max(c.keepAliveInterval, c.rttStats.PTO(true)*3/2)
|
|
858
|
+
return c.lastPacketReceivedTime.Add(keepAliveInterval)
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
func (c *Conn) maybeResetTimer() {
|
|
862
|
+
var deadline monotime.Time
|
|
863
|
+
if !c.handshakeComplete {
|
|
864
|
+
deadline = c.creationTime.Add(c.config.handshakeTimeout())
|
|
865
|
+
if t := c.idleTimeoutStartTime().Add(c.config.HandshakeIdleTimeout); t.Before(deadline) {
|
|
866
|
+
deadline = t
|
|
867
|
+
}
|
|
868
|
+
} else {
|
|
869
|
+
// A keep-alive packet is ack-eliciting, so it can only be sent if the connection is
|
|
870
|
+
// neither congestion limited nor hard-blocked.
|
|
871
|
+
if c.blocked != blockModeNone {
|
|
872
|
+
deadline = c.nextIdleTimeoutTime()
|
|
873
|
+
} else {
|
|
874
|
+
if keepAliveTime := c.nextKeepAliveTime(); !keepAliveTime.IsZero() {
|
|
875
|
+
deadline = keepAliveTime
|
|
876
|
+
} else {
|
|
877
|
+
deadline = c.nextIdleTimeoutTime()
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
// If the connection is hard-blocked, we can't even send acknowledgments,
|
|
882
|
+
// nor can we send PTO probe packets.
|
|
883
|
+
if c.blocked == blockModeHardBlocked {
|
|
884
|
+
c.timer.Reset(monotime.Until(deadline))
|
|
885
|
+
return
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
if t := c.receivedPacketHandler.GetAlarmTimeout(); !t.IsZero() && t.Before(deadline) {
|
|
889
|
+
deadline = t
|
|
890
|
+
}
|
|
891
|
+
if t := c.sentPacketHandler.GetLossDetectionTimeout(); !t.IsZero() && t.Before(deadline) {
|
|
892
|
+
deadline = t
|
|
893
|
+
}
|
|
894
|
+
if c.blocked == blockModeCongestionLimited {
|
|
895
|
+
c.timer.Reset(monotime.Until(deadline))
|
|
896
|
+
return
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if !c.pacingDeadline.IsZero() && c.pacingDeadline.Before(deadline) {
|
|
900
|
+
deadline = c.pacingDeadline
|
|
901
|
+
}
|
|
902
|
+
c.timer.Reset(monotime.Until(deadline))
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
func (c *Conn) idleTimeoutStartTime() monotime.Time {
|
|
906
|
+
startTime := c.lastPacketReceivedTime
|
|
907
|
+
if t := c.firstAckElicitingPacketAfterIdleSentTime; !t.IsZero() && t.After(startTime) {
|
|
908
|
+
startTime = t
|
|
909
|
+
}
|
|
910
|
+
return startTime
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
func (c *Conn) switchToNewPath(tr *Transport, now monotime.Time) {
|
|
914
|
+
initialPacketSize := protocol.ByteCount(c.config.InitialPacketSize)
|
|
915
|
+
c.sentPacketHandler.MigratedPath(now, initialPacketSize)
|
|
916
|
+
maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)
|
|
917
|
+
if c.peerParams.MaxUDPPayloadSize > 0 && c.peerParams.MaxUDPPayloadSize < maxPacketSize {
|
|
918
|
+
maxPacketSize = c.peerParams.MaxUDPPayloadSize
|
|
919
|
+
}
|
|
920
|
+
c.mtuDiscoverer.Reset(now, initialPacketSize, maxPacketSize)
|
|
921
|
+
c.conn = newSendConn(tr.conn, c.conn.RemoteAddr(), packetInfo{}, utils.DefaultLogger) // TODO: find a better way
|
|
922
|
+
c.sendQueue.Close()
|
|
923
|
+
c.sendQueue = newSendQueue(c.conn)
|
|
924
|
+
go func() {
|
|
925
|
+
if err := c.sendQueue.Run(); err != nil {
|
|
926
|
+
c.destroyImpl(err)
|
|
927
|
+
}
|
|
928
|
+
}()
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
func (c *Conn) handleHandshakeComplete(now monotime.Time) error {
|
|
932
|
+
defer close(c.handshakeCompleteChan)
|
|
933
|
+
// Once the handshake completes, we have derived 1-RTT keys.
|
|
934
|
+
// There's no point in queueing undecryptable packets for later decryption anymore.
|
|
935
|
+
c.undecryptablePackets = nil
|
|
936
|
+
|
|
937
|
+
c.connIDManager.SetHandshakeComplete()
|
|
938
|
+
c.connIDGenerator.SetHandshakeComplete(now.Add(3 * c.rttStats.PTO(false)))
|
|
939
|
+
|
|
940
|
+
if c.qlogger != nil {
|
|
941
|
+
c.qlogger.RecordEvent(qlog.ALPNInformation{
|
|
942
|
+
ChosenALPN: c.cryptoStreamHandler.ConnectionState().NegotiatedProtocol,
|
|
943
|
+
})
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// The server applies transport parameters right away, but the client side has to wait for handshake completion.
|
|
947
|
+
// During a 0-RTT connection, the client is only allowed to use the new transport parameters for 1-RTT packets.
|
|
948
|
+
if c.perspective == protocol.PerspectiveClient {
|
|
949
|
+
c.applyTransportParameters()
|
|
950
|
+
return nil
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// All these only apply to the server side.
|
|
954
|
+
if err := c.handleHandshakeConfirmed(now); err != nil {
|
|
955
|
+
return err
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
ticket, err := c.cryptoStreamHandler.GetSessionTicket()
|
|
959
|
+
if err != nil {
|
|
960
|
+
return err
|
|
961
|
+
}
|
|
962
|
+
if ticket != nil { // may be nil if session tickets are disabled via tls.Config.SessionTicketsDisabled
|
|
963
|
+
c.oneRTTStream.Write(ticket)
|
|
964
|
+
for c.oneRTTStream.HasData() {
|
|
965
|
+
if cf := c.oneRTTStream.PopCryptoFrame(protocol.MaxPostHandshakeCryptoFrameSize); cf != nil {
|
|
966
|
+
c.queueControlFrame(cf)
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
token, err := c.tokenGenerator.NewToken(c.conn.RemoteAddr(), c.rttStats.SmoothedRTT())
|
|
971
|
+
if err != nil {
|
|
972
|
+
return err
|
|
973
|
+
}
|
|
974
|
+
c.queueControlFrame(&wire.NewTokenFrame{Token: token})
|
|
975
|
+
c.queueControlFrame(&wire.HandshakeDoneFrame{})
|
|
976
|
+
return nil
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
func (c *Conn) handleHandshakeConfirmed(now monotime.Time) error {
|
|
980
|
+
// Drop initial keys.
|
|
981
|
+
// On the client side, this should have happened when sending the first Handshake packet,
|
|
982
|
+
// but this is not guaranteed if the server misbehaves.
|
|
983
|
+
// See CVE-2025-59530 for more details.
|
|
984
|
+
if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {
|
|
985
|
+
return err
|
|
986
|
+
}
|
|
987
|
+
if err := c.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {
|
|
988
|
+
return err
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
c.handshakeConfirmed = true
|
|
992
|
+
c.cryptoStreamHandler.SetHandshakeConfirmed()
|
|
993
|
+
|
|
994
|
+
if !c.config.DisablePathMTUDiscovery && c.conn.capabilities().DF {
|
|
995
|
+
c.mtuDiscoverer.Start(now)
|
|
996
|
+
}
|
|
997
|
+
return nil
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
const maxPacketsToProcess = 32
|
|
1001
|
+
|
|
1002
|
+
func (c *Conn) handlePackets() (wasProcessed bool, _ error) {
|
|
1003
|
+
// Process packets from the receivedPackets queue.
|
|
1004
|
+
// Limit the number of packets to process to maxPacketsToProcess,
|
|
1005
|
+
// so we eventually get a chance to send out an ACK when receiving a lot of packets.
|
|
1006
|
+
c.receivedPacketMx.Lock()
|
|
1007
|
+
|
|
1008
|
+
if c.receivedPackets.Empty() {
|
|
1009
|
+
c.receivedPacketMx.Unlock()
|
|
1010
|
+
return false, nil
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
var hasMorePackets bool
|
|
1014
|
+
for range maxPacketsToProcess {
|
|
1015
|
+
p := c.receivedPackets.PopFront()
|
|
1016
|
+
c.receivedPacketMx.Unlock()
|
|
1017
|
+
|
|
1018
|
+
var datagramPayloadChecksum qlog.DatagramPayloadChecksum
|
|
1019
|
+
if c.qlogger != nil && wire.IsLongHeaderPacket(p.data[0]) {
|
|
1020
|
+
datagramPayloadChecksum = qlog.CalculateDatagramPayloadChecksum(p.data)
|
|
1021
|
+
}
|
|
1022
|
+
processed, err := c.handleOnePacket(p, datagramPayloadChecksum)
|
|
1023
|
+
if err != nil {
|
|
1024
|
+
return false, err
|
|
1025
|
+
}
|
|
1026
|
+
if processed {
|
|
1027
|
+
wasProcessed = true
|
|
1028
|
+
}
|
|
1029
|
+
c.receivedPacketMx.Lock()
|
|
1030
|
+
hasMorePackets = !c.receivedPackets.Empty()
|
|
1031
|
+
if !hasMorePackets {
|
|
1032
|
+
break
|
|
1033
|
+
}
|
|
1034
|
+
// Prioritize sending of new CRYPTO data.
|
|
1035
|
+
// This is especially relevant when processing 0-RTT packets.
|
|
1036
|
+
if !c.handshakeComplete && (c.initialStream.HasData() || c.handshakeStream.HasData()) {
|
|
1037
|
+
break
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
c.receivedPacketMx.Unlock()
|
|
1041
|
+
|
|
1042
|
+
if hasMorePackets {
|
|
1043
|
+
select {
|
|
1044
|
+
case c.notifyReceivedPacket <- struct{}{}:
|
|
1045
|
+
default:
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return wasProcessed, nil
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
func (c *Conn) handleOnePacket(rp receivedPacket, datagramPayloadChecksum qlog.DatagramPayloadChecksum) (wasProcessed bool, _ error) {
|
|
1052
|
+
c.sentPacketHandler.ReceivedBytes(rp.Size(), rp.rcvTime)
|
|
1053
|
+
|
|
1054
|
+
if wire.IsVersionNegotiationPacket(rp.data) {
|
|
1055
|
+
return false, c.handleVersionNegotiationPacket(rp)
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
var counter uint8
|
|
1059
|
+
var lastConnID protocol.ConnectionID
|
|
1060
|
+
data := rp.data
|
|
1061
|
+
p := rp
|
|
1062
|
+
for len(data) > 0 {
|
|
1063
|
+
if counter > 0 {
|
|
1064
|
+
p = *(p.Clone())
|
|
1065
|
+
p.data = data
|
|
1066
|
+
|
|
1067
|
+
destConnID, err := wire.ParseConnectionID(p.data, c.srcConnIDLen)
|
|
1068
|
+
if err != nil {
|
|
1069
|
+
if c.qlogger != nil {
|
|
1070
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1071
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1072
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1073
|
+
Trigger: qlog.PacketDropHeaderParseError,
|
|
1074
|
+
})
|
|
1075
|
+
}
|
|
1076
|
+
c.logger.Debugf("error parsing packet, couldn't parse connection ID: %s", err)
|
|
1077
|
+
break
|
|
1078
|
+
}
|
|
1079
|
+
if destConnID != lastConnID {
|
|
1080
|
+
if c.qlogger != nil {
|
|
1081
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1082
|
+
Header: qlog.PacketHeader{DestConnectionID: destConnID},
|
|
1083
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1084
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1085
|
+
Trigger: qlog.PacketDropUnknownConnectionID,
|
|
1086
|
+
})
|
|
1087
|
+
}
|
|
1088
|
+
c.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", destConnID, lastConnID)
|
|
1089
|
+
break
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
if wire.IsLongHeaderPacket(p.data[0]) {
|
|
1094
|
+
hdr, packetData, rest, err := wire.ParsePacket(p.data)
|
|
1095
|
+
if err != nil {
|
|
1096
|
+
if c.qlogger != nil {
|
|
1097
|
+
if err == wire.ErrUnsupportedVersion {
|
|
1098
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1099
|
+
Header: qlog.PacketHeader{Version: hdr.Version},
|
|
1100
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1101
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1102
|
+
Trigger: qlog.PacketDropUnsupportedVersion,
|
|
1103
|
+
})
|
|
1104
|
+
} else {
|
|
1105
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1106
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1107
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1108
|
+
Trigger: qlog.PacketDropHeaderParseError,
|
|
1109
|
+
})
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
c.logger.Debugf("error parsing packet: %s", err)
|
|
1113
|
+
break
|
|
1114
|
+
}
|
|
1115
|
+
lastConnID = hdr.DestConnectionID
|
|
1116
|
+
|
|
1117
|
+
if hdr.Version != c.version {
|
|
1118
|
+
if c.qlogger != nil {
|
|
1119
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1120
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1121
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1122
|
+
Trigger: qlog.PacketDropUnexpectedVersion,
|
|
1123
|
+
})
|
|
1124
|
+
}
|
|
1125
|
+
c.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, c.version)
|
|
1126
|
+
break
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
if counter > 0 {
|
|
1130
|
+
p.buffer.Split()
|
|
1131
|
+
}
|
|
1132
|
+
counter++
|
|
1133
|
+
|
|
1134
|
+
// only log if this actually a coalesced packet
|
|
1135
|
+
if c.logger.Debug() && (counter > 1 || len(rest) > 0) {
|
|
1136
|
+
c.logger.Debugf("Parsed a coalesced packet. Part %d: %d bytes. Remaining: %d bytes.", counter, len(packetData), len(rest))
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
p.data = packetData
|
|
1140
|
+
|
|
1141
|
+
processed, err := c.handleLongHeaderPacket(p, hdr, datagramPayloadChecksum)
|
|
1142
|
+
if err != nil {
|
|
1143
|
+
return false, err
|
|
1144
|
+
}
|
|
1145
|
+
if processed {
|
|
1146
|
+
wasProcessed = true
|
|
1147
|
+
}
|
|
1148
|
+
data = rest
|
|
1149
|
+
} else {
|
|
1150
|
+
if counter > 0 {
|
|
1151
|
+
p.buffer.Split()
|
|
1152
|
+
}
|
|
1153
|
+
processed, err := c.handleShortHeaderPacket(p, counter > 0, datagramPayloadChecksum)
|
|
1154
|
+
if err != nil {
|
|
1155
|
+
return false, err
|
|
1156
|
+
}
|
|
1157
|
+
if processed {
|
|
1158
|
+
wasProcessed = true
|
|
1159
|
+
}
|
|
1160
|
+
break
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
p.buffer.MaybeRelease()
|
|
1165
|
+
c.blocked = blockModeNone
|
|
1166
|
+
return wasProcessed, nil
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
func (c *Conn) handleShortHeaderPacket(
|
|
1170
|
+
p receivedPacket,
|
|
1171
|
+
isCoalesced bool,
|
|
1172
|
+
datagramPayloadChecksum qlog.DatagramPayloadChecksum, // only for logging
|
|
1173
|
+
) (wasProcessed bool, _ error) {
|
|
1174
|
+
var wasQueued bool
|
|
1175
|
+
|
|
1176
|
+
defer func() {
|
|
1177
|
+
// Put back the packet buffer if the packet wasn't queued for later decryption.
|
|
1178
|
+
if !wasQueued {
|
|
1179
|
+
p.buffer.Decrement()
|
|
1180
|
+
}
|
|
1181
|
+
}()
|
|
1182
|
+
|
|
1183
|
+
destConnID, err := wire.ParseConnectionID(p.data, c.srcConnIDLen)
|
|
1184
|
+
if err != nil {
|
|
1185
|
+
if c.qlogger != nil {
|
|
1186
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1187
|
+
Header: qlog.PacketHeader{
|
|
1188
|
+
PacketType: qlog.PacketType1RTT,
|
|
1189
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
1190
|
+
},
|
|
1191
|
+
Raw: qlog.RawInfo{Length: len(p.data)},
|
|
1192
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1193
|
+
Trigger: qlog.PacketDropHeaderParseError,
|
|
1194
|
+
})
|
|
1195
|
+
}
|
|
1196
|
+
return false, nil
|
|
1197
|
+
}
|
|
1198
|
+
pn, pnLen, keyPhase, data, err := c.unpacker.UnpackShortHeader(p.rcvTime, p.data)
|
|
1199
|
+
if err != nil {
|
|
1200
|
+
// Stateless reset packets (see RFC 9000, section 10.3):
|
|
1201
|
+
// * fill the entire UDP datagram (i.e. they cannot be part of a coalesced packet)
|
|
1202
|
+
// * are short header packets (first bit is 0)
|
|
1203
|
+
// * have the QUIC bit set (second bit is 1)
|
|
1204
|
+
// * are at least 21 bytes long
|
|
1205
|
+
if !isCoalesced && len(p.data) >= protocol.MinReceivedStatelessResetSize && p.data[0]&0b11000000 == 0b01000000 {
|
|
1206
|
+
token := protocol.StatelessResetToken(p.data[len(p.data)-16:])
|
|
1207
|
+
if c.connIDManager.IsActiveStatelessResetToken(token) {
|
|
1208
|
+
return false, &StatelessResetError{}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
wasQueued, err = c.handleUnpackError(err, p, qlog.PacketType1RTT, datagramPayloadChecksum)
|
|
1212
|
+
return false, err
|
|
1213
|
+
}
|
|
1214
|
+
c.largestRcvdAppData = max(c.largestRcvdAppData, pn)
|
|
1215
|
+
|
|
1216
|
+
if c.logger.Debug() {
|
|
1217
|
+
c.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, 1-RTT", pn, p.Size(), destConnID)
|
|
1218
|
+
wire.LogShortHeader(c.logger, destConnID, pn, pnLen, keyPhase)
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
if c.receivedPacketHandler.IsPotentiallyDuplicate(pn, protocol.Encryption1RTT) {
|
|
1222
|
+
c.logger.Debugf("Dropping (potentially) duplicate packet.")
|
|
1223
|
+
if c.qlogger != nil {
|
|
1224
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1225
|
+
Header: qlog.PacketHeader{
|
|
1226
|
+
PacketType: qlog.PacketType1RTT,
|
|
1227
|
+
PacketNumber: pn,
|
|
1228
|
+
},
|
|
1229
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1230
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1231
|
+
Trigger: qlog.PacketDropDuplicate,
|
|
1232
|
+
})
|
|
1233
|
+
}
|
|
1234
|
+
return false, nil
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
var log func([]qlog.Frame)
|
|
1238
|
+
if c.qlogger != nil {
|
|
1239
|
+
log = func(frames []qlog.Frame) {
|
|
1240
|
+
c.qlogger.RecordEvent(qlog.PacketReceived{
|
|
1241
|
+
Header: qlog.PacketHeader{
|
|
1242
|
+
PacketType: qlog.PacketType1RTT,
|
|
1243
|
+
DestConnectionID: destConnID,
|
|
1244
|
+
PacketNumber: pn,
|
|
1245
|
+
KeyPhaseBit: keyPhase,
|
|
1246
|
+
},
|
|
1247
|
+
Raw: qlog.RawInfo{
|
|
1248
|
+
Length: int(p.Size()),
|
|
1249
|
+
PayloadLength: int(p.Size() - wire.ShortHeaderLen(destConnID, pnLen)),
|
|
1250
|
+
},
|
|
1251
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1252
|
+
Frames: frames,
|
|
1253
|
+
ECN: toQlogECN(p.ecn),
|
|
1254
|
+
})
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
isNonProbing, pathChallenge, err := c.handleUnpackedShortHeaderPacket(destConnID, pn, data, p.ecn, p.rcvTime, log)
|
|
1258
|
+
if err != nil {
|
|
1259
|
+
return false, err
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
// In RFC 9000, only the client can migrate between paths.
|
|
1263
|
+
if c.perspective == protocol.PerspectiveClient {
|
|
1264
|
+
return true, nil
|
|
1265
|
+
}
|
|
1266
|
+
if addrsEqual(p.remoteAddr, c.RemoteAddr()) {
|
|
1267
|
+
return true, nil
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
var shouldSwitchPath bool
|
|
1271
|
+
if c.pathManager == nil {
|
|
1272
|
+
c.pathManager = newPathManager(
|
|
1273
|
+
c.connIDManager.GetConnIDForPath,
|
|
1274
|
+
c.connIDManager.RetireConnIDForPath,
|
|
1275
|
+
c.logger,
|
|
1276
|
+
)
|
|
1277
|
+
}
|
|
1278
|
+
destConnID, frames, shouldSwitchPath := c.pathManager.HandlePacket(p.remoteAddr, p.rcvTime, pathChallenge, isNonProbing)
|
|
1279
|
+
if len(frames) > 0 {
|
|
1280
|
+
probe, buf, err := c.packer.PackPathProbePacket(destConnID, frames, c.version)
|
|
1281
|
+
if err != nil {
|
|
1282
|
+
return true, err
|
|
1283
|
+
}
|
|
1284
|
+
c.logger.Debugf("sending path probe packet to %s", p.remoteAddr)
|
|
1285
|
+
c.logShortHeaderPacketWithDatagramPayloadChecksum(probe, protocol.ECNNon, buf.Len(), false, datagramPayloadChecksum)
|
|
1286
|
+
c.registerPackedShortHeaderPacket(probe, protocol.ECNNon, p.rcvTime)
|
|
1287
|
+
c.sendQueue.SendProbe(buf, p.remoteAddr, p.info)
|
|
1288
|
+
}
|
|
1289
|
+
// We only switch paths in response to the highest-numbered non-probing packet,
|
|
1290
|
+
// see section 9.3 of RFC 9000.
|
|
1291
|
+
if !shouldSwitchPath || pn != c.largestRcvdAppData {
|
|
1292
|
+
return true, nil
|
|
1293
|
+
}
|
|
1294
|
+
c.pathManager.SwitchToPath(p.remoteAddr)
|
|
1295
|
+
c.sentPacketHandler.MigratedPath(p.rcvTime, protocol.ByteCount(c.config.InitialPacketSize))
|
|
1296
|
+
maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)
|
|
1297
|
+
if c.peerParams.MaxUDPPayloadSize > 0 && c.peerParams.MaxUDPPayloadSize < maxPacketSize {
|
|
1298
|
+
maxPacketSize = c.peerParams.MaxUDPPayloadSize
|
|
1299
|
+
}
|
|
1300
|
+
c.mtuDiscoverer.Reset(
|
|
1301
|
+
p.rcvTime,
|
|
1302
|
+
protocol.ByteCount(c.config.InitialPacketSize),
|
|
1303
|
+
maxPacketSize,
|
|
1304
|
+
)
|
|
1305
|
+
c.conn.ChangeRemoteAddr(p.remoteAddr, p.info)
|
|
1306
|
+
return true, nil
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
func (c *Conn) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header, datagramPayloadChecksum qlog.DatagramPayloadChecksum) (wasProcessed bool, _ error) {
|
|
1310
|
+
var wasQueued bool
|
|
1311
|
+
|
|
1312
|
+
defer func() {
|
|
1313
|
+
// Put back the packet buffer if the packet wasn't queued for later decryption.
|
|
1314
|
+
if !wasQueued {
|
|
1315
|
+
p.buffer.Decrement()
|
|
1316
|
+
}
|
|
1317
|
+
}()
|
|
1318
|
+
|
|
1319
|
+
if hdr.Type == protocol.PacketTypeRetry {
|
|
1320
|
+
return c.handleRetryPacket(hdr, p.data, p.rcvTime), nil
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
// The server can change the source connection ID with the first Handshake packet.
|
|
1324
|
+
// After this, all packets with a different source connection have to be ignored.
|
|
1325
|
+
if c.receivedFirstPacket && hdr.Type == protocol.PacketTypeInitial && hdr.SrcConnectionID != c.handshakeDestConnID {
|
|
1326
|
+
if c.qlogger != nil {
|
|
1327
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1328
|
+
Header: qlog.PacketHeader{
|
|
1329
|
+
PacketType: qlog.PacketTypeInitial,
|
|
1330
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
1331
|
+
},
|
|
1332
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1333
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1334
|
+
Trigger: qlog.PacketDropUnknownConnectionID,
|
|
1335
|
+
})
|
|
1336
|
+
}
|
|
1337
|
+
c.logger.Debugf("Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)", p.Size(), hdr.SrcConnectionID, c.handshakeDestConnID)
|
|
1338
|
+
return false, nil
|
|
1339
|
+
}
|
|
1340
|
+
// drop 0-RTT packets, if we are a client
|
|
1341
|
+
if c.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT {
|
|
1342
|
+
if c.qlogger != nil {
|
|
1343
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1344
|
+
Header: qlog.PacketHeader{
|
|
1345
|
+
PacketType: qlog.PacketType0RTT,
|
|
1346
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
1347
|
+
},
|
|
1348
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1349
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1350
|
+
Trigger: qlog.PacketDropUnexpectedPacket,
|
|
1351
|
+
})
|
|
1352
|
+
}
|
|
1353
|
+
return false, nil
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
packet, err := c.unpacker.UnpackLongHeader(hdr, p.data)
|
|
1357
|
+
if err != nil {
|
|
1358
|
+
wasQueued, err = c.handleUnpackError(err, p, toQlogPacketType(hdr.Type), datagramPayloadChecksum)
|
|
1359
|
+
return false, err
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
if c.logger.Debug() {
|
|
1363
|
+
c.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, %s", packet.hdr.PacketNumber, p.Size(), hdr.DestConnectionID, packet.encryptionLevel)
|
|
1364
|
+
packet.hdr.Log(c.logger)
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
if pn := packet.hdr.PacketNumber; c.receivedPacketHandler.IsPotentiallyDuplicate(pn, packet.encryptionLevel) {
|
|
1368
|
+
c.logger.Debugf("Dropping (potentially) duplicate packet.")
|
|
1369
|
+
if c.qlogger != nil {
|
|
1370
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1371
|
+
Header: qlog.PacketHeader{
|
|
1372
|
+
PacketType: toQlogPacketType(packet.hdr.Type),
|
|
1373
|
+
DestConnectionID: hdr.DestConnectionID,
|
|
1374
|
+
SrcConnectionID: hdr.SrcConnectionID,
|
|
1375
|
+
PacketNumber: pn,
|
|
1376
|
+
Version: packet.hdr.Version,
|
|
1377
|
+
},
|
|
1378
|
+
Raw: qlog.RawInfo{Length: int(p.Size()), PayloadLength: int(packet.hdr.Length)},
|
|
1379
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1380
|
+
Trigger: qlog.PacketDropDuplicate,
|
|
1381
|
+
})
|
|
1382
|
+
}
|
|
1383
|
+
return false, nil
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
if err := c.handleUnpackedLongHeaderPacket(packet, p.ecn, p.rcvTime, datagramPayloadChecksum, p.Size()); err != nil {
|
|
1387
|
+
return false, err
|
|
1388
|
+
}
|
|
1389
|
+
return true, nil
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
func (c *Conn) handleUnpackError(err error, p receivedPacket, pt qlog.PacketType, datagramPayloadChecksum qlog.DatagramPayloadChecksum) (wasQueued bool, _ error) {
|
|
1393
|
+
switch err {
|
|
1394
|
+
case handshake.ErrKeysDropped:
|
|
1395
|
+
if c.qlogger != nil {
|
|
1396
|
+
connID, _ := wire.ParseConnectionID(p.data, c.srcConnIDLen)
|
|
1397
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1398
|
+
Header: qlog.PacketHeader{
|
|
1399
|
+
PacketType: pt,
|
|
1400
|
+
DestConnectionID: connID,
|
|
1401
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
1402
|
+
},
|
|
1403
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1404
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1405
|
+
Trigger: qlog.PacketDropKeyUnavailable,
|
|
1406
|
+
})
|
|
1407
|
+
}
|
|
1408
|
+
c.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", pt, p.Size())
|
|
1409
|
+
return false, nil
|
|
1410
|
+
case handshake.ErrKeysNotYetAvailable:
|
|
1411
|
+
// Sealer for this encryption level not yet available.
|
|
1412
|
+
// Try again later.
|
|
1413
|
+
c.tryQueueingUndecryptablePacket(p, pt, datagramPayloadChecksum)
|
|
1414
|
+
return true, nil
|
|
1415
|
+
case wire.ErrInvalidReservedBits:
|
|
1416
|
+
return false, &qerr.TransportError{
|
|
1417
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
1418
|
+
ErrorMessage: err.Error(),
|
|
1419
|
+
}
|
|
1420
|
+
case handshake.ErrDecryptionFailed:
|
|
1421
|
+
// This might be a packet injected by an attacker. Drop it.
|
|
1422
|
+
if c.qlogger != nil {
|
|
1423
|
+
connID, _ := wire.ParseConnectionID(p.data, c.srcConnIDLen)
|
|
1424
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1425
|
+
Header: qlog.PacketHeader{
|
|
1426
|
+
PacketType: pt,
|
|
1427
|
+
DestConnectionID: connID,
|
|
1428
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
1429
|
+
},
|
|
1430
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1431
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1432
|
+
Trigger: qlog.PacketDropPayloadDecryptError,
|
|
1433
|
+
})
|
|
1434
|
+
}
|
|
1435
|
+
c.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", pt, p.Size(), err)
|
|
1436
|
+
return false, nil
|
|
1437
|
+
default:
|
|
1438
|
+
var headerErr *headerParseError
|
|
1439
|
+
if errors.As(err, &headerErr) {
|
|
1440
|
+
// This might be a packet injected by an attacker. Drop it.
|
|
1441
|
+
if c.qlogger != nil {
|
|
1442
|
+
connID, _ := wire.ParseConnectionID(p.data, c.srcConnIDLen)
|
|
1443
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1444
|
+
Header: qlog.PacketHeader{
|
|
1445
|
+
PacketType: pt,
|
|
1446
|
+
DestConnectionID: connID,
|
|
1447
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
1448
|
+
},
|
|
1449
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1450
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1451
|
+
Trigger: qlog.PacketDropHeaderParseError,
|
|
1452
|
+
})
|
|
1453
|
+
}
|
|
1454
|
+
c.logger.Debugf("Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s", pt, p.Size(), err)
|
|
1455
|
+
return false, nil
|
|
1456
|
+
}
|
|
1457
|
+
// This is an error returned by the AEAD (other than ErrDecryptionFailed).
|
|
1458
|
+
// For example, a PROTOCOL_VIOLATION due to key updates.
|
|
1459
|
+
return false, err
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
func (c *Conn) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime monotime.Time) bool /* was this a valid Retry */ {
|
|
1464
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
1465
|
+
if c.qlogger != nil {
|
|
1466
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1467
|
+
Header: qlog.PacketHeader{
|
|
1468
|
+
PacketType: qlog.PacketTypeRetry,
|
|
1469
|
+
SrcConnectionID: hdr.SrcConnectionID,
|
|
1470
|
+
DestConnectionID: hdr.DestConnectionID,
|
|
1471
|
+
Version: hdr.Version,
|
|
1472
|
+
},
|
|
1473
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1474
|
+
Trigger: qlog.PacketDropUnexpectedPacket,
|
|
1475
|
+
})
|
|
1476
|
+
}
|
|
1477
|
+
c.logger.Debugf("Ignoring Retry.")
|
|
1478
|
+
return false
|
|
1479
|
+
}
|
|
1480
|
+
if c.receivedFirstPacket {
|
|
1481
|
+
if c.qlogger != nil {
|
|
1482
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1483
|
+
Header: qlog.PacketHeader{
|
|
1484
|
+
PacketType: qlog.PacketTypeRetry,
|
|
1485
|
+
SrcConnectionID: hdr.SrcConnectionID,
|
|
1486
|
+
DestConnectionID: hdr.DestConnectionID,
|
|
1487
|
+
Version: hdr.Version,
|
|
1488
|
+
},
|
|
1489
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1490
|
+
Trigger: qlog.PacketDropUnexpectedPacket,
|
|
1491
|
+
})
|
|
1492
|
+
}
|
|
1493
|
+
c.logger.Debugf("Ignoring Retry, since we already received a packet.")
|
|
1494
|
+
return false
|
|
1495
|
+
}
|
|
1496
|
+
destConnID := c.connIDManager.Get()
|
|
1497
|
+
if hdr.SrcConnectionID == destConnID {
|
|
1498
|
+
if c.qlogger != nil {
|
|
1499
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1500
|
+
Header: qlog.PacketHeader{
|
|
1501
|
+
PacketType: qlog.PacketTypeRetry,
|
|
1502
|
+
SrcConnectionID: hdr.SrcConnectionID,
|
|
1503
|
+
DestConnectionID: hdr.DestConnectionID,
|
|
1504
|
+
Version: hdr.Version,
|
|
1505
|
+
},
|
|
1506
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1507
|
+
Trigger: qlog.PacketDropUnexpectedPacket,
|
|
1508
|
+
})
|
|
1509
|
+
}
|
|
1510
|
+
c.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.")
|
|
1511
|
+
return false
|
|
1512
|
+
}
|
|
1513
|
+
// If a token is already set, this means that we already received a Retry from the server.
|
|
1514
|
+
// Ignore this Retry packet.
|
|
1515
|
+
if c.receivedRetry {
|
|
1516
|
+
c.logger.Debugf("Ignoring Retry, since a Retry was already received.")
|
|
1517
|
+
return false
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version)
|
|
1521
|
+
if !bytes.Equal(data[len(data)-16:], tag[:]) {
|
|
1522
|
+
if c.qlogger != nil {
|
|
1523
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1524
|
+
Header: qlog.PacketHeader{
|
|
1525
|
+
PacketType: qlog.PacketTypeRetry,
|
|
1526
|
+
SrcConnectionID: hdr.SrcConnectionID,
|
|
1527
|
+
DestConnectionID: hdr.DestConnectionID,
|
|
1528
|
+
Version: hdr.Version,
|
|
1529
|
+
},
|
|
1530
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1531
|
+
Trigger: qlog.PacketDropPayloadDecryptError,
|
|
1532
|
+
})
|
|
1533
|
+
}
|
|
1534
|
+
c.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.")
|
|
1535
|
+
return false
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
newDestConnID := hdr.SrcConnectionID
|
|
1539
|
+
c.receivedRetry = true
|
|
1540
|
+
c.sentPacketHandler.ResetForRetry(rcvTime)
|
|
1541
|
+
c.handshakeDestConnID = newDestConnID
|
|
1542
|
+
c.retrySrcConnID = &newDestConnID
|
|
1543
|
+
c.cryptoStreamHandler.ChangeConnectionID(newDestConnID)
|
|
1544
|
+
c.packer.SetToken(hdr.Token)
|
|
1545
|
+
c.connIDManager.ChangeInitialConnID(newDestConnID)
|
|
1546
|
+
|
|
1547
|
+
if c.logger.Debug() {
|
|
1548
|
+
c.logger.Debugf("<- Received Retry:")
|
|
1549
|
+
(&wire.ExtendedHeader{Header: *hdr}).Log(c.logger)
|
|
1550
|
+
c.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID)
|
|
1551
|
+
}
|
|
1552
|
+
if c.qlogger != nil {
|
|
1553
|
+
c.qlogger.RecordEvent(qlog.PacketReceived{
|
|
1554
|
+
Header: qlog.PacketHeader{
|
|
1555
|
+
PacketType: qlog.PacketTypeRetry,
|
|
1556
|
+
DestConnectionID: destConnID,
|
|
1557
|
+
SrcConnectionID: newDestConnID,
|
|
1558
|
+
Version: hdr.Version,
|
|
1559
|
+
Token: &qlog.Token{Raw: hdr.Token},
|
|
1560
|
+
},
|
|
1561
|
+
Raw: qlog.RawInfo{Length: len(data)},
|
|
1562
|
+
})
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
c.scheduleSending()
|
|
1566
|
+
return true
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
func (c *Conn) handleVersionNegotiationPacket(p receivedPacket) error {
|
|
1570
|
+
if c.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets
|
|
1571
|
+
c.receivedFirstPacket || c.versionNegotiated { // ignore delayed / duplicated version negotiation packets
|
|
1572
|
+
if c.qlogger != nil {
|
|
1573
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1574
|
+
Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation},
|
|
1575
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1576
|
+
Trigger: qlog.PacketDropUnexpectedPacket,
|
|
1577
|
+
})
|
|
1578
|
+
}
|
|
1579
|
+
return nil
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
src, dest, supportedVersions, err := wire.ParseVersionNegotiationPacket(p.data)
|
|
1583
|
+
if err != nil {
|
|
1584
|
+
if c.qlogger != nil {
|
|
1585
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1586
|
+
Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation},
|
|
1587
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1588
|
+
Trigger: qlog.PacketDropHeaderParseError,
|
|
1589
|
+
})
|
|
1590
|
+
}
|
|
1591
|
+
c.logger.Debugf("Error parsing Version Negotiation packet: %s", err)
|
|
1592
|
+
return nil
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
if slices.Contains(supportedVersions, c.version) {
|
|
1596
|
+
if c.qlogger != nil {
|
|
1597
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1598
|
+
Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation},
|
|
1599
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1600
|
+
Trigger: qlog.PacketDropUnexpectedVersion,
|
|
1601
|
+
})
|
|
1602
|
+
}
|
|
1603
|
+
// The Version Negotiation packet contains the version that we offered.
|
|
1604
|
+
// This might be a packet sent by an attacker, or it was corrupted.
|
|
1605
|
+
return nil
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
c.logger.Infof("Received a Version Negotiation packet. Supported Versions: %s", supportedVersions)
|
|
1609
|
+
if c.qlogger != nil {
|
|
1610
|
+
c.qlogger.RecordEvent(qlog.VersionNegotiationReceived{
|
|
1611
|
+
Header: qlog.PacketHeaderVersionNegotiation{
|
|
1612
|
+
DestConnectionID: dest,
|
|
1613
|
+
SrcConnectionID: src,
|
|
1614
|
+
},
|
|
1615
|
+
SupportedVersions: supportedVersions,
|
|
1616
|
+
})
|
|
1617
|
+
}
|
|
1618
|
+
newVersion, ok := protocol.ChooseSupportedVersion(c.config.Versions, supportedVersions)
|
|
1619
|
+
if !ok {
|
|
1620
|
+
c.destroyImpl(&VersionNegotiationError{
|
|
1621
|
+
Ours: c.config.Versions,
|
|
1622
|
+
Theirs: supportedVersions,
|
|
1623
|
+
})
|
|
1624
|
+
c.logger.Infof("No compatible QUIC version found.")
|
|
1625
|
+
return nil
|
|
1626
|
+
}
|
|
1627
|
+
if c.qlogger != nil {
|
|
1628
|
+
c.qlogger.RecordEvent(qlog.VersionInformation{
|
|
1629
|
+
ChosenVersion: newVersion,
|
|
1630
|
+
ClientVersions: c.config.Versions,
|
|
1631
|
+
ServerVersions: supportedVersions,
|
|
1632
|
+
})
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
c.logger.Infof("Switching to QUIC version %s.", newVersion)
|
|
1636
|
+
nextPN, _ := c.sentPacketHandler.PeekPacketNumber(protocol.EncryptionInitial)
|
|
1637
|
+
return &errCloseForRecreating{
|
|
1638
|
+
nextPacketNumber: nextPN,
|
|
1639
|
+
nextVersion: newVersion,
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
func (c *Conn) handleUnpackedLongHeaderPacket(
|
|
1644
|
+
packet *unpackedPacket,
|
|
1645
|
+
ecn protocol.ECN,
|
|
1646
|
+
rcvTime monotime.Time,
|
|
1647
|
+
datagramPayloadChecksum qlog.DatagramPayloadChecksum, // only for logging
|
|
1648
|
+
packetSize protocol.ByteCount, // only for logging
|
|
1649
|
+
) error {
|
|
1650
|
+
if !c.receivedFirstPacket {
|
|
1651
|
+
c.receivedFirstPacket = true
|
|
1652
|
+
if !c.versionNegotiated && c.qlogger != nil {
|
|
1653
|
+
var clientVersions, serverVersions []Version
|
|
1654
|
+
switch c.perspective {
|
|
1655
|
+
case protocol.PerspectiveClient:
|
|
1656
|
+
clientVersions = c.config.Versions
|
|
1657
|
+
case protocol.PerspectiveServer:
|
|
1658
|
+
serverVersions = c.config.Versions
|
|
1659
|
+
}
|
|
1660
|
+
c.qlogger.RecordEvent(qlog.VersionInformation{
|
|
1661
|
+
ChosenVersion: c.version,
|
|
1662
|
+
ClientVersions: clientVersions,
|
|
1663
|
+
ServerVersions: serverVersions,
|
|
1664
|
+
})
|
|
1665
|
+
}
|
|
1666
|
+
// The server can change the source connection ID with the first Handshake packet.
|
|
1667
|
+
if c.perspective == protocol.PerspectiveClient && packet.hdr.SrcConnectionID != c.handshakeDestConnID {
|
|
1668
|
+
cid := packet.hdr.SrcConnectionID
|
|
1669
|
+
c.logger.Debugf("Received first packet. Switching destination connection ID to: %s", cid)
|
|
1670
|
+
c.handshakeDestConnID = cid
|
|
1671
|
+
c.connIDManager.ChangeInitialConnID(cid)
|
|
1672
|
+
}
|
|
1673
|
+
// We create the connection as soon as we receive the first packet from the client.
|
|
1674
|
+
// We do that before authenticating the packet.
|
|
1675
|
+
// That means that if the source connection ID was corrupted,
|
|
1676
|
+
// we might have created a connection with an incorrect source connection ID.
|
|
1677
|
+
// Once we authenticate the first packet, we need to update it.
|
|
1678
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
1679
|
+
if packet.hdr.SrcConnectionID != c.handshakeDestConnID {
|
|
1680
|
+
c.handshakeDestConnID = packet.hdr.SrcConnectionID
|
|
1681
|
+
c.connIDManager.ChangeInitialConnID(packet.hdr.SrcConnectionID)
|
|
1682
|
+
}
|
|
1683
|
+
if c.qlogger != nil {
|
|
1684
|
+
var srcAddr, destAddr *net.UDPAddr
|
|
1685
|
+
if addr, ok := c.conn.LocalAddr().(*net.UDPAddr); ok {
|
|
1686
|
+
srcAddr = addr
|
|
1687
|
+
}
|
|
1688
|
+
if addr, ok := c.conn.RemoteAddr().(*net.UDPAddr); ok {
|
|
1689
|
+
destAddr = addr
|
|
1690
|
+
}
|
|
1691
|
+
c.qlogger.RecordEvent(startedConnectionEvent(srcAddr, destAddr))
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
if c.perspective == protocol.PerspectiveServer && packet.encryptionLevel == protocol.EncryptionHandshake &&
|
|
1697
|
+
!c.droppedInitialKeys {
|
|
1698
|
+
// On the server side, Initial keys are dropped as soon as the first Handshake packet is received.
|
|
1699
|
+
// See Section 4.9.1 of RFC 9001.
|
|
1700
|
+
if err := c.dropEncryptionLevel(protocol.EncryptionInitial, rcvTime); err != nil {
|
|
1701
|
+
return err
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
c.lastPacketReceivedTime = rcvTime
|
|
1706
|
+
c.firstAckElicitingPacketAfterIdleSentTime = 0
|
|
1707
|
+
c.keepAlivePingSent = false
|
|
1708
|
+
|
|
1709
|
+
if packet.hdr.Type == protocol.PacketType0RTT {
|
|
1710
|
+
c.largestRcvdAppData = max(c.largestRcvdAppData, packet.hdr.PacketNumber)
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
var log func([]qlog.Frame)
|
|
1714
|
+
if c.qlogger != nil {
|
|
1715
|
+
log = func(frames []qlog.Frame) {
|
|
1716
|
+
var token *qlog.Token
|
|
1717
|
+
if len(packet.hdr.Token) > 0 {
|
|
1718
|
+
token = &qlog.Token{Raw: packet.hdr.Token}
|
|
1719
|
+
}
|
|
1720
|
+
c.qlogger.RecordEvent(qlog.PacketReceived{
|
|
1721
|
+
Header: qlog.PacketHeader{
|
|
1722
|
+
PacketType: toQlogPacketType(packet.hdr.Type),
|
|
1723
|
+
DestConnectionID: packet.hdr.DestConnectionID,
|
|
1724
|
+
SrcConnectionID: packet.hdr.SrcConnectionID,
|
|
1725
|
+
PacketNumber: packet.hdr.PacketNumber,
|
|
1726
|
+
Version: packet.hdr.Version,
|
|
1727
|
+
Token: token,
|
|
1728
|
+
},
|
|
1729
|
+
Raw: qlog.RawInfo{
|
|
1730
|
+
Length: int(packetSize),
|
|
1731
|
+
PayloadLength: int(packet.hdr.Length),
|
|
1732
|
+
},
|
|
1733
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1734
|
+
Frames: frames,
|
|
1735
|
+
ECN: toQlogECN(ecn),
|
|
1736
|
+
})
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
isAckEliciting, _, _, err := c.handleFrames(packet.data, packet.hdr.DestConnectionID, packet.encryptionLevel, log, rcvTime)
|
|
1740
|
+
if err != nil {
|
|
1741
|
+
return err
|
|
1742
|
+
}
|
|
1743
|
+
c.sentPacketHandler.ReceivedPacket(packet.encryptionLevel, rcvTime)
|
|
1744
|
+
return c.receivedPacketHandler.ReceivedPacket(packet.hdr.PacketNumber, ecn, packet.encryptionLevel, rcvTime, isAckEliciting)
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
func (c *Conn) handleUnpackedShortHeaderPacket(
|
|
1748
|
+
destConnID protocol.ConnectionID,
|
|
1749
|
+
pn protocol.PacketNumber,
|
|
1750
|
+
data []byte,
|
|
1751
|
+
ecn protocol.ECN,
|
|
1752
|
+
rcvTime monotime.Time,
|
|
1753
|
+
log func([]qlog.Frame),
|
|
1754
|
+
) (isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) {
|
|
1755
|
+
c.lastPacketReceivedTime = rcvTime
|
|
1756
|
+
c.firstAckElicitingPacketAfterIdleSentTime = 0
|
|
1757
|
+
c.keepAlivePingSent = false
|
|
1758
|
+
|
|
1759
|
+
isAckEliciting, isNonProbing, pathChallenge, err := c.handleFrames(data, destConnID, protocol.Encryption1RTT, log, rcvTime)
|
|
1760
|
+
if err != nil {
|
|
1761
|
+
return false, nil, err
|
|
1762
|
+
}
|
|
1763
|
+
c.sentPacketHandler.ReceivedPacket(protocol.Encryption1RTT, rcvTime)
|
|
1764
|
+
if err := c.receivedPacketHandler.ReceivedPacket(pn, ecn, protocol.Encryption1RTT, rcvTime, isAckEliciting); err != nil {
|
|
1765
|
+
return false, nil, err
|
|
1766
|
+
}
|
|
1767
|
+
return isNonProbing, pathChallenge, nil
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// handleFrames parses the frames, one after the other, and handles them.
|
|
1771
|
+
// It returns the last PATH_CHALLENGE frame contained in the packet, if any.
|
|
1772
|
+
func (c *Conn) handleFrames(
|
|
1773
|
+
data []byte,
|
|
1774
|
+
destConnID protocol.ConnectionID,
|
|
1775
|
+
encLevel protocol.EncryptionLevel,
|
|
1776
|
+
log func([]qlog.Frame),
|
|
1777
|
+
rcvTime monotime.Time,
|
|
1778
|
+
) (isAckEliciting, isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) {
|
|
1779
|
+
// Only used for tracing.
|
|
1780
|
+
// If we're not tracing, this slice will always remain empty.
|
|
1781
|
+
var frames []qlog.Frame
|
|
1782
|
+
if log != nil {
|
|
1783
|
+
frames = make([]qlog.Frame, 0, 4)
|
|
1784
|
+
}
|
|
1785
|
+
handshakeWasComplete := c.handshakeComplete
|
|
1786
|
+
var handleErr error
|
|
1787
|
+
var skipHandling bool
|
|
1788
|
+
|
|
1789
|
+
for len(data) > 0 {
|
|
1790
|
+
frameType, l, err := c.frameParser.ParseType(data, encLevel)
|
|
1791
|
+
if err != nil {
|
|
1792
|
+
// The frame parser skips over PADDING frames, and returns an io.EOF if the PADDING
|
|
1793
|
+
// frames were the last frames in this packet.
|
|
1794
|
+
if err == io.EOF {
|
|
1795
|
+
break
|
|
1796
|
+
}
|
|
1797
|
+
return false, false, nil, err
|
|
1798
|
+
}
|
|
1799
|
+
data = data[l:]
|
|
1800
|
+
|
|
1801
|
+
if ackhandler.IsFrameTypeAckEliciting(frameType) {
|
|
1802
|
+
isAckEliciting = true
|
|
1803
|
+
}
|
|
1804
|
+
if !wire.IsProbingFrameType(frameType) {
|
|
1805
|
+
isNonProbing = true
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
// We're inlining common cases, to avoid using interfaces
|
|
1809
|
+
// Fast path: STREAM, DATAGRAM and ACK
|
|
1810
|
+
if frameType.IsStreamFrameType() {
|
|
1811
|
+
streamFrame, l, err := c.frameParser.ParseStreamFrame(frameType, data, c.version)
|
|
1812
|
+
if err != nil {
|
|
1813
|
+
return false, false, nil, err
|
|
1814
|
+
}
|
|
1815
|
+
data = data[l:]
|
|
1816
|
+
|
|
1817
|
+
if log != nil {
|
|
1818
|
+
frames = append(frames, toQlogFrame(streamFrame))
|
|
1819
|
+
}
|
|
1820
|
+
// an error occurred handling a previous frame, don't handle the current frame
|
|
1821
|
+
if skipHandling {
|
|
1822
|
+
continue
|
|
1823
|
+
}
|
|
1824
|
+
wire.LogFrame(c.logger, streamFrame, false)
|
|
1825
|
+
handleErr = c.streamsMap.HandleStreamFrame(streamFrame, rcvTime)
|
|
1826
|
+
} else if frameType.IsAckFrameType() {
|
|
1827
|
+
ackFrame, l, err := c.frameParser.ParseAckFrame(frameType, data, encLevel, c.version)
|
|
1828
|
+
if err != nil {
|
|
1829
|
+
return false, false, nil, err
|
|
1830
|
+
}
|
|
1831
|
+
data = data[l:]
|
|
1832
|
+
if log != nil {
|
|
1833
|
+
frames = append(frames, toQlogFrame(ackFrame))
|
|
1834
|
+
}
|
|
1835
|
+
// an error occurred handling a previous frame, don't handle the current frame
|
|
1836
|
+
if skipHandling {
|
|
1837
|
+
continue
|
|
1838
|
+
}
|
|
1839
|
+
wire.LogFrame(c.logger, ackFrame, false)
|
|
1840
|
+
handleErr = c.handleAckFrame(ackFrame, encLevel, rcvTime)
|
|
1841
|
+
} else if frameType.IsDatagramFrameType() {
|
|
1842
|
+
datagramFrame, l, err := c.frameParser.ParseDatagramFrame(frameType, data, c.version)
|
|
1843
|
+
if err != nil {
|
|
1844
|
+
return false, false, nil, err
|
|
1845
|
+
}
|
|
1846
|
+
data = data[l:]
|
|
1847
|
+
|
|
1848
|
+
if log != nil {
|
|
1849
|
+
frames = append(frames, toQlogFrame(datagramFrame))
|
|
1850
|
+
}
|
|
1851
|
+
// an error occurred handling a previous frame, don't handle the current frame
|
|
1852
|
+
if skipHandling {
|
|
1853
|
+
continue
|
|
1854
|
+
}
|
|
1855
|
+
wire.LogFrame(c.logger, datagramFrame, false)
|
|
1856
|
+
handleErr = c.handleDatagramFrame(datagramFrame)
|
|
1857
|
+
} else {
|
|
1858
|
+
frame, l, err := c.frameParser.ParseLessCommonFrame(frameType, data, c.version)
|
|
1859
|
+
if err != nil {
|
|
1860
|
+
return false, false, nil, err
|
|
1861
|
+
}
|
|
1862
|
+
data = data[l:]
|
|
1863
|
+
|
|
1864
|
+
if log != nil {
|
|
1865
|
+
frames = append(frames, toQlogFrame(frame))
|
|
1866
|
+
}
|
|
1867
|
+
// an error occurred handling a previous frame, don't handle the current frame
|
|
1868
|
+
if skipHandling {
|
|
1869
|
+
continue
|
|
1870
|
+
}
|
|
1871
|
+
pc, err := c.handleFrame(frame, encLevel, destConnID, rcvTime)
|
|
1872
|
+
if pc != nil {
|
|
1873
|
+
pathChallenge = pc
|
|
1874
|
+
}
|
|
1875
|
+
handleErr = err
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
if handleErr != nil {
|
|
1879
|
+
// if we're logging, we need to keep parsing (but not handling) all frames
|
|
1880
|
+
skipHandling = true
|
|
1881
|
+
if log == nil {
|
|
1882
|
+
return false, false, nil, handleErr
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
if log != nil {
|
|
1888
|
+
log(frames)
|
|
1889
|
+
if handleErr != nil {
|
|
1890
|
+
return false, false, nil, handleErr
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
// Handle completion of the handshake after processing all the frames.
|
|
1895
|
+
// This ensures that we correctly handle the following case on the server side:
|
|
1896
|
+
// We receive a Handshake packet that contains the CRYPTO frame that allows us to complete the handshake,
|
|
1897
|
+
// and an ACK serialized after that CRYPTO frame. In this case, we still want to process the ACK frame.
|
|
1898
|
+
if !handshakeWasComplete && c.handshakeComplete {
|
|
1899
|
+
if err := c.handleHandshakeComplete(rcvTime); err != nil {
|
|
1900
|
+
return false, false, nil, err
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
return
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
func (c *Conn) handleFrame(
|
|
1907
|
+
f wire.Frame,
|
|
1908
|
+
encLevel protocol.EncryptionLevel,
|
|
1909
|
+
destConnID protocol.ConnectionID,
|
|
1910
|
+
rcvTime monotime.Time,
|
|
1911
|
+
) (pathChallenge *wire.PathChallengeFrame, _ error) {
|
|
1912
|
+
var err error
|
|
1913
|
+
wire.LogFrame(c.logger, f, false)
|
|
1914
|
+
switch frame := f.(type) {
|
|
1915
|
+
case *wire.CryptoFrame:
|
|
1916
|
+
err = c.handleCryptoFrame(frame, encLevel, rcvTime)
|
|
1917
|
+
case *wire.ConnectionCloseFrame:
|
|
1918
|
+
err = c.handleConnectionCloseFrame(frame)
|
|
1919
|
+
case *wire.ResetStreamFrame:
|
|
1920
|
+
err = c.streamsMap.HandleResetStreamFrame(frame, rcvTime)
|
|
1921
|
+
case *wire.MaxDataFrame:
|
|
1922
|
+
c.connFlowController.UpdateSendWindow(frame.MaximumData)
|
|
1923
|
+
case *wire.MaxStreamDataFrame:
|
|
1924
|
+
err = c.streamsMap.HandleMaxStreamDataFrame(frame)
|
|
1925
|
+
case *wire.MaxStreamsFrame:
|
|
1926
|
+
c.streamsMap.HandleMaxStreamsFrame(frame)
|
|
1927
|
+
case *wire.DataBlockedFrame:
|
|
1928
|
+
case *wire.StreamDataBlockedFrame:
|
|
1929
|
+
err = c.streamsMap.HandleStreamDataBlockedFrame(frame)
|
|
1930
|
+
case *wire.StreamsBlockedFrame:
|
|
1931
|
+
case *wire.StopSendingFrame:
|
|
1932
|
+
err = c.streamsMap.HandleStopSendingFrame(frame)
|
|
1933
|
+
case *wire.PingFrame:
|
|
1934
|
+
case *wire.PathChallengeFrame:
|
|
1935
|
+
c.handlePathChallengeFrame(frame)
|
|
1936
|
+
pathChallenge = frame
|
|
1937
|
+
case *wire.PathResponseFrame:
|
|
1938
|
+
err = c.handlePathResponseFrame(frame)
|
|
1939
|
+
case *wire.NewTokenFrame:
|
|
1940
|
+
err = c.handleNewTokenFrame(frame)
|
|
1941
|
+
case *wire.NewConnectionIDFrame:
|
|
1942
|
+
err = c.connIDManager.Add(frame)
|
|
1943
|
+
case *wire.RetireConnectionIDFrame:
|
|
1944
|
+
err = c.connIDGenerator.Retire(frame.SequenceNumber, destConnID, rcvTime.Add(3*c.rttStats.PTO(false)))
|
|
1945
|
+
case *wire.HandshakeDoneFrame:
|
|
1946
|
+
err = c.handleHandshakeDoneFrame(rcvTime)
|
|
1947
|
+
default:
|
|
1948
|
+
err = fmt.Errorf("unexpected frame type: %s", reflect.ValueOf(&frame).Elem().Type().Name())
|
|
1949
|
+
}
|
|
1950
|
+
return pathChallenge, err
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
// handlePacket is called by the server with a new packet
|
|
1954
|
+
func (c *Conn) handlePacket(p receivedPacket) {
|
|
1955
|
+
c.receivedPacketMx.Lock()
|
|
1956
|
+
// Discard packets once the amount of queued packets is larger than
|
|
1957
|
+
// the channel size, protocol.MaxConnUnprocessedPackets
|
|
1958
|
+
if c.receivedPackets.Len() >= protocol.MaxConnUnprocessedPackets {
|
|
1959
|
+
if c.qlogger != nil {
|
|
1960
|
+
var datagramPayloadChecksum qlog.DatagramPayloadChecksum
|
|
1961
|
+
if wire.IsLongHeaderPacket(p.data[0]) {
|
|
1962
|
+
datagramPayloadChecksum = qlog.CalculateDatagramPayloadChecksum(p.data)
|
|
1963
|
+
}
|
|
1964
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
1965
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
1966
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
1967
|
+
Trigger: qlog.PacketDropDOSPrevention,
|
|
1968
|
+
})
|
|
1969
|
+
}
|
|
1970
|
+
c.receivedPacketMx.Unlock()
|
|
1971
|
+
return
|
|
1972
|
+
}
|
|
1973
|
+
c.receivedPackets.PushBack(p)
|
|
1974
|
+
c.receivedPacketMx.Unlock()
|
|
1975
|
+
|
|
1976
|
+
select {
|
|
1977
|
+
case c.notifyReceivedPacket <- struct{}{}:
|
|
1978
|
+
default:
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
func (c *Conn) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame) error {
|
|
1983
|
+
if frame.IsApplicationError {
|
|
1984
|
+
return &qerr.ApplicationError{
|
|
1985
|
+
Remote: true,
|
|
1986
|
+
ErrorCode: qerr.ApplicationErrorCode(frame.ErrorCode),
|
|
1987
|
+
ErrorMessage: frame.ReasonPhrase,
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
return &qerr.TransportError{
|
|
1991
|
+
Remote: true,
|
|
1992
|
+
ErrorCode: qerr.TransportErrorCode(frame.ErrorCode),
|
|
1993
|
+
FrameType: frame.FrameType,
|
|
1994
|
+
ErrorMessage: frame.ReasonPhrase,
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
func (c *Conn) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) error {
|
|
1999
|
+
if err := c.cryptoStreamManager.HandleCryptoFrame(frame, encLevel); err != nil {
|
|
2000
|
+
return err
|
|
2001
|
+
}
|
|
2002
|
+
for {
|
|
2003
|
+
data := c.cryptoStreamManager.GetCryptoData(encLevel)
|
|
2004
|
+
if data == nil {
|
|
2005
|
+
break
|
|
2006
|
+
}
|
|
2007
|
+
if err := c.cryptoStreamHandler.HandleMessage(data, encLevel); err != nil {
|
|
2008
|
+
return err
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
return c.handleHandshakeEvents(rcvTime)
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
func (c *Conn) handleHandshakeEvents(now monotime.Time) error {
|
|
2015
|
+
for {
|
|
2016
|
+
ev := c.cryptoStreamHandler.NextEvent()
|
|
2017
|
+
var err error
|
|
2018
|
+
switch ev.Kind {
|
|
2019
|
+
case handshake.EventNoEvent:
|
|
2020
|
+
return nil
|
|
2021
|
+
case handshake.EventHandshakeComplete:
|
|
2022
|
+
// Don't call handleHandshakeComplete yet.
|
|
2023
|
+
// It's advantageous to process ACK frames that might be serialized after the CRYPTO frame first.
|
|
2024
|
+
c.handshakeComplete = true
|
|
2025
|
+
case handshake.EventReceivedTransportParameters:
|
|
2026
|
+
err = c.handleTransportParameters(ev.TransportParameters)
|
|
2027
|
+
case handshake.EventRestoredTransportParameters:
|
|
2028
|
+
c.restoreTransportParameters(ev.TransportParameters)
|
|
2029
|
+
close(c.earlyConnReadyChan)
|
|
2030
|
+
case handshake.EventReceivedReadKeys:
|
|
2031
|
+
// queue all previously undecryptable packets
|
|
2032
|
+
c.undecryptablePacketsToProcess = append(c.undecryptablePacketsToProcess, c.undecryptablePackets...)
|
|
2033
|
+
c.undecryptablePackets = nil
|
|
2034
|
+
case handshake.EventDiscard0RTTKeys:
|
|
2035
|
+
err = c.dropEncryptionLevel(protocol.Encryption0RTT, now)
|
|
2036
|
+
case handshake.EventWriteInitialData:
|
|
2037
|
+
_, err = c.initialStream.Write(ev.Data)
|
|
2038
|
+
case handshake.EventWriteHandshakeData:
|
|
2039
|
+
_, err = c.handshakeStream.Write(ev.Data)
|
|
2040
|
+
}
|
|
2041
|
+
if err != nil {
|
|
2042
|
+
return err
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
func (c *Conn) handlePathChallengeFrame(f *wire.PathChallengeFrame) {
|
|
2048
|
+
if c.perspective == protocol.PerspectiveClient {
|
|
2049
|
+
c.queueControlFrame(&wire.PathResponseFrame{Data: f.Data})
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
func (c *Conn) handlePathResponseFrame(f *wire.PathResponseFrame) error {
|
|
2054
|
+
switch c.perspective {
|
|
2055
|
+
case protocol.PerspectiveClient:
|
|
2056
|
+
return c.handlePathResponseFrameClient(f)
|
|
2057
|
+
case protocol.PerspectiveServer:
|
|
2058
|
+
return c.handlePathResponseFrameServer(f)
|
|
2059
|
+
default:
|
|
2060
|
+
panic("unreachable")
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
func (c *Conn) handlePathResponseFrameClient(f *wire.PathResponseFrame) error {
|
|
2065
|
+
pm := c.pathManagerOutgoing.Load()
|
|
2066
|
+
if pm == nil {
|
|
2067
|
+
return &qerr.TransportError{
|
|
2068
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
2069
|
+
ErrorMessage: "unexpected PATH_RESPONSE frame",
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
pm.HandlePathResponseFrame(f)
|
|
2073
|
+
return nil
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
func (c *Conn) handlePathResponseFrameServer(f *wire.PathResponseFrame) error {
|
|
2077
|
+
if c.pathManager == nil {
|
|
2078
|
+
// since we didn't send PATH_CHALLENGEs yet, we don't expect PATH_RESPONSEs
|
|
2079
|
+
return &qerr.TransportError{
|
|
2080
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
2081
|
+
ErrorMessage: "unexpected PATH_RESPONSE frame",
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
c.pathManager.HandlePathResponseFrame(f)
|
|
2085
|
+
return nil
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
func (c *Conn) handleNewTokenFrame(frame *wire.NewTokenFrame) error {
|
|
2089
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
2090
|
+
return &qerr.TransportError{
|
|
2091
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
2092
|
+
ErrorMessage: "received NEW_TOKEN frame from the client",
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
if c.config.TokenStore != nil {
|
|
2096
|
+
c.config.TokenStore.Put(c.tokenStoreKey, &ClientToken{data: frame.Token, rtt: c.rttStats.SmoothedRTT()})
|
|
2097
|
+
}
|
|
2098
|
+
return nil
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
func (c *Conn) handleHandshakeDoneFrame(rcvTime monotime.Time) error {
|
|
2102
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
2103
|
+
return &qerr.TransportError{
|
|
2104
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
2105
|
+
ErrorMessage: "received a HANDSHAKE_DONE frame",
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
if !c.handshakeConfirmed {
|
|
2109
|
+
return c.handleHandshakeConfirmed(rcvTime)
|
|
2110
|
+
}
|
|
2111
|
+
return nil
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
func (c *Conn) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) error {
|
|
2115
|
+
acked1RTTPacket, err := c.sentPacketHandler.ReceivedAck(frame, encLevel, c.lastPacketReceivedTime)
|
|
2116
|
+
if err != nil {
|
|
2117
|
+
return err
|
|
2118
|
+
}
|
|
2119
|
+
if !acked1RTTPacket {
|
|
2120
|
+
return nil
|
|
2121
|
+
}
|
|
2122
|
+
// On the client side: If the packet acknowledged a 1-RTT packet, this confirms the handshake.
|
|
2123
|
+
// This is only possible if the ACK was sent in a 1-RTT packet.
|
|
2124
|
+
// This is an optimization over simply waiting for a HANDSHAKE_DONE frame, see section 4.1.2 of RFC 9001.
|
|
2125
|
+
if c.perspective == protocol.PerspectiveClient && !c.handshakeConfirmed {
|
|
2126
|
+
if err := c.handleHandshakeConfirmed(rcvTime); err != nil {
|
|
2127
|
+
return err
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
// If one of the acknowledged packets was a Path MTU probe packet, this might have increased the Path MTU estimate.
|
|
2131
|
+
if c.mtuDiscoverer != nil {
|
|
2132
|
+
mtu := c.mtuDiscoverer.CurrentSize()
|
|
2133
|
+
maxPayloadSize := estimateMaxPayloadSize(mtu)
|
|
2134
|
+
if maxPayloadSize > protocol.ByteCount(c.maxPayloadSizeEstimate.Load()) {
|
|
2135
|
+
c.maxPayloadSizeEstimate.Store(uint32(maxPayloadSize))
|
|
2136
|
+
c.sentPacketHandler.SetMaxDatagramSize(mtu)
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
return c.cryptoStreamHandler.SetLargest1RTTAcked(frame.LargestAcked())
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
func (c *Conn) handleDatagramFrame(f *wire.DatagramFrame) error {
|
|
2143
|
+
if f.Length(c.version) > wire.MaxDatagramSize {
|
|
2144
|
+
return &qerr.TransportError{
|
|
2145
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
2146
|
+
ErrorMessage: "DATAGRAM frame too large",
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
c.datagramQueue.HandleDatagramFrame(f)
|
|
2150
|
+
return nil
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
func (c *Conn) setCloseError(e *closeError) {
|
|
2154
|
+
c.closeErr.CompareAndSwap(nil, e)
|
|
2155
|
+
select {
|
|
2156
|
+
case c.closeChan <- struct{}{}:
|
|
2157
|
+
default:
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
// closeLocal closes the connection and send a CONNECTION_CLOSE containing the error
|
|
2162
|
+
func (c *Conn) closeLocal(e error) {
|
|
2163
|
+
c.setCloseError(&closeError{err: e, immediate: false})
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
// destroy closes the connection without sending the error on the wire
|
|
2167
|
+
func (c *Conn) destroy(e error) {
|
|
2168
|
+
c.destroyImpl(e)
|
|
2169
|
+
<-c.ctx.Done()
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
func (c *Conn) destroyImpl(e error) {
|
|
2173
|
+
c.setCloseError(&closeError{err: e, immediate: true})
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
// CloseWithError closes the connection with an error.
|
|
2177
|
+
// The error string will be sent to the peer.
|
|
2178
|
+
func (c *Conn) CloseWithError(code ApplicationErrorCode, desc string) error {
|
|
2179
|
+
c.closeLocal(&qerr.ApplicationError{
|
|
2180
|
+
ErrorCode: code,
|
|
2181
|
+
ErrorMessage: desc,
|
|
2182
|
+
})
|
|
2183
|
+
<-c.ctx.Done()
|
|
2184
|
+
return nil
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
func (c *Conn) closeWithTransportError(code TransportErrorCode) {
|
|
2188
|
+
c.closeLocal(&qerr.TransportError{ErrorCode: code})
|
|
2189
|
+
<-c.ctx.Done()
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
func (c *Conn) handleCloseError(closeErr *closeError) {
|
|
2193
|
+
if closeErr.immediate {
|
|
2194
|
+
if nerr, ok := closeErr.err.(net.Error); ok && nerr.Timeout() {
|
|
2195
|
+
c.logger.Errorf("Destroying connection: %s", closeErr.err)
|
|
2196
|
+
} else {
|
|
2197
|
+
c.logger.Errorf("Destroying connection with error: %s", closeErr.err)
|
|
2198
|
+
}
|
|
2199
|
+
} else {
|
|
2200
|
+
if closeErr.err == nil {
|
|
2201
|
+
c.logger.Infof("Closing connection.")
|
|
2202
|
+
} else {
|
|
2203
|
+
c.logger.Errorf("Closing connection with error: %s", closeErr.err)
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
e := closeErr.err
|
|
2208
|
+
if e == nil {
|
|
2209
|
+
e = &qerr.ApplicationError{}
|
|
2210
|
+
} else {
|
|
2211
|
+
defer func() { closeErr.err = e }()
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
var (
|
|
2215
|
+
statelessResetErr *StatelessResetError
|
|
2216
|
+
versionNegotiationErr *VersionNegotiationError
|
|
2217
|
+
recreateErr *errCloseForRecreating
|
|
2218
|
+
applicationErr *ApplicationError
|
|
2219
|
+
transportErr *TransportError
|
|
2220
|
+
)
|
|
2221
|
+
var isRemoteClose bool
|
|
2222
|
+
var trigger qlog.ConnectionCloseTrigger
|
|
2223
|
+
var reason string
|
|
2224
|
+
var transportErrorCode *qlog.TransportErrorCode
|
|
2225
|
+
var applicationErrorCode *qlog.ApplicationErrorCode
|
|
2226
|
+
switch {
|
|
2227
|
+
case errors.Is(e, qerr.ErrIdleTimeout),
|
|
2228
|
+
errors.Is(e, qerr.ErrHandshakeTimeout):
|
|
2229
|
+
trigger = qlog.ConnectionCloseTriggerIdleTimeout
|
|
2230
|
+
case errors.As(e, &statelessResetErr):
|
|
2231
|
+
trigger = qlog.ConnectionCloseTriggerStatelessReset
|
|
2232
|
+
case errors.As(e, &versionNegotiationErr):
|
|
2233
|
+
trigger = qlog.ConnectionCloseTriggerVersionMismatch
|
|
2234
|
+
case errors.As(e, &recreateErr):
|
|
2235
|
+
case errors.As(e, &applicationErr):
|
|
2236
|
+
isRemoteClose = applicationErr.Remote
|
|
2237
|
+
reason = applicationErr.ErrorMessage
|
|
2238
|
+
applicationErrorCode = &applicationErr.ErrorCode
|
|
2239
|
+
case errors.As(e, &transportErr):
|
|
2240
|
+
isRemoteClose = transportErr.Remote
|
|
2241
|
+
reason = transportErr.ErrorMessage
|
|
2242
|
+
transportErrorCode = &transportErr.ErrorCode
|
|
2243
|
+
case closeErr.immediate:
|
|
2244
|
+
e = closeErr.err
|
|
2245
|
+
default:
|
|
2246
|
+
te := &qerr.TransportError{
|
|
2247
|
+
ErrorCode: qerr.InternalError,
|
|
2248
|
+
ErrorMessage: e.Error(),
|
|
2249
|
+
}
|
|
2250
|
+
e = te
|
|
2251
|
+
reason = te.ErrorMessage
|
|
2252
|
+
code := te.ErrorCode
|
|
2253
|
+
transportErrorCode = &code
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
c.streamsMap.CloseWithError(e)
|
|
2257
|
+
if c.datagramQueue != nil {
|
|
2258
|
+
c.datagramQueue.CloseWithError(e)
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
// In rare instances, the connection ID manager might switch to a new connection ID
|
|
2262
|
+
// when sending the CONNECTION_CLOSE frame.
|
|
2263
|
+
// The connection ID manager removes the active stateless reset token from the packet
|
|
2264
|
+
// handler map when it is closed, so we need to make sure that this happens last.
|
|
2265
|
+
defer c.connIDManager.Close()
|
|
2266
|
+
|
|
2267
|
+
if c.qlogger != nil && !errors.As(e, &recreateErr) {
|
|
2268
|
+
initiator := qlog.InitiatorLocal
|
|
2269
|
+
if isRemoteClose {
|
|
2270
|
+
initiator = qlog.InitiatorRemote
|
|
2271
|
+
}
|
|
2272
|
+
c.qlogger.RecordEvent(qlog.ConnectionClosed{
|
|
2273
|
+
Initiator: initiator,
|
|
2274
|
+
ConnectionError: transportErrorCode,
|
|
2275
|
+
ApplicationError: applicationErrorCode,
|
|
2276
|
+
Trigger: trigger,
|
|
2277
|
+
Reason: reason,
|
|
2278
|
+
})
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
// If this is a remote close we're done here
|
|
2282
|
+
if isRemoteClose {
|
|
2283
|
+
c.connIDGenerator.ReplaceWithClosed(nil, 3*c.rttStats.PTO(false))
|
|
2284
|
+
return
|
|
2285
|
+
}
|
|
2286
|
+
if closeErr.immediate {
|
|
2287
|
+
c.connIDGenerator.RemoveAll()
|
|
2288
|
+
return
|
|
2289
|
+
}
|
|
2290
|
+
// Don't send out any CONNECTION_CLOSE if this is an error that occurred
|
|
2291
|
+
// before we even sent out the first packet.
|
|
2292
|
+
if c.perspective == protocol.PerspectiveClient && !c.sentFirstPacket {
|
|
2293
|
+
c.connIDGenerator.RemoveAll()
|
|
2294
|
+
return
|
|
2295
|
+
}
|
|
2296
|
+
connClosePacket, err := c.sendConnectionClose(e)
|
|
2297
|
+
if err != nil {
|
|
2298
|
+
c.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err)
|
|
2299
|
+
}
|
|
2300
|
+
c.connIDGenerator.ReplaceWithClosed(connClosePacket, 3*c.rttStats.PTO(false))
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
func (c *Conn) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now monotime.Time) error {
|
|
2304
|
+
c.sentPacketHandler.DropPackets(encLevel, now)
|
|
2305
|
+
c.receivedPacketHandler.DropPackets(encLevel)
|
|
2306
|
+
//nolint:exhaustive // only Initial and 0-RTT need special treatment
|
|
2307
|
+
switch encLevel {
|
|
2308
|
+
case protocol.EncryptionInitial:
|
|
2309
|
+
c.droppedInitialKeys = true
|
|
2310
|
+
c.cryptoStreamHandler.DiscardInitialKeys()
|
|
2311
|
+
case protocol.Encryption0RTT:
|
|
2312
|
+
c.streamsMap.ResetFor0RTT()
|
|
2313
|
+
c.framer.Handle0RTTRejection()
|
|
2314
|
+
return c.connFlowController.Reset()
|
|
2315
|
+
}
|
|
2316
|
+
return c.cryptoStreamManager.Drop(encLevel)
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
// is called for the client, when restoring transport parameters saved for 0-RTT
|
|
2320
|
+
func (c *Conn) restoreTransportParameters(params *wire.TransportParameters) {
|
|
2321
|
+
if c.logger.Debug() {
|
|
2322
|
+
c.logger.Debugf("Restoring Transport Parameters: %s", params)
|
|
2323
|
+
}
|
|
2324
|
+
if c.qlogger != nil {
|
|
2325
|
+
c.qlogger.RecordEvent(qlog.ParametersSet{
|
|
2326
|
+
Restore: true,
|
|
2327
|
+
Initiator: qlog.InitiatorRemote,
|
|
2328
|
+
SentBy: c.perspective,
|
|
2329
|
+
OriginalDestinationConnectionID: params.OriginalDestinationConnectionID,
|
|
2330
|
+
InitialSourceConnectionID: params.InitialSourceConnectionID,
|
|
2331
|
+
RetrySourceConnectionID: params.RetrySourceConnectionID,
|
|
2332
|
+
StatelessResetToken: params.StatelessResetToken,
|
|
2333
|
+
DisableActiveMigration: params.DisableActiveMigration,
|
|
2334
|
+
MaxIdleTimeout: params.MaxIdleTimeout,
|
|
2335
|
+
MaxUDPPayloadSize: params.MaxUDPPayloadSize,
|
|
2336
|
+
AckDelayExponent: params.AckDelayExponent,
|
|
2337
|
+
MaxAckDelay: params.MaxAckDelay,
|
|
2338
|
+
ActiveConnectionIDLimit: params.ActiveConnectionIDLimit,
|
|
2339
|
+
InitialMaxData: params.InitialMaxData,
|
|
2340
|
+
InitialMaxStreamDataBidiLocal: params.InitialMaxStreamDataBidiLocal,
|
|
2341
|
+
InitialMaxStreamDataBidiRemote: params.InitialMaxStreamDataBidiRemote,
|
|
2342
|
+
InitialMaxStreamDataUni: params.InitialMaxStreamDataUni,
|
|
2343
|
+
InitialMaxStreamsBidi: int64(params.MaxBidiStreamNum),
|
|
2344
|
+
InitialMaxStreamsUni: int64(params.MaxUniStreamNum),
|
|
2345
|
+
MaxDatagramFrameSize: params.MaxDatagramFrameSize,
|
|
2346
|
+
EnableResetStreamAt: params.EnableResetStreamAt,
|
|
2347
|
+
})
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
c.peerParams = params
|
|
2351
|
+
c.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit)
|
|
2352
|
+
c.connFlowController.UpdateSendWindow(params.InitialMaxData)
|
|
2353
|
+
c.streamsMap.HandleTransportParameters(params)
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
func (c *Conn) handleTransportParameters(params *wire.TransportParameters) error {
|
|
2357
|
+
if c.qlogger != nil {
|
|
2358
|
+
c.qlogTransportParameters(params, c.perspective.Opposite(), false)
|
|
2359
|
+
}
|
|
2360
|
+
if err := c.checkTransportParameters(params); err != nil {
|
|
2361
|
+
return &qerr.TransportError{
|
|
2362
|
+
ErrorCode: qerr.TransportParameterError,
|
|
2363
|
+
ErrorMessage: err.Error(),
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
if c.perspective == protocol.PerspectiveClient && c.peerParams != nil && c.ConnectionState().Used0RTT && !params.ValidForUpdate(c.peerParams) {
|
|
2368
|
+
return &qerr.TransportError{
|
|
2369
|
+
ErrorCode: qerr.ProtocolViolation,
|
|
2370
|
+
ErrorMessage: "server sent reduced limits after accepting 0-RTT data",
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
c.peerParams = params
|
|
2375
|
+
// On the client side we have to wait for handshake completion.
|
|
2376
|
+
// During a 0-RTT connection, we are only allowed to use the new transport parameters for 1-RTT packets.
|
|
2377
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
2378
|
+
c.applyTransportParameters()
|
|
2379
|
+
// On the server side, the early connection is ready as soon as we processed
|
|
2380
|
+
// the client's transport parameters.
|
|
2381
|
+
close(c.earlyConnReadyChan)
|
|
2382
|
+
}
|
|
2383
|
+
return nil
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
func (c *Conn) checkTransportParameters(params *wire.TransportParameters) error {
|
|
2387
|
+
if c.logger.Debug() {
|
|
2388
|
+
c.logger.Debugf("Processed Transport Parameters: %s", params)
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
// check the initial_source_connection_id
|
|
2392
|
+
if params.InitialSourceConnectionID != c.handshakeDestConnID {
|
|
2393
|
+
return fmt.Errorf("expected initial_source_connection_id to equal %s, is %s", c.handshakeDestConnID, params.InitialSourceConnectionID)
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
2397
|
+
return nil
|
|
2398
|
+
}
|
|
2399
|
+
// check the original_destination_connection_id
|
|
2400
|
+
if params.OriginalDestinationConnectionID != c.origDestConnID {
|
|
2401
|
+
return fmt.Errorf("expected original_destination_connection_id to equal %s, is %s", c.origDestConnID, params.OriginalDestinationConnectionID)
|
|
2402
|
+
}
|
|
2403
|
+
if c.retrySrcConnID != nil { // a Retry was performed
|
|
2404
|
+
if params.RetrySourceConnectionID == nil {
|
|
2405
|
+
return errors.New("missing retry_source_connection_id")
|
|
2406
|
+
}
|
|
2407
|
+
if *params.RetrySourceConnectionID != *c.retrySrcConnID {
|
|
2408
|
+
return fmt.Errorf("expected retry_source_connection_id to equal %s, is %s", c.retrySrcConnID, *params.RetrySourceConnectionID)
|
|
2409
|
+
}
|
|
2410
|
+
} else if params.RetrySourceConnectionID != nil {
|
|
2411
|
+
return errors.New("received retry_source_connection_id, although no Retry was performed")
|
|
2412
|
+
}
|
|
2413
|
+
return nil
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
func (c *Conn) applyTransportParameters() {
|
|
2417
|
+
params := c.peerParams
|
|
2418
|
+
// Our local idle timeout will always be > 0.
|
|
2419
|
+
c.idleTimeout = c.config.MaxIdleTimeout
|
|
2420
|
+
// If the peer advertised an idle timeout, take the minimum of the values.
|
|
2421
|
+
if params.MaxIdleTimeout > 0 {
|
|
2422
|
+
c.idleTimeout = min(c.idleTimeout, params.MaxIdleTimeout)
|
|
2423
|
+
}
|
|
2424
|
+
c.keepAliveInterval = min(c.config.KeepAlivePeriod, c.idleTimeout/2)
|
|
2425
|
+
c.streamsMap.HandleTransportParameters(params)
|
|
2426
|
+
c.frameParser.SetAckDelayExponent(params.AckDelayExponent)
|
|
2427
|
+
c.connFlowController.UpdateSendWindow(params.InitialMaxData)
|
|
2428
|
+
c.rttStats.SetMaxAckDelay(params.MaxAckDelay)
|
|
2429
|
+
c.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit)
|
|
2430
|
+
if params.StatelessResetToken != nil {
|
|
2431
|
+
c.connIDManager.SetStatelessResetToken(*params.StatelessResetToken)
|
|
2432
|
+
}
|
|
2433
|
+
// We don't support connection migration yet, so we don't have any use for the preferred_address.
|
|
2434
|
+
if params.PreferredAddress != nil {
|
|
2435
|
+
// Retire the connection ID.
|
|
2436
|
+
c.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, params.PreferredAddress.StatelessResetToken)
|
|
2437
|
+
}
|
|
2438
|
+
maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)
|
|
2439
|
+
if params.MaxUDPPayloadSize > 0 && params.MaxUDPPayloadSize < maxPacketSize {
|
|
2440
|
+
maxPacketSize = params.MaxUDPPayloadSize
|
|
2441
|
+
}
|
|
2442
|
+
c.mtuDiscoverer = newMTUDiscoverer(
|
|
2443
|
+
c.rttStats,
|
|
2444
|
+
protocol.ByteCount(c.config.InitialPacketSize),
|
|
2445
|
+
maxPacketSize,
|
|
2446
|
+
c.qlogger,
|
|
2447
|
+
)
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
func (c *Conn) triggerSending(now monotime.Time) error {
|
|
2451
|
+
c.pacingDeadline = 0
|
|
2452
|
+
|
|
2453
|
+
sendMode := c.sentPacketHandler.SendMode(now)
|
|
2454
|
+
switch sendMode {
|
|
2455
|
+
case ackhandler.SendAny:
|
|
2456
|
+
return c.sendPackets(now)
|
|
2457
|
+
case ackhandler.SendNone:
|
|
2458
|
+
c.blocked = blockModeHardBlocked
|
|
2459
|
+
return nil
|
|
2460
|
+
case ackhandler.SendPacingLimited:
|
|
2461
|
+
deadline := c.sentPacketHandler.TimeUntilSend()
|
|
2462
|
+
if deadline.IsZero() {
|
|
2463
|
+
deadline = deadlineSendImmediately
|
|
2464
|
+
}
|
|
2465
|
+
c.pacingDeadline = deadline
|
|
2466
|
+
// Allow sending of an ACK if we're pacing limit.
|
|
2467
|
+
// This makes sure that a peer that is mostly receiving data (and thus has an inaccurate cwnd estimate)
|
|
2468
|
+
// sends enough ACKs to allow its peer to utilize the bandwidth.
|
|
2469
|
+
return c.maybeSendAckOnlyPacket(now)
|
|
2470
|
+
case ackhandler.SendAck:
|
|
2471
|
+
// We can at most send a single ACK only packet.
|
|
2472
|
+
// There will only be a new ACK after receiving new packets.
|
|
2473
|
+
// SendAck is only returned when we're congestion limited, so we don't need to set the pacing timer.
|
|
2474
|
+
c.blocked = blockModeCongestionLimited
|
|
2475
|
+
return c.maybeSendAckOnlyPacket(now)
|
|
2476
|
+
case ackhandler.SendPTOInitial, ackhandler.SendPTOHandshake, ackhandler.SendPTOAppData:
|
|
2477
|
+
if err := c.sendProbePacket(sendMode, now); err != nil {
|
|
2478
|
+
return err
|
|
2479
|
+
}
|
|
2480
|
+
if c.sendQueue.WouldBlock() {
|
|
2481
|
+
c.scheduleSending()
|
|
2482
|
+
return nil
|
|
2483
|
+
}
|
|
2484
|
+
return c.triggerSending(now)
|
|
2485
|
+
default:
|
|
2486
|
+
return fmt.Errorf("BUG: invalid send mode %d", sendMode)
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
|
|
2490
|
+
func (c *Conn) sendPackets(now monotime.Time) error {
|
|
2491
|
+
if c.perspective == protocol.PerspectiveClient && c.handshakeConfirmed {
|
|
2492
|
+
if pm := c.pathManagerOutgoing.Load(); pm != nil {
|
|
2493
|
+
connID, frame, tr, ok := pm.NextPathToProbe()
|
|
2494
|
+
if ok {
|
|
2495
|
+
probe, buf, err := c.packer.PackPathProbePacket(connID, []ackhandler.Frame{frame}, c.version)
|
|
2496
|
+
if err != nil {
|
|
2497
|
+
return err
|
|
2498
|
+
}
|
|
2499
|
+
c.logger.Debugf("sending path probe packet from %s", c.LocalAddr())
|
|
2500
|
+
c.logShortHeaderPacket(probe, protocol.ECNNon, buf.Len())
|
|
2501
|
+
c.registerPackedShortHeaderPacket(probe, protocol.ECNNon, now)
|
|
2502
|
+
tr.WriteTo(buf.Data, c.conn.RemoteAddr())
|
|
2503
|
+
// There's (likely) more data to send. Loop around again.
|
|
2504
|
+
c.scheduleSending()
|
|
2505
|
+
return nil
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
// Path MTU Discovery
|
|
2511
|
+
// Can't use GSO, since we need to send a single packet that's larger than our current maximum size.
|
|
2512
|
+
// Performance-wise, this doesn't matter, since we only send a very small (<10) number of
|
|
2513
|
+
// MTU probe packets per connection.
|
|
2514
|
+
if c.handshakeConfirmed && c.mtuDiscoverer != nil && c.mtuDiscoverer.ShouldSendProbe(now) {
|
|
2515
|
+
ping, size := c.mtuDiscoverer.GetPing(now)
|
|
2516
|
+
p, buf, err := c.packer.PackMTUProbePacket(ping, size, c.version)
|
|
2517
|
+
if err != nil {
|
|
2518
|
+
return err
|
|
2519
|
+
}
|
|
2520
|
+
ecn := c.sentPacketHandler.ECNMode(true)
|
|
2521
|
+
c.logShortHeaderPacket(p, ecn, buf.Len())
|
|
2522
|
+
c.registerPackedShortHeaderPacket(p, ecn, now)
|
|
2523
|
+
c.sendQueue.Send(buf, 0, ecn)
|
|
2524
|
+
// There's (likely) more data to send. Loop around again.
|
|
2525
|
+
c.scheduleSending()
|
|
2526
|
+
return nil
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
if offset := c.connFlowController.GetWindowUpdate(now); offset > 0 {
|
|
2530
|
+
c.framer.QueueControlFrame(&wire.MaxDataFrame{MaximumData: offset})
|
|
2531
|
+
}
|
|
2532
|
+
if cf := c.cryptoStreamManager.GetPostHandshakeData(protocol.MaxPostHandshakeCryptoFrameSize); cf != nil {
|
|
2533
|
+
c.queueControlFrame(cf)
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
if !c.handshakeConfirmed {
|
|
2537
|
+
packet, err := c.packer.PackCoalescedPacket(false, c.maxPacketSize(), now, c.version)
|
|
2538
|
+
if err != nil || packet == nil {
|
|
2539
|
+
return err
|
|
2540
|
+
}
|
|
2541
|
+
c.sentFirstPacket = true
|
|
2542
|
+
if err := c.sendPackedCoalescedPacket(packet, c.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now); err != nil {
|
|
2543
|
+
return err
|
|
2544
|
+
}
|
|
2545
|
+
//nolint:exhaustive // only need to handle pacing-related events here
|
|
2546
|
+
switch c.sentPacketHandler.SendMode(now) {
|
|
2547
|
+
case ackhandler.SendPacingLimited:
|
|
2548
|
+
c.resetPacingDeadline()
|
|
2549
|
+
case ackhandler.SendAny:
|
|
2550
|
+
c.pacingDeadline = deadlineSendImmediately
|
|
2551
|
+
}
|
|
2552
|
+
return nil
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
if c.conn.capabilities().GSO {
|
|
2556
|
+
return c.sendPacketsWithGSO(now)
|
|
2557
|
+
}
|
|
2558
|
+
return c.sendPacketsWithoutGSO(now)
|
|
2559
|
+
}
|
|
2560
|
+
|
|
2561
|
+
func (c *Conn) sendPacketsWithoutGSO(now monotime.Time) error {
|
|
2562
|
+
for {
|
|
2563
|
+
buf := getPacketBuffer()
|
|
2564
|
+
ecn := c.sentPacketHandler.ECNMode(true)
|
|
2565
|
+
if _, err := c.appendOneShortHeaderPacket(buf, c.maxPacketSize(), ecn, now); err != nil {
|
|
2566
|
+
if err == errNothingToPack {
|
|
2567
|
+
buf.Release()
|
|
2568
|
+
return nil
|
|
2569
|
+
}
|
|
2570
|
+
return err
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2573
|
+
c.sendQueue.Send(buf, 0, ecn)
|
|
2574
|
+
|
|
2575
|
+
if c.sendQueue.WouldBlock() {
|
|
2576
|
+
return nil
|
|
2577
|
+
}
|
|
2578
|
+
sendMode := c.sentPacketHandler.SendMode(now)
|
|
2579
|
+
if sendMode == ackhandler.SendPacingLimited {
|
|
2580
|
+
c.resetPacingDeadline()
|
|
2581
|
+
return nil
|
|
2582
|
+
}
|
|
2583
|
+
if sendMode != ackhandler.SendAny {
|
|
2584
|
+
return nil
|
|
2585
|
+
}
|
|
2586
|
+
// Prioritize receiving of packets over sending out more packets.
|
|
2587
|
+
c.receivedPacketMx.Lock()
|
|
2588
|
+
hasPackets := !c.receivedPackets.Empty()
|
|
2589
|
+
c.receivedPacketMx.Unlock()
|
|
2590
|
+
if hasPackets {
|
|
2591
|
+
c.pacingDeadline = deadlineSendImmediately
|
|
2592
|
+
return nil
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
func (c *Conn) sendPacketsWithGSO(now monotime.Time) error {
|
|
2598
|
+
buf := getLargePacketBuffer()
|
|
2599
|
+
maxSize := c.maxPacketSize()
|
|
2600
|
+
|
|
2601
|
+
ecn := c.sentPacketHandler.ECNMode(true)
|
|
2602
|
+
for {
|
|
2603
|
+
var dontSendMore bool
|
|
2604
|
+
size, err := c.appendOneShortHeaderPacket(buf, maxSize, ecn, now)
|
|
2605
|
+
if err != nil {
|
|
2606
|
+
if err != errNothingToPack {
|
|
2607
|
+
return err
|
|
2608
|
+
}
|
|
2609
|
+
if buf.Len() == 0 {
|
|
2610
|
+
buf.Release()
|
|
2611
|
+
return nil
|
|
2612
|
+
}
|
|
2613
|
+
dontSendMore = true
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
if !dontSendMore {
|
|
2617
|
+
sendMode := c.sentPacketHandler.SendMode(now)
|
|
2618
|
+
if sendMode == ackhandler.SendPacingLimited {
|
|
2619
|
+
c.resetPacingDeadline()
|
|
2620
|
+
}
|
|
2621
|
+
if sendMode != ackhandler.SendAny {
|
|
2622
|
+
dontSendMore = true
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
// Don't send more packets in this batch if they require a different ECN marking than the previous ones.
|
|
2627
|
+
nextECN := c.sentPacketHandler.ECNMode(true)
|
|
2628
|
+
|
|
2629
|
+
// Append another packet if
|
|
2630
|
+
// 1. The congestion controller and pacer allow sending more
|
|
2631
|
+
// 2. The last packet appended was a full-size packet
|
|
2632
|
+
// 3. The next packet will have the same ECN marking
|
|
2633
|
+
// 4. We still have enough space for another full-size packet in the buffer
|
|
2634
|
+
if !dontSendMore && size == maxSize && nextECN == ecn && buf.Len()+maxSize <= buf.Cap() {
|
|
2635
|
+
continue
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
c.sendQueue.Send(buf, uint16(maxSize), ecn)
|
|
2639
|
+
|
|
2640
|
+
if dontSendMore {
|
|
2641
|
+
return nil
|
|
2642
|
+
}
|
|
2643
|
+
if c.sendQueue.WouldBlock() {
|
|
2644
|
+
return nil
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
// Prioritize receiving of packets over sending out more packets.
|
|
2648
|
+
c.receivedPacketMx.Lock()
|
|
2649
|
+
hasPackets := !c.receivedPackets.Empty()
|
|
2650
|
+
c.receivedPacketMx.Unlock()
|
|
2651
|
+
if hasPackets {
|
|
2652
|
+
c.pacingDeadline = deadlineSendImmediately
|
|
2653
|
+
return nil
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
ecn = nextECN
|
|
2657
|
+
buf = getLargePacketBuffer()
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
func (c *Conn) resetPacingDeadline() {
|
|
2662
|
+
deadline := c.sentPacketHandler.TimeUntilSend()
|
|
2663
|
+
if deadline.IsZero() {
|
|
2664
|
+
deadline = deadlineSendImmediately
|
|
2665
|
+
}
|
|
2666
|
+
c.pacingDeadline = deadline
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
func (c *Conn) maybeSendAckOnlyPacket(now monotime.Time) error {
|
|
2670
|
+
if !c.handshakeConfirmed {
|
|
2671
|
+
ecn := c.sentPacketHandler.ECNMode(false)
|
|
2672
|
+
packet, err := c.packer.PackCoalescedPacket(true, c.maxPacketSize(), now, c.version)
|
|
2673
|
+
if err != nil {
|
|
2674
|
+
return err
|
|
2675
|
+
}
|
|
2676
|
+
if packet == nil {
|
|
2677
|
+
return nil
|
|
2678
|
+
}
|
|
2679
|
+
return c.sendPackedCoalescedPacket(packet, ecn, now)
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
ecn := c.sentPacketHandler.ECNMode(true)
|
|
2683
|
+
p, buf, err := c.packer.PackAckOnlyPacket(c.maxPacketSize(), now, c.version)
|
|
2684
|
+
if err != nil {
|
|
2685
|
+
if err == errNothingToPack {
|
|
2686
|
+
return nil
|
|
2687
|
+
}
|
|
2688
|
+
return err
|
|
2689
|
+
}
|
|
2690
|
+
c.logShortHeaderPacket(p, ecn, buf.Len())
|
|
2691
|
+
c.registerPackedShortHeaderPacket(p, ecn, now)
|
|
2692
|
+
c.sendQueue.Send(buf, 0, ecn)
|
|
2693
|
+
return nil
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2696
|
+
func (c *Conn) sendProbePacket(sendMode ackhandler.SendMode, now monotime.Time) error {
|
|
2697
|
+
var encLevel protocol.EncryptionLevel
|
|
2698
|
+
//nolint:exhaustive // We only need to handle the PTO send modes here.
|
|
2699
|
+
switch sendMode {
|
|
2700
|
+
case ackhandler.SendPTOInitial:
|
|
2701
|
+
encLevel = protocol.EncryptionInitial
|
|
2702
|
+
case ackhandler.SendPTOHandshake:
|
|
2703
|
+
encLevel = protocol.EncryptionHandshake
|
|
2704
|
+
case ackhandler.SendPTOAppData:
|
|
2705
|
+
encLevel = protocol.Encryption1RTT
|
|
2706
|
+
default:
|
|
2707
|
+
return fmt.Errorf("connection BUG: unexpected send mode: %d", sendMode)
|
|
2708
|
+
}
|
|
2709
|
+
// Queue probe packets until we actually send out a packet,
|
|
2710
|
+
// or until there are no more packets to queue.
|
|
2711
|
+
var packet *coalescedPacket
|
|
2712
|
+
for packet == nil {
|
|
2713
|
+
if wasQueued := c.sentPacketHandler.QueueProbePacket(encLevel); !wasQueued {
|
|
2714
|
+
break
|
|
2715
|
+
}
|
|
2716
|
+
var err error
|
|
2717
|
+
packet, err = c.packer.PackPTOProbePacket(encLevel, c.maxPacketSize(), false, now, c.version)
|
|
2718
|
+
if err != nil {
|
|
2719
|
+
return err
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
if packet == nil {
|
|
2723
|
+
var err error
|
|
2724
|
+
packet, err = c.packer.PackPTOProbePacket(encLevel, c.maxPacketSize(), true, now, c.version)
|
|
2725
|
+
if err != nil {
|
|
2726
|
+
return err
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
if packet == nil || (len(packet.longHdrPackets) == 0 && packet.shortHdrPacket == nil) {
|
|
2730
|
+
return fmt.Errorf("connection BUG: couldn't pack %s probe packet: %v", encLevel, packet)
|
|
2731
|
+
}
|
|
2732
|
+
return c.sendPackedCoalescedPacket(packet, c.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now)
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
// appendOneShortHeaderPacket appends a new packet to the given packetBuffer.
|
|
2736
|
+
// If there was nothing to pack, the returned size is 0.
|
|
2737
|
+
func (c *Conn) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now monotime.Time) (protocol.ByteCount, error) {
|
|
2738
|
+
startLen := buf.Len()
|
|
2739
|
+
p, err := c.packer.AppendPacket(buf, maxSize, now, c.version)
|
|
2740
|
+
if err != nil {
|
|
2741
|
+
return 0, err
|
|
2742
|
+
}
|
|
2743
|
+
size := buf.Len() - startLen
|
|
2744
|
+
c.logShortHeaderPacket(p, ecn, size)
|
|
2745
|
+
c.registerPackedShortHeaderPacket(p, ecn, now)
|
|
2746
|
+
return size, nil
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
func (c *Conn) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now monotime.Time) {
|
|
2750
|
+
if p.IsPathProbePacket {
|
|
2751
|
+
c.sentPacketHandler.SentPacket(
|
|
2752
|
+
now,
|
|
2753
|
+
p.PacketNumber,
|
|
2754
|
+
protocol.InvalidPacketNumber,
|
|
2755
|
+
p.StreamFrames,
|
|
2756
|
+
p.Frames,
|
|
2757
|
+
protocol.Encryption1RTT,
|
|
2758
|
+
ecn,
|
|
2759
|
+
p.Length,
|
|
2760
|
+
p.IsPathMTUProbePacket,
|
|
2761
|
+
true,
|
|
2762
|
+
)
|
|
2763
|
+
return
|
|
2764
|
+
}
|
|
2765
|
+
if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && (len(p.StreamFrames) > 0 || ackhandler.HasAckElicitingFrames(p.Frames)) {
|
|
2766
|
+
c.firstAckElicitingPacketAfterIdleSentTime = now
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
largestAcked := protocol.InvalidPacketNumber
|
|
2770
|
+
if p.Ack != nil {
|
|
2771
|
+
largestAcked = p.Ack.LargestAcked()
|
|
2772
|
+
}
|
|
2773
|
+
c.sentPacketHandler.SentPacket(
|
|
2774
|
+
now,
|
|
2775
|
+
p.PacketNumber,
|
|
2776
|
+
largestAcked,
|
|
2777
|
+
p.StreamFrames,
|
|
2778
|
+
p.Frames,
|
|
2779
|
+
protocol.Encryption1RTT,
|
|
2780
|
+
ecn,
|
|
2781
|
+
p.Length,
|
|
2782
|
+
p.IsPathMTUProbePacket,
|
|
2783
|
+
false,
|
|
2784
|
+
)
|
|
2785
|
+
c.connIDManager.SentPacket()
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
func (c *Conn) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now monotime.Time) error {
|
|
2789
|
+
c.logCoalescedPacket(packet, ecn)
|
|
2790
|
+
for _, p := range packet.longHdrPackets {
|
|
2791
|
+
if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {
|
|
2792
|
+
c.firstAckElicitingPacketAfterIdleSentTime = now
|
|
2793
|
+
}
|
|
2794
|
+
largestAcked := protocol.InvalidPacketNumber
|
|
2795
|
+
if p.ack != nil {
|
|
2796
|
+
largestAcked = p.ack.LargestAcked()
|
|
2797
|
+
}
|
|
2798
|
+
c.sentPacketHandler.SentPacket(
|
|
2799
|
+
now,
|
|
2800
|
+
p.header.PacketNumber,
|
|
2801
|
+
largestAcked,
|
|
2802
|
+
p.streamFrames,
|
|
2803
|
+
p.frames,
|
|
2804
|
+
p.EncryptionLevel(),
|
|
2805
|
+
ecn,
|
|
2806
|
+
p.length,
|
|
2807
|
+
false,
|
|
2808
|
+
false,
|
|
2809
|
+
)
|
|
2810
|
+
if c.perspective == protocol.PerspectiveClient && p.EncryptionLevel() == protocol.EncryptionHandshake &&
|
|
2811
|
+
!c.droppedInitialKeys {
|
|
2812
|
+
// On the client side, Initial keys are dropped as soon as the first Handshake packet is sent.
|
|
2813
|
+
// See Section 4.9.1 of RFC 9001.
|
|
2814
|
+
if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {
|
|
2815
|
+
return err
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
if p := packet.shortHdrPacket; p != nil {
|
|
2820
|
+
if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {
|
|
2821
|
+
c.firstAckElicitingPacketAfterIdleSentTime = now
|
|
2822
|
+
}
|
|
2823
|
+
largestAcked := protocol.InvalidPacketNumber
|
|
2824
|
+
if p.Ack != nil {
|
|
2825
|
+
largestAcked = p.Ack.LargestAcked()
|
|
2826
|
+
}
|
|
2827
|
+
c.sentPacketHandler.SentPacket(
|
|
2828
|
+
now,
|
|
2829
|
+
p.PacketNumber,
|
|
2830
|
+
largestAcked,
|
|
2831
|
+
p.StreamFrames,
|
|
2832
|
+
p.Frames,
|
|
2833
|
+
protocol.Encryption1RTT,
|
|
2834
|
+
ecn,
|
|
2835
|
+
p.Length,
|
|
2836
|
+
p.IsPathMTUProbePacket,
|
|
2837
|
+
false,
|
|
2838
|
+
)
|
|
2839
|
+
}
|
|
2840
|
+
c.connIDManager.SentPacket()
|
|
2841
|
+
c.sendQueue.Send(packet.buffer, 0, ecn)
|
|
2842
|
+
return nil
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
func (c *Conn) sendConnectionClose(e error) ([]byte, error) {
|
|
2846
|
+
var packet *coalescedPacket
|
|
2847
|
+
var err error
|
|
2848
|
+
var transportErr *qerr.TransportError
|
|
2849
|
+
var applicationErr *qerr.ApplicationError
|
|
2850
|
+
if errors.As(e, &transportErr) {
|
|
2851
|
+
packet, err = c.packer.PackConnectionClose(transportErr, c.maxPacketSize(), c.version)
|
|
2852
|
+
} else if errors.As(e, &applicationErr) {
|
|
2853
|
+
packet, err = c.packer.PackApplicationClose(applicationErr, c.maxPacketSize(), c.version)
|
|
2854
|
+
} else {
|
|
2855
|
+
packet, err = c.packer.PackConnectionClose(&qerr.TransportError{
|
|
2856
|
+
ErrorCode: qerr.InternalError,
|
|
2857
|
+
ErrorMessage: fmt.Sprintf("connection BUG: unspecified error type (msg: %s)", e.Error()),
|
|
2858
|
+
}, c.maxPacketSize(), c.version)
|
|
2859
|
+
}
|
|
2860
|
+
if err != nil {
|
|
2861
|
+
return nil, err
|
|
2862
|
+
}
|
|
2863
|
+
ecn := c.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket())
|
|
2864
|
+
c.logCoalescedPacket(packet, ecn)
|
|
2865
|
+
return packet.buffer.Data, c.conn.Write(packet.buffer.Data, 0, ecn)
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2868
|
+
func (c *Conn) maxPacketSize() protocol.ByteCount {
|
|
2869
|
+
if c.mtuDiscoverer == nil {
|
|
2870
|
+
// Use the configured packet size on the client side.
|
|
2871
|
+
// If the server sends a max_udp_payload_size that's smaller than this size, we can ignore this:
|
|
2872
|
+
// Apparently the server still processed the (fully padded) Initial packet anyway.
|
|
2873
|
+
if c.perspective == protocol.PerspectiveClient {
|
|
2874
|
+
return protocol.ByteCount(c.config.InitialPacketSize)
|
|
2875
|
+
}
|
|
2876
|
+
// On the server side, there's no downside to using 1200 bytes until we received the client's transport
|
|
2877
|
+
// parameters:
|
|
2878
|
+
// * If the first packet didn't contain the entire ClientHello, all we can do is ACK that packet. We don't
|
|
2879
|
+
// need a lot of bytes for that.
|
|
2880
|
+
// * If it did, we will have processed the transport parameters and initialized the MTU discoverer.
|
|
2881
|
+
return protocol.MinInitialPacketSize
|
|
2882
|
+
}
|
|
2883
|
+
return c.mtuDiscoverer.CurrentSize()
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
// AcceptStream returns the next stream opened by the peer, blocking until one is available.
|
|
2887
|
+
func (c *Conn) AcceptStream(ctx context.Context) (*Stream, error) {
|
|
2888
|
+
return c.streamsMap.AcceptStream(ctx)
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
// AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available.
|
|
2892
|
+
func (c *Conn) AcceptUniStream(ctx context.Context) (*ReceiveStream, error) {
|
|
2893
|
+
return c.streamsMap.AcceptUniStream(ctx)
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
// OpenStream opens a new bidirectional QUIC stream.
|
|
2897
|
+
// There is no signaling to the peer about new streams:
|
|
2898
|
+
// The peer can only accept the stream after data has been sent on the stream,
|
|
2899
|
+
// or the stream has been reset or closed.
|
|
2900
|
+
// When reaching the peer's stream limit, it is not possible to open a new stream until the
|
|
2901
|
+
// peer raises the stream limit. In that case, a [StreamLimitReachedError] is returned.
|
|
2902
|
+
func (c *Conn) OpenStream() (*Stream, error) {
|
|
2903
|
+
return c.streamsMap.OpenStream()
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
// OpenStreamSync opens a new bidirectional QUIC stream.
|
|
2907
|
+
// It blocks until a new stream can be opened.
|
|
2908
|
+
// There is no signaling to the peer about new streams:
|
|
2909
|
+
// The peer can only accept the stream after data has been sent on the stream,
|
|
2910
|
+
// or the stream has been reset or closed.
|
|
2911
|
+
func (c *Conn) OpenStreamSync(ctx context.Context) (*Stream, error) {
|
|
2912
|
+
return c.streamsMap.OpenStreamSync(ctx)
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
// OpenUniStream opens a new outgoing unidirectional QUIC stream.
|
|
2916
|
+
// There is no signaling to the peer about new streams:
|
|
2917
|
+
// The peer can only accept the stream after data has been sent on the stream,
|
|
2918
|
+
// or the stream has been reset or closed.
|
|
2919
|
+
// When reaching the peer's stream limit, it is not possible to open a new stream until the
|
|
2920
|
+
// peer raises the stream limit. In that case, a [StreamLimitReachedError] is returned.
|
|
2921
|
+
func (c *Conn) OpenUniStream() (*SendStream, error) {
|
|
2922
|
+
return c.streamsMap.OpenUniStream()
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
// OpenUniStreamSync opens a new outgoing unidirectional QUIC stream.
|
|
2926
|
+
// It blocks until a new stream can be opened.
|
|
2927
|
+
// There is no signaling to the peer about new streams:
|
|
2928
|
+
// The peer can only accept the stream after data has been sent on the stream,
|
|
2929
|
+
// or the stream has been reset or closed.
|
|
2930
|
+
func (c *Conn) OpenUniStreamSync(ctx context.Context) (*SendStream, error) {
|
|
2931
|
+
return c.streamsMap.OpenUniStreamSync(ctx)
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
func (c *Conn) newFlowController(id protocol.StreamID) *streamFlowController {
|
|
2935
|
+
initialSendWindow := c.peerParams.InitialMaxStreamDataUni
|
|
2936
|
+
if protocol.StreamTypeOf(id) == protocol.StreamTypeBidi {
|
|
2937
|
+
if protocol.StreamInitiator(id) == c.perspective {
|
|
2938
|
+
initialSendWindow = c.peerParams.InitialMaxStreamDataBidiRemote
|
|
2939
|
+
} else {
|
|
2940
|
+
initialSendWindow = c.peerParams.InitialMaxStreamDataBidiLocal
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
return newStreamFlowController(
|
|
2944
|
+
id,
|
|
2945
|
+
c.connFlowController,
|
|
2946
|
+
protocol.ByteCount(c.config.InitialStreamReceiveWindow),
|
|
2947
|
+
protocol.ByteCount(c.config.MaxStreamReceiveWindow),
|
|
2948
|
+
initialSendWindow,
|
|
2949
|
+
c.rttStats,
|
|
2950
|
+
c.logger,
|
|
2951
|
+
)
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
// scheduleSending signals that we have data for sending
|
|
2955
|
+
func (c *Conn) scheduleSending() {
|
|
2956
|
+
select {
|
|
2957
|
+
case c.sendingScheduled <- struct{}{}:
|
|
2958
|
+
default:
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
|
|
2962
|
+
// tryQueueingUndecryptablePacket queues a packet for which we're missing the decryption keys.
|
|
2963
|
+
// The qlogevents.PacketType is only used for logging purposes.
|
|
2964
|
+
func (c *Conn) tryQueueingUndecryptablePacket(p receivedPacket, pt qlog.PacketType, datagramPayloadChecksum qlog.DatagramPayloadChecksum) {
|
|
2965
|
+
if c.handshakeComplete {
|
|
2966
|
+
panic("shouldn't queue undecryptable packets after handshake completion")
|
|
2967
|
+
}
|
|
2968
|
+
if len(c.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets {
|
|
2969
|
+
if c.qlogger != nil {
|
|
2970
|
+
c.qlogger.RecordEvent(qlog.PacketDropped{
|
|
2971
|
+
Header: qlog.PacketHeader{
|
|
2972
|
+
PacketType: pt,
|
|
2973
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
2974
|
+
},
|
|
2975
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
2976
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
2977
|
+
Trigger: qlog.PacketDropDOSPrevention,
|
|
2978
|
+
})
|
|
2979
|
+
}
|
|
2980
|
+
c.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size())
|
|
2981
|
+
return
|
|
2982
|
+
}
|
|
2983
|
+
c.logger.Infof("Queueing packet (%d bytes) for later decryption", p.Size())
|
|
2984
|
+
if c.qlogger != nil {
|
|
2985
|
+
c.qlogger.RecordEvent(qlog.PacketBuffered{
|
|
2986
|
+
Header: qlog.PacketHeader{
|
|
2987
|
+
PacketType: pt,
|
|
2988
|
+
PacketNumber: protocol.InvalidPacketNumber,
|
|
2989
|
+
},
|
|
2990
|
+
Raw: qlog.RawInfo{Length: int(p.Size())},
|
|
2991
|
+
DatagramPayloadChecksum: datagramPayloadChecksum,
|
|
2992
|
+
})
|
|
2993
|
+
}
|
|
2994
|
+
c.undecryptablePackets = append(c.undecryptablePackets, receivedPacketWithChecksum{receivedPacket: p, checksum: datagramPayloadChecksum})
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
func (c *Conn) queueControlFrame(f wire.Frame) {
|
|
2998
|
+
c.framer.QueueControlFrame(f)
|
|
2999
|
+
c.scheduleSending()
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
func (c *Conn) onHasConnectionData() { c.scheduleSending() }
|
|
3003
|
+
|
|
3004
|
+
func (c *Conn) onHasStreamData(id protocol.StreamID, str *SendStream) {
|
|
3005
|
+
c.framer.AddActiveStream(id, str)
|
|
3006
|
+
c.scheduleSending()
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
func (c *Conn) onHasStreamControlFrame(id protocol.StreamID, str streamControlFrameGetter) {
|
|
3010
|
+
c.framer.AddStreamWithControlFrames(id, str)
|
|
3011
|
+
c.scheduleSending()
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
func (c *Conn) onStreamCompleted(id protocol.StreamID) {
|
|
3015
|
+
if err := c.streamsMap.DeleteStream(id); err != nil {
|
|
3016
|
+
c.closeLocal(err)
|
|
3017
|
+
}
|
|
3018
|
+
c.framer.RemoveActiveStream(id)
|
|
3019
|
+
}
|
|
3020
|
+
|
|
3021
|
+
// SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221,
|
|
3022
|
+
// if the peer enabled datagram support.
|
|
3023
|
+
// There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost.
|
|
3024
|
+
// The payload of the datagram needs to fit into a single QUIC packet.
|
|
3025
|
+
// In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases.
|
|
3026
|
+
// If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned.
|
|
3027
|
+
func (c *Conn) SendDatagram(p []byte) error {
|
|
3028
|
+
if !c.supportsDatagrams() {
|
|
3029
|
+
return errors.New("datagram support disabled")
|
|
3030
|
+
}
|
|
3031
|
+
|
|
3032
|
+
f := &wire.DatagramFrame{DataLenPresent: true}
|
|
3033
|
+
// The payload size estimate is conservative.
|
|
3034
|
+
// Under many circumstances we could send a few more bytes.
|
|
3035
|
+
maxDataLen := min(
|
|
3036
|
+
f.MaxDataLen(c.peerParams.MaxDatagramFrameSize, c.version),
|
|
3037
|
+
protocol.ByteCount(c.maxPayloadSizeEstimate.Load()),
|
|
3038
|
+
)
|
|
3039
|
+
if protocol.ByteCount(len(p)) > maxDataLen {
|
|
3040
|
+
return &DatagramTooLargeError{MaxDatagramPayloadSize: int64(maxDataLen)}
|
|
3041
|
+
}
|
|
3042
|
+
f.Data = make([]byte, len(p))
|
|
3043
|
+
copy(f.Data, p)
|
|
3044
|
+
return c.datagramQueue.Add(f)
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
// ReceiveDatagram gets a message received in a QUIC datagram, as specified in RFC 9221.
|
|
3048
|
+
func (c *Conn) ReceiveDatagram(ctx context.Context) ([]byte, error) {
|
|
3049
|
+
if !c.config.EnableDatagrams {
|
|
3050
|
+
return nil, errors.New("datagram support disabled")
|
|
3051
|
+
}
|
|
3052
|
+
return c.datagramQueue.Receive(ctx)
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
// LocalAddr returns the local address of the QUIC connection.
|
|
3056
|
+
func (c *Conn) LocalAddr() net.Addr { return c.conn.LocalAddr() }
|
|
3057
|
+
|
|
3058
|
+
// RemoteAddr returns the remote address of the QUIC connection.
|
|
3059
|
+
func (c *Conn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() }
|
|
3060
|
+
|
|
3061
|
+
// getPathManager lazily initializes the Conn's pathManagerOutgoing.
|
|
3062
|
+
// May create multiple pathManagerOutgoing objects if called concurrently.
|
|
3063
|
+
func (c *Conn) getPathManager() *pathManagerOutgoing {
|
|
3064
|
+
old := c.pathManagerOutgoing.Load()
|
|
3065
|
+
if old != nil {
|
|
3066
|
+
// Path manager is already initialized
|
|
3067
|
+
return old
|
|
3068
|
+
}
|
|
3069
|
+
|
|
3070
|
+
// Initialize the path manager
|
|
3071
|
+
new := newPathManagerOutgoing(
|
|
3072
|
+
c.connIDManager.GetConnIDForPath,
|
|
3073
|
+
c.connIDManager.RetireConnIDForPath,
|
|
3074
|
+
c.scheduleSending,
|
|
3075
|
+
)
|
|
3076
|
+
if c.pathManagerOutgoing.CompareAndSwap(old, new) {
|
|
3077
|
+
return new
|
|
3078
|
+
}
|
|
3079
|
+
|
|
3080
|
+
// Swap failed. A concurrent writer wrote first, use their value.
|
|
3081
|
+
return c.pathManagerOutgoing.Load()
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
func (c *Conn) AddPath(t *Transport) (*Path, error) {
|
|
3085
|
+
if c.perspective == protocol.PerspectiveServer {
|
|
3086
|
+
return nil, errors.New("server cannot initiate connection migration")
|
|
3087
|
+
}
|
|
3088
|
+
if c.peerParams.DisableActiveMigration {
|
|
3089
|
+
return nil, errors.New("server disabled connection migration")
|
|
3090
|
+
}
|
|
3091
|
+
if err := t.init(false); err != nil {
|
|
3092
|
+
return nil, err
|
|
3093
|
+
}
|
|
3094
|
+
return c.getPathManager().NewPath(
|
|
3095
|
+
t,
|
|
3096
|
+
200*time.Millisecond, // initial RTT estimate
|
|
3097
|
+
func() {
|
|
3098
|
+
runner := (*packetHandlerMap)(t)
|
|
3099
|
+
c.connIDGenerator.AddConnRunner(
|
|
3100
|
+
runner,
|
|
3101
|
+
connRunnerCallbacks{
|
|
3102
|
+
AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, c) },
|
|
3103
|
+
RemoveConnectionID: runner.Remove,
|
|
3104
|
+
ReplaceWithClosed: runner.ReplaceWithClosed,
|
|
3105
|
+
},
|
|
3106
|
+
)
|
|
3107
|
+
},
|
|
3108
|
+
), nil
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
// HandshakeComplete blocks until the handshake completes (or fails).
|
|
3112
|
+
// For the client, data sent before completion of the handshake is encrypted with 0-RTT keys.
|
|
3113
|
+
// For the server, data sent before completion of the handshake is encrypted with 1-RTT keys,
|
|
3114
|
+
// however the client's identity is only verified once the handshake completes.
|
|
3115
|
+
func (c *Conn) HandshakeComplete() <-chan struct{} {
|
|
3116
|
+
return c.handshakeCompleteChan
|
|
3117
|
+
}
|
|
3118
|
+
|
|
3119
|
+
// QlogTrace returns the qlog trace of the QUIC connection.
|
|
3120
|
+
// It is nil if qlog is not enabled.
|
|
3121
|
+
func (c *Conn) QlogTrace() qlogwriter.Trace {
|
|
3122
|
+
return c.qlogTrace
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
// NextConnection transitions a connection to be usable after a 0-RTT rejection.
|
|
3126
|
+
// It waits for the handshake to complete and then enables the connection for normal use.
|
|
3127
|
+
// This should be called when the server rejects 0-RTT and the application receives
|
|
3128
|
+
// [Err0RTTRejected] errors.
|
|
3129
|
+
//
|
|
3130
|
+
// Note that 0-RTT rejection invalidates all data sent in 0-RTT packets. It is the
|
|
3131
|
+
// application's responsibility to handle this (for example by resending the data).
|
|
3132
|
+
func (c *Conn) NextConnection(ctx context.Context) (*Conn, error) {
|
|
3133
|
+
// The handshake might fail after the server rejected 0-RTT.
|
|
3134
|
+
// This could happen if the Finished message is malformed or never received.
|
|
3135
|
+
select {
|
|
3136
|
+
case <-ctx.Done():
|
|
3137
|
+
return nil, context.Cause(ctx)
|
|
3138
|
+
case <-c.Context().Done():
|
|
3139
|
+
case <-c.HandshakeComplete():
|
|
3140
|
+
c.streamsMap.UseResetMaps()
|
|
3141
|
+
}
|
|
3142
|
+
return c, nil
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
// estimateMaxPayloadSize estimates the maximum payload size for short header packets.
|
|
3146
|
+
// It is not very sophisticated: it just subtracts the size of header (assuming the maximum
|
|
3147
|
+
// connection ID length), and the size of the encryption tag.
|
|
3148
|
+
func estimateMaxPayloadSize(mtu protocol.ByteCount) protocol.ByteCount {
|
|
3149
|
+
return mtu - 1 /* type byte */ - 20 /* maximum connection ID length */ - 16 /* tag size */
|
|
3150
|
+
}
|