@@ -210,25 +210,40 @@ func (s *connIDState) validateTransportParameters(c *Conn, isRetry bool, p trans
210210 // the transient remote connection ID we chose (client)
211211 // or is empty (server).
212212 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+ }
214217 }
215218 s .originalDstConnID = nil // we have no further need for this
216219 // Verify retry_source_connection_id matches the value from
217220 // the server's Retry packet (when one was sent), or is empty.
218221 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+ }
220226 }
221227 s .retrySrcConnID = nil // we have no further need for this
222228 // Verify initial_source_connection_id matches the first remote connection ID.
223229 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+ }
225234 }
226235 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+ }
228240 }
229241 if len (p .statelessResetToken ) > 0 {
230242 if c .side == serverSide {
231- return localTransportError (errTransportParameter )
243+ return localTransportError {
244+ code : errTransportParameter ,
245+ reason : "client sent stateless_reset_token" ,
246+ }
232247 }
233248 token := statelessResetToken (p .statelessResetToken )
234249 s .remote [0 ].resetToken = token
@@ -255,17 +270,6 @@ func (s *connIDState) handlePacket(c *Conn, ptype packetType, srcConnID []byte)
255270 },
256271 }
257272 }
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- }
269273 case ptype == packetTypeHandshake && c .side == serverSide :
270274 if len (s .local ) > 0 && s .local [0 ].seq == - 1 && ! s .local [0 ].retired {
271275 // 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
294298 // Destination Connection ID MUST treat receipt of a NEW_CONNECTION_ID
295299 // frame as a connection error of type PROTOCOL_VIOLATION."
296300 // 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+ }
298305 }
299306
300307 if retire > s .retireRemotePriorTo {
@@ -316,7 +323,10 @@ func (s *connIDState) handleNewConnID(c *Conn, seq, retire int64, cid []byte, re
316323 }
317324 if rcid .seq == seq {
318325 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+ }
320330 }
321331 have = true // yes, we've seen this sequence number
322332 }
@@ -350,7 +360,10 @@ func (s *connIDState) handleNewConnID(c *Conn, seq, retire int64, cid []byte, re
350360 // Retired connection IDs (including newly-retired ones) do not count
351361 // against the limit.
352362 // 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+ }
354367 }
355368
356369 // "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
360373 // Set a limit of four times the active_connection_id_limit for
361374 // the total number of remote connection IDs we keep state for locally.
362375 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+ }
364380 }
365381
366382 return nil
@@ -375,7 +391,10 @@ func (s *connIDState) retireRemote(rcid *remoteConnID) {
375391
376392func (s * connIDState ) handleRetireConnID (c * Conn , seq int64 ) error {
377393 if seq >= s .nextLocalSeq {
378- return localTransportError (errProtocolViolation )
394+ return localTransportError {
395+ code : errProtocolViolation ,
396+ reason : "RETIRE_CONNECTION_ID for unissued sequence number" ,
397+ }
379398 }
380399 for i := range s .local {
381400 if s .local [i ].seq == seq {
0 commit comments