impl: uquic with utls

This commit is contained in:
Gaukas Wang 2023-07-29 23:45:16 -06:00
parent 251b3afe6e
commit fca46117e4
No known key found for this signature in database
GPG key ID: 9E2F8986D76F8B5D
56 changed files with 445 additions and 88 deletions

View file

@ -2,10 +2,11 @@ package quic
import (
"context"
"crypto/tls"
"errors"
"net"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/utils"
"github.com/quic-go/quic-go/logging"
@ -37,6 +38,8 @@ type client struct {
tracer logging.ConnectionTracer
tracingID uint64
logger utils.Logger
chs *tls.ClientHelloSpec // [UQUIC]
}
// make it possible to mock connection ID for initial generation in the tests
@ -157,6 +160,42 @@ func dial(
if c.tracer != nil {
c.tracer.StartedConnection(c.sendConn.LocalAddr(), c.sendConn.RemoteAddr(), c.srcConnID, c.destConnID)
}
if err := c.dial(ctx); err != nil {
return nil, err
}
return c.conn, nil
}
func dialWithCHS(
ctx context.Context,
conn sendConn,
connIDGenerator ConnectionIDGenerator,
packetHandlers packetHandlerManager,
tlsConf *tls.Config,
config *Config,
onClose func(),
use0RTT bool,
chs *tls.ClientHelloSpec,
) (quicConn, error) {
c, err := newClient(conn, connIDGenerator, config, tlsConf, onClose, use0RTT)
if err != nil {
return nil, err
}
c.packetHandlers = packetHandlers
c.tracingID = nextConnTracingID()
if c.config.Tracer != nil {
c.tracer = c.config.Tracer(context.WithValue(ctx, ConnectionTracingKey, c.tracingID), protocol.PerspectiveClient, c.destConnID)
}
if c.tracer != nil {
c.tracer.StartedConnection(c.sendConn.LocalAddr(), c.sendConn.RemoteAddr(), c.srcConnID, c.destConnID)
}
// [UQUIC]
c.chs = chs
// [/UQUIC]
if err := c.dial(ctx); err != nil {
return nil, err
}
@ -213,22 +252,46 @@ func newClient(sendConn sendConn, connIDGenerator ConnectionIDGenerator, config
func (c *client) dial(ctx context.Context) error {
c.logger.Infof("Starting new connection to %s (%s -> %s), source connection ID %s, destination connection ID %s, version %s", c.tlsConf.ServerName, c.sendConn.LocalAddr(), c.sendConn.RemoteAddr(), c.srcConnID, c.destConnID, c.version)
c.conn = newClientConnection(
c.sendConn,
c.packetHandlers,
c.destConnID,
c.srcConnID,
c.connIDGenerator,
c.config,
c.tlsConf,
c.initialPacketNumber,
c.use0RTT,
c.hasNegotiatedVersion,
c.tracer,
c.tracingID,
c.logger,
c.version,
)
// [UQUIC]
if c.chs == nil {
c.conn = newClientConnection(
c.sendConn,
c.packetHandlers,
c.destConnID,
c.srcConnID,
c.connIDGenerator,
c.config,
c.tlsConf,
c.initialPacketNumber,
c.use0RTT,
c.hasNegotiatedVersion,
c.tracer,
c.tracingID,
c.logger,
c.version,
)
} else {
// [UQUIC]: use custom version of the connection
c.conn = newUClientConnection(
c.sendConn,
c.packetHandlers,
c.destConnID,
c.srcConnID,
c.connIDGenerator,
c.config,
c.tlsConf,
c.initialPacketNumber,
c.use0RTT,
c.hasNegotiatedVersion,
c.tracer,
c.tracingID,
c.logger,
c.version,
c.chs,
)
}
// [/UQUIC]
c.packetHandlers.Add(c.srcConnID, c.conn)
errorChan := make(chan error, 1)

View file

@ -2,11 +2,12 @@ package quic
import (
"context"
"crypto/tls"
"errors"
"net"
"time"
tls "github.com/refraction-networking/utls"
mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/utils"

View file

@ -3,7 +3,6 @@ package quic
import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
@ -13,6 +12,8 @@ import (
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/ackhandler"
"github.com/quic-go/quic-go/internal/flowcontrol"
"github.com/quic-go/quic-go/internal/handshake"
@ -442,6 +443,138 @@ var newClientConnection = func(
logger,
s.version,
)
s.cryptoStreamHandler = cs
s.cryptoStreamManager = newCryptoStreamManager(cs, s.initialStream, s.handshakeStream, oneRTTStream)
s.unpacker = newPacketUnpacker(cs, s.srcConnIDLen)
s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, s.receivedPacketHandler, s.datagramQueue, s.perspective)
if len(tlsConf.ServerName) > 0 {
s.tokenStoreKey = tlsConf.ServerName
} else {
s.tokenStoreKey = conn.RemoteAddr().String()
}
if s.config.TokenStore != nil {
if token := s.config.TokenStore.Pop(s.tokenStoreKey); token != nil {
s.packer.SetToken(token.data)
}
}
return s
}
// [UQUIC]
var newUClientConnection = func(
conn sendConn,
runner connRunner,
destConnID protocol.ConnectionID,
srcConnID protocol.ConnectionID,
connIDGenerator ConnectionIDGenerator,
conf *Config,
tlsConf *tls.Config,
initialPacketNumber protocol.PacketNumber,
enable0RTT bool,
hasNegotiatedVersion bool,
tracer logging.ConnectionTracer,
tracingID uint64,
logger utils.Logger,
v protocol.VersionNumber,
chs *tls.ClientHelloSpec,
) quicConn {
s := &connection{
conn: conn,
config: conf,
origDestConnID: destConnID,
handshakeDestConnID: destConnID,
srcConnIDLen: srcConnID.Len(),
perspective: protocol.PerspectiveClient,
logID: destConnID.String(),
logger: logger,
tracer: tracer,
versionNegotiated: hasNegotiatedVersion,
version: v,
}
s.connIDManager = newConnIDManager(
destConnID,
func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) },
runner.RemoveResetToken,
s.queueControlFrame,
)
s.connIDGenerator = newConnIDGenerator(
srcConnID,
nil,
func(connID protocol.ConnectionID) { runner.Add(connID, s) },
runner.GetStatelessResetToken,
runner.Remove,
runner.Retire,
runner.ReplaceWithClosed,
s.queueControlFrame,
connIDGenerator,
)
s.preSetup()
s.ctx, s.ctxCancel = context.WithCancelCause(context.WithValue(context.Background(), ConnectionTracingKey, tracingID))
s.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler(
initialPacketNumber,
getMaxPacketSize(s.conn.RemoteAddr()),
s.rttStats,
false, /* has no effect */
s.perspective,
s.tracer,
s.logger,
)
if conf.InitPacketNumberLength != 0 {
ackhandler.SetInitialPacketNumberLength(s.sentPacketHandler, conf.InitPacketNumberLength)
}
s.mtuDiscoverer = newMTUDiscoverer(s.rttStats, getMaxPacketSize(s.conn.RemoteAddr()), s.sentPacketHandler.SetMaxDatagramSize)
oneRTTStream := newCryptoStream()
var params *wire.TransportParameters
if s.config.TransportParameters != nil {
params = &wire.TransportParameters{
InitialSourceConnectionID: srcConnID,
}
params.PopulateFromUQUIC(s.config.TransportParameters)
s.connIDManager.SetConnectionIDLimit(params.ActiveConnectionIDLimit)
} else {
params = &wire.TransportParameters{
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamReceiveWindow),
InitialMaxData: protocol.ByteCount(s.config.InitialConnectionReceiveWindow),
MaxIdleTimeout: s.config.MaxIdleTimeout,
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams),
MaxAckDelay: protocol.MaxAckDelayInclGranularity,
AckDelayExponent: protocol.AckDelayExponent,
DisableActiveMigration: true,
// For interoperability with quic-go versions before May 2023, this value must be set to a value
// different from protocol.DefaultActiveConnectionIDLimit.
// If set to the default value, it will be omitted from the transport parameters, which will make
// old quic-go versions interpret it as 0, instead of the default value of 2.
// See https://github.com/quic-go/quic-go/pull/3806.
ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs,
InitialSourceConnectionID: srcConnID,
}
if s.config.EnableDatagrams {
params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize
} else {
params.MaxDatagramFrameSize = protocol.InvalidByteCount
}
}
if s.tracer != nil {
s.tracer.SentTransportParameters(params)
}
cs := handshake.NewUCryptoSetupClient(
destConnID,
params,
tlsConf,
enable0RTT,
s.rttStats,
tracer,
logger,
s.version,
chs,
)
s.cryptoStreamHandler = cs
s.cryptoStreamManager = newCryptoStreamManager(cs, s.initialStream, s.handshakeStream, oneRTTStream)
s.unpacker = newPacketUnpacker(cs, s.srcConnIDLen)

View file

@ -4,7 +4,6 @@ import (
"bytes"
"context"
"crypto/rand"
"crypto/tls"
"errors"
"fmt"
"io"
@ -13,6 +12,8 @@ import (
"strings"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/ackhandler"
"github.com/quic-go/quic-go/internal/handshake"
"github.com/quic-go/quic-go/internal/mocks"

View file

@ -4,7 +4,6 @@ import (
"bufio"
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
@ -14,6 +13,8 @@ import (
"os"
"sync"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3"
"github.com/quic-go/quic-go/internal/testdata"

View file

@ -4,7 +4,6 @@ import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
@ -12,6 +11,8 @@ import (
"log"
"math/big"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
)

View file

@ -1,9 +1,10 @@
package main
import (
"crypto/tls"
"log"
tls "github.com/refraction-networking/utls"
fuzzhandshake "github.com/quic-go/quic-go/fuzzing/handshake"
"github.com/quic-go/quic-go/fuzzing/internal/helper"
"github.com/quic-go/quic-go/internal/handshake"

View file

@ -3,7 +3,6 @@ package handshake
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
@ -13,6 +12,8 @@ import (
mrand "math/rand"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/fuzzing/internal/helper"
"github.com/quic-go/quic-go/internal/handshake"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -4,7 +4,6 @@ import (
"crypto"
"crypto/rand"
"crypto/sha1"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
@ -12,6 +11,8 @@ import (
"os"
"path/filepath"
"time"
tls "github.com/refraction-networking/utls"
)
// NthBit gets the n-th bit of a byte (counting starts at 0).

14
go.mod
View file

@ -2,6 +2,8 @@ module github.com/quic-go/quic-go
go 1.20
replace github.com/refraction-networking/utls => ../utls
require (
github.com/francoispqt/gojay v1.2.13
github.com/golang/mock v1.6.0
@ -9,20 +11,24 @@ require (
github.com/onsi/gomega v1.27.6
github.com/quic-go/qpack v0.4.0
github.com/quic-go/qtls-go1-20 v0.3.0
golang.org/x/crypto v0.4.0
github.com/refraction-networking/utls v0.0.0-00010101000000-000000000000
golang.org/x/crypto v0.10.0
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
golang.org/x/net v0.10.0
golang.org/x/net v0.11.0
golang.org/x/sync v0.2.0
golang.org/x/sys v0.8.0
golang.org/x/sys v0.9.0
)
require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/gaukas/godicttls v0.0.3 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/klauspost/compress v1.16.6 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/tools v0.9.1 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

22
go.sum
View file

@ -8,6 +8,8 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
@ -25,6 +27,8 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk=
github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@ -62,6 +66,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -133,8 +139,8 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
@ -155,8 +161,8 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -180,14 +186,14 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View file

@ -2,7 +2,6 @@ package http3
import (
"context"
"crypto/tls"
"errors"
"fmt"
"io"
@ -13,6 +12,10 @@ import (
"sync/atomic"
"time"
ctls "crypto/tls"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/utils"
@ -424,7 +427,25 @@ func (c *client) doRequest(req *http.Request, conn quic.EarlyConnection, str qui
return nil, newStreamError(ErrCodeMessageError, err)
}
connState := conn.ConnectionState().TLS
res.TLS = &connState
// [UQUIC] copy utls.ConnectionState to crypto/tls.ConnectionState
cryptoConnState := &ctls.ConnectionState{
Version: connState.Version,
HandshakeComplete: connState.HandshakeComplete,
DidResume: connState.DidResume,
CipherSuite: connState.CipherSuite,
NegotiatedProtocol: connState.NegotiatedProtocol,
NegotiatedProtocolIsMutual: connState.NegotiatedProtocolIsMutual,
ServerName: connState.ServerName,
PeerCertificates: connState.PeerCertificates,
VerifiedChains: connState.VerifiedChains,
SignedCertificateTimestamps: connState.SignedCertificateTimestamps,
OCSPResponse: connState.OCSPResponse,
TLSUnique: connState.TLSUnique,
}
res.TLS = cryptoConnState
// [/UQUIC]
res.Request = req
// Check that the server doesn't send more data in DATA frames than indicated by the Content-Length header (if set).
// See section 4.1.2 of RFC 9114.

View file

@ -4,7 +4,6 @@ import (
"bytes"
"compress/gzip"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
@ -12,6 +11,8 @@ import (
"sync"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
mockquic "github.com/quic-go/quic-go/internal/mocks/quic"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -2,7 +2,6 @@ package http3
import (
"context"
"crypto/tls"
"errors"
"fmt"
"io"
@ -12,6 +11,8 @@ import (
"sync"
"sync/atomic"
tls "github.com/refraction-networking/utls"
"golang.org/x/net/http/httpguts"
"github.com/quic-go/quic-go"
@ -87,6 +88,9 @@ type RoundTripper struct {
newClient func(hostname string, tlsConf *tls.Config, opts *roundTripperOpts, conf *quic.Config, dialer dialFunc) (roundTripCloser, error) // so we can mock it in tests
clients map[string]*roundTripCloserWithCount
transport *quic.Transport
// [UQUIC]
ClientHelloSpec *tls.ClientHelloSpec
}
// RoundTripOpt are options for the Transport.RoundTripOpt method.
@ -189,7 +193,10 @@ func (r *RoundTripper) getClient(hostname string, onlyCached bool) (rtc *roundTr
if err != nil {
return nil, false, err
}
r.transport = &quic.Transport{Conn: udpConn}
r.transport = &quic.Transport{
Conn: udpConn,
ClientHelloSpec: r.ClientHelloSpec,
}
}
dial = r.makeDialer()
}

View file

@ -3,13 +3,14 @@ package http3
import (
"bytes"
"context"
"crypto/tls"
"errors"
"io"
"net/http"
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/internal/qerr"

View file

@ -2,7 +2,7 @@ package http3
import (
"context"
"crypto/tls"
ctls "crypto/tls"
"errors"
"fmt"
"io"
@ -13,6 +13,8 @@ import (
"sync"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/utils"
@ -577,7 +579,25 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q
}
connState := conn.ConnectionState().TLS
req.TLS = &connState
// [UQUIC] copy utls.ConnectionState to crypto/tls.ConnectionState
cryptoConnState := &ctls.ConnectionState{
Version: connState.Version,
HandshakeComplete: connState.HandshakeComplete,
DidResume: connState.DidResume,
CipherSuite: connState.CipherSuite,
NegotiatedProtocol: connState.NegotiatedProtocol,
NegotiatedProtocolIsMutual: connState.NegotiatedProtocolIsMutual,
ServerName: connState.ServerName,
PeerCertificates: connState.PeerCertificates,
VerifiedChains: connState.VerifiedChains,
SignedCertificateTimestamps: connState.SignedCertificateTimestamps,
OCSPResponse: connState.OCSPResponse,
TLSUnique: connState.TLSUnique,
}
req.TLS = cryptoConnState
// [/UQUIC]
req.RemoteAddr = conn.RemoteAddr().String()
// Check that the client doesn't send more data in DATA frames than indicated by the Content-Length header (if set).

View file

@ -3,7 +3,6 @@ package http3
import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
@ -13,6 +12,8 @@ import (
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
mockquic "github.com/quic-go/quic-go/internal/mocks/quic"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -2,7 +2,6 @@ package self_test
import (
"context"
"crypto/tls"
"fmt"
"io"
mrand "math/rand"
@ -11,6 +10,8 @@ import (
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/quicvarint"
"github.com/quic-go/quic-go"

View file

@ -2,12 +2,13 @@ package self_test
import (
"context"
"crypto/tls"
"fmt"
"io"
"net"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
quicproxy "github.com/quic-go/quic-go/integrationtests/tools/proxy"

View file

@ -2,13 +2,14 @@ package self_test
import (
"context"
"crypto/tls"
"errors"
"fmt"
"io"
"net"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/qerr"

View file

@ -2,11 +2,12 @@ package self_test
import (
"context"
"crypto/tls"
"fmt"
"net"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
. "github.com/onsi/ginkgo/v2"

View file

@ -3,7 +3,6 @@ package self_test
import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
@ -16,6 +15,8 @@ import (
"testing"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/integrationtests/tools"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -4,7 +4,6 @@ package self_test
import (
"context"
"crypto/tls"
"fmt"
"io"
mrand "math/rand"
@ -13,6 +12,8 @@ import (
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
quicproxy "github.com/quic-go/quic-go/integrationtests/tools/proxy"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -4,8 +4,8 @@ package self_test
import (
"context"
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"io"
mrand "math/rand"
"net"

View file

@ -5,12 +5,13 @@ import (
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"net"
"time"
tls "github.com/refraction-networking/utls"
)
const ALPN = "quic-go integration tests"

View file

@ -2,10 +2,11 @@ package versionnegotiation
import (
"context"
"crypto/tls"
"fmt"
"net"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/integrationtests/tools/israce"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -2,11 +2,12 @@ package versionnegotiation
import (
"context"
"crypto/tls"
"crypto/x509"
"flag"
"testing"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/integrationtests/tools"
"github.com/quic-go/quic-go/logging"

View file

@ -2,12 +2,13 @@ package quic
import (
"context"
"crypto/tls"
"errors"
"io"
"net"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/handshake"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/logging"

View file

@ -5,9 +5,10 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
. "github.com/onsi/ginkgo/v2"

View file

@ -4,9 +4,10 @@ import (
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"golang.org/x/crypto/chacha20poly1305"
)

View file

@ -3,13 +3,14 @@ package handshake
import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"sync"
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/qerr"
"github.com/quic-go/quic-go/internal/qtls"
@ -101,6 +102,41 @@ func NewCryptoSetupClient(
return cs
}
// [UQUIC]
// NewUCryptoSetupClient creates a new crypto setup for the client with UTLS
func NewUCryptoSetupClient(
connID protocol.ConnectionID,
tp *wire.TransportParameters,
tlsConf *tls.Config,
enable0RTT bool,
rttStats *utils.RTTStats,
tracer logging.ConnectionTracer,
logger utils.Logger,
version protocol.VersionNumber,
chs *tls.ClientHelloSpec,
) CryptoSetup {
cs := newCryptoSetup(
connID,
tp,
rttStats,
tracer,
logger,
protocol.PerspectiveClient,
version,
)
tlsConf = tlsConf.Clone()
tlsConf.MinVersion = tls.VersionTLS13
quicConf := &qtls.QUICConfig{TLSConfig: tlsConf}
qtls.SetupConfigForClient(quicConf, cs.marshalDataForSessionState, cs.handleDataFromSessionState)
cs.tlsConf = tlsConf
cs.conn = qtls.UQUICClient(quicConf, chs)
cs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient))
return cs
}
// NewCryptoSetupServer creates a new crypto setup for the server
func NewCryptoSetupServer(
connID protocol.ConnectionID,

View file

@ -3,12 +3,13 @@ package handshake
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"time"
tls "github.com/refraction-networking/utls"
mocktls "github.com/quic-go/quic-go/internal/mocks/tls"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/qerr"

View file

@ -1,11 +1,12 @@
package handshake
import (
"crypto/tls"
"encoding/hex"
"strings"
"testing"
tls "github.com/refraction-networking/utls"
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo/v2"

View file

@ -3,10 +3,11 @@ package handshake
import (
"crypto/aes"
"crypto/cipher"
"crypto/tls"
"encoding/binary"
"fmt"
tls "github.com/refraction-networking/utls"
"golang.org/x/crypto/chacha20"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -2,7 +2,8 @@ package handshake
import (
"crypto"
"crypto/tls"
tls "github.com/refraction-networking/utls"
"golang.org/x/crypto/hkdf"

View file

@ -1,11 +1,12 @@
package handshake
import (
"crypto/tls"
"errors"
"io"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/wire"
)

View file

@ -3,11 +3,12 @@ package handshake
import (
"crypto"
"crypto/cipher"
"crypto/tls"
"encoding/binary"
"fmt"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/qerr"
"github.com/quic-go/quic-go/internal/utils"

View file

@ -2,11 +2,12 @@ package handshake
import (
"crypto/rand"
"crypto/tls"
"fmt"
"testing"
"time"
tls "github.com/refraction-networking/utls"
mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/qerr"

View file

@ -5,7 +5,7 @@
package mocktls
import (
tls "crypto/tls"
tls "github.com/refraction-networking/utls"
reflect "reflect"
gomock "github.com/golang/mock/gomock"

View file

@ -5,8 +5,8 @@ package qtls
import (
"crypto"
"crypto/cipher"
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"unsafe"
)

View file

@ -3,8 +3,8 @@
package qtls
import (
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"net"
"github.com/quic-go/quic-go/internal/testdata"

View file

@ -3,7 +3,7 @@
package qtls
import (
"crypto/tls"
tls "github.com/refraction-networking/utls"
)
type clientSessionCache struct {

View file

@ -3,8 +3,8 @@
package qtls
import (
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"net"
"github.com/quic-go/quic-go/internal/testdata"

View file

@ -3,10 +3,11 @@
package qtls
import (
"crypto/tls"
"fmt"
"unsafe"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/qtls-go1-20"

View file

@ -4,14 +4,14 @@ package qtls
import (
"bytes"
"crypto/tls"
"fmt"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"
)
type (
QUICConn = tls.QUICConn
QUICConn = tls.UQUICConn // [UQUIC]
QUICConfig = tls.QUICConfig
QUICEvent = tls.QUICEvent
QUICEventKind = tls.QUICEventKind
@ -37,8 +37,21 @@ const (
QUICHandshakeDone = tls.QUICHandshakeDone
)
func QUICServer(config *QUICConfig) *QUICConn { return tls.QUICServer(config) }
func QUICClient(config *QUICConfig) *QUICConn { return tls.QUICClient(config) }
func QUICServer(config *QUICConfig) *QUICConn { return nil } // [UQUIC]
// [UQUIC]
func QUICClient(config *QUICConfig) *QUICConn {
return tls.UQUICClient(config, tls.HelloGolang)
}
// [UQUIC]
func UQUICClient(config *QUICConfig, clientHelloSpec *tls.ClientHelloSpec) *QUICConn {
uqc := tls.UQUICClient(config, tls.HelloCustom)
if err := uqc.ApplyPreset(clientHelloSpec); err != nil {
panic(err)
}
return uqc
}
func SetupConfigForServer(qconf *QUICConfig, _ bool, getData func() []byte, accept0RTT func([]byte) bool) {
conf := qconf.TLSConfig

View file

@ -3,7 +3,7 @@
package qtls
import (
"crypto/tls"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -1,11 +1,12 @@
package testdata
import (
"crypto/tls"
"crypto/x509"
"os"
"path"
"runtime"
tls "github.com/refraction-networking/utls"
)
var certPath string

View file

@ -1,9 +1,10 @@
package testdata
import (
"crypto/tls"
"io"
tls "github.com/refraction-networking/utls"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View file

@ -1,7 +1,6 @@
package main
import (
"crypto/tls"
"errors"
"flag"
"fmt"
@ -12,6 +11,8 @@ import (
"strings"
"time"
tls "github.com/refraction-networking/utls"
"golang.org/x/sync/errgroup"
"github.com/quic-go/quic-go"

View file

@ -2,7 +2,6 @@ package http09
import (
"context"
"crypto/tls"
"errors"
"io"
"log"
@ -11,6 +10,8 @@ import (
"strings"
"sync"
tls "github.com/refraction-networking/utls"
"golang.org/x/net/idna"
"github.com/quic-go/quic-go"

View file

@ -1,13 +1,14 @@
package http09
import (
"crypto/tls"
"fmt"
"io"
"net"
"net/http"
"net/http/httptest"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/internal/testdata"

View file

@ -1,13 +1,14 @@
package main
import (
"crypto/tls"
"fmt"
"log"
"net"
"net/http"
"os"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go"
"github.com/quic-go/quic-go/http3"
"github.com/quic-go/quic-go/internal/qtls"

View file

@ -3,7 +3,6 @@ package quic
import (
"context"
"crypto/rand"
"crypto/tls"
"errors"
"fmt"
"net"
@ -11,6 +10,8 @@ import (
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/handshake"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/qerr"

View file

@ -3,7 +3,6 @@ package quic
import (
"context"
"crypto/rand"
"crypto/tls"
"errors"
"net"
"reflect"
@ -11,6 +10,8 @@ import (
"sync/atomic"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/handshake"
mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
"github.com/quic-go/quic-go/internal/protocol"

View file

@ -3,12 +3,13 @@ package quic
import (
"context"
"crypto/rand"
"crypto/tls"
"errors"
"net"
"sync"
"time"
tls "github.com/refraction-networking/utls"
"github.com/quic-go/quic-go/internal/wire"
"github.com/quic-go/quic-go/internal/protocol"
@ -86,6 +87,8 @@ type Transport struct {
isSingleUse bool // was created for a single server or client, i.e. by calling quic.Listen or quic.Dial
logger utils.Logger
ClientHelloSpec *tls.ClientHelloSpec // [UQUIC]
}
// Listen starts listening for incoming QUIC connections.
@ -157,6 +160,7 @@ func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config
if conf.SrcConnIDLength != 0 {
t.ConnectionIDGenerator = &protocol.DefaultConnectionIDGenerator{ConnLen: conf.SrcConnIDLength}
}
// [/UQUIC]
if err := t.init(t.isSingleUse); err != nil {
return nil, err
@ -167,6 +171,10 @@ func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config
}
tlsConf = tlsConf.Clone()
tlsConf.MinVersion = tls.VersionTLS13
if t.ClientHelloSpec != nil { // [UQUIC]
return dialWithCHS(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, false, t.ClientHelloSpec)
}
return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, false)
}
@ -181,6 +189,7 @@ func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.C
if conf.SrcConnIDLength != 0 {
t.ConnectionIDGenerator = &protocol.DefaultConnectionIDGenerator{ConnLen: conf.SrcConnIDLength}
}
// [/UQUIC]
if err := t.init(t.isSingleUse); err != nil {
return nil, err
@ -191,6 +200,10 @@ func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.C
}
tlsConf = tlsConf.Clone()
tlsConf.MinVersion = tls.VersionTLS13
if t.ClientHelloSpec != nil { // [UQUIC]
return dialWithCHS(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, false, t.ClientHelloSpec)
}
return dial(ctx, newSendConn(t.conn, addr), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, true)
}

View file

@ -3,12 +3,13 @@ package quic
import (
"bytes"
"crypto/rand"
"crypto/tls"
"errors"
"net"
"syscall"
"time"
tls "github.com/refraction-networking/utls"
mocklogging "github.com/quic-go/quic-go/internal/mocks/logging"
"github.com/quic-go/quic-go/internal/protocol"
"github.com/quic-go/quic-go/internal/wire"