mirror of
https://github.com/DNSCrypt/dnscrypt-proxy.git
synced 2024-09-11 21:17:40 +03:00
Update quic-go
This commit is contained in:
parent
d48c811ea9
commit
c86e9a90cc
6
go.mod
6
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/dnscrypt/dnscrypt-proxy
|
||||
|
||||
go 1.20
|
||||
go 1.21.0
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
@ -20,7 +20,7 @@ require (
|
||||
github.com/kardianos/service v1.2.2
|
||||
github.com/miekg/dns v1.1.55
|
||||
github.com/powerman/check v1.7.0
|
||||
github.com/quic-go/quic-go v0.37.4
|
||||
github.com/quic-go/quic-go v0.38.1
|
||||
golang.org/x/crypto v0.12.0
|
||||
golang.org/x/net v0.14.0
|
||||
golang.org/x/sys v0.11.0
|
||||
@ -39,7 +39,7 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/powerman/deepequal v0.1.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect
|
||||
github.com/smartystreets/goconvey v1.7.2 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
|
13
go.sum
13
go.sum
@ -13,6 +13,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 h1:3T8ZyTDp5QxTx3NU48JVb2u+75xc040fofcBaN+6jPA=
|
||||
github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185/go.mod h1:cFRxtTwTOJkz2x3rQUNCYKWC93yP1VKjR8NUhqFxZNU=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
@ -22,6 +23,7 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
@ -61,6 +63,7 @@ github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60
|
||||
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
|
||||
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
|
||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -71,10 +74,10 @@ github.com/powerman/deepequal v0.1.0 h1:sVwtyTsBuYIvdbLR1O2wzRY63YgPqdGZmk/o80l+
|
||||
github.com/powerman/deepequal v0.1.0/go.mod h1:3k7aG/slufBhUANdN67o/UPg8i5YaiJ6FmibWX0cn04=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4=
|
||||
github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE=
|
||||
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
|
||||
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
|
||||
@ -101,6 +104,7 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -139,3 +143,4 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
14
vendor/github.com/quic-go/qtls-go1-20/common.go
generated
vendored
14
vendor/github.com/quic-go/qtls-go1-20/common.go
generated
vendored
@ -1451,16 +1451,4 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg
|
||||
}
|
||||
|
||||
// CertificateVerificationError is returned when certificate verification fails during the handshake.
|
||||
type CertificateVerificationError struct {
|
||||
// UnverifiedCertificates and its contents should not be modified.
|
||||
UnverifiedCertificates []*x509.Certificate
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *CertificateVerificationError) Error() string {
|
||||
return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
|
||||
}
|
||||
|
||||
func (e *CertificateVerificationError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
type CertificateVerificationError = tls.CertificateVerificationError
|
||||
|
3
vendor/github.com/quic-go/quic-go/README.md
generated
vendored
3
vendor/github.com/quic-go/quic-go/README.md
generated
vendored
@ -4,6 +4,7 @@
|
||||
|
||||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/quic-go/quic-go)](https://pkg.go.dev/github.com/quic-go/quic-go)
|
||||
[![Code Coverage](https://img.shields.io/codecov/c/github/quic-go/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/quic-go/quic-go/)
|
||||
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/quic-go.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:quic-go)
|
||||
|
||||
quic-go is an implementation of the QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)) in Go. It has support for HTTP/3 ([RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114)), including QPACK ([RFC 9204](https://datatracker.ietf.org/doc/html/rfc9204)).
|
||||
|
||||
@ -32,7 +33,7 @@ go func() {
|
||||
// ... error handling
|
||||
// handle the connection, usually in a new Go routine
|
||||
}
|
||||
}
|
||||
}()
|
||||
```
|
||||
|
||||
The listener `ln` can now be used to accept incoming QUIC connections by (repeatedly) calling the `Accept` method (see below for more information on the `quic.Connection`).
|
||||
|
16
vendor/github.com/quic-go/quic-go/client.go
generated
vendored
16
vendor/github.com/quic-go/quic-go/client.go
generated
vendored
@ -55,11 +55,11 @@ func DialAddr(ctx context.Context, addr string, tlsConf *tls.Config, conf *Confi
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dl, err := setupTransport(udpConn, tlsConf, true)
|
||||
tr, err := setupTransport(udpConn, tlsConf, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dl.Dial(ctx, udpAddr, tlsConf, conf)
|
||||
return tr.dial(ctx, udpAddr, addr, tlsConf, conf, false)
|
||||
}
|
||||
|
||||
// DialAddrEarly establishes a new 0-RTT QUIC connection to a server.
|
||||
@ -73,13 +73,13 @@ func DialAddrEarly(ctx context.Context, addr string, tlsConf *tls.Config, conf *
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dl, err := setupTransport(udpConn, tlsConf, true)
|
||||
tr, err := setupTransport(udpConn, tlsConf, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, err := dl.DialEarly(ctx, udpAddr, tlsConf, conf)
|
||||
conn, err := tr.dial(ctx, udpAddr, addr, tlsConf, conf, true)
|
||||
if err != nil {
|
||||
dl.Close()
|
||||
tr.Close()
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
@ -163,12 +163,6 @@ func dial(
|
||||
}
|
||||
|
||||
func newClient(sendConn sendConn, connIDGenerator ConnectionIDGenerator, config *Config, tlsConf *tls.Config, onClose func(), use0RTT bool) (*client, error) {
|
||||
if tlsConf == nil {
|
||||
tlsConf = &tls.Config{}
|
||||
} else {
|
||||
tlsConf = tlsConf.Clone()
|
||||
}
|
||||
|
||||
srcConnID, err := connIDGenerator.GenerateConnectionID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
16
vendor/github.com/quic-go/quic-go/connection.go
generated
vendored
16
vendor/github.com/quic-go/quic-go/connection.go
generated
vendored
@ -243,7 +243,7 @@ type connection struct {
|
||||
handshakeDestConnID: destConnID,
|
||||
srcConnIDLen: srcConnID.Len(),
|
||||
tokenGenerator: tokenGenerator,
|
||||
oneRTTStream: newCryptoStream(),
|
||||
oneRTTStream: newCryptoStream(true),
|
||||
perspective: protocol.PerspectiveServer,
|
||||
tracer: tracer,
|
||||
logger: logger,
|
||||
@ -391,7 +391,7 @@ func(connID protocol.ConnectionID) { runner.Add(connID, s) },
|
||||
s.logger,
|
||||
)
|
||||
s.mtuDiscoverer = newMTUDiscoverer(s.rttStats, getMaxPacketSize(s.conn.RemoteAddr()), s.sentPacketHandler.SetMaxDatagramSize)
|
||||
oneRTTStream := newCryptoStream()
|
||||
oneRTTStream := newCryptoStream(true)
|
||||
params := &wire.TransportParameters{
|
||||
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
||||
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
|
||||
@ -447,8 +447,8 @@ func(connID protocol.ConnectionID) { runner.Add(connID, s) },
|
||||
}
|
||||
|
||||
func (s *connection) preSetup() {
|
||||
s.initialStream = newCryptoStream()
|
||||
s.handshakeStream = newCryptoStream()
|
||||
s.initialStream = newCryptoStream(false)
|
||||
s.handshakeStream = newCryptoStream(false)
|
||||
s.sendQueue = newSendQueue(s.conn)
|
||||
s.retransmissionQueue = newRetransmissionQueue()
|
||||
s.frameParser = wire.NewFrameParser(s.config.EnableDatagrams)
|
||||
@ -1687,6 +1687,14 @@ func (s *connection) handleTransportParameters(params *wire.TransportParameters)
|
||||
ErrorMessage: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if s.perspective == protocol.PerspectiveClient && s.peerParams != nil && s.ConnectionState().Used0RTT && !params.ValidForUpdate(s.peerParams) {
|
||||
return &qerr.TransportError{
|
||||
ErrorCode: qerr.ProtocolViolation,
|
||||
ErrorMessage: "server sent reduced limits after accepting 0-RTT data",
|
||||
}
|
||||
}
|
||||
|
||||
s.peerParams = params
|
||||
// On the client side we have to wait for handshake completion.
|
||||
// During a 0-RTT connection, we are only allowed to use the new transport parameters for 1-RTT packets.
|
||||
|
25
vendor/github.com/quic-go/quic-go/crypto_stream.go
generated
vendored
25
vendor/github.com/quic-go/quic-go/crypto_stream.go
generated
vendored
@ -30,10 +30,17 @@ type cryptoStreamImpl struct {
|
||||
|
||||
writeOffset protocol.ByteCount
|
||||
writeBuf []byte
|
||||
|
||||
// Reassemble TLS handshake messages before returning them from GetCryptoData.
|
||||
// This is only needed because crypto/tls doesn't correctly handle post-handshake messages.
|
||||
onlyCompleteMsg bool
|
||||
}
|
||||
|
||||
func newCryptoStream() cryptoStream {
|
||||
return &cryptoStreamImpl{queue: newFrameSorter()}
|
||||
func newCryptoStream(onlyCompleteMsg bool) cryptoStream {
|
||||
return &cryptoStreamImpl{
|
||||
queue: newFrameSorter(),
|
||||
onlyCompleteMsg: onlyCompleteMsg,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error {
|
||||
@ -71,6 +78,20 @@ func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error {
|
||||
|
||||
// GetCryptoData retrieves data that was received in CRYPTO frames
|
||||
func (s *cryptoStreamImpl) GetCryptoData() []byte {
|
||||
if s.onlyCompleteMsg {
|
||||
if len(s.msgBuf) < 4 {
|
||||
return nil
|
||||
}
|
||||
msgLen := 4 + int(s.msgBuf[1])<<16 + int(s.msgBuf[2])<<8 + int(s.msgBuf[3])
|
||||
if len(s.msgBuf) < msgLen {
|
||||
return nil
|
||||
}
|
||||
msg := make([]byte, msgLen)
|
||||
copy(msg, s.msgBuf[:msgLen])
|
||||
s.msgBuf = s.msgBuf[msgLen:]
|
||||
return msg
|
||||
}
|
||||
|
||||
b := s.msgBuf
|
||||
s.msgBuf = nil
|
||||
return b
|
||||
|
2
vendor/github.com/quic-go/quic-go/http3/error_codes.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/http3/error_codes.go
generated
vendored
@ -26,7 +26,7 @@
|
||||
ErrCodeMessageError ErrCode = 0x10e
|
||||
ErrCodeConnectError ErrCode = 0x10f
|
||||
ErrCodeVersionFallback ErrCode = 0x110
|
||||
ErrCodeDatagramError ErrCode = 0x4a1268
|
||||
ErrCodeDatagramError ErrCode = 0x33
|
||||
)
|
||||
|
||||
func (e ErrCode) String() string {
|
||||
|
2
vendor/github.com/quic-go/quic-go/http3/frames.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/http3/frames.go
generated
vendored
@ -88,7 +88,7 @@ func (f *headersFrame) Append(b []byte) []byte {
|
||||
return quicvarint.Append(b, f.Length)
|
||||
}
|
||||
|
||||
const settingDatagram = 0xffd277
|
||||
const settingDatagram = 0x33
|
||||
|
||||
type settingsFrame struct {
|
||||
Datagram bool
|
||||
|
97
vendor/github.com/quic-go/quic-go/http3/response_writer.go
generated
vendored
97
vendor/github.com/quic-go/quic-go/http3/response_writer.go
generated
vendored
@ -15,19 +15,61 @@
|
||||
"github.com/quic-go/qpack"
|
||||
)
|
||||
|
||||
// The maximum length of an encoded HTTP/3 frame header is 16:
|
||||
// The frame has a type and length field, both QUIC varints (maximum 8 bytes in length)
|
||||
const frameHeaderLen = 16
|
||||
|
||||
// headerWriter wraps the stream, so that the first Write call flushes the header to the stream
|
||||
type headerWriter struct {
|
||||
str quic.Stream
|
||||
header http.Header
|
||||
status int // status code passed to WriteHeader
|
||||
written bool
|
||||
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
// writeHeader encodes and flush header to the stream
|
||||
func (hw *headerWriter) writeHeader() error {
|
||||
var headers bytes.Buffer
|
||||
enc := qpack.NewEncoder(&headers)
|
||||
enc.WriteField(qpack.HeaderField{Name: ":status", Value: strconv.Itoa(hw.status)})
|
||||
|
||||
for k, v := range hw.header {
|
||||
for index := range v {
|
||||
enc.WriteField(qpack.HeaderField{Name: strings.ToLower(k), Value: v[index]})
|
||||
}
|
||||
}
|
||||
|
||||
buf := make([]byte, 0, frameHeaderLen+headers.Len())
|
||||
buf = (&headersFrame{Length: uint64(headers.Len())}).Append(buf)
|
||||
hw.logger.Infof("Responding with %d", hw.status)
|
||||
buf = append(buf, headers.Bytes()...)
|
||||
|
||||
_, err := hw.str.Write(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// first Write will trigger flushing header
|
||||
func (hw *headerWriter) Write(p []byte) (int, error) {
|
||||
if !hw.written {
|
||||
if err := hw.writeHeader(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hw.written = true
|
||||
}
|
||||
return hw.str.Write(p)
|
||||
}
|
||||
|
||||
type responseWriter struct {
|
||||
*headerWriter
|
||||
conn quic.Connection
|
||||
str quic.Stream
|
||||
bufferedStr *bufio.Writer
|
||||
buf []byte
|
||||
|
||||
header http.Header
|
||||
status int // status code passed to WriteHeader
|
||||
headerWritten bool
|
||||
contentLen int64 // if handler set valid Content-Length header
|
||||
numWritten int64 // bytes written
|
||||
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
var (
|
||||
@ -37,13 +79,16 @@ type responseWriter struct {
|
||||
)
|
||||
|
||||
func newResponseWriter(str quic.Stream, conn quic.Connection, logger utils.Logger) *responseWriter {
|
||||
hw := &headerWriter{
|
||||
str: str,
|
||||
header: http.Header{},
|
||||
logger: logger,
|
||||
}
|
||||
return &responseWriter{
|
||||
header: http.Header{},
|
||||
buf: make([]byte, 16),
|
||||
conn: conn,
|
||||
str: str,
|
||||
bufferedStr: bufio.NewWriter(str),
|
||||
logger: logger,
|
||||
headerWriter: hw,
|
||||
buf: make([]byte, frameHeaderLen),
|
||||
conn: conn,
|
||||
bufferedStr: bufio.NewWriter(hw),
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,27 +128,8 @@ func (w *responseWriter) WriteHeader(status int) {
|
||||
}
|
||||
w.status = status
|
||||
|
||||
var headers bytes.Buffer
|
||||
enc := qpack.NewEncoder(&headers)
|
||||
enc.WriteField(qpack.HeaderField{Name: ":status", Value: strconv.Itoa(status)})
|
||||
|
||||
for k, v := range w.header {
|
||||
for index := range v {
|
||||
enc.WriteField(qpack.HeaderField{Name: strings.ToLower(k), Value: v[index]})
|
||||
}
|
||||
}
|
||||
|
||||
w.buf = w.buf[:0]
|
||||
w.buf = (&headersFrame{Length: uint64(headers.Len())}).Append(w.buf)
|
||||
w.logger.Infof("Responding with %d", status)
|
||||
if _, err := w.bufferedStr.Write(w.buf); err != nil {
|
||||
w.logger.Errorf("could not write headers frame: %s", err.Error())
|
||||
}
|
||||
if _, err := w.bufferedStr.Write(headers.Bytes()); err != nil {
|
||||
w.logger.Errorf("could not write header frame payload: %s", err.Error())
|
||||
}
|
||||
if !w.headerWritten {
|
||||
w.Flush()
|
||||
w.writeHeader()
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,6 +172,15 @@ func (w *responseWriter) Write(p []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (w *responseWriter) FlushError() error {
|
||||
if !w.headerWritten {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
if !w.written {
|
||||
if err := w.writeHeader(); err != nil {
|
||||
return err
|
||||
}
|
||||
w.written = true
|
||||
}
|
||||
return w.bufferedStr.Flush()
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/quic-go/quic-go/http3/roundtrip.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/http3/roundtrip.go
generated
vendored
@ -52,7 +52,7 @@ type RoundTripper struct {
|
||||
|
||||
// Enable support for HTTP/3 datagrams.
|
||||
// If set to true, QuicConfig.EnableDatagram will be set.
|
||||
// See https://www.ietf.org/archive/id/draft-schinazi-masque-h3-datagram-02.html.
|
||||
// See https://datatracker.ietf.org/doc/html/rfc9297.
|
||||
EnableDatagrams bool
|
||||
|
||||
// Additional HTTP/3 settings.
|
||||
|
18
vendor/github.com/quic-go/quic-go/http3/server.go
generated
vendored
18
vendor/github.com/quic-go/quic-go/http3/server.go
generated
vendored
@ -9,6 +9,7 @@
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -31,12 +32,8 @@
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
// NextProtoH3Draft29 is the ALPN protocol negotiated during the TLS handshake, for QUIC draft 29.
|
||||
NextProtoH3Draft29 = "h3-29"
|
||||
// NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2.
|
||||
NextProtoH3 = "h3"
|
||||
)
|
||||
// NextProtoH3 is the ALPN protocol negotiated during the TLS handshake, for QUIC v1 and v2.
|
||||
const NextProtoH3 = "h3"
|
||||
|
||||
// StreamType is the stream type of a unidirectional stream.
|
||||
type StreamType uint64
|
||||
@ -176,7 +173,7 @@ type Server struct {
|
||||
|
||||
// EnableDatagrams enables support for HTTP/3 datagrams.
|
||||
// If set to true, QuicConfig.EnableDatagram will be set.
|
||||
// See https://datatracker.ietf.org/doc/html/draft-ietf-masque-h3-datagram-07.
|
||||
// See https://datatracker.ietf.org/doc/html/rfc9297.
|
||||
EnableDatagrams bool
|
||||
|
||||
// MaxHeaderBytes controls the maximum number of bytes the server will
|
||||
@ -631,7 +628,12 @@ func() {
|
||||
|
||||
// only write response when there is no panic
|
||||
if !panicked {
|
||||
r.WriteHeader(http.StatusOK)
|
||||
// response not written to the client yet, set Content-Length
|
||||
if !r.written {
|
||||
if _, haveCL := r.header["Content-Length"]; !haveCL {
|
||||
r.header.Set("Content-Length", strconv.FormatInt(r.numWritten, 10))
|
||||
}
|
||||
}
|
||||
r.Flush()
|
||||
}
|
||||
// If the EOF was read by the handler, CancelRead() is a no-op.
|
||||
|
2
vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go
generated
vendored
2
vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go
generated
vendored
@ -30,7 +30,7 @@ func getCipherSuite(id uint16) *cipherSuite {
|
||||
case tls.TLS_CHACHA20_POLY1305_SHA256:
|
||||
return &cipherSuite{ID: tls.TLS_CHACHA20_POLY1305_SHA256, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadChaCha20Poly1305}
|
||||
case tls.TLS_AES_256_GCM_SHA384:
|
||||
return &cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadAESGCMTLS13}
|
||||
return &cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA384, KeyLen: 32, AEAD: aeadAESGCMTLS13}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown cypher suite: %d", id))
|
||||
}
|
||||
|
15
vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go
generated
vendored
15
vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go
generated
vendored
@ -7,6 +7,7 @@
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -356,10 +357,15 @@ func (h *cryptoSetup) getDataForSessionTicket() []byte {
|
||||
// Due to limitations in crypto/tls, it's only possible to generate a single session ticket per connection.
|
||||
// It is only valid for the server.
|
||||
func (h *cryptoSetup) GetSessionTicket() ([]byte, error) {
|
||||
if h.tlsConf.SessionTicketsDisabled {
|
||||
return nil, nil
|
||||
}
|
||||
if err := qtls.SendSessionTicket(h.conn, h.allow0RTT); err != nil {
|
||||
// Session tickets might be disabled by tls.Config.SessionTicketsDisabled.
|
||||
// We can't check h.tlsConfig here, since the actual config might have been obtained from
|
||||
// the GetConfigForClient callback.
|
||||
// See https://github.com/golang/go/issues/62032.
|
||||
// Once that issue is resolved, this error assertion can be removed.
|
||||
if strings.Contains(err.Error(), "session ticket keys unavailable") {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
ev := h.conn.NextEvent()
|
||||
@ -658,8 +664,9 @@ func (h *cryptoSetup) ConnectionState() ConnectionState {
|
||||
}
|
||||
|
||||
func wrapError(err error) error {
|
||||
// alert 80 is an internal error
|
||||
if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 {
|
||||
return qerr.NewLocalCryptoError(uint8(alertErr), err.Error())
|
||||
return qerr.NewLocalCryptoError(uint8(alertErr), err)
|
||||
}
|
||||
return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()}
|
||||
}
|
||||
|
15
vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go
generated
vendored
15
vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go
generated
vendored
@ -43,6 +43,21 @@ func (t PacketType) String() string {
|
||||
ECNCE // 11
|
||||
)
|
||||
|
||||
func (e ECN) String() string {
|
||||
switch e {
|
||||
case ECNNon:
|
||||
return "Not-ECT"
|
||||
case ECT1:
|
||||
return "ECT(1)"
|
||||
case ECT0:
|
||||
return "ECT(0)"
|
||||
case ECNCE:
|
||||
return "CE"
|
||||
default:
|
||||
return fmt.Sprintf("invalid ECN value: %d", e)
|
||||
}
|
||||
}
|
||||
|
||||
// A ByteCount in QUIC
|
||||
type ByteCount int64
|
||||
|
||||
|
14
vendor/github.com/quic-go/quic-go/internal/qerr/errors.go
generated
vendored
14
vendor/github.com/quic-go/quic-go/internal/qerr/errors.go
generated
vendored
@ -17,15 +17,16 @@ type TransportError struct {
|
||||
FrameType uint64
|
||||
ErrorCode TransportErrorCode
|
||||
ErrorMessage string
|
||||
error error // only set for local errors, sometimes
|
||||
}
|
||||
|
||||
var _ error = &TransportError{}
|
||||
|
||||
// NewLocalCryptoError create a new TransportError instance for a crypto error
|
||||
func NewLocalCryptoError(tlsAlert uint8, errorMessage string) *TransportError {
|
||||
func NewLocalCryptoError(tlsAlert uint8, err error) *TransportError {
|
||||
return &TransportError{
|
||||
ErrorCode: 0x100 + TransportErrorCode(tlsAlert),
|
||||
ErrorMessage: errorMessage,
|
||||
ErrorCode: 0x100 + TransportErrorCode(tlsAlert),
|
||||
error: err,
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +36,9 @@ func (e *TransportError) Error() string {
|
||||
str += fmt.Sprintf(" (frame type: %#x)", e.FrameType)
|
||||
}
|
||||
msg := e.ErrorMessage
|
||||
if len(msg) == 0 && e.error != nil {
|
||||
msg = e.error.Error()
|
||||
}
|
||||
if len(msg) == 0 {
|
||||
msg = e.ErrorCode.Message()
|
||||
}
|
||||
@ -48,6 +52,10 @@ func (e *TransportError) Is(target error) bool {
|
||||
return target == net.ErrClosed
|
||||
}
|
||||
|
||||
func (e *TransportError) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// An ApplicationErrorCode is an application-defined error code.
|
||||
type ApplicationErrorCode uint64
|
||||
|
||||
|
4
vendor/github.com/quic-go/quic-go/internal/wire/header.go
generated
vendored
4
vendor/github.com/quic-go/quic-go/internal/wire/header.go
generated
vendored
@ -74,6 +74,10 @@ func parseArbitraryLenConnectionIDs(r *bytes.Reader) (dest, src protocol.Arbitra
|
||||
return destConnID, srcConnID, nil
|
||||
}
|
||||
|
||||
func IsPotentialQUICPacket(firstByte byte) bool {
|
||||
return firstByte&0x40 > 0
|
||||
}
|
||||
|
||||
// IsLongHeaderPacket says if this is a Long Header packet
|
||||
func IsLongHeaderPacket(firstByte byte) bool {
|
||||
return firstByte&0x80 > 0
|
||||
|
22
vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go
generated
vendored
22
vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go
generated
vendored
@ -454,6 +454,10 @@ func (p *TransportParameters) MarshalForSessionTicket(b []byte) []byte {
|
||||
b = p.marshalVarintParam(b, initialMaxStreamsBidiParameterID, uint64(p.MaxBidiStreamNum))
|
||||
// initial_max_uni_streams
|
||||
b = p.marshalVarintParam(b, initialMaxStreamsUniParameterID, uint64(p.MaxUniStreamNum))
|
||||
// max_datagram_frame_size
|
||||
if p.MaxDatagramFrameSize != protocol.InvalidByteCount {
|
||||
b = p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize))
|
||||
}
|
||||
// active_connection_id_limit
|
||||
return p.marshalVarintParam(b, activeConnectionIDLimitParameterID, p.ActiveConnectionIDLimit)
|
||||
}
|
||||
@ -472,6 +476,9 @@ func (p *TransportParameters) UnmarshalFromSessionTicket(r *bytes.Reader) error
|
||||
|
||||
// ValidFor0RTT checks if the transport parameters match those saved in the session ticket.
|
||||
func (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool {
|
||||
if saved.MaxDatagramFrameSize != protocol.InvalidByteCount && (p.MaxDatagramFrameSize == protocol.InvalidByteCount || p.MaxDatagramFrameSize < saved.MaxDatagramFrameSize) {
|
||||
return false
|
||||
}
|
||||
return p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal &&
|
||||
p.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote &&
|
||||
p.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni &&
|
||||
@ -481,6 +488,21 @@ func (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool {
|
||||
p.ActiveConnectionIDLimit == saved.ActiveConnectionIDLimit
|
||||
}
|
||||
|
||||
// ValidForUpdate checks that the new transport parameters don't reduce limits after resuming a 0-RTT connection.
|
||||
// It is only used on the client side.
|
||||
func (p *TransportParameters) ValidForUpdate(saved *TransportParameters) bool {
|
||||
if saved.MaxDatagramFrameSize != protocol.InvalidByteCount && (p.MaxDatagramFrameSize == protocol.InvalidByteCount || p.MaxDatagramFrameSize < saved.MaxDatagramFrameSize) {
|
||||
return false
|
||||
}
|
||||
return p.ActiveConnectionIDLimit >= saved.ActiveConnectionIDLimit &&
|
||||
p.InitialMaxData >= saved.InitialMaxData &&
|
||||
p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal &&
|
||||
p.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote &&
|
||||
p.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni &&
|
||||
p.MaxBidiStreamNum >= saved.MaxBidiStreamNum &&
|
||||
p.MaxUniStreamNum >= saved.MaxUniStreamNum
|
||||
}
|
||||
|
||||
// String returns a string representation, intended for logging.
|
||||
func (p *TransportParameters) String() string {
|
||||
logString := "&wire.TransportParameters{OriginalDestinationConnectionID: %s, InitialSourceConnectionID: %s, "
|
||||
|
5
vendor/github.com/quic-go/quic-go/internal/wire/version_negotiation.go
generated
vendored
5
vendor/github.com/quic-go/quic-go/internal/wire/version_negotiation.go
generated
vendored
@ -40,7 +40,10 @@ func ComposeVersionNegotiation(destConnID, srcConnID protocol.ArbitraryLenConnec
|
||||
buf := bytes.NewBuffer(make([]byte, 0, expectedLen))
|
||||
r := make([]byte, 1)
|
||||
_, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here.
|
||||
buf.WriteByte(r[0] | 0x80)
|
||||
// Setting the "QUIC bit" (0x40) is not required by the RFC,
|
||||
// but it allows clients to demultiplex QUIC with a long list of other protocols.
|
||||
// See RFC 9443 and https://mailarchive.ietf.org/arch/msg/quic/oR4kxGKY6mjtPC1CZegY1ED4beg/ for details.
|
||||
buf.WriteByte(r[0] | 0xc0)
|
||||
utils.BigEndian.WriteUint32(buf, 0) // version 0
|
||||
buf.WriteByte(uint8(destConnID.Len()))
|
||||
buf.Write(destConnID.Bytes())
|
||||
|
3
vendor/github.com/quic-go/quic-go/mockgen.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/mockgen.go
generated
vendored
@ -5,6 +5,9 @@
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn"
|
||||
type SendConn = sendConn
|
||||
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn"
|
||||
type RawConn = rawConn
|
||||
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender"
|
||||
type Sender = sender
|
||||
|
||||
|
6
vendor/github.com/quic-go/quic-go/packet_handler_map.go
generated
vendored
6
vendor/github.com/quic-go/quic-go/packet_handler_map.go
generated
vendored
@ -26,9 +26,9 @@ type connCapabilities struct {
|
||||
// rawConn is a connection that allow reading of a receivedPackeh.
|
||||
type rawConn interface {
|
||||
ReadPacket() (receivedPacket, error)
|
||||
// The size parameter is used for GSO.
|
||||
// If GSO is not support, len(b) must be equal to size.
|
||||
WritePacket(b []byte, size uint16, addr net.Addr, oob []byte) (int, error)
|
||||
// WritePacket writes a packet on the wire.
|
||||
// If GSO is enabled, it's the caller's responsibility to set the correct control message.
|
||||
WritePacket(b []byte, addr net.Addr, oob []byte) (int, error)
|
||||
LocalAddr() net.Addr
|
||||
SetReadDeadline(time.Time) error
|
||||
io.Closer
|
||||
|
93
vendor/github.com/quic-go/quic-go/send_conn.go
generated
vendored
93
vendor/github.com/quic-go/quic-go/send_conn.go
generated
vendored
@ -1,10 +1,12 @@
|
||||
package quic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
// A sendConn allows sending using a simple Write() on a non-connected packet conn.
|
||||
@ -20,61 +22,86 @@ type sendConn interface {
|
||||
type sconn struct {
|
||||
rawConn
|
||||
|
||||
localAddr net.Addr
|
||||
remoteAddr net.Addr
|
||||
info packetInfo
|
||||
oob []byte
|
||||
|
||||
logger utils.Logger
|
||||
|
||||
info packetInfo
|
||||
oob []byte
|
||||
// If GSO enabled, and we receive a GSO error for this remote address, GSO is disabled.
|
||||
gotGSOError bool
|
||||
}
|
||||
|
||||
var _ sendConn = &sconn{}
|
||||
|
||||
func newSendConn(c rawConn, remote net.Addr) *sconn {
|
||||
sc := &sconn{
|
||||
rawConn: c,
|
||||
remoteAddr: remote,
|
||||
func newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logger) *sconn {
|
||||
localAddr := c.LocalAddr()
|
||||
if info.addr.IsValid() {
|
||||
if udpAddr, ok := localAddr.(*net.UDPAddr); ok {
|
||||
addrCopy := *udpAddr
|
||||
addrCopy.IP = info.addr.AsSlice()
|
||||
localAddr = &addrCopy
|
||||
}
|
||||
}
|
||||
if c.capabilities().GSO {
|
||||
// add 32 bytes, so we can add the UDP_SEGMENT msg
|
||||
sc.oob = make([]byte, 0, 32)
|
||||
}
|
||||
return sc
|
||||
}
|
||||
|
||||
func newSendConnWithPacketInfo(c rawConn, remote net.Addr, info packetInfo) *sconn {
|
||||
oob := info.OOB()
|
||||
if c.capabilities().GSO {
|
||||
// add 32 bytes, so we can add the UDP_SEGMENT msg
|
||||
l := len(oob)
|
||||
oob = append(oob, make([]byte, 32)...)
|
||||
oob = oob[:l]
|
||||
}
|
||||
// add 32 bytes, so we can add the UDP_SEGMENT msg
|
||||
l := len(oob)
|
||||
oob = append(oob, make([]byte, 32)...)
|
||||
oob = oob[:l]
|
||||
return &sconn{
|
||||
rawConn: c,
|
||||
localAddr: localAddr,
|
||||
remoteAddr: remote,
|
||||
info: info,
|
||||
oob: oob,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *sconn) Write(p []byte, size protocol.ByteCount) error {
|
||||
if !c.capabilities().GSO {
|
||||
if protocol.ByteCount(len(p)) != size {
|
||||
panic(fmt.Sprintf("inconsistent packet size (%d vs %d)", len(p), size))
|
||||
}
|
||||
_, err := c.WritePacket(p, c.remoteAddr, c.oob)
|
||||
return err
|
||||
}
|
||||
// GSO is supported. Append the control message and send.
|
||||
if size > math.MaxUint16 {
|
||||
panic("size overflow")
|
||||
}
|
||||
_, err := c.WritePacket(p, uint16(size), c.remoteAddr, c.oob)
|
||||
_, err := c.WritePacket(p, c.remoteAddr, appendUDPSegmentSizeMsg(c.oob, uint16(size)))
|
||||
if err != nil && isGSOError(err) {
|
||||
// disable GSO for future calls
|
||||
c.gotGSOError = true
|
||||
if c.logger.Debug() {
|
||||
c.logger.Debugf("GSO failed when sending to %s", c.remoteAddr)
|
||||
}
|
||||
// send out the packets one by one
|
||||
for len(p) > 0 {
|
||||
l := len(p)
|
||||
if l > int(size) {
|
||||
l = int(size)
|
||||
}
|
||||
if _, err := c.WritePacket(p[:l], c.remoteAddr, c.oob); err != nil {
|
||||
return err
|
||||
}
|
||||
p = p[l:]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *sconn) RemoteAddr() net.Addr {
|
||||
return c.remoteAddr
|
||||
func (c *sconn) capabilities() connCapabilities {
|
||||
capabilities := c.rawConn.capabilities()
|
||||
if capabilities.GSO {
|
||||
capabilities.GSO = !c.gotGSOError
|
||||
}
|
||||
return capabilities
|
||||
}
|
||||
|
||||
func (c *sconn) LocalAddr() net.Addr {
|
||||
addr := c.rawConn.LocalAddr()
|
||||
if c.info.addr.IsValid() {
|
||||
if udpAddr, ok := addr.(*net.UDPAddr); ok {
|
||||
addrCopy := *udpAddr
|
||||
addrCopy.IP = c.info.addr.AsSlice()
|
||||
addr = &addrCopy
|
||||
}
|
||||
}
|
||||
return addr
|
||||
}
|
||||
func (c *sconn) RemoteAddr() net.Addr { return c.remoteAddr }
|
||||
func (c *sconn) LocalAddr() net.Addr { return c.localAddr }
|
||||
|
8
vendor/github.com/quic-go/quic-go/server.go
generated
vendored
8
vendor/github.com/quic-go/quic-go/server.go
generated
vendored
@ -632,7 +632,7 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error
|
||||
tracer = config.Tracer(context.WithValue(context.Background(), ConnectionTracingKey, tracingID), protocol.PerspectiveServer, connID)
|
||||
}
|
||||
conn = s.newConn(
|
||||
newSendConnWithPacketInfo(s.conn, p.remoteAddr, p.info),
|
||||
newSendConn(s.conn, p.remoteAddr, p.info, s.logger),
|
||||
s.connHandler,
|
||||
origDestConnID,
|
||||
retrySrcConnID,
|
||||
@ -742,7 +742,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info packe
|
||||
if s.tracer != nil {
|
||||
s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil)
|
||||
}
|
||||
_, err = s.conn.WritePacket(buf.Data, uint16(len(buf.Data)), remoteAddr, info.OOB())
|
||||
_, err = s.conn.WritePacket(buf.Data, remoteAddr, info.OOB())
|
||||
return err
|
||||
}
|
||||
|
||||
@ -841,7 +841,7 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han
|
||||
if s.tracer != nil {
|
||||
s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf})
|
||||
}
|
||||
_, err = s.conn.WritePacket(b.Data, uint16(len(b.Data)), remoteAddr, info.OOB())
|
||||
_, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB())
|
||||
return err
|
||||
}
|
||||
|
||||
@ -879,7 +879,7 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) {
|
||||
if s.tracer != nil {
|
||||
s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions)
|
||||
}
|
||||
if _, err := s.conn.WritePacket(data, uint16(len(data)), p.remoteAddr, p.info.OOB()); err != nil {
|
||||
if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil {
|
||||
s.logger.Debugf("Error sending Version Negotiation: %s", err)
|
||||
}
|
||||
}
|
||||
|
6
vendor/github.com/quic-go/quic-go/sys_conn.go
generated
vendored
6
vendor/github.com/quic-go/quic-go/sys_conn.go
generated
vendored
@ -1,7 +1,6 @@
|
||||
package quic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
@ -105,10 +104,7 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *basicConn) WritePacket(b []byte, packetSize uint16, addr net.Addr, _ []byte) (n int, err error) {
|
||||
if uint16(len(b)) != packetSize {
|
||||
panic(fmt.Sprintf("inconsistent length. got: %d. expected %d", packetSize, len(b)))
|
||||
}
|
||||
func (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte) (n int, err error) {
|
||||
return c.PacketConn.WriteTo(b, addr)
|
||||
}
|
||||
|
||||
|
40
vendor/github.com/quic-go/quic-go/sys_conn_df_linux.go
generated
vendored
40
vendor/github.com/quic-go/quic-go/sys_conn_df_linux.go
generated
vendored
@ -4,11 +4,7 @@
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
@ -38,43 +34,9 @@ func setDF(rawConn syscall.RawConn) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func maybeSetGSO(rawConn syscall.RawConn) bool {
|
||||
enable, _ := strconv.ParseBool(os.Getenv("QUIC_GO_ENABLE_GSO"))
|
||||
if !enable {
|
||||
return false
|
||||
}
|
||||
|
||||
var setErr error
|
||||
if err := rawConn.Control(func(fd uintptr) {
|
||||
setErr = unix.SetsockoptInt(int(fd), syscall.IPPROTO_UDP, unix.UDP_SEGMENT, 1)
|
||||
}); err != nil {
|
||||
setErr = err
|
||||
}
|
||||
if setErr != nil {
|
||||
log.Println("failed to enable GSO")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isSendMsgSizeErr(err error) bool {
|
||||
// https://man7.org/linux/man-pages/man7/udp.7.html
|
||||
return errors.Is(err, unix.EMSGSIZE)
|
||||
}
|
||||
|
||||
func isRecvMsgSizeErr(err error) bool { return false }
|
||||
|
||||
func appendUDPSegmentSizeMsg(b []byte, size uint16) []byte {
|
||||
startLen := len(b)
|
||||
const dataLen = 2 // payload is a uint16
|
||||
b = append(b, make([]byte, unix.CmsgSpace(dataLen))...)
|
||||
h := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen]))
|
||||
h.Level = syscall.IPPROTO_UDP
|
||||
h.Type = unix.UDP_SEGMENT
|
||||
h.SetLen(unix.CmsgLen(dataLen))
|
||||
|
||||
// UnixRights uses the private `data` method, but I *think* this achieves the same goal.
|
||||
offset := startLen + unix.CmsgSpace(0)
|
||||
*(*uint16)(unsafe.Pointer(&b[offset])) = size
|
||||
return b
|
||||
}
|
||||
func isRecvMsgSizeErr(error) bool { return false }
|
||||
|
3
vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go
generated
vendored
@ -5,6 +5,7 @@
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -29,3 +30,5 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) {
|
||||
}
|
||||
return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true
|
||||
}
|
||||
|
||||
func isGSOSupported(syscall.RawConn) bool { return false }
|
||||
|
3
vendor/github.com/quic-go/quic-go/sys_conn_helper_freebsd.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/sys_conn_helper_freebsd.go
generated
vendored
@ -4,6 +4,7 @@
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -24,3 +25,5 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, _ uint32, ok bool) {
|
||||
}
|
||||
return netip.AddrFrom4(*(*[4]byte)(body)), 0, true
|
||||
}
|
||||
|
||||
func isGSOSupported(syscall.RawConn) bool { return false }
|
||||
|
47
vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go
generated
vendored
47
vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go
generated
vendored
@ -4,8 +4,12 @@
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -48,3 +52,46 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) {
|
||||
}
|
||||
return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true
|
||||
}
|
||||
|
||||
// isGSOSupported tests if the kernel supports GSO.
|
||||
// Sending with GSO might still fail later on, if the interface doesn't support it (see isGSOError).
|
||||
func isGSOSupported(conn syscall.RawConn) bool {
|
||||
disabled, err := strconv.ParseBool(os.Getenv("QUIC_GO_DISABLE_GSO"))
|
||||
if err == nil && disabled {
|
||||
return false
|
||||
}
|
||||
var serr error
|
||||
if err := conn.Control(func(fd uintptr) {
|
||||
_, serr = unix.GetsockoptInt(int(fd), unix.IPPROTO_UDP, unix.UDP_SEGMENT)
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return serr == nil
|
||||
}
|
||||
|
||||
func appendUDPSegmentSizeMsg(b []byte, size uint16) []byte {
|
||||
startLen := len(b)
|
||||
const dataLen = 2 // payload is a uint16
|
||||
b = append(b, make([]byte, unix.CmsgSpace(dataLen))...)
|
||||
h := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen]))
|
||||
h.Level = syscall.IPPROTO_UDP
|
||||
h.Type = unix.UDP_SEGMENT
|
||||
h.SetLen(unix.CmsgLen(dataLen))
|
||||
|
||||
// UnixRights uses the private `data` method, but I *think* this achieves the same goal.
|
||||
offset := startLen + unix.CmsgSpace(0)
|
||||
*(*uint16)(unsafe.Pointer(&b[offset])) = size
|
||||
return b
|
||||
}
|
||||
|
||||
func isGSOError(err error) bool {
|
||||
var serr *os.SyscallError
|
||||
if errors.As(err, &serr) {
|
||||
// EIO is returned by udp_send_skb() if the device driver does not have tx checksums enabled,
|
||||
// which is a hard requirement of UDP_SEGMENT. See:
|
||||
// https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man7/udp.7?id=806eabd74910447f21005160e90957bde4db0183#n228
|
||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/udp.c?h=v6.2&id=c9c3395d5e3dcc6daee66c6908354d47bf98cb0c#n942
|
||||
return serr.Err == unix.EIO
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
3
vendor/github.com/quic-go/quic-go/sys_conn_helper_nonlinux.go
generated
vendored
3
vendor/github.com/quic-go/quic-go/sys_conn_helper_nonlinux.go
generated
vendored
@ -4,3 +4,6 @@
|
||||
|
||||
func forceSetReceiveBuffer(c any, bytes int) error { return nil }
|
||||
func forceSetSendBuffer(c any, bytes int) error { return nil }
|
||||
|
||||
func appendUDPSegmentSizeMsg([]byte, uint16) []byte { return nil }
|
||||
func isGSOError(error) bool { return false }
|
||||
|
8
vendor/github.com/quic-go/quic-go/sys_conn_no_gso.go
generated
vendored
8
vendor/github.com/quic-go/quic-go/sys_conn_no_gso.go
generated
vendored
@ -1,8 +0,0 @@
|
||||
//go:build darwin || freebsd
|
||||
|
||||
package quic
|
||||
|
||||
import "syscall"
|
||||
|
||||
func maybeSetGSO(_ syscall.RawConn) bool { return false }
|
||||
func appendUDPSegmentSizeMsg(_ []byte, _ uint16) []byte { return nil }
|
25
vendor/github.com/quic-go/quic-go/sys_conn_oob.go
generated
vendored
25
vendor/github.com/quic-go/quic-go/sys_conn_oob.go
generated
vendored
@ -5,7 +5,6 @@
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
@ -128,10 +127,6 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) {
|
||||
bc = ipv4.NewPacketConn(c)
|
||||
}
|
||||
|
||||
// Try enabling GSO.
|
||||
// This will only succeed on Linux, and only for kernels > 4.18.
|
||||
supportsGSO := maybeSetGSO(rawConn)
|
||||
|
||||
msgs := make([]ipv4.Message, batchSize)
|
||||
for i := range msgs {
|
||||
// preallocate the [][]byte
|
||||
@ -142,9 +137,11 @@ func newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) {
|
||||
batchConn: bc,
|
||||
messages: msgs,
|
||||
readPos: batchSize,
|
||||
cap: connCapabilities{
|
||||
DF: supportsDF,
|
||||
GSO: isGSOSupported(rawConn),
|
||||
},
|
||||
}
|
||||
oobConn.cap.DF = supportsDF
|
||||
oobConn.cap.GSO = supportsGSO
|
||||
for i := 0; i < batchSize; i++ {
|
||||
oobConn.messages[i].OOB = make([]byte, oobBufferSize)
|
||||
}
|
||||
@ -231,17 +228,9 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) {
|
||||
}
|
||||
|
||||
// WritePacket writes a new packet.
|
||||
// If the connection supports GSO (and we activated GSO support before),
|
||||
// it appends the UDP_SEGMENT size message to oob.
|
||||
// Callers are advised to make sure that oob has a sufficient capacity,
|
||||
// such that appending the UDP_SEGMENT size message doesn't cause an allocation.
|
||||
func (c *oobConn) WritePacket(b []byte, packetSize uint16, addr net.Addr, oob []byte) (n int, err error) {
|
||||
if c.cap.GSO {
|
||||
oob = appendUDPSegmentSizeMsg(oob, packetSize)
|
||||
} else if uint16(len(b)) != packetSize {
|
||||
panic(fmt.Sprintf("inconsistent length. got: %d. expected %d", packetSize, len(b)))
|
||||
}
|
||||
n, _, err = c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr))
|
||||
// If the connection supports GSO, it's the caller's responsibility to append the right control mesage.
|
||||
func (c *oobConn) WritePacket(b []byte, addr net.Addr, oob []byte) (int, error) {
|
||||
n, _, err := c.OOBCapablePacketConn.WriteMsgUDP(b, oob, addr.(*net.UDPAddr))
|
||||
return n, err
|
||||
}
|
||||
|
||||
|
101
vendor/github.com/quic-go/quic-go/transport.go
generated
vendored
101
vendor/github.com/quic-go/quic-go/transport.go
generated
vendored
@ -7,12 +7,12 @@
|
||||
"errors"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/wire"
|
||||
|
||||
"github.com/quic-go/quic-go/internal/protocol"
|
||||
"github.com/quic-go/quic-go/internal/utils"
|
||||
"github.com/quic-go/quic-go/internal/wire"
|
||||
"github.com/quic-go/quic-go/logging"
|
||||
)
|
||||
|
||||
@ -85,6 +85,9 @@ type Transport struct {
|
||||
createdConn bool
|
||||
isSingleUse bool // was created for a single server or client, i.e. by calling quic.Listen or quic.Dial
|
||||
|
||||
readingNonQUICPackets atomic.Bool
|
||||
nonQUICPackets chan receivedPacket
|
||||
|
||||
logger utils.Logger
|
||||
}
|
||||
|
||||
@ -148,24 +151,15 @@ func (t *Transport) ListenEarly(tlsConf *tls.Config, conf *Config) (*EarlyListen
|
||||
|
||||
// Dial dials a new connection to a remote host (not using 0-RTT).
|
||||
func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) {
|
||||
if err := validateConfig(conf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conf = populateConfig(conf)
|
||||
if err := t.init(t.isSingleUse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var onClose func()
|
||||
if t.isSingleUse {
|
||||
onClose = func() { t.Close() }
|
||||
}
|
||||
tlsConf = tlsConf.Clone()
|
||||
tlsConf.MinVersion = tls.VersionTLS13
|
||||
return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, false)
|
||||
return t.dial(ctx, addr, "", tlsConf, conf, false)
|
||||
}
|
||||
|
||||
// DialEarly dials a new connection, attempting to use 0-RTT if possible.
|
||||
func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) {
|
||||
return t.dial(ctx, addr, "", tlsConf, conf, true)
|
||||
}
|
||||
|
||||
func (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) {
|
||||
if err := validateConfig(conf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -179,7 +173,8 @@ func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.C
|
||||
}
|
||||
tlsConf = tlsConf.Clone()
|
||||
tlsConf.MinVersion = tls.VersionTLS13
|
||||
return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, true)
|
||||
setTLSConfigServerName(tlsConf, addr, host)
|
||||
return dial(ctx, newSendConn(t.conn, addr, packetInfo{}, utils.DefaultLogger), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT)
|
||||
}
|
||||
|
||||
func (t *Transport) init(allowZeroLengthConnIDs bool) error {
|
||||
@ -195,7 +190,6 @@ func (t *Transport) init(allowZeroLengthConnIDs bool) error {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.conn = conn
|
||||
|
||||
t.logger = utils.DefaultLogger // TODO: make this configurable
|
||||
t.conn = conn
|
||||
@ -229,7 +223,7 @@ func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||
if err := t.init(false); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return t.conn.WritePacket(b, uint16(len(b)), addr, nil)
|
||||
return t.conn.WritePacket(b, addr, nil)
|
||||
}
|
||||
|
||||
func (t *Transport) enqueueClosePacket(p closePacket) {
|
||||
@ -247,7 +241,7 @@ func (t *Transport) runSendQueue() {
|
||||
case <-t.listening:
|
||||
return
|
||||
case p := <-t.closeQueue:
|
||||
t.conn.WritePacket(p.payload, uint16(len(p.payload)), p.addr, p.info.OOB())
|
||||
t.conn.WritePacket(p.payload, p.addr, p.info.OOB())
|
||||
case p := <-t.statelessResetQueue:
|
||||
t.sendStatelessReset(p)
|
||||
}
|
||||
@ -342,6 +336,13 @@ func (t *Transport) listen(conn rawConn) {
|
||||
}
|
||||
|
||||
func (t *Transport) handlePacket(p receivedPacket) {
|
||||
if len(p.data) == 0 {
|
||||
return
|
||||
}
|
||||
if !wire.IsPotentialQUICPacket(p.data[0]) && !wire.IsLongHeaderPacket(p.data[0]) {
|
||||
t.handleNonQUICPacket(p)
|
||||
return
|
||||
}
|
||||
connID, err := wire.ParseConnectionID(p.data, t.connIDLen)
|
||||
if err != nil {
|
||||
t.logger.Debugf("error parsing connection ID on packet from %s: %s", p.remoteAddr, err)
|
||||
@ -408,7 +409,7 @@ func (t *Transport) sendStatelessReset(p receivedPacket) {
|
||||
rand.Read(data)
|
||||
data[0] = (data[0] & 0x7f) | 0x40
|
||||
data = append(data, token[:]...)
|
||||
if _, err := t.conn.WritePacket(data, uint16(len(data)), p.remoteAddr, p.info.OOB()); err != nil {
|
||||
if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB()); err != nil {
|
||||
t.logger.Debugf("Error sending Stateless Reset to %s: %s", p.remoteAddr, err)
|
||||
}
|
||||
}
|
||||
@ -430,3 +431,61 @@ func (t *Transport) maybeHandleStatelessReset(data []byte) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *Transport) handleNonQUICPacket(p receivedPacket) {
|
||||
// Strictly speaking, this is racy,
|
||||
// but we only care about receiving packets at some point after ReadNonQUICPacket has been called.
|
||||
if !t.readingNonQUICPackets.Load() {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case t.nonQUICPackets <- p:
|
||||
default:
|
||||
if t.Tracer != nil {
|
||||
t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const maxQueuedNonQUICPackets = 32
|
||||
|
||||
// ReadNonQUICPacket reads non-QUIC packets received on the underlying connection.
|
||||
// The detection logic is very simple: Any packet that has the first and second bit of the packet set to 0.
|
||||
// Note that this is stricter than the detection logic defined in RFC 9443.
|
||||
func (t *Transport) ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.Addr, error) {
|
||||
if err := t.init(false); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if !t.readingNonQUICPackets.Load() {
|
||||
t.nonQUICPackets = make(chan receivedPacket, maxQueuedNonQUICPackets)
|
||||
t.readingNonQUICPackets.Store(true)
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return 0, nil, ctx.Err()
|
||||
case p := <-t.nonQUICPackets:
|
||||
n := copy(b, p.data)
|
||||
return n, p.remoteAddr, nil
|
||||
case <-t.listening:
|
||||
return 0, nil, errors.New("closed")
|
||||
}
|
||||
}
|
||||
|
||||
func setTLSConfigServerName(tlsConf *tls.Config, addr net.Addr, host string) {
|
||||
// If no ServerName is set, infer the ServerName from the host we're connecting to.
|
||||
if tlsConf.ServerName != "" {
|
||||
return
|
||||
}
|
||||
if host == "" {
|
||||
if udpAddr, ok := addr.(*net.UDPAddr); ok {
|
||||
tlsConf.ServerName = udpAddr.IP.String()
|
||||
return
|
||||
}
|
||||
}
|
||||
h, _, err := net.SplitHostPort(host)
|
||||
if err != nil { // This happens if the host doesn't contain a port number.
|
||||
tlsConf.ServerName = host
|
||||
return
|
||||
}
|
||||
tlsConf.ServerName = h
|
||||
}
|
||||
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@ -106,10 +106,10 @@ github.com/powerman/deepequal
|
||||
# github.com/quic-go/qpack v0.4.0
|
||||
## explicit; go 1.18
|
||||
github.com/quic-go/qpack
|
||||
# github.com/quic-go/qtls-go1-20 v0.3.1
|
||||
# github.com/quic-go/qtls-go1-20 v0.3.3
|
||||
## explicit; go 1.20
|
||||
github.com/quic-go/qtls-go1-20
|
||||
# github.com/quic-go/quic-go v0.37.4
|
||||
# github.com/quic-go/quic-go v0.38.1
|
||||
## explicit; go 1.20
|
||||
github.com/quic-go/quic-go
|
||||
github.com/quic-go/quic-go/http3
|
||||
|
Loading…
Reference in New Issue
Block a user