chore: upgrade deps and attempt to enable using go1.19 (#869)
* upgrade to our go.mod enabled of psiphon-tunnel-core such that we're now using v2.0.24 of the tunnel-core; * upgrade to the latest lucas-clemente/quic-go release; * upgrade to the latest ooni/oohttp release (which is based on go1.19 but the diff seems good enough to continue using go1.18.x as well); * upgrade to the latest ooni/oocrypto release (for which we can make the same remarks regarding using go1.18.x); * deal with changes in lucas-clemente/quic-go API as well as changes in what a go1.19 *tls.Conn compatible type should look like. Unfortunately, we cannot switch to go1.19 because psiphon forks quic-go and their fork's still not building using such a version of go. Part of ooni/probe#2211.
This commit is contained in:
@@ -179,7 +179,7 @@ func (m *Measurer) quicHandshake(ctx context.Context, index int64,
|
||||
RootCAs: netxlite.NewDefaultCertPool(),
|
||||
ServerName: sni,
|
||||
}
|
||||
_, err := dialer.DialContext(ctx, "udp", address, tlsConfig, &quic.Config{})
|
||||
_, err := dialer.DialContext(ctx, address, tlsConfig, &quic.Config{})
|
||||
ol.Stop(err)
|
||||
sp.QUICHandshake = trace.FirstQUICHandshakeOrNil() // record the first handshake from the buffer
|
||||
sp.NetworkEvents = append(sp.NetworkEvents, trace.NetworkEvents()...)
|
||||
|
||||
@@ -423,7 +423,7 @@ func (mx *Measurer) QUICHandshakeWithDB(ctx context.Context, db WritableDB,
|
||||
defer cancel()
|
||||
qd := mx.NewQUICDialerWithoutResolver(db, mx.Logger)
|
||||
defer qd.CloseIdleConnections()
|
||||
qconn, err := qd.DialContext(ctx, "udp", address, config, &quic.Config{})
|
||||
qconn, err := qd.DialContext(ctx, address, config, &quic.Config{})
|
||||
ol.Stop(err)
|
||||
return qconn, err
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ type quicDialerDB struct {
|
||||
logger model.Logger
|
||||
}
|
||||
|
||||
func (qh *quicDialerDB) DialContext(ctx context.Context, network, address string,
|
||||
func (qh *quicDialerDB) DialContext(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
started := time.Since(qh.begin).Seconds()
|
||||
var state tls.ConnectionState
|
||||
@@ -116,7 +116,7 @@ func (qh *quicDialerDB) DialContext(ctx context.Context, network, address string
|
||||
}
|
||||
dialer := netxlite.NewQUICDialerWithoutResolver(listener, qh.logger)
|
||||
defer dialer.CloseIdleConnections()
|
||||
sess, err := dialer.DialContext(ctx, network, address, tlsConfig, quicConfig)
|
||||
sess, err := dialer.DialContext(ctx, address, tlsConfig, quicConfig)
|
||||
if err == nil {
|
||||
<-sess.HandshakeComplete().Done() // robustness (the dialer already does that)
|
||||
state = sess.ConnectionState().TLS.ConnectionState
|
||||
|
||||
@@ -32,10 +32,10 @@ type quicDialerTrace struct {
|
||||
var _ model.QUICDialer = &quicDialerTrace{}
|
||||
|
||||
// DialContext implements model.QUICDialer.DialContext.
|
||||
func (qdx *quicDialerTrace) DialContext(ctx context.Context, network string,
|
||||
func (qdx *quicDialerTrace) DialContext(ctx context.Context,
|
||||
address string, tlsConfig *tls.Config, quicConfig *quic.Config) (
|
||||
quic.EarlyConnection, error) {
|
||||
return qdx.qd.DialContext(netxlite.ContextWithTrace(ctx, qdx.tx), network, address, tlsConfig, quicConfig)
|
||||
return qdx.qd.DialContext(netxlite.ContextWithTrace(ctx, qdx.tx), address, tlsConfig, quicConfig)
|
||||
}
|
||||
|
||||
// CloseIdleConnections implements model.QUICDialer.CloseIdleConnections.
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestNewQUICDialerWithoutResolver(t *testing.T) {
|
||||
trace := NewTrace(0, zeroTime)
|
||||
var hasCorrectTrace bool
|
||||
underlying := &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string, tlsConfig *tls.Config,
|
||||
MockDialContext: func(ctx context.Context, address string, tlsConfig *tls.Config,
|
||||
quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
gotTrace := netxlite.ContextTraceOrDefault(ctx)
|
||||
hasCorrectTrace = (gotTrace == trace)
|
||||
@@ -55,7 +55,7 @@ func TestNewQUICDialerWithoutResolver(t *testing.T) {
|
||||
listener := &mocks.QUICListener{}
|
||||
dialer := trace.NewQUICDialerWithoutResolver(listener, model.DiscardLogger)
|
||||
ctx := context.Background()
|
||||
conn, err := dialer.DialContext(ctx, "udp", "1.1.1.1:443", &tls.Config{}, &quic.Config{})
|
||||
conn, err := dialer.DialContext(ctx, "1.1.1.1:443", &tls.Config{}, &quic.Config{})
|
||||
if !errors.Is(err, expectedErr) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func TestNewQUICDialerWithoutResolver(t *testing.T) {
|
||||
ServerName: "dns.cloudflare.com",
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := dialer.DialContext(ctx, "udp", "1.1.1.1:443", tlsConfig, &quic.Config{})
|
||||
qconn, err := dialer.DialContext(ctx, "1.1.1.1:443", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, mockedErr) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
@@ -231,7 +231,7 @@ func TestNewQUICDialerWithoutResolver(t *testing.T) {
|
||||
ServerName: "dns.cloudflare.com",
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := dialer.DialContext(ctx, "udp", "1.1.1.1:443", tlsConfig, &quic.Config{})
|
||||
qconn, err := dialer.DialContext(ctx, "1.1.1.1:443", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, mockedErr) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ func TestTrace(t *testing.T) {
|
||||
tx := &Trace{
|
||||
NewQUICDialerWithoutResolverFn: func(listener model.QUICListener, dl model.DebugLogger) model.QUICDialer {
|
||||
return &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return nil, mockedErr
|
||||
},
|
||||
@@ -422,7 +422,7 @@ func TestTrace(t *testing.T) {
|
||||
}
|
||||
qdx := tx.newQUICDialerWithoutResolver(&mocks.QUICListener{}, model.DiscardLogger)
|
||||
ctx := context.Background()
|
||||
qconn, err := qdx.DialContext(ctx, "udp", "1.1.1.1:443", &tls.Config{}, &quic.Config{})
|
||||
qconn, err := qdx.DialContext(ctx, "1.1.1.1:443", &tls.Config{}, &quic.Config{})
|
||||
if !errors.Is(err, mockedErr) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
@@ -464,7 +464,7 @@ func TestTrace(t *testing.T) {
|
||||
}
|
||||
dialer := tx.newQUICDialerWithoutResolver(listener, model.DiscardLogger)
|
||||
ctx := context.Background()
|
||||
qconn, err := dialer.DialContext(ctx, "udp", "1.1.1.1:443", tlsConfig, &quic.Config{})
|
||||
qconn, err := dialer.DialContext(ctx, "1.1.1.1:443", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, mockedErr) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
|
||||
@@ -24,17 +24,19 @@ func (ql *QUICListener) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) {
|
||||
// QUICDialer is a mockable netxlite.QUICDialer.
|
||||
type QUICDialer struct {
|
||||
// MockDialContext allows mocking DialContext.
|
||||
MockDialContext func(ctx context.Context, network, address string,
|
||||
MockDialContext func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error)
|
||||
|
||||
// MockCloseIdleConnections allows mocking CloseIdleConnections.
|
||||
MockCloseIdleConnections func()
|
||||
}
|
||||
|
||||
var _ model.QUICDialer = &QUICDialer{}
|
||||
|
||||
// DialContext calls MockDialContext.
|
||||
func (qcd *QUICDialer) DialContext(ctx context.Context, network, address string,
|
||||
func (qcd *QUICDialer) DialContext(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return qcd.MockDialContext(ctx, network, address, tlsConfig, quicConfig)
|
||||
return qcd.MockDialContext(ctx, address, tlsConfig, quicConfig)
|
||||
}
|
||||
|
||||
// CloseIdleConnections calls MockCloseIdleConnections.
|
||||
|
||||
@@ -37,14 +37,14 @@ func TestQUICDialer(t *testing.T) {
|
||||
t.Run("DialContext", func(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
qcd := &QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network string, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
MockDialContext: func(ctx context.Context, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return nil, expected
|
||||
},
|
||||
}
|
||||
ctx := context.Background()
|
||||
tlsConfig := &tls.Config{}
|
||||
quicConfig := &quic.Config{}
|
||||
qconn, err := qcd.DialContext(ctx, "udp", "dns.google:443", tlsConfig, quicConfig)
|
||||
qconn, err := qcd.DialContext(ctx, "dns.google:443", tlsConfig, quicConfig)
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected")
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ type TLSConn struct {
|
||||
|
||||
// MockHandshakeContext allows to mock the HandshakeContext method.
|
||||
MockHandshakeContext func(ctx context.Context) error
|
||||
|
||||
// MockNetConn returns the underlying net.Conn
|
||||
MockNetConn func() net.Conn
|
||||
}
|
||||
|
||||
// ConnectionState calls MockConnectionState.
|
||||
@@ -40,6 +43,11 @@ func (c *TLSConn) HandshakeContext(ctx context.Context) error {
|
||||
return c.MockHandshakeContext(ctx)
|
||||
}
|
||||
|
||||
// NetConn calls MockNetConn.
|
||||
func (c *TLSConn) NetConn() net.Conn {
|
||||
return c.MockNetConn()
|
||||
}
|
||||
|
||||
// TLSDialer allows to mock netxlite.TLSDialer.
|
||||
type TLSDialer struct {
|
||||
// MockCloseIdleConnections allows to mock the CloseIdleConnections method.
|
||||
|
||||
@@ -60,6 +60,18 @@ func TestTLSConn(t *testing.T) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("NetConn", func(t *testing.T) {
|
||||
conn := &Conn{}
|
||||
c := &TLSConn{
|
||||
MockNetConn: func() net.Conn {
|
||||
return conn
|
||||
},
|
||||
}
|
||||
if o := c.NetConn(); o != conn {
|
||||
t.Fatal("unexpected result")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTLSDialer(t *testing.T) {
|
||||
|
||||
@@ -204,7 +204,7 @@ type QUICDialer interface {
|
||||
// - set NextProtos to []string{"h3"}.
|
||||
//
|
||||
// Typically, you want to pass `&quic.Config{}` as quicConfig.
|
||||
DialContext(ctx context.Context, network, address string,
|
||||
DialContext(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error)
|
||||
|
||||
// CloseIdleConnections closes idle connections, if any.
|
||||
|
||||
@@ -435,7 +435,7 @@ func TestMeasureWithQUICDialer(t *testing.T) {
|
||||
NextProtos: []string{"h3"},
|
||||
RootCAs: netxlite.NewDefaultCertPool(),
|
||||
}
|
||||
sess, err := d.DialContext(ctx, "udp", quictesting.Endpoint("443"), config, &quic.Config{})
|
||||
sess, err := d.DialContext(ctx, quictesting.Endpoint("443"), config, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -456,7 +456,7 @@ func TestMeasureWithQUICDialer(t *testing.T) {
|
||||
RootCAs: netxlite.NewDefaultCertPool(),
|
||||
}
|
||||
// Here we assume <target-address>:1 is filtered
|
||||
sess, err := d.DialContext(ctx, "udp", quictesting.Endpoint("1"), config, &quic.Config{})
|
||||
sess, err := d.DialContext(ctx, quictesting.Endpoint("1"), config, &quic.Config{})
|
||||
if err == nil || err.Error() != netxlite.FailureGenericTimeoutError {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
|
||||
+14
-14
@@ -122,7 +122,7 @@ func ParseUDPAddr(address string) (*net.UDPAddr, error) {
|
||||
//
|
||||
// 2. if tlsConfig.NextProtos is empty _and_ the port is 443 or 8853,
|
||||
// then we configure, respectively, "h3" and "dq".
|
||||
func (d *quicDialerQUICGo) DialContext(ctx context.Context, network string,
|
||||
func (d *quicDialerQUICGo) DialContext(ctx context.Context,
|
||||
address string, tlsConfig *tls.Config, quicConfig *quic.Config) (
|
||||
quic.EarlyConnection, error) {
|
||||
udpAddr, err := ParseUDPAddr(address)
|
||||
@@ -194,9 +194,9 @@ var _ model.QUICDialer = &quicDialerHandshakeCompleter{}
|
||||
|
||||
// DialContext implements model.QUICDialer.DialContext.
|
||||
func (d *quicDialerHandshakeCompleter) DialContext(
|
||||
ctx context.Context, network, address string,
|
||||
ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
conn, err := d.Dialer.DialContext(ctx, network, address, tlsConfig, quicConfig)
|
||||
conn, err := d.Dialer.DialContext(ctx, address, tlsConfig, quicConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -253,7 +253,7 @@ var _ model.QUICDialer = &quicDialerResolver{}
|
||||
// 1. if tlsConfig.ServerName is empty, we will use the hostname
|
||||
// contained inside of the `address` endpoint.
|
||||
func (d *quicDialerResolver) DialContext(
|
||||
ctx context.Context, network, address string,
|
||||
ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
onlyhost, onlyport, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
@@ -272,7 +272,7 @@ func (d *quicDialerResolver) DialContext(
|
||||
for _, addr := range addrs {
|
||||
target := net.JoinHostPort(addr, onlyport)
|
||||
qconn, err := d.Dialer.DialContext(
|
||||
ctx, network, target, tlsConfig, quicConfig)
|
||||
ctx, target, tlsConfig, quicConfig)
|
||||
if err == nil {
|
||||
return qconn, nil
|
||||
}
|
||||
@@ -325,16 +325,16 @@ var _ model.QUICDialer = &quicDialerLogger{}
|
||||
|
||||
// DialContext implements QUICContextDialer.DialContext.
|
||||
func (d *quicDialerLogger) DialContext(
|
||||
ctx context.Context, network, address string,
|
||||
ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
d.Logger.Debugf("quic_dial%s %s/%s...", d.operationSuffix, address, network)
|
||||
qconn, err := d.Dialer.DialContext(ctx, network, address, tlsConfig, quicConfig)
|
||||
d.Logger.Debugf("quic_dial%s %s/udp...", d.operationSuffix, address)
|
||||
qconn, err := d.Dialer.DialContext(ctx, address, tlsConfig, quicConfig)
|
||||
if err != nil {
|
||||
d.Logger.Debugf("quic_dial%s %s/%s... %s", d.operationSuffix,
|
||||
address, network, err)
|
||||
d.Logger.Debugf("quic_dial%s %s/udp... %s", d.operationSuffix,
|
||||
address, err)
|
||||
return nil, err
|
||||
}
|
||||
d.Logger.Debugf("quic_dial%s %s/%s... ok", d.operationSuffix, address, network)
|
||||
d.Logger.Debugf("quic_dial%s %s/udp... ok", d.operationSuffix, address)
|
||||
return qconn, nil
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ var _ model.QUICDialer = &quicDialerSingleUse{}
|
||||
|
||||
// DialContext implements QUICDialer.DialContext.
|
||||
func (s *quicDialerSingleUse) DialContext(
|
||||
ctx context.Context, network, addr string, tlsCfg *tls.Config,
|
||||
ctx context.Context, addr string, tlsCfg *tls.Config,
|
||||
cfg *quic.Config) (quic.EarlyConnection, error) {
|
||||
var qconn quic.EarlyConnection
|
||||
defer s.mu.Unlock()
|
||||
@@ -436,9 +436,9 @@ var _ model.QUICDialer = &quicDialerErrWrapper{}
|
||||
|
||||
// DialContext implements ContextDialer.DialContext
|
||||
func (d *quicDialerErrWrapper) DialContext(
|
||||
ctx context.Context, network string, host string,
|
||||
ctx context.Context, host string,
|
||||
tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
|
||||
qconn, err := d.QUICDialer.DialContext(ctx, network, host, tlsCfg, cfg)
|
||||
qconn, err := d.QUICDialer.DialContext(ctx, host, tlsCfg, cfg)
|
||||
if err != nil {
|
||||
return nil, NewErrWrapper(
|
||||
ClassifyQUICHandshakeError, QUICHandshakeOperation, err)
|
||||
|
||||
@@ -134,7 +134,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
defer systemdialer.CloseIdleConnections() // just to see it running
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "a.b.c.d", tlsConfig, &quic.Config{})
|
||||
ctx, "a.b.c.d", tlsConfig, &quic.Config{})
|
||||
if err == nil || !strings.HasSuffix(err.Error(), "missing port in address") {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -152,7 +152,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "8.8.4.4:xyz", tlsConfig, &quic.Config{})
|
||||
ctx, "8.8.4.4:xyz", tlsConfig, &quic.Config{})
|
||||
if err == nil || !strings.HasSuffix(err.Error(), "invalid syntax") {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -170,7 +170,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "a.b.c.d:0", tlsConfig, &quic.Config{})
|
||||
ctx, "a.b.c.d:0", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, ErrInvalidIP) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -193,7 +193,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
ctx, "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -212,7 +212,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel() // fail immediately
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
ctx, "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -238,7 +238,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
ctx, "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -279,7 +279,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "8.8.8.8:8853", tlsConfig, &quic.Config{})
|
||||
ctx, "8.8.8.8:8853", tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -318,7 +318,7 @@ func TestQUICDialerQUICGo(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := systemdialer.DialContext(
|
||||
ctx, "udp", "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
ctx, "8.8.8.8:443", tlsConfig, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -336,14 +336,14 @@ func TestQUICDialerHandshakeCompleter(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
d := &quicDialerHandshakeCompleter{
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return nil, expected
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := context.Background()
|
||||
conn, err := d.DialContext(ctx, "udp", "8.8.8.8:443", &tls.Config{}, &quic.Config{})
|
||||
conn, err := d.DialContext(ctx, "8.8.8.8:443", &tls.Config{}, &quic.Config{})
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
@@ -369,13 +369,13 @@ func TestQUICDialerHandshakeCompleter(t *testing.T) {
|
||||
}
|
||||
d := &quicDialerHandshakeCompleter{
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return expected, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
conn, err := d.DialContext(ctx, "udp", "8.8.8.8:443", &tls.Config{}, &quic.Config{})
|
||||
conn, err := d.DialContext(ctx, "8.8.8.8:443", &tls.Config{}, &quic.Config{})
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
@@ -398,14 +398,14 @@ func TestQUICDialerHandshakeCompleter(t *testing.T) {
|
||||
}
|
||||
d := &quicDialerHandshakeCompleter{
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return expected, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
conn, err := d.DialContext(
|
||||
context.Background(), "udp", "8.8.8.8:443", &tls.Config{}, &quic.Config{})
|
||||
context.Background(), "8.8.8.8:443", &tls.Config{}, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -489,7 +489,7 @@ func TestQUICDialerResolver(t *testing.T) {
|
||||
Resolver: NewStdlibResolver(log.Log),
|
||||
Dialer: &quicDialerQUICGo{}}
|
||||
qconn, err := dialer.DialContext(
|
||||
context.Background(), "udp", "www.google.com",
|
||||
context.Background(), "www.google.com",
|
||||
tlsConfig, &quic.Config{})
|
||||
if err == nil || !strings.HasSuffix(err.Error(), "missing port in address") {
|
||||
t.Fatal("not the error we expected")
|
||||
@@ -508,7 +508,7 @@ func TestQUICDialerResolver(t *testing.T) {
|
||||
},
|
||||
}}
|
||||
qconn, err := dialer.DialContext(
|
||||
context.Background(), "udp", "dns.google.com:853",
|
||||
context.Background(), "dns.google.com:853",
|
||||
tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected")
|
||||
@@ -528,7 +528,7 @@ func TestQUICDialerResolver(t *testing.T) {
|
||||
QUICListener: &quicListenerStdlib{},
|
||||
}}
|
||||
qconn, err := dialer.DialContext(
|
||||
context.Background(), "udp", "8.8.4.4:x",
|
||||
context.Background(), "8.8.4.4:x",
|
||||
tlsConf, &quic.Config{})
|
||||
if err == nil {
|
||||
t.Fatal("expected an error here")
|
||||
@@ -548,14 +548,14 @@ func TestQUICDialerResolver(t *testing.T) {
|
||||
dialer := &quicDialerResolver{
|
||||
Resolver: NewStdlibResolver(log.Log),
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
gotTLSConfig = tlsConfig
|
||||
return nil, expected
|
||||
},
|
||||
}}
|
||||
qconn, err := dialer.DialContext(
|
||||
context.Background(), "udp", "8.8.4.4:443",
|
||||
context.Background(), "8.8.4.4:443",
|
||||
tlsConfig, &quic.Config{})
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
@@ -576,13 +576,13 @@ func TestQUICDialerResolver(t *testing.T) {
|
||||
dialer := &quicDialerResolver{
|
||||
Resolver: NewStdlibResolver(log.Log),
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return expectedQConn, nil
|
||||
},
|
||||
}}
|
||||
qconn, err := dialer.DialContext(
|
||||
context.Background(), "udp", "8.8.4.4:443",
|
||||
context.Background(), "8.8.4.4:443",
|
||||
&tls.Config{}, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -637,7 +637,7 @@ func TestQUICLoggerDialer(t *testing.T) {
|
||||
}
|
||||
d := &quicDialerLogger{
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network string,
|
||||
MockDialContext: func(ctx context.Context,
|
||||
address string, tlsConfig *tls.Config,
|
||||
quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return &mocks.QUICEarlyConnection{
|
||||
@@ -653,7 +653,7 @@ func TestQUICLoggerDialer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
tlsConfig := &tls.Config{}
|
||||
quicConfig := &quic.Config{}
|
||||
qconn, err := d.DialContext(ctx, "udp", "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
qconn, err := d.DialContext(ctx, "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -675,7 +675,7 @@ func TestQUICLoggerDialer(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
d := &quicDialerLogger{
|
||||
Dialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network string,
|
||||
MockDialContext: func(ctx context.Context,
|
||||
address string, tlsConfig *tls.Config,
|
||||
quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return nil, expected
|
||||
@@ -686,7 +686,7 @@ func TestQUICLoggerDialer(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
tlsConfig := &tls.Config{}
|
||||
quicConfig := &quic.Config{}
|
||||
qconn, err := d.DialContext(ctx, "udp", "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
qconn, err := d.DialContext(ctx, "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -705,7 +705,7 @@ func TestNewSingleUseQUICDialer(t *testing.T) {
|
||||
qd := NewSingleUseQUICDialer(qconn)
|
||||
defer qd.CloseIdleConnections()
|
||||
outconn, err := qd.DialContext(
|
||||
context.Background(), "", "", &tls.Config{}, &quic.Config{})
|
||||
context.Background(), "", &tls.Config{}, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -714,7 +714,7 @@ func TestNewSingleUseQUICDialer(t *testing.T) {
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
outconn, err = qd.DialContext(
|
||||
context.Background(), "", "", &tls.Config{}, &quic.Config{})
|
||||
context.Background(), "", &tls.Config{}, &quic.Config{})
|
||||
if !errors.Is(err, ErrNoConnReuse) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
@@ -904,13 +904,13 @@ func TestQUICDialerErrWrapper(t *testing.T) {
|
||||
expectedConn := &mocks.QUICEarlyConnection{}
|
||||
d := &quicDialerErrWrapper{
|
||||
QUICDialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
MockDialContext: func(ctx context.Context, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return expectedConn, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := d.DialContext(ctx, "", "", &tls.Config{}, &quic.Config{})
|
||||
qconn, err := d.DialContext(ctx, "", &tls.Config{}, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -923,13 +923,13 @@ func TestQUICDialerErrWrapper(t *testing.T) {
|
||||
expectedErr := io.EOF
|
||||
d := &quicDialerErrWrapper{
|
||||
QUICDialer: &mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
MockDialContext: func(ctx context.Context, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return nil, expectedErr
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := context.Background()
|
||||
qconn, err := d.DialContext(ctx, "", "", &tls.Config{}, &quic.Config{})
|
||||
qconn, err := d.DialContext(ctx, "", &tls.Config{}, &quic.Config{})
|
||||
if err == nil || err.Error() != FailureEOFError {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
ootls "github.com/ooni/oocrypto/tls"
|
||||
oohttp "github.com/ooni/oohttp"
|
||||
"github.com/ooni/probe-cli/v3/internal/model"
|
||||
"github.com/ooni/probe-cli/v3/internal/runtimex"
|
||||
@@ -238,14 +239,7 @@ func (h *tlsHandshakerConfigurable) newConn(conn net.Conn, config *tls.Config) (
|
||||
if h.NewConn != nil {
|
||||
return h.NewConn(conn, config)
|
||||
}
|
||||
// This used to be the place where we created a TLSConn using
|
||||
// github.com/ooni/oocrypto's TLS. However, it seems this strategy
|
||||
// does not correctly pick up the CPU capabilities. So, we have
|
||||
// now disabled oocrypto until we investigate, to avoid making the
|
||||
// development branch worse than it could in terms of TLS fingerprint.
|
||||
//
|
||||
// TODO(https://github.com/ooni/probe/issues/2122)
|
||||
return tls.Client(conn, config), nil
|
||||
return ootls.NewClientConnStdlib(conn, config)
|
||||
}
|
||||
|
||||
// tlsHandshakerLogger is a TLSHandshaker with logging.
|
||||
|
||||
@@ -36,8 +36,14 @@ func NewTLSHandshakerUTLS(logger model.DebugLogger, id *utls.ClientHelloID) mode
|
||||
|
||||
// utlsConn implements TLSConn and uses a utls UConn as its underlying connection
|
||||
type utlsConn struct {
|
||||
// We include the real UConn
|
||||
*utls.UConn
|
||||
|
||||
// This field helps with writing tests
|
||||
testableHandshake func() error
|
||||
|
||||
// Required by NetConn
|
||||
nc net.Conn
|
||||
}
|
||||
|
||||
// Ensures that a utlsConn implements the TLSConn interface.
|
||||
@@ -85,7 +91,12 @@ func newConnUTLSWithHelloID(conn net.Conn, config *tls.Config, cid *utls.ClientH
|
||||
ServerName: config.ServerName,
|
||||
}
|
||||
tlsConn := utls.UClient(conn, uConfig, *cid)
|
||||
return &utlsConn{UConn: tlsConn}, nil
|
||||
oconn := &utlsConn{
|
||||
UConn: tlsConn,
|
||||
testableHandshake: nil,
|
||||
nc: conn,
|
||||
}
|
||||
return oconn, nil
|
||||
}
|
||||
|
||||
// ErrUTLSHandshakePanic indicates that there was panic handshaking
|
||||
@@ -136,3 +147,7 @@ func (c *utlsConn) ConnectionState() tls.ConnectionState {
|
||||
TLSUnique: uState.TLSUnique,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *utlsConn) NetConn() net.Conn {
|
||||
return c.nc
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||
utls "gitlab.com/yawning/utls.git"
|
||||
)
|
||||
|
||||
@@ -92,6 +93,18 @@ func TestUTLSConn(t *testing.T) {
|
||||
wg.Wait()
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("NetConn", func(t *testing.T) {
|
||||
factory := newConnUTLS(&utls.HelloChrome_70)
|
||||
conn := &mocks.Conn{}
|
||||
tconn, err := factory(conn, &tls.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if tconn.NetConn() != conn {
|
||||
t.Fatal("NetConn is not WAI")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_newConnUTLSWithHelloID(t *testing.T) {
|
||||
|
||||
@@ -40,7 +40,7 @@ func (s *Saver) WrapQUICDialer(qd model.QUICDialer) model.QUICDialer {
|
||||
}
|
||||
|
||||
// DialContext implements QUICDialer.DialContext
|
||||
func (h *QUICDialerSaver) DialContext(ctx context.Context, network string,
|
||||
func (h *QUICDialerSaver) DialContext(ctx context.Context,
|
||||
host string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
|
||||
start := time.Now()
|
||||
// TODO(bassosimone): in the future we probably want to also save
|
||||
@@ -48,12 +48,12 @@ func (h *QUICDialerSaver) DialContext(ctx context.Context, network string,
|
||||
h.Saver.Write(&EventQUICHandshakeStart{&EventValue{
|
||||
Address: host,
|
||||
NoTLSVerify: tlsCfg.InsecureSkipVerify,
|
||||
Proto: network,
|
||||
Proto: "udp",
|
||||
TLSNextProtos: tlsCfg.NextProtos,
|
||||
TLSServerName: tlsCfg.ServerName,
|
||||
Time: start,
|
||||
}})
|
||||
sess, err := h.QUICDialer.DialContext(ctx, network, host, tlsCfg, cfg)
|
||||
sess, err := h.QUICDialer.DialContext(ctx, host, tlsCfg, cfg)
|
||||
stop := time.Now()
|
||||
if err != nil {
|
||||
// TODO(bassosimone): here we should save the peer certs
|
||||
@@ -62,7 +62,7 @@ func (h *QUICDialerSaver) DialContext(ctx context.Context, network string,
|
||||
Duration: stop.Sub(start),
|
||||
Err: NewFailureStr(err),
|
||||
NoTLSVerify: tlsCfg.InsecureSkipVerify,
|
||||
Proto: network,
|
||||
Proto: "udp",
|
||||
TLSNextProtos: tlsCfg.NextProtos,
|
||||
TLSPeerCerts: [][]byte{},
|
||||
TLSServerName: tlsCfg.ServerName,
|
||||
@@ -75,7 +75,7 @@ func (h *QUICDialerSaver) DialContext(ctx context.Context, network string,
|
||||
Address: host,
|
||||
Duration: stop.Sub(start),
|
||||
NoTLSVerify: tlsCfg.InsecureSkipVerify,
|
||||
Proto: network,
|
||||
Proto: "udp",
|
||||
TLSCipherSuite: netxlite.TLSCipherSuiteString(state.CipherSuite),
|
||||
TLSNegotiatedProto: state.NegotiatedProtocol,
|
||||
TLSNextProtos: tlsCfg.NextProtos,
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestQUICDialerSaver(t *testing.T) {
|
||||
},
|
||||
}
|
||||
dialer := saver.WrapQUICDialer(&mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return returnedConn, nil
|
||||
},
|
||||
@@ -103,7 +103,7 @@ func TestQUICDialerSaver(t *testing.T) {
|
||||
ServerName: "dns.google",
|
||||
}
|
||||
quicConfig := &quic.Config{}
|
||||
conn, err := dialer.DialContext(ctx, "udp", "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
conn, err := dialer.DialContext(ctx, "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func TestQUICDialerSaver(t *testing.T) {
|
||||
expected := errors.New("mocked error")
|
||||
saver := &Saver{}
|
||||
dialer := saver.WrapQUICDialer(&mocks.QUICDialer{
|
||||
MockDialContext: func(ctx context.Context, network, address string,
|
||||
MockDialContext: func(ctx context.Context, address string,
|
||||
tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
|
||||
return nil, expected
|
||||
},
|
||||
@@ -143,7 +143,7 @@ func TestQUICDialerSaver(t *testing.T) {
|
||||
ServerName: "dns.google",
|
||||
}
|
||||
quicConfig := &quic.Config{}
|
||||
conn, err := dialer.DialContext(ctx, "udp", "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
conn, err := dialer.DialContext(ctx, "8.8.8.8:443", tlsConfig, quicConfig)
|
||||
if !errors.Is(err, expected) {
|
||||
t.Fatal("unexpected err", err)
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func dialQUIC(ctx context.Context, address string,
|
||||
config *tls.Config) (quic.EarlyConnection, tls.ConnectionState, error) {
|
||||
ql := netxlite.NewQUICListener()
|
||||
d := netxlite.NewQUICDialerWithoutResolver(ql, log.Log)
|
||||
qconn, err := d.DialContext(ctx, "udp", address, config, &quic.Config{})
|
||||
qconn, err := d.DialContext(ctx, address, config, &quic.Config{})
|
||||
if err != nil {
|
||||
return nil, tls.ConnectionState{}, err
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ func dialQUIC(ctx context.Context, address string,
|
||||
config *tls.Config) (quic.EarlyConnection, tls.ConnectionState, error) {
|
||||
ql := netxlite.NewQUICListener()
|
||||
d := netxlite.NewQUICDialerWithoutResolver(ql, log.Log)
|
||||
qconn, err := d.DialContext(ctx, "udp", address, config, &quic.Config{})
|
||||
qconn, err := d.DialContext(ctx, address, config, &quic.Config{})
|
||||
if err != nil {
|
||||
return nil, tls.ConnectionState{}, err
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ creating a system resolver, except that we also need to specify the
|
||||
UDP endpoint address at which the server is listening.
|
||||
|
||||
```Go
|
||||
reso := netxlite.NewParallelResolverUDP(log.Log, dialer, *serverAddr)
|
||||
reso := netxlite.NewParallelUDPResolver(log.Log, dialer, *serverAddr)
|
||||
```
|
||||
|
||||
The API we invoke is the same as in the previous chapter, though,
|
||||
|
||||
@@ -106,7 +106,7 @@ func dialQUIC(ctx context.Context, address string,
|
||||
config *tls.Config) (quic.EarlyConnection, tls.ConnectionState, error) {
|
||||
ql := netxlite.NewQUICListener()
|
||||
d := netxlite.NewQUICDialerWithoutResolver(ql, log.Log)
|
||||
qconn, err := d.DialContext(ctx, "udp", address, config, &quic.Config{})
|
||||
qconn, err := d.DialContext(ctx, address, config, &quic.Config{})
|
||||
if err != nil {
|
||||
return nil, tls.ConnectionState{}, err
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func dialQUIC(ctx context.Context, address string,
|
||||
config *tls.Config) (quic.EarlyConnection, tls.ConnectionState, error) {
|
||||
ql := netxlite.NewQUICListener()
|
||||
d := netxlite.NewQUICDialerWithoutResolver(ql, log.Log)
|
||||
qconn, err := d.DialContext(ctx, "udp", address, config, &quic.Config{})
|
||||
qconn, err := d.DialContext(ctx, address, config, &quic.Config{})
|
||||
if err != nil {
|
||||
return nil, tls.ConnectionState{}, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user