@@ -210,25 +210,40 @@ func (s *connIDState) validateTransportParameters(c *Conn, isRetry bool, p trans
210
210
// the transient remote connection ID we chose (client)
211
211
// or is empty (server).
212
212
if ! bytes .Equal (s .originalDstConnID , p .originalDstConnID ) {
213
- return localTransportError (errTransportParameter )
213
+ return localTransportError {
214
+ code : errTransportParameter ,
215
+ reason : "original_destination_connection_id mismatch" ,
216
+ }
214
217
}
215
218
s .originalDstConnID = nil // we have no further need for this
216
219
// Verify retry_source_connection_id matches the value from
217
220
// the server's Retry packet (when one was sent), or is empty.
218
221
if ! bytes .Equal (p .retrySrcConnID , s .retrySrcConnID ) {
219
- return localTransportError (errTransportParameter )
222
+ return localTransportError {
223
+ code : errTransportParameter ,
224
+ reason : "retry_source_connection_id mismatch" ,
225
+ }
220
226
}
221
227
s .retrySrcConnID = nil // we have no further need for this
222
228
// Verify initial_source_connection_id matches the first remote connection ID.
223
229
if len (s .remote ) == 0 || s .remote [0 ].seq != 0 {
224
- return localTransportError (errInternal )
230
+ return localTransportError {
231
+ code : errInternal ,
232
+ reason : "remote connection id missing" ,
233
+ }
225
234
}
226
235
if ! bytes .Equal (p .initialSrcConnID , s .remote [0 ].cid ) {
227
- return localTransportError (errTransportParameter )
236
+ return localTransportError {
237
+ code : errTransportParameter ,
238
+ reason : "initial_source_connection_id mismatch" ,
239
+ }
228
240
}
229
241
if len (p .statelessResetToken ) > 0 {
230
242
if c .side == serverSide {
231
- return localTransportError (errTransportParameter )
243
+ return localTransportError {
244
+ code : errTransportParameter ,
245
+ reason : "client sent stateless_reset_token" ,
246
+ }
232
247
}
233
248
token := statelessResetToken (p .statelessResetToken )
234
249
s .remote [0 ].resetToken = token
@@ -255,17 +270,6 @@ func (s *connIDState) handlePacket(c *Conn, ptype packetType, srcConnID []byte)
255
270
},
256
271
}
257
272
}
258
- case ptype == packetTypeInitial && c .side == serverSide :
259
- if len (s .remote ) == 0 {
260
- // We're a server connection processing the first Initial packet
261
- // from the client. Set the client's connection ID.
262
- s .remote = append (s .remote , remoteConnID {
263
- connID : connID {
264
- seq : 0 ,
265
- cid : cloneBytes (srcConnID ),
266
- },
267
- })
268
- }
269
273
case ptype == packetTypeHandshake && c .side == serverSide :
270
274
if len (s .local ) > 0 && s .local [0 ].seq == - 1 && ! s .local [0 ].retired {
271
275
// We're a server connection processing the first Handshake packet from
@@ -294,7 +298,10 @@ func (s *connIDState) handleNewConnID(c *Conn, seq, retire int64, cid []byte, re
294
298
// Destination Connection ID MUST treat receipt of a NEW_CONNECTION_ID
295
299
// frame as a connection error of type PROTOCOL_VIOLATION."
296
300
// https://www.rfc-editor.org/rfc/rfc9000.html#section-19.15-6
297
- return localTransportError (errProtocolViolation )
301
+ return localTransportError {
302
+ code : errProtocolViolation ,
303
+ reason : "NEW_CONNECTION_ID from peer with zero-length DCID" ,
304
+ }
298
305
}
299
306
300
307
if retire > s .retireRemotePriorTo {
@@ -316,7 +323,10 @@ func (s *connIDState) handleNewConnID(c *Conn, seq, retire int64, cid []byte, re
316
323
}
317
324
if rcid .seq == seq {
318
325
if ! bytes .Equal (rcid .cid , cid ) {
319
- return localTransportError (errProtocolViolation )
326
+ return localTransportError {
327
+ code : errProtocolViolation ,
328
+ reason : "NEW_CONNECTION_ID does not match prior id" ,
329
+ }
320
330
}
321
331
have = true // yes, we've seen this sequence number
322
332
}
@@ -350,7 +360,10 @@ func (s *connIDState) handleNewConnID(c *Conn, seq, retire int64, cid []byte, re
350
360
// Retired connection IDs (including newly-retired ones) do not count
351
361
// against the limit.
352
362
// https://www.rfc-editor.org/rfc/rfc9000.html#section-5.1.1-5
353
- return localTransportError (errConnectionIDLimit )
363
+ return localTransportError {
364
+ code : errConnectionIDLimit ,
365
+ reason : "active_connection_id_limit exceeded" ,
366
+ }
354
367
}
355
368
356
369
// "An endpoint SHOULD limit the number of connection IDs it has retired locally
@@ -360,7 +373,10 @@ func (s *connIDState) handleNewConnID(c *Conn, seq, retire int64, cid []byte, re
360
373
// Set a limit of four times the active_connection_id_limit for
361
374
// the total number of remote connection IDs we keep state for locally.
362
375
if len (s .remote ) > 4 * activeConnIDLimit {
363
- return localTransportError (errConnectionIDLimit )
376
+ return localTransportError {
377
+ code : errConnectionIDLimit ,
378
+ reason : "too many unacknowledged RETIRE_CONNECTION_ID frames" ,
379
+ }
364
380
}
365
381
366
382
return nil
@@ -375,7 +391,10 @@ func (s *connIDState) retireRemote(rcid *remoteConnID) {
375
391
376
392
func (s * connIDState ) handleRetireConnID (c * Conn , seq int64 ) error {
377
393
if seq >= s .nextLocalSeq {
378
- return localTransportError (errProtocolViolation )
394
+ return localTransportError {
395
+ code : errProtocolViolation ,
396
+ reason : "RETIRE_CONNECTION_ID for unissued sequence number" ,
397
+ }
379
398
}
380
399
for i := range s .local {
381
400
if s .local [i ].seq == seq {
0 commit comments