@@ -22,11 +22,11 @@ import (
22
22
//
23
23
// Multiple goroutines may invoke methods on an Endpoint simultaneously.
24
24
type Endpoint struct {
25
- config * Config
26
- packetConn packetConn
27
- testHooks endpointTestHooks
28
- resetGen statelessResetTokenGenerator
29
- retry retryState
25
+ listenConfig * Config
26
+ packetConn packetConn
27
+ testHooks endpointTestHooks
28
+ resetGen statelessResetTokenGenerator
29
+ retry retryState
30
30
31
31
acceptQueue queue [* Conn ] // new inbound connections
32
32
connsMap connsMap // only accessed by the listen loop
@@ -51,9 +51,11 @@ type packetConn interface {
51
51
}
52
52
53
53
// Listen listens on a local network address.
54
- // The configuration config must be non-nil.
55
- func Listen (network , address string , config * Config ) (* Endpoint , error ) {
56
- if config .TLSConfig == nil {
54
+ //
55
+ // The config is used to for connections accepted by the endpoint.
56
+ // If the config is nil, the endpoint will not accept connections.
57
+ func Listen (network , address string , listenConfig * Config ) (* Endpoint , error ) {
58
+ if listenConfig != nil && listenConfig .TLSConfig == nil {
57
59
return nil , errors .New ("TLSConfig is not set" )
58
60
}
59
61
a , err := net .ResolveUDPAddr (network , address )
@@ -68,21 +70,25 @@ func Listen(network, address string, config *Config) (*Endpoint, error) {
68
70
if err != nil {
69
71
return nil , err
70
72
}
71
- return newEndpoint (pc , config , nil )
73
+ return newEndpoint (pc , listenConfig , nil )
72
74
}
73
75
74
76
func newEndpoint (pc packetConn , config * Config , hooks endpointTestHooks ) (* Endpoint , error ) {
75
77
e := & Endpoint {
76
- config : config ,
77
- packetConn : pc ,
78
- testHooks : hooks ,
79
- conns : make (map [* Conn ]struct {}),
80
- acceptQueue : newQueue [* Conn ](),
81
- closec : make (chan struct {}),
82
- }
83
- e .resetGen .init (config .StatelessResetKey )
78
+ listenConfig : config ,
79
+ packetConn : pc ,
80
+ testHooks : hooks ,
81
+ conns : make (map [* Conn ]struct {}),
82
+ acceptQueue : newQueue [* Conn ](),
83
+ closec : make (chan struct {}),
84
+ }
85
+ var statelessResetKey [32 ]byte
86
+ if config != nil {
87
+ statelessResetKey = config .StatelessResetKey
88
+ }
89
+ e .resetGen .init (statelessResetKey )
84
90
e .connsMap .init ()
85
- if config .RequireAddressValidation {
91
+ if config != nil && config .RequireAddressValidation {
86
92
if err := e .retry .init (); err != nil {
87
93
return nil , err
88
94
}
@@ -141,14 +147,15 @@ func (e *Endpoint) Accept(ctx context.Context) (*Conn, error) {
141
147
}
142
148
143
149
// Dial creates and returns a connection to a network address.
144
- func (e * Endpoint ) Dial (ctx context.Context , network , address string ) (* Conn , error ) {
150
+ // The config cannot be nil.
151
+ func (e * Endpoint ) Dial (ctx context.Context , network , address string , config * Config ) (* Conn , error ) {
145
152
u , err := net .ResolveUDPAddr (network , address )
146
153
if err != nil {
147
154
return nil , err
148
155
}
149
156
addr := u .AddrPort ()
150
157
addr = netip .AddrPortFrom (addr .Addr ().Unmap (), addr .Port ())
151
- c , err := e .newConn (time .Now (), clientSide , newServerConnIDs {}, addr )
158
+ c , err := e .newConn (time .Now (), config , clientSide , newServerConnIDs {}, address , addr )
152
159
if err != nil {
153
160
return nil , err
154
161
}
@@ -159,13 +166,13 @@ func (e *Endpoint) Dial(ctx context.Context, network, address string) (*Conn, er
159
166
return c , nil
160
167
}
161
168
162
- func (e * Endpoint ) newConn (now time.Time , side connSide , cids newServerConnIDs , peerAddr netip.AddrPort ) (* Conn , error ) {
169
+ func (e * Endpoint ) newConn (now time.Time , config * Config , side connSide , cids newServerConnIDs , peerHostname string , peerAddr netip.AddrPort ) (* Conn , error ) {
163
170
e .connsMu .Lock ()
164
171
defer e .connsMu .Unlock ()
165
172
if e .closing {
166
173
return nil , errors .New ("endpoint closed" )
167
174
}
168
- c , err := newConn (now , side , cids , peerAddr , e . config , e )
175
+ c , err := newConn (now , side , cids , peerHostname , peerAddr , config , e )
169
176
if err != nil {
170
177
return nil , err
171
178
}
@@ -288,11 +295,15 @@ func (e *Endpoint) handleUnknownDestinationDatagram(m *datagram) {
288
295
// https://www.rfc-editor.org/rfc/rfc9000#section-10.3-16
289
296
return
290
297
}
298
+ if e .listenConfig == nil {
299
+ // We are not configured to accept connections.
300
+ return
301
+ }
291
302
cids := newServerConnIDs {
292
303
srcConnID : p .srcConnID ,
293
304
dstConnID : p .dstConnID ,
294
305
}
295
- if e .config .RequireAddressValidation {
306
+ if e .listenConfig .RequireAddressValidation {
296
307
var ok bool
297
308
cids .retrySrcConnID = p .dstConnID
298
309
cids .originalDstConnID , ok = e .validateInitialAddress (now , p , m .peerAddr )
@@ -303,7 +314,7 @@ func (e *Endpoint) handleUnknownDestinationDatagram(m *datagram) {
303
314
cids .originalDstConnID = p .dstConnID
304
315
}
305
316
var err error
306
- c , err := e .newConn (now , serverSide , cids , m .peerAddr )
317
+ c , err := e .newConn (now , e . listenConfig , serverSide , cids , "" , m .peerAddr )
307
318
if err != nil {
308
319
// The accept queue is probably full.
309
320
// We could send a CONNECTION_CLOSE to the peer to reject the connection.
0 commit comments