Skip to content

Commit 22f3934

Browse files
committed
Define a path migration event
1 parent 9edeb52 commit 22f3934

6 files changed

Lines changed: 49 additions & 7 deletions

File tree

neqo-bin/src/server/http09.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ impl super::HttpServer for HttpServer {
232232
}
233233
ConnectionEvent::StateChange(_)
234234
| ConnectionEvent::SendStreamCreatable { .. }
235-
| ConnectionEvent::SendStreamComplete { .. } => (),
235+
| ConnectionEvent::SendStreamComplete { .. }
236+
| ConnectionEvent::PathMigrated { .. } => (),
236237
e => qwarn!("unhandled event {e:?}"),
237238
}
238239
}

neqo-http3/src/connection_client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,8 @@ impl Http3Client {
11701170
ConnectionEvent::SendStreamComplete { .. }
11711171
| ConnectionEvent::OutgoingDatagramOutcome { .. }
11721172
| ConnectionEvent::IncomingDatagramDropped
1173-
| ConnectionEvent::SconeUpdated(_) => {}
1173+
| ConnectionEvent::SconeUpdated(_)
1174+
| ConnectionEvent::PathMigrated { .. } => {}
11741175
}
11751176
}
11761177
Ok(())

neqo-http3/src/connection_server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ impl Http3ServerHandler {
377377
| ConnectionEvent::SendStreamCreatable { .. }
378378
| ConnectionEvent::OutgoingDatagramOutcome { .. }
379379
| ConnectionEvent::IncomingDatagramDropped
380-
| ConnectionEvent::SconeUpdated(_) => {}
380+
| ConnectionEvent::SconeUpdated(_)
381+
| ConnectionEvent::PathMigrated { .. } => {}
381382
}
382383
}
383384
Ok(())

neqo-transport/src/connection/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,9 @@ impl Connection {
20962096
.migrate(&path, force, now, &mut self.stats.borrow_mut())
20972097
{
20982098
self.loss_recovery.migrate();
2099+
let local = path.borrow().local_address();
2100+
let remote = path.borrow().remote_address();
2101+
self.events.path_migrated(local, remote);
20992102
}
21002103
Ok(())
21012104
}
@@ -2164,8 +2167,14 @@ impl Connection {
21642167
}
21652168

21662169
if self.ensure_permanent(path, now).is_ok() {
2170+
let was_primary = path.borrow().is_primary();
21672171
self.paths
21682172
.handle_migration(path, remote, now, &mut self.stats.borrow_mut());
2173+
if !was_primary {
2174+
let local = path.borrow().local_address();
2175+
let remote_addr = path.borrow().remote_address();
2176+
self.events.path_migrated(local, remote_addr);
2177+
}
21692178
} else {
21702179
qinfo!(
21712180
"[{self}] {} Peer migrated, but no connection ID available",
@@ -3382,6 +3391,11 @@ impl Connection {
33823391
{
33833392
// This PATH_RESPONSE enabled migration; tell loss recovery.
33843393
self.loss_recovery.migrate();
3394+
if let Some(primary) = self.paths.primary() {
3395+
let local = primary.borrow().local_address();
3396+
let remote = primary.borrow().remote_address();
3397+
self.events.path_migrated(local, remote);
3398+
}
33853399
}
33863400
}
33873401
Frame::ConnectionClose {

neqo-transport/src/connection/tests/migration.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::{
1717
time::{Duration, Instant},
1818
};
1919

20-
use neqo_common::{Datagram, Decoder, qdebug};
20+
use neqo_common::{Datagram, Decoder, event::Provider as _, qdebug};
2121
use test_fixture::{
2222
DEFAULT_ADDR, DEFAULT_ADDR_V4,
2323
assertions::{assert_v4_path, assert_v6_path},
@@ -31,8 +31,9 @@ use super::{
3131
zero_len_cid_client,
3232
};
3333
use crate::{
34-
CloseReason, ConnectionId, ConnectionIdDecoder as _, ConnectionIdGenerator, ConnectionIdRef,
35-
ConnectionParameters, EmptyConnectionIdGenerator, Error, MIN_INITIAL_PACKET_SIZE,
34+
CloseReason, ConnectionEvent, ConnectionId, ConnectionIdDecoder as _, ConnectionIdGenerator,
35+
ConnectionIdRef, ConnectionParameters, EmptyConnectionIdGenerator, Error,
36+
MIN_INITIAL_PACKET_SIZE,
3637
cid::ConnectionIdManager,
3738
connection::tests::{
3839
assert_path_challenge_min_len, connect, send_something_paced, send_with_extra,
@@ -434,6 +435,11 @@ fn migrate_immediate() {
434435
client
435436
.migrate(Some(DEFAULT_ADDR_V4), Some(DEFAULT_ADDR_V4), true, now)
436437
.unwrap();
438+
assert!(client.events().any(|e| matches!(
439+
e,
440+
ConnectionEvent::PathMigrated { local, remote }
441+
if local == DEFAULT_ADDR_V4 && remote == DEFAULT_ADDR_V4
442+
)));
437443

438444
let client1 = send_something(&mut client, now);
439445
assert_v4_path(&client1, true); // Contains PATH_CHALLENGE.
@@ -447,6 +453,11 @@ fn migrate_immediate() {
447453
// The server accepts the first packet and migrates (but probes).
448454
let server1 = server.process(Some(client1), now).dgram().unwrap();
449455
assert_v4_path(&server1, true);
456+
assert!(
457+
server
458+
.events()
459+
.any(|e| matches!(e, ConnectionEvent::PathMigrated { .. }))
460+
);
450461
let server2 = server.process_output(now).dgram().unwrap();
451462
assert_v6_path(&server2, true);
452463

@@ -655,6 +666,11 @@ fn migration(mut client: Connection) {
655666

656667
// Once the client receives the probe response, it migrates to the new path.
657668
client.process_input(resp, now);
669+
assert!(client.events().any(|e| matches!(
670+
e,
671+
ConnectionEvent::PathMigrated { local, remote }
672+
if local == DEFAULT_ADDR_V4 && remote == DEFAULT_ADDR_V4
673+
)));
658674
assert_eq!(client.stats().frame_rx.path_challenge, 1);
659675
let migrate_client = send_something(&mut client, now);
660676
assert_v4_path(&migrate_client, true); // Responds to server probe.

neqo-transport/src/events.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// Collecting a list of events relevant to whoever is using the Connection.
88

9-
use std::{cell::RefCell, collections::VecDeque, num::NonZeroU64, rc::Rc};
9+
use std::{cell::RefCell, collections::VecDeque, num::NonZeroU64, net::SocketAddr, rc::Rc};
1010

1111
use neqo_common::event::Provider as EventProvider;
1212
use nss::ResumptionToken;
@@ -82,6 +82,11 @@ pub enum ConnectionEvent {
8282
/// An update was received to SCONE throughput advice.
8383
/// The value is the approximate rate in bits per second; None = unknown.
8484
SconeUpdated(Option<NonZeroU64>),
85+
/// A path migration completed; the connection is now sending on this path.
86+
PathMigrated {
87+
local: SocketAddr,
88+
remote: SocketAddr,
89+
},
8590
}
8691

8792
#[derive(Debug, Default, Clone)]
@@ -216,6 +221,10 @@ impl ConnectionEvents {
216221
}
217222
}
218223

224+
pub fn path_migrated(&self, local: SocketAddr, remote: SocketAddr) {
225+
self.insert(ConnectionEvent::PathMigrated { local, remote });
226+
}
227+
219228
fn insert(&self, event: ConnectionEvent) {
220229
let mut q = self.events.borrow_mut();
221230

0 commit comments

Comments
 (0)