@@ -45,18 +45,20 @@ type datagramConn struct {
45
45
conn QuicConnection
46
46
index uint8
47
47
sessionManager SessionManager
48
+ metrics Metrics
48
49
logger * zerolog.Logger
49
50
50
51
datagrams chan []byte
51
52
readErrors chan error
52
53
}
53
54
54
- func NewDatagramConn (conn QuicConnection , sessionManager SessionManager , index uint8 , logger * zerolog.Logger ) DatagramConn {
55
+ func NewDatagramConn (conn QuicConnection , sessionManager SessionManager , index uint8 , metrics Metrics , logger * zerolog.Logger ) DatagramConn {
55
56
log := logger .With ().Uint8 ("datagramVersion" , 3 ).Logger ()
56
57
return & datagramConn {
57
58
conn : conn ,
58
59
index : index ,
59
60
sessionManager : sessionManager ,
61
+ metrics : metrics ,
60
62
logger : & log ,
61
63
datagrams : make (chan []byte , demuxChanCapacity ),
62
64
readErrors : make (chan error , 2 ),
@@ -143,19 +145,21 @@ func (c *datagramConn) Serve(ctx context.Context) error {
143
145
c .logger .Err (err ).Msgf ("unable to unmarshal session registration datagram" )
144
146
return
145
147
}
148
+ logger := c .logger .With ().Str (logFlowID , reg .RequestID .String ()).Logger ()
146
149
// We bind the new session to the quic connection context instead of cloudflared context to allow for the
147
150
// quic connection to close and close only the sessions bound to it. Closing of cloudflared will also
148
151
// initiate the close of the quic connection, so we don't have to worry about the application context
149
152
// in the scope of a session.
150
- c .handleSessionRegistrationDatagram (connCtx , reg )
153
+ c .handleSessionRegistrationDatagram (connCtx , reg , & logger )
151
154
case UDPSessionPayloadType :
152
155
payload := & UDPSessionPayloadDatagram {}
153
156
err := payload .UnmarshalBinary (datagram )
154
157
if err != nil {
155
158
c .logger .Err (err ).Msgf ("unable to unmarshal session payload datagram" )
156
159
return
157
160
}
158
- c .handleSessionPayloadDatagram (payload )
161
+ logger := c .logger .With ().Str (logFlowID , payload .RequestID .String ()).Logger ()
162
+ c .handleSessionPayloadDatagram (payload , & logger )
159
163
case UDPSessionRegistrationResponseType :
160
164
// cloudflared should never expect to receive UDP session responses as it will not initiate new
161
165
// sessions towards the edge.
@@ -169,31 +173,33 @@ func (c *datagramConn) Serve(ctx context.Context) error {
169
173
}
170
174
171
175
// This method handles new registrations of a session and the serve loop for the session.
172
- func (c * datagramConn ) handleSessionRegistrationDatagram (ctx context.Context , datagram * UDPSessionRegistrationDatagram ) {
176
+ func (c * datagramConn ) handleSessionRegistrationDatagram (ctx context.Context , datagram * UDPSessionRegistrationDatagram , logger * zerolog. Logger ) {
173
177
session , err := c .sessionManager .RegisterSession (datagram , c )
174
178
switch err {
175
179
case nil :
176
180
// Continue as normal
177
181
case ErrSessionAlreadyRegistered :
178
182
// Session is already registered and likely the response got lost
179
- c .handleSessionAlreadyRegistered (datagram .RequestID )
183
+ c .handleSessionAlreadyRegistered (datagram .RequestID , logger )
180
184
return
181
185
case ErrSessionBoundToOtherConn :
182
186
// Session is already registered but to a different connection
183
- c .handleSessionMigration (datagram .RequestID )
187
+ c .handleSessionMigration (datagram .RequestID , logger )
184
188
return
185
189
default :
186
- c . logger .Err (err ).Msgf ("session registration failure" )
187
- c .handleSessionRegistrationFailure (datagram .RequestID )
190
+ logger .Err (err ).Msgf ("flow registration failure" )
191
+ c .handleSessionRegistrationFailure (datagram .RequestID , logger )
188
192
return
189
193
}
194
+ c .metrics .IncrementFlows ()
190
195
// Make sure to eventually remove the session from the session manager when the session is closed
191
196
defer c .sessionManager .UnregisterSession (session .ID ())
197
+ defer c .metrics .DecrementFlows ()
192
198
193
199
// Respond that we are able to process the new session
194
200
err = c .SendUDPSessionResponse (datagram .RequestID , ResponseOk )
195
201
if err != nil {
196
- c . logger .Err (err ).Msgf ("session registration failure: unable to send session registration response" )
202
+ logger .Err (err ).Msgf ("flow registration failure: unable to send session registration response" )
197
203
return
198
204
}
199
205
@@ -203,24 +209,24 @@ func (c *datagramConn) handleSessionRegistrationDatagram(ctx context.Context, da
203
209
if err == nil {
204
210
// We typically don't expect a session to close without some error response. [SessionIdleErr] is the typical
205
211
// expected error response.
206
- c . logger .Warn ().Msg ("session was closed without explicit close or timeout" )
212
+ logger .Warn ().Msg ("flow was closed without explicit close or timeout" )
207
213
return
208
214
}
209
215
// SessionIdleErr and SessionCloseErr are valid and successful error responses to end a session.
210
216
if errors .Is (err , SessionIdleErr {}) || errors .Is (err , SessionCloseErr ) {
211
- c . logger .Debug ().Msg (err .Error ())
217
+ logger .Debug ().Msg (err .Error ())
212
218
return
213
219
}
214
220
215
221
// All other errors should be reported as errors
216
- c . logger .Err (err ).Msgf ("session was closed with an error" )
222
+ logger .Err (err ).Msgf ("flow was closed with an error" )
217
223
}
218
224
219
- func (c * datagramConn ) handleSessionAlreadyRegistered (requestID RequestID ) {
225
+ func (c * datagramConn ) handleSessionAlreadyRegistered (requestID RequestID , logger * zerolog. Logger ) {
220
226
// Send another registration response since the session is already active
221
227
err := c .SendUDPSessionResponse (requestID , ResponseOk )
222
228
if err != nil {
223
- c . logger .Err (err ).Msgf ("session registration failure: unable to send an additional session registration response" )
229
+ logger .Err (err ).Msgf ("flow registration failure: unable to send an additional flow registration response" )
224
230
return
225
231
}
226
232
@@ -233,9 +239,10 @@ func (c *datagramConn) handleSessionAlreadyRegistered(requestID RequestID) {
233
239
// The session is already running in another routine so we want to restart the idle timeout since no proxied
234
240
// packets have come down yet.
235
241
session .ResetIdleTimer ()
242
+ c .metrics .RetryFlowResponse ()
236
243
}
237
244
238
- func (c * datagramConn ) handleSessionMigration (requestID RequestID ) {
245
+ func (c * datagramConn ) handleSessionMigration (requestID RequestID , logger * zerolog. Logger ) {
239
246
// We need to migrate the currently running session to this edge connection.
240
247
session , err := c .sessionManager .GetSession (requestID )
241
248
if err != nil {
@@ -250,29 +257,29 @@ func (c *datagramConn) handleSessionMigration(requestID RequestID) {
250
257
// Send another registration response since the session is already active
251
258
err = c .SendUDPSessionResponse (requestID , ResponseOk )
252
259
if err != nil {
253
- c . logger .Err (err ).Msgf ("session registration failure: unable to send an additional session registration response" )
260
+ logger .Err (err ).Msgf ("flow registration failure: unable to send an additional flow registration response" )
254
261
return
255
262
}
256
263
}
257
264
258
- func (c * datagramConn ) handleSessionRegistrationFailure (requestID RequestID ) {
265
+ func (c * datagramConn ) handleSessionRegistrationFailure (requestID RequestID , logger * zerolog. Logger ) {
259
266
err := c .SendUDPSessionResponse (requestID , ResponseUnableToBindSocket )
260
267
if err != nil {
261
- c . logger .Err (err ).Msgf ("unable to send session registration error response (%d)" , ResponseUnableToBindSocket )
268
+ logger .Err (err ).Msgf ("unable to send flow registration error response (%d)" , ResponseUnableToBindSocket )
262
269
}
263
270
}
264
271
265
272
// Handles incoming datagrams that need to be sent to a registered session.
266
- func (c * datagramConn ) handleSessionPayloadDatagram (datagram * UDPSessionPayloadDatagram ) {
273
+ func (c * datagramConn ) handleSessionPayloadDatagram (datagram * UDPSessionPayloadDatagram , logger * zerolog. Logger ) {
267
274
s , err := c .sessionManager .GetSession (datagram .RequestID )
268
275
if err != nil {
269
- c . logger .Err (err ).Msgf ("unable to find session " )
276
+ logger .Err (err ).Msgf ("unable to find flow " )
270
277
return
271
278
}
272
279
// We ignore the bytes written to the socket because any partial write must return an error.
273
280
_ , err = s .Write (datagram .Payload )
274
281
if err != nil {
275
- c . logger .Err (err ).Msgf ("unable to write payload for unavailable session " )
282
+ logger .Err (err ).Msgf ("unable to write payload for the flow " )
276
283
return
277
284
}
278
285
}
0 commit comments