Skip to content

Commit abc646a

Browse files
add tests
1 parent cb8ccc8 commit abc646a

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
@@ -3184,6 +3184,280 @@ fn voluntary_ack_with_large_datagrams() {
31843184
);
31853185
}
31863186

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

0 commit comments

Comments
 (0)