Skip to content

Commit c5622d5

Browse files
committed
Allow to specific dcid when creating a client side connection
Motivation: Sometimes the user want to have control over generating the dcid when creating a new client side connection. This was not possible before. Modification: - Only use dcid for local transport params when the connection is for server side - Use provided odcid as dcid on the client side when given and if not just randomly generate one Result: More flexible usage possible
1 parent a4f08bc commit c5622d5

File tree

3 files changed

+69
-19
lines changed

3 files changed

+69
-19
lines changed

quiche/include/quiche.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ ssize_t quiche_retry(const uint8_t *scid, size_t scid_len,
317317
bool quiche_version_is_supported(uint32_t version);
318318

319319
quiche_conn *quiche_conn_new_with_tls(const uint8_t *scid, size_t scid_len,
320-
const uint8_t *odcid, size_t odcid_len,
320+
const uint8_t *dcid, size_t dcid_len,
321321
const struct sockaddr *local, socklen_t local_len,
322322
const struct sockaddr *peer, socklen_t peer_len,
323323
const quiche_config *config, void *ssl,

quiche/src/ffi.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,16 +606,16 @@ pub extern "C" fn quiche_retry(
606606

607607
#[no_mangle]
608608
pub extern "C" fn quiche_conn_new_with_tls(
609-
scid: *const u8, scid_len: size_t, odcid: *const u8, odcid_len: size_t,
609+
scid: *const u8, scid_len: size_t, dcid: *const u8, dcid_len: size_t,
610610
local: &sockaddr, local_len: socklen_t, peer: &sockaddr, peer_len: socklen_t,
611611
config: &Config, ssl: *mut c_void, is_server: bool,
612612
) -> *mut Connection {
613613
let scid = unsafe { slice::from_raw_parts(scid, scid_len) };
614614
let scid = ConnectionId::from_ref(scid);
615615

616-
let odcid = if !odcid.is_null() && odcid_len > 0 {
616+
let dcid = if !dcid.is_null() && dcid_len > 0 {
617617
Some(ConnectionId::from_ref(unsafe {
618-
slice::from_raw_parts(odcid, odcid_len)
618+
slice::from_raw_parts(dcid, dcid_len)
619619
}))
620620
} else {
621621
None
@@ -628,7 +628,7 @@ pub extern "C" fn quiche_conn_new_with_tls(
628628

629629
match Connection::with_tls(
630630
&scid,
631-
odcid.as_ref(),
631+
dcid.as_ref(),
632632
local,
633633
peer,
634634
config,

quiche/src/lib.rs

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

19752013
impl<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

Comments
 (0)