Skip to content

Commit e695df6

Browse files
add tests
1 parent d9c00fb commit e695df6

File tree

1 file changed

+274
-0
lines changed

1 file changed

+274
-0
lines changed

quinn-proto/src/tests/mod.rs

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,6 +3185,280 @@ fn voluntary_ack_with_large_datagrams() {
31853185
);
31863186
}
31873187

3188+
/// Test the address discovery extension on a normal setup.
3189+
#[test]
3190+
fn address_discovery() {
3191+
let _guard = subscribe();
3192+
3193+
let server = ServerConfig {
3194+
transport: Arc::new(TransportConfig {
3195+
address_discovery_role: crate::address_discovery::Role::Both,
3196+
..TransportConfig::default()
3197+
}),
3198+
..server_config()
3199+
};
3200+
let mut pair = Pair::new(Default::default(), server);
3201+
let client_config = ClientConfig {
3202+
transport: Arc::new(TransportConfig {
3203+
address_discovery_role: crate::address_discovery::Role::Both,
3204+
..TransportConfig::default()
3205+
}),
3206+
..client_config()
3207+
};
3208+
let conn_handle = pair.begin_connect(client_config);
3209+
3210+
// wait for idle connections
3211+
pair.drive();
3212+
3213+
// check that the client received the correct address
3214+
let expected_addr = pair.client.addr;
3215+
let conn = pair.client_conn_mut(conn_handle);
3216+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3217+
assert_matches!(conn.poll(), Some(Event::Connected));
3218+
assert_matches!(conn.poll(), Some(Event::ObservedAddr(addr)) if addr == expected_addr);
3219+
assert_matches!(conn.poll(), None);
3220+
3221+
// check that the server received the correct address
3222+
let conn_handle = pair.server.assert_accept();
3223+
let expected_addr = pair.server.addr;
3224+
let conn = pair.server_conn_mut(conn_handle);
3225+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3226+
assert_matches!(conn.poll(), Some(Event::Connected));
3227+
assert_matches!(conn.poll(), Some(Event::ObservedAddr(addr)) if addr == expected_addr);
3228+
assert_matches!(conn.poll(), None);
3229+
}
3230+
3231+
/// Test that a different address discovery configuration on 0rtt used by the client is accepted by
3232+
/// the server.
3233+
/// NOTE: this test is the same as zero_rtt_happypath, changing client transport parameters on
3234+
/// resumption.
3235+
#[test]
3236+
fn address_discovery_zero_rtt_accepted() {
3237+
let _guard = subscribe();
3238+
let server = ServerConfig {
3239+
transport: Arc::new(TransportConfig {
3240+
address_discovery_role: crate::address_discovery::Role::Both,
3241+
..TransportConfig::default()
3242+
}),
3243+
..server_config()
3244+
};
3245+
let mut pair = Pair::new(Default::default(), server);
3246+
3247+
pair.server.incoming_connection_behavior = IncomingConnectionBehavior::Validate;
3248+
let client_cfg = ClientConfig {
3249+
transport: Arc::new(TransportConfig {
3250+
address_discovery_role: crate::address_discovery::Role::Both,
3251+
..TransportConfig::default()
3252+
}),
3253+
..client_config()
3254+
};
3255+
let alt_client_cfg = ClientConfig {
3256+
transport: Arc::new(TransportConfig {
3257+
address_discovery_role: crate::address_discovery::Role::Disabled,
3258+
..TransportConfig::default()
3259+
}),
3260+
..client_cfg.clone()
3261+
};
3262+
3263+
// Establish normal connection
3264+
let client_ch = pair.begin_connect(client_cfg);
3265+
pair.drive();
3266+
pair.server.assert_accept();
3267+
pair.client
3268+
.connections
3269+
.get_mut(&client_ch)
3270+
.unwrap()
3271+
.close(pair.time, VarInt(0), [][..].into());
3272+
pair.drive();
3273+
3274+
pair.client.addr = SocketAddr::new(
3275+
Ipv6Addr::LOCALHOST.into(),
3276+
CLIENT_PORTS.lock().unwrap().next().unwrap(),
3277+
);
3278+
info!("resuming session");
3279+
let client_ch = pair.begin_connect(alt_client_cfg);
3280+
assert!(pair.client_conn_mut(client_ch).has_0rtt());
3281+
let s = pair.client_streams(client_ch).open(Dir::Uni).unwrap();
3282+
const MSG: &[u8] = b"Hello, 0-RTT!";
3283+
pair.client_send(client_ch, s).write(MSG).unwrap();
3284+
pair.drive();
3285+
3286+
let conn = pair.client_conn_mut(client_ch);
3287+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3288+
assert_matches!(conn.poll(), Some(Event::Connected));
3289+
3290+
assert!(pair.client_conn_mut(client_ch).accepted_0rtt());
3291+
let server_ch = pair.server.assert_accept();
3292+
3293+
let conn = pair.server_conn_mut(server_ch);
3294+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3295+
// We don't currently preserve stream event order wrt. connection events
3296+
assert_matches!(conn.poll(), Some(Event::Connected));
3297+
assert_matches!(
3298+
conn.poll(),
3299+
Some(Event::Stream(StreamEvent::Opened { dir: Dir::Uni }))
3300+
);
3301+
3302+
let mut recv = pair.server_recv(server_ch, s);
3303+
let mut chunks = recv.read(false).unwrap();
3304+
assert_matches!(
3305+
chunks.next(usize::MAX),
3306+
Ok(Some(chunk)) if chunk.offset == 0 && chunk.bytes == MSG
3307+
);
3308+
let _ = chunks.finalize();
3309+
assert_eq!(pair.client_conn_mut(client_ch).lost_packets(), 0);
3310+
}
3311+
3312+
/// Test that a different address discovery configuration on 0rtt used by the server is rejected by
3313+
/// the client.
3314+
/// NOTE: the server MUST not change configuration on resumption. However, there is no designed
3315+
/// behaviour when this is encountered. Quinn chooses to accept and then close the connection,
3316+
/// which is what this test checks.
3317+
#[test]
3318+
fn address_discovery_zero_rtt_rejection() {
3319+
let _guard = subscribe();
3320+
let server_cfg = ServerConfig {
3321+
transport: Arc::new(TransportConfig {
3322+
address_discovery_role: crate::address_discovery::Role::Disabled,
3323+
..TransportConfig::default()
3324+
}),
3325+
..server_config()
3326+
};
3327+
let alt_server_cfg = ServerConfig {
3328+
transport: Arc::new(TransportConfig {
3329+
address_discovery_role: crate::address_discovery::Role::SendOnly,
3330+
..TransportConfig::default()
3331+
}),
3332+
..server_cfg.clone()
3333+
};
3334+
let mut pair = Pair::new(Default::default(), server_cfg);
3335+
let client_cfg = ClientConfig {
3336+
transport: Arc::new(TransportConfig {
3337+
address_discovery_role: crate::address_discovery::Role::Both,
3338+
..TransportConfig::default()
3339+
}),
3340+
..client_config()
3341+
};
3342+
3343+
// Establish normal connection
3344+
let client_ch = pair.begin_connect(client_cfg.clone());
3345+
pair.drive();
3346+
let server_ch = pair.server.assert_accept();
3347+
let conn = pair.server_conn_mut(server_ch);
3348+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3349+
assert_matches!(conn.poll(), Some(Event::Connected));
3350+
assert_matches!(conn.poll(), None);
3351+
pair.client
3352+
.connections
3353+
.get_mut(&client_ch)
3354+
.unwrap()
3355+
.close(pair.time, VarInt(0), [][..].into());
3356+
pair.drive();
3357+
assert_matches!(
3358+
pair.server_conn_mut(server_ch).poll(),
3359+
Some(Event::ConnectionLost { .. })
3360+
);
3361+
assert_matches!(pair.server_conn_mut(server_ch).poll(), None);
3362+
pair.client.connections.clear();
3363+
pair.server.connections.clear();
3364+
3365+
// Changing address discovery configurations makes the client close the connection
3366+
pair.server
3367+
.set_server_config(Some(Arc::new(alt_server_cfg)));
3368+
info!("resuming session");
3369+
let client_ch = pair.begin_connect(client_cfg);
3370+
assert!(pair.client_conn_mut(client_ch).has_0rtt());
3371+
let s = pair.client_streams(client_ch).open(Dir::Uni).unwrap();
3372+
const MSG: &[u8] = b"Hello, 0-RTT!";
3373+
pair.client_send(client_ch, s).write(MSG).unwrap();
3374+
pair.drive();
3375+
let conn = pair.client_conn_mut(server_ch);
3376+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3377+
assert_matches!(
3378+
conn.poll(),
3379+
Some(Event::ConnectionLost { reason }) if matches!(reason, ConnectionError::TransportError(_) )
3380+
);
3381+
}
3382+
3383+
#[test]
3384+
fn address_discovery_retransmission() {
3385+
let _guard = subscribe();
3386+
3387+
let server = ServerConfig {
3388+
transport: Arc::new(TransportConfig {
3389+
address_discovery_role: crate::address_discovery::Role::Both,
3390+
..TransportConfig::default()
3391+
}),
3392+
..server_config()
3393+
};
3394+
let mut pair = Pair::new(Default::default(), server);
3395+
let client_config = ClientConfig {
3396+
transport: Arc::new(TransportConfig {
3397+
address_discovery_role: crate::address_discovery::Role::Both,
3398+
..TransportConfig::default()
3399+
}),
3400+
..client_config()
3401+
};
3402+
let client_ch = pair.begin_connect(client_config);
3403+
pair.step();
3404+
3405+
// lose the last packet
3406+
pair.client.inbound.pop_back().unwrap();
3407+
pair.step();
3408+
let conn = pair.client_conn_mut(client_ch);
3409+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3410+
assert_matches!(conn.poll(), Some(Event::Connected));
3411+
assert_matches!(conn.poll(), None);
3412+
3413+
pair.drive();
3414+
let conn = pair.client_conn_mut(client_ch);
3415+
assert_matches!(conn.poll(),
3416+
Some(Event::ObservedAddr(addr)) if addr == pair.client.addr);
3417+
}
3418+
3419+
#[test]
3420+
fn address_discovery_rebind_retransmission() {
3421+
let _guard = subscribe();
3422+
3423+
let server = ServerConfig {
3424+
transport: Arc::new(TransportConfig {
3425+
address_discovery_role: crate::address_discovery::Role::Both,
3426+
..TransportConfig::default()
3427+
}),
3428+
..server_config()
3429+
};
3430+
let mut pair = Pair::new(Default::default(), server);
3431+
let client_config = ClientConfig {
3432+
transport: Arc::new(TransportConfig {
3433+
address_discovery_role: crate::address_discovery::Role::Both,
3434+
..TransportConfig::default()
3435+
}),
3436+
..client_config()
3437+
};
3438+
let client_ch = pair.begin_connect(client_config);
3439+
pair.step();
3440+
3441+
// lose the last packet
3442+
pair.client.inbound.pop_back().unwrap();
3443+
pair.step();
3444+
let conn = pair.client_conn_mut(client_ch);
3445+
assert_matches!(conn.poll(), Some(Event::HandshakeDataReady));
3446+
assert_matches!(conn.poll(), Some(Event::Connected));
3447+
assert_matches!(conn.poll(), None);
3448+
3449+
// simulate a rebind to ensure we will get an updated address instead of retransmitting
3450+
// outdated info
3451+
pair.client_conn_mut(client_ch).local_address_changed();
3452+
pair.client
3453+
.addr
3454+
.set_port(pair.client.addr.port().overflowing_add(1).0);
3455+
3456+
pair.drive();
3457+
let conn = pair.client_conn_mut(client_ch);
3458+
assert_matches!(conn.poll(),
3459+
Some(Event::ObservedAddr(addr)) if addr == pair.client.addr);
3460+
}
3461+
31883462
#[test]
31893463
fn reject_short_idcid() {
31903464
let _guard = subscribe();

0 commit comments

Comments
 (0)