-
Notifications
You must be signed in to change notification settings - Fork 15
/
quic.go
98 lines (81 loc) · 2.47 KB
/
quic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package oohelperd
//
// QUIC handshake measurements
//
import (
"context"
"crypto/tls"
"sync"
"time"
"github.com/ooni/probe-engine/pkg/logx"
"github.com/ooni/probe-engine/pkg/measurexlite"
"github.com/ooni/probe-engine/pkg/model"
"github.com/quic-go/quic-go"
)
// ctrlQUICResult is the result of the QUIC check performed by the test helper.
type ctrlQUICResult = model.THTLSHandshakeResult
// quicResult contains the endpoint and the corresponding result.
type quicResult struct {
// Address is the IP address we measured.
Address string
// Endpoint is the endpoint we measured.
Endpoint string
// QUIC contains the QUIC results
QUIC ctrlQUICResult
}
// quicConfig configures the QUIC connect check.
type quicConfig struct {
// Address is the MANDATORY address to measure.
Address string
// Endpoint is the MANDATORY endpoint to connect to.
Endpoint string
// Logger is the MANDATORY logger to use.
Logger model.Logger
// NewQUICDialer is the MANDATORY factory for creating a new QUIC dialer.
NewQUICDialer func(model.Logger) model.QUICDialer
// Out is the MANDATORY chan where we'll post the QUIC measurement results.
Out chan *quicResult
// URLHostname is the MANDATORY URL.Hostname() to use.
URLHostname string
// Wg is MANDATORY and is used to sync with the parent.
Wg *sync.WaitGroup
}
// quicDo performs the QUIC handshake check.
func quicDo(ctx context.Context, config *quicConfig) {
const timeout = 15 * time.Second
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()
defer config.Wg.Done()
out := &quicResult{
Address: config.Address,
Endpoint: config.Endpoint,
QUIC: ctrlQUICResult{},
}
defer func() {
config.Out <- out
}()
ol := logx.NewOperationLogger(
config.Logger,
"QUICConnect %s SNI=%s",
config.Endpoint,
config.URLHostname,
)
dialer := config.NewQUICDialer(config.Logger)
defer dialer.CloseIdleConnections()
// See https://github.com/ooni/probe/issues/2413 to understand
// why we're using nil to force netxlite to use the cached
// default Mozilla cert pool.
tlsConfig := &tls.Config{ // #nosec G402 - we need to use a large TLS versions range for measuring
NextProtos: []string{"h3"},
RootCAs: nil,
ServerName: config.URLHostname,
}
quicConn, err := dialer.DialContext(ctx, config.Endpoint, tlsConfig, &quic.Config{})
defer measurexlite.MaybeCloseQUICConn(quicConn)
ol.Stop(err)
out.QUIC = ctrlQUICResult{
ServerName: config.URLHostname,
Status: err == nil,
Failure: newfailure(err),
}
}