@@ -161,6 +161,39 @@ func (s *connIDState) issueLocalIDs(c *Conn) error {
161161 return nil
162162}
163163
164+ // validateTransportParameters verifies the original_destination_connection_id and
165+ // initial_source_connection_id transport parameters match the expected values.
166+ func (s * connIDState ) validateTransportParameters (side connSide , p transportParameters ) error {
167+ // TODO: Consider returning more detailed errors, for debugging.
168+ switch side {
169+ case clientSide :
170+ // Verify original_destination_connection_id matches
171+ // the transient remote connection ID we chose.
172+ if len (s .remote ) == 0 || s .remote [0 ].seq != - 1 {
173+ return localTransportError (errInternal )
174+ }
175+ if ! bytes .Equal (s .remote [0 ].cid , p .originalDstConnID ) {
176+ return localTransportError (errTransportParameter )
177+ }
178+ // Remove the transient remote connection ID.
179+ // We have no further need for it.
180+ s .remote = append (s .remote [:0 ], s .remote [1 :]... )
181+ case serverSide :
182+ if p .originalDstConnID != nil {
183+ // Clients do not send original_destination_connection_id.
184+ return localTransportError (errTransportParameter )
185+ }
186+ }
187+ // Verify initial_source_connection_id matches the first remote connection ID.
188+ if len (s .remote ) == 0 || s .remote [0 ].seq != 0 {
189+ return localTransportError (errInternal )
190+ }
191+ if ! bytes .Equal (p .initialSrcConnID , s .remote [0 ].cid ) {
192+ return localTransportError (errTransportParameter )
193+ }
194+ return nil
195+ }
196+
164197// handlePacket updates the connection ID state during the handshake
165198// (Initial and Handshake packets).
166199func (s * connIDState ) handlePacket (c * Conn , ptype packetType , srcConnID []byte ) {
@@ -170,10 +203,13 @@ func (s *connIDState) handlePacket(c *Conn, ptype packetType, srcConnID []byte)
170203 // We're a client connection processing the first Initial packet
171204 // from the server. Replace the transient remote connection ID
172205 // with the Source Connection ID from the packet.
173- s .remote [0 ] = connID {
206+ // Leave the transient ID the list for now, since we'll need it when
207+ // processing the transport parameters.
208+ s .remote [0 ].retired = true
209+ s .remote = append (s .remote , connID {
174210 seq : 0 ,
175211 cid : cloneBytes (srcConnID ),
176- }
212+ })
177213 }
178214 case ptype == packetTypeInitial && c .side == serverSide :
179215 if len (s .remote ) == 0 {
@@ -185,7 +221,7 @@ func (s *connIDState) handlePacket(c *Conn, ptype packetType, srcConnID []byte)
185221 })
186222 }
187223 case ptype == packetTypeHandshake && c .side == serverSide :
188- if len (s .local ) > 0 && s .local [0 ].seq == - 1 {
224+ if len (s .local ) > 0 && s .local [0 ].seq == - 1 && ! s . local [ 0 ]. retired {
189225 // We're a server connection processing the first Handshake packet from
190226 // the client. Discard the transient, client-chosen connection ID used
191227 // for Initial packets; the client will never send it again.
@@ -213,7 +249,7 @@ func (s *connIDState) handleNewConnID(seq, retire int64, cid []byte, resetToken
213249 active := 0
214250 for i := range s .remote {
215251 rcid := & s .remote [i ]
216- if ! rcid .retired && rcid .seq < s .retireRemotePriorTo {
252+ if ! rcid .retired && rcid .seq >= 0 && rcid . seq < s .retireRemotePriorTo {
217253 s .retireRemote (rcid )
218254 }
219255 if ! rcid .retired {
0 commit comments