1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4 // option. This file may not be copied, modified, or distributed
5 // except according to those terms.
6 
7 use super::{
8     connect, connect_with_rtt, default_client, default_server, exchange_ticket, get_tokens,
9     send_something, AT_LEAST_PTO,
10 };
11 use crate::addr_valid::{AddressValidation, ValidateAddress};
12 
13 use std::cell::RefCell;
14 use std::mem;
15 use std::rc::Rc;
16 use std::time::Duration;
17 use test_fixture::{self, assertions, now};
18 
19 #[test]
resume()20 fn resume() {
21     let mut client = default_client();
22     let mut server = default_server();
23     connect(&mut client, &mut server);
24 
25     let token = exchange_ticket(&mut client, &mut server, now());
26     let mut client = default_client();
27     client
28         .enable_resumption(now(), token)
29         .expect("should set token");
30     let mut server = default_server();
31     connect(&mut client, &mut server);
32     assert!(client.tls_info().unwrap().resumed());
33     assert!(server.tls_info().unwrap().resumed());
34 }
35 
36 #[test]
remember_smoothed_rtt()37 fn remember_smoothed_rtt() {
38     const RTT1: Duration = Duration::from_millis(130);
39     const RTT2: Duration = Duration::from_millis(70);
40 
41     let mut client = default_client();
42     let mut server = default_server();
43 
44     let mut now = connect_with_rtt(&mut client, &mut server, now(), RTT1);
45     assert_eq!(client.paths.rtt(), RTT1);
46 
47     // We can't use exchange_ticket here because it doesn't respect RTT.
48     // Also, connect_with_rtt() ends with the server receiving a packet it
49     // wants to acknowledge; so the ticket will include an ACK frame too.
50     let validation = AddressValidation::new(now, ValidateAddress::NoToken).unwrap();
51     let validation = Rc::new(RefCell::new(validation));
52     server.set_validation(Rc::clone(&validation));
53     server.send_ticket(now, &[]).expect("can send ticket");
54     let ticket = server.process_output(now).dgram();
55     assert!(ticket.is_some());
56     now += RTT1 / 2;
57     client.process_input(ticket.unwrap(), now);
58     let token = get_tokens(&mut client).pop().unwrap();
59 
60     let mut client = default_client();
61     let mut server = default_server();
62     client.enable_resumption(now, token).unwrap();
63     assert_eq!(
64         client.paths.rtt(),
65         RTT1,
66         "client should remember previous RTT"
67     );
68 
69     connect_with_rtt(&mut client, &mut server, now, RTT2);
70     assert_eq!(
71         client.paths.rtt(),
72         RTT2,
73         "previous RTT should be completely erased"
74     );
75 }
76 
77 /// Check that a resumed connection uses a token on Initial packets.
78 #[test]
address_validation_token_resume()79 fn address_validation_token_resume() {
80     const RTT: Duration = Duration::from_millis(10);
81 
82     let mut client = default_client();
83     let mut server = default_server();
84     let validation = AddressValidation::new(now(), ValidateAddress::Always).unwrap();
85     let validation = Rc::new(RefCell::new(validation));
86     server.set_validation(Rc::clone(&validation));
87     let mut now = connect_with_rtt(&mut client, &mut server, now(), RTT);
88 
89     let token = exchange_ticket(&mut client, &mut server, now);
90     let mut client = default_client();
91     client.enable_resumption(now, token).unwrap();
92     let mut server = default_server();
93 
94     // Grab an Initial packet from the client.
95     let dgram = client.process(None, now).dgram();
96     assertions::assert_initial(dgram.as_ref().unwrap(), true);
97 
98     // Now try to complete the handshake after giving time for a client PTO.
99     now += AT_LEAST_PTO;
100     connect_with_rtt(&mut client, &mut server, now, RTT);
101     assert!(client.crypto.tls.info().unwrap().resumed());
102     assert!(server.crypto.tls.info().unwrap().resumed());
103 }
104 
can_resume(token: impl AsRef<[u8]>, initial_has_token: bool)105 fn can_resume(token: impl AsRef<[u8]>, initial_has_token: bool) {
106     let mut client = default_client();
107     client.enable_resumption(now(), token).unwrap();
108     let initial = client.process_output(now()).dgram();
109     assertions::assert_initial(initial.as_ref().unwrap(), initial_has_token);
110 }
111 
112 #[test]
two_tickets_on_timer()113 fn two_tickets_on_timer() {
114     let mut client = default_client();
115     let mut server = default_server();
116     connect(&mut client, &mut server);
117 
118     // Send two tickets and then bundle those into a packet.
119     server.send_ticket(now(), &[]).expect("send ticket1");
120     server.send_ticket(now(), &[]).expect("send ticket2");
121     let pkt = send_something(&mut server, now());
122 
123     // process() will return an ack first
124     assert!(client.process(Some(pkt), now()).dgram().is_some());
125     // We do not have a ResumptionToken event yet, because NEW_TOKEN was not sent.
126     assert_eq!(get_tokens(&mut client).len(), 0);
127 
128     // We need to wait for release_resumption_token_timer to expire. The timer will be
129     // set to 3 * PTO
130     let mut now = now() + 3 * client.pto();
131     mem::drop(client.process(None, now));
132     let mut recv_tokens = get_tokens(&mut client);
133     assert_eq!(recv_tokens.len(), 1);
134     let token1 = recv_tokens.pop().unwrap();
135     // Wai for anottheer 3 * PTO to get the nex okeen.
136     now += 3 * client.pto();
137     mem::drop(client.process(None, now));
138     let mut recv_tokens = get_tokens(&mut client);
139     assert_eq!(recv_tokens.len(), 1);
140     let token2 = recv_tokens.pop().unwrap();
141     // Wait for 3 * PTO, but now there are no more tokens.
142     now += 3 * client.pto();
143     mem::drop(client.process(None, now));
144     assert_eq!(get_tokens(&mut client).len(), 0);
145     assert_ne!(token1.as_ref(), token2.as_ref());
146 
147     can_resume(&token1, false);
148     can_resume(&token2, false);
149 }
150 
151 #[test]
two_tickets_with_new_token()152 fn two_tickets_with_new_token() {
153     let mut client = default_client();
154     let mut server = default_server();
155     let validation = AddressValidation::new(now(), ValidateAddress::Always).unwrap();
156     let validation = Rc::new(RefCell::new(validation));
157     server.set_validation(Rc::clone(&validation));
158     connect(&mut client, &mut server);
159 
160     // Send two tickets with tokens and then bundle those into a packet.
161     server.send_ticket(now(), &[]).expect("send ticket1");
162     server.send_ticket(now(), &[]).expect("send ticket2");
163     let pkt = send_something(&mut server, now());
164 
165     client.process_input(pkt, now());
166     let mut all_tokens = get_tokens(&mut client);
167     assert_eq!(all_tokens.len(), 2);
168     let token1 = all_tokens.pop().unwrap();
169     let token2 = all_tokens.pop().unwrap();
170     assert_ne!(token1.as_ref(), token2.as_ref());
171 
172     can_resume(&token1, true);
173     can_resume(&token2, true);
174 }
175 
176 /// By disabling address validation, the server won't send `NEW_TOKEN`, but
177 /// we can take the session ticket still.
178 #[test]
take_token()179 fn take_token() {
180     let mut client = default_client();
181     let mut server = default_server();
182     connect(&mut client, &mut server);
183 
184     server.send_ticket(now(), &[]).unwrap();
185     let dgram = server.process(None, now()).dgram();
186     client.process_input(dgram.unwrap(), now());
187 
188     // There should be no ResumptionToken event here.
189     let tokens = get_tokens(&mut client);
190     assert_eq!(tokens.len(), 0);
191 
192     // But we should be able to get the token directly, and use it.
193     let token = client.take_resumption_token(now()).unwrap();
194     can_resume(&token, false);
195 }
196