Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions quinn-proto/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use crate::{
Dir, Duration, EndpointConfig, Frame, INITIAL_MTU, Instant, MAX_CID_SIZE, MAX_STREAM_COUNT,
MIN_INITIAL_SIZE, Side, StreamId, TIMER_GRANULARITY, TokenStore, Transmit, TransportError,
TransportErrorCode, VarInt,
cid_generator::ConnectionIdGenerator,
cid_queue::CidQueue,
coding::BufMutExt,
config::{ServerConfig, TransportConfig},
Expand Down Expand Up @@ -251,7 +250,8 @@ impl Connection {
remote: SocketAddr,
local_ip: Option<IpAddr>,
crypto: Box<dyn crypto::Session>,
cid_gen: &dyn ConnectionIdGenerator,
local_cid_len: usize,
local_cid_lifetime: Option<Duration>,
now: Instant,
version: u32,
allow_mtud: bool,
Expand All @@ -278,8 +278,8 @@ impl Connection {
handshake_cid: loc_cid,
rem_handshake_cid: rem_cid,
local_cid_state: CidState::new(
cid_gen.cid_len(),
cid_gen.cid_lifetime(),
local_cid_len,
local_cid_lifetime,
now,
if pref_addr_cid.is_some() { 2 } else { 1 },
),
Expand Down
92 changes: 50 additions & 42 deletions quinn-proto/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl Endpoint {
trace!(initial_dcid = %remote_id);

let ch = ConnectionHandle(self.connections.vacant_key());
let loc_cid = self.new_cid(ch);
let loc_cid = self.new_cid(RouteDatagramTo::Connection(ch));
let params = TransportParameters::new(
&config.transport,
&self.config,
Expand Down Expand Up @@ -385,7 +385,7 @@ impl Endpoint {
) -> ConnectionEvent {
let mut ids = vec![];
for _ in 0..num {
let id = self.new_cid(ch);
let id = self.new_cid(RouteDatagramTo::Connection(ch));
let meta = &mut self.connections[ch];
let sequence = meta.cids_issued;
meta.cids_issued += 1;
Expand All @@ -399,8 +399,8 @@ impl Endpoint {
ConnectionEvent(ConnectionEventInner::NewIdentifiers(ids, now))
}

/// Generate a connection ID for `ch`
fn new_cid(&mut self, ch: ConnectionHandle) -> ConnectionId {
/// Generate and reserve a local connection ID
fn new_cid(&mut self, route_to: RouteDatagramTo) -> ConnectionId {
loop {
let cid = self.local_cid_generator.generate_cid();
if cid.is_empty() {
Expand All @@ -409,7 +409,7 @@ impl Endpoint {
return cid;
}
if let hash_map::Entry::Vacant(e) = self.index.connection_ids.entry(cid) {
e.insert(ch);
e.insert(route_to);
break cid;
}
}
Expand Down Expand Up @@ -601,7 +601,7 @@ impl Endpoint {
};

let ch = ConnectionHandle(self.connections.vacant_key());
let loc_cid = self.new_cid(ch);
let loc_cid = self.new_cid(RouteDatagramTo::Connection(ch));
let mut params = TransportParameters::new(
&server_config.transport,
&self.config,
Expand All @@ -615,7 +615,7 @@ impl Endpoint {
params.retry_src_cid = incoming.token.retry_src_cid;
let mut pref_addr_cid = None;
if server_config.has_preferred_address() {
let cid = self.new_cid(ch);
let cid = self.new_cid(RouteDatagramTo::Connection(ch));
pref_addr_cid = Some(cid);
params.preferred_address = Some(PreferredAddress {
address_v4: server_config.preferred_address_v4,
Expand Down Expand Up @@ -815,14 +815,30 @@ impl Endpoint {
addresses.remote,
addresses.local_ip,
tls,
self.local_cid_generator.as_ref(),
self.local_cid_generator.cid_len(),
self.local_cid_generator.cid_lifetime(),
now,
version,
self.allow_mtud,
rng_seed,
side_args,
);

self.register_connection(ch, init_cid, loc_cid, pref_addr_cid, addresses, side);

conn
}

/// Register endpoint-owned metadata and routes for an active connection.
fn register_connection(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have reviewed up to this commit, the previous commits looked fine. I want a different commit history for this:

  • Extract the logic that previously lived in add_connection() into a separate method register_connection(). The new method should live below the existing one, since it is called by it and we follow top-down ordering.
  • Move logic from insert_conn() into register_connection().
  • Move the self.index.insert_initial() call.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! Split it into 3 separate commits starting with 885c1fc

&mut self,
ch: ConnectionHandle,
init_cid: ConnectionId,
loc_cid: ConnectionId,
pref_addr_cid: Option<ConnectionId>,
addresses: FourTuple,
side: Side,
) {
let mut cids_issued = 0;
let mut loc_cids = FxHashMap::default();

Expand All @@ -845,9 +861,27 @@ impl Endpoint {
});
debug_assert_eq!(id, ch.0, "connection handle allocation out of sync");

self.index.insert_conn(addresses, loc_cid, ch, side);

conn
let conn_meta = &self.connections[ch];
for cid in conn_meta.loc_cids.values() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I got to "inline insert_conn into register_connection". For these changes, I want to split into (1) a commit that moves the code and (2) a commit that changes the code.

(This is basically the same for all the changes you're submitting -- please self-review.)

In order to make progress here, maybe submit a separate PR with the commits before this one, so we can get it merged? This is pretty hard to digest.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The first part is here #2771

if cid.is_empty() {
match conn_meta.side {
Side::Server => {
self.index
.incoming_connection_remotes
.insert(conn_meta.addresses, ch);
}
Side::Client => {
self.index
.outgoing_connection_remotes
.insert(conn_meta.addresses.remote, ch);
}
}
} else {
self.index
.connection_ids
.insert(*cid, RouteDatagramTo::Connection(ch));
}
}
}

fn initial_close(
Expand Down Expand Up @@ -984,7 +1018,7 @@ struct ConnectionIndex {
/// Identifies connections based on locally created CIDs
///
/// Uses a cheaper hash function since keys are locally created
connection_ids: FxHashMap<ConnectionId, ConnectionHandle>,
connection_ids: FxHashMap<ConnectionId, RouteDatagramTo>,
/// Identifies incoming connections with zero-length CIDs
///
/// Uses a standard `HashMap` to protect against hash collision attacks.
Expand Down Expand Up @@ -1033,32 +1067,6 @@ impl ConnectionIndex {
.insert(dst_cid, RouteDatagramTo::Connection(connection));
}

/// Associate a connection with its first locally-chosen destination CID if used, or otherwise
/// its current 4-tuple
fn insert_conn(
&mut self,
addresses: FourTuple,
dst_cid: ConnectionId,
connection: ConnectionHandle,
side: Side,
) {
match dst_cid.len() {
0 => match side {
Side::Server => {
self.incoming_connection_remotes
.insert(addresses, connection);
}
Side::Client => {
self.outgoing_connection_remotes
.insert(addresses.remote, connection);
}
},
_ => {
self.connection_ids.insert(dst_cid, connection);
}
}
}

/// Discard a connection ID
fn retire(&mut self, dst_cid: ConnectionId) {
self.connection_ids.remove(&dst_cid);
Expand All @@ -1083,13 +1091,13 @@ impl ConnectionIndex {
/// Find the existing connection that `datagram` should be routed to, if any
fn get(&self, addresses: &FourTuple, datagram: &PartialDecode) -> Option<RouteDatagramTo> {
if !datagram.dst_cid().is_empty() {
if let Some(&ch) = self.connection_ids.get(&datagram.dst_cid()) {
return Some(RouteDatagramTo::Connection(ch));
if let Some(&route) = self.connection_ids.get(&datagram.dst_cid()) {
return Some(route);
}
}
if datagram.is_initial() || datagram.is_0rtt() {
if let Some(&ch) = self.connection_ids_initial.get(&datagram.dst_cid()) {
return Some(ch);
if let Some(&route) = self.connection_ids_initial.get(&datagram.dst_cid()) {
return Some(route);
}
}
if datagram.dst_cid().is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion quinn-udp/src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ impl ControlMetadata {
(libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => {
let pktinfo = unsafe { cmsg::decode::<libc::in6_pktinfo, libc::cmsghdr>(cmsg) };
self.dst_ip = Some(IpAddr::V6(Ipv6Addr::from(pktinfo.ipi6_addr.s6_addr)));
#[cfg_attr(not(target_os = "android"), expect(clippy::unnecessary_cast))]
#[allow(clippy::unnecessary_cast)]
{
self.interface_index = Some(pktinfo.ipi6_ifindex as u32);
}
Expand Down