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