@@ -1771,6 +1771,25 @@ pub fn connect(
17711771 Ok ( conn)
17721772}
17731773
1774+ /// Creates a new client-side connection using the given dcid initially.
1775+ ///
1776+ /// The `scid` parameter is used as the connection's source connection ID,
1777+ /// while the optional `server_name` parameter is used to verify the peer's
1778+ /// certificate.
1779+ #[ inline]
1780+ pub fn connect_with_dcid (
1781+ server_name : Option < & str > , scid : & ConnectionId , dcid : & ConnectionId ,
1782+ local : SocketAddr , peer : SocketAddr , config : & mut Config ,
1783+ ) -> Result < Connection > {
1784+ let mut conn = Connection :: new ( scid, Some ( dcid) , local, peer, config, false ) ?;
1785+
1786+ if let Some ( server_name) = server_name {
1787+ conn. handshake . set_host_name ( server_name) ?;
1788+ }
1789+
1790+ Ok ( conn)
1791+ }
1792+
17741793/// Creates a new client-side connection, with a custom buffer generation
17751794/// method.
17761795///
@@ -1790,6 +1809,25 @@ pub fn connect_with_buffer_factory<F: BufFactory>(
17901809 Ok ( conn)
17911810}
17921811
1812+ /// Creates a new client-side connection, with a custom buffer generation
1813+ /// method using the given dcid initially.
1814+ ///
1815+ /// The buffers generated can be anything that can be drereferenced as a byte
1816+ /// slice. See [`connect`] and [`BufFactory`] for more info.
1817+ #[ inline]
1818+ pub fn connect_with_dcid_and_buffer_factory < F : BufFactory > (
1819+ server_name : Option < & str > , scid : & ConnectionId , dcid : & ConnectionId ,
1820+ local : SocketAddr , peer : SocketAddr , config : & mut Config ,
1821+ ) -> Result < Connection < F > > {
1822+ let mut conn = Connection :: new ( scid, Some ( dcid) , local, peer, config, false ) ?;
1823+
1824+ if let Some ( server_name) = server_name {
1825+ conn. handshake . set_host_name ( server_name) ?;
1826+ }
1827+
1828+ Ok ( conn)
1829+ }
1830+
17931831/// Writes a version negotiation packet.
17941832///
17951833/// The `scid` and `dcid` parameters are the source connection ID and the
@@ -1974,15 +2012,15 @@ impl Default for QlogInfo {
19742012
19752013impl < F : BufFactory > Connection < F > {
19762014 fn new (
1977- scid : & ConnectionId , odcid : Option < & ConnectionId > , local : SocketAddr ,
2015+ scid : & ConnectionId , dcid : Option < & ConnectionId > , local : SocketAddr ,
19782016 peer : SocketAddr , config : & mut Config , is_server : bool ,
19792017 ) -> Result < Connection < F > > {
19802018 let tls = config. tls_ctx . new_handshake ( ) ?;
1981- Connection :: with_tls ( scid, odcid , local, peer, config, tls, is_server)
2019+ Connection :: with_tls ( scid, dcid , local, peer, config, tls, is_server)
19822020 }
19832021
19842022 fn with_tls (
1985- scid : & ConnectionId , odcid : Option < & ConnectionId > , local : SocketAddr ,
2023+ scid : & ConnectionId , dcid : Option < & ConnectionId > , local : SocketAddr ,
19862024 peer : SocketAddr , config : & Config , tls : tls:: Handshake , is_server : bool ,
19872025 ) -> Result < Connection < F > > {
19882026 let max_rx_data = config. local_transport_params . initial_max_data ;
@@ -2008,7 +2046,7 @@ impl<F: BufFactory> Connection<F> {
20082046 ) ;
20092047
20102048 // If we did stateless retry assume the peer's address is verified.
2011- path. verified_peer_address = odcid . is_some ( ) ;
2049+ path. verified_peer_address = is_server && dcid . is_some ( ) ;
20122050 // Assume clients validate the server's address implicitly.
20132051 path. peer_verified_local_address = is_server;
20142052
@@ -2185,14 +2223,19 @@ impl<F: BufFactory> Connection<F> {
21852223 max_amplification_factor : config. max_amplification_factor ,
21862224 } ;
21872225
2188- if let Some ( odcid) = odcid {
2189- conn. local_transport_params
2190- . original_destination_connection_id = Some ( odcid. to_vec ( ) . into ( ) ) ;
2226+ // If this is a connection for a server we need to use the odcid to encode
2227+ // it to the local transport parameters.
2228+ if is_server {
2229+ if let Some ( dcid) = dcid {
2230+ conn. local_transport_params
2231+ . original_destination_connection_id =
2232+ Some ( dcid. to_vec ( ) . into ( ) ) ;
21912233
2192- conn. local_transport_params . retry_source_connection_id =
2193- Some ( conn. ids . get_scid ( 0 ) ?. cid . to_vec ( ) . into ( ) ) ;
2234+ conn. local_transport_params . retry_source_connection_id =
2235+ Some ( conn. ids . get_scid ( 0 ) ?. cid . to_vec ( ) . into ( ) ) ;
21942236
2195- conn. did_retry = true ;
2237+ conn. did_retry = true ;
2238+ }
21962239 }
21972240
21982241 conn. local_transport_params . initial_source_connection_id =
@@ -2205,11 +2248,18 @@ impl<F: BufFactory> Connection<F> {
22052248
22062249 conn. encode_transport_params ( ) ?;
22072250
2208- // Derive initial secrets for the client. We can do this here because
2209- // we already generated the random destination connection ID.
22102251 if !is_server {
2211- let mut dcid = [ 0 ; 16 ] ;
2212- rand:: rand_bytes ( & mut dcid[ ..] ) ;
2252+ let dcid = if let Some ( dcid) = dcid {
2253+ // We already had an dcid generated for us, use it.
2254+ dcid. to_vec ( )
2255+ } else {
2256+ // Derive initial secrets for the client. We can do this here
2257+ // because we already generated the random
2258+ // destination connection ID.
2259+ let mut dcid = [ 0 ; 16 ] ;
2260+ rand:: rand_bytes ( & mut dcid[ ..] ) ;
2261+ dcid. to_vec ( )
2262+ } ;
22132263
22142264 let ( aead_open, aead_seal) = crypto:: derive_initial_key_material (
22152265 & dcid,
0 commit comments