BadVPN – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #include "test_tcp_oos.h" |
2 | |||
3 | #include "lwip/priv/tcp_priv.h" |
||
4 | #include "lwip/stats.h" |
||
5 | #include "tcp_helper.h" |
||
6 | |||
7 | #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS |
||
8 | #error "This tests needs TCP- and MEMP-statistics enabled" |
||
9 | #endif |
||
10 | #if !TCP_QUEUE_OOSEQ |
||
11 | #error "This tests needs TCP_QUEUE_OOSEQ enabled" |
||
12 | #endif |
||
13 | |||
14 | /** CHECK_SEGMENTS_ON_OOSEQ: |
||
15 | * 1: check count, seqno and len of segments on pcb->ooseq (strict) |
||
16 | * 0: only check that bytes are received in correct order (less strict) */ |
||
17 | #define CHECK_SEGMENTS_ON_OOSEQ 1 |
||
18 | |||
19 | #if CHECK_SEGMENTS_ON_OOSEQ |
||
20 | #define EXPECT_OOSEQ(x) EXPECT(x) |
||
21 | #else |
||
22 | #define EXPECT_OOSEQ(x) |
||
23 | #endif |
||
24 | |||
25 | /* helper functions */ |
||
26 | |||
27 | /** Get the numbers of segments on the ooseq list */ |
||
28 | static int tcp_oos_count(struct tcp_pcb* pcb) |
||
29 | { |
||
30 | int num = 0; |
||
31 | struct tcp_seg* seg = pcb->ooseq; |
||
32 | while(seg != NULL) { |
||
33 | num++; |
||
34 | seg = seg->next; |
||
35 | } |
||
36 | return num; |
||
37 | } |
||
38 | |||
39 | #if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) |
||
40 | /** Get the numbers of pbufs on the ooseq list */ |
||
41 | static int tcp_oos_pbuf_count(struct tcp_pcb* pcb) |
||
42 | { |
||
43 | int num = 0; |
||
44 | struct tcp_seg* seg = pcb->ooseq; |
||
45 | while(seg != NULL) { |
||
46 | num += pbuf_clen(seg->p); |
||
47 | seg = seg->next; |
||
48 | } |
||
49 | return num; |
||
50 | } |
||
51 | #endif |
||
52 | |||
53 | /** Get the seqno of a segment (by index) on the ooseq list |
||
54 | * |
||
55 | * @param pcb the pcb to check for ooseq segments |
||
56 | * @param seg_index index of the segment on the ooseq list |
||
57 | * @return seqno of the segment |
||
58 | */ |
||
59 | static u32_t |
||
60 | tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index) |
||
61 | { |
||
62 | int num = 0; |
||
63 | struct tcp_seg* seg = pcb->ooseq; |
||
64 | |||
65 | /* then check the actual segment */ |
||
66 | while(seg != NULL) { |
||
67 | if(num == seg_index) { |
||
68 | return seg->tcphdr->seqno; |
||
69 | } |
||
70 | num++; |
||
71 | seg = seg->next; |
||
72 | } |
||
73 | fail(); |
||
74 | return 0; |
||
75 | } |
||
76 | |||
77 | /** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list |
||
78 | * |
||
79 | * @param pcb the pcb to check for ooseq segments |
||
80 | * @param seg_index index of the segment on the ooseq list |
||
81 | * @return tcplen of the segment |
||
82 | */ |
||
83 | static int |
||
84 | tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index) |
||
85 | { |
||
86 | int num = 0; |
||
87 | struct tcp_seg* seg = pcb->ooseq; |
||
88 | |||
89 | /* then check the actual segment */ |
||
90 | while(seg != NULL) { |
||
91 | if(num == seg_index) { |
||
92 | return TCP_TCPLEN(seg); |
||
93 | } |
||
94 | num++; |
||
95 | seg = seg->next; |
||
96 | } |
||
97 | fail(); |
||
98 | return -1; |
||
99 | } |
||
100 | |||
101 | /** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list |
||
102 | * |
||
103 | * @param pcb the pcb to check for ooseq segments |
||
104 | * @return tcplen of all segment |
||
105 | */ |
||
106 | static int |
||
107 | tcp_oos_tcplen(struct tcp_pcb* pcb) |
||
108 | { |
||
109 | int len = 0; |
||
110 | struct tcp_seg* seg = pcb->ooseq; |
||
111 | |||
112 | /* then check the actual segment */ |
||
113 | while(seg != NULL) { |
||
114 | len += TCP_TCPLEN(seg); |
||
115 | seg = seg->next; |
||
116 | } |
||
117 | return len; |
||
118 | } |
||
119 | |||
120 | /* Setup/teardown functions */ |
||
121 | static struct netif *old_netif_list; |
||
122 | static struct netif *old_netif_default; |
||
123 | |||
124 | static void |
||
125 | tcp_oos_setup(void) |
||
126 | { |
||
127 | old_netif_list = netif_list; |
||
128 | old_netif_default = netif_default; |
||
129 | netif_list = NULL; |
||
130 | netif_default = NULL; |
||
131 | tcp_remove_all(); |
||
132 | lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT)); |
||
133 | } |
||
134 | |||
135 | static void |
||
136 | tcp_oos_teardown(void) |
||
137 | { |
||
138 | netif_list = NULL; |
||
139 | netif_default = NULL; |
||
140 | tcp_remove_all(); |
||
141 | /* restore netif_list for next tests (e.g. loopif) */ |
||
142 | netif_list = old_netif_list; |
||
143 | netif_default = old_netif_default; |
||
144 | lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT)); |
||
145 | } |
||
146 | |||
147 | |||
148 | |||
149 | /* Test functions */ |
||
150 | |||
151 | /** create multiple segments and pass them to tcp_input in a wrong |
||
152 | * order to see if ooseq-caching works correctly |
||
153 | * FIN is received in out-of-sequence segments only */ |
||
154 | START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) |
||
155 | { |
||
156 | struct test_tcp_counters counters; |
||
157 | struct tcp_pcb* pcb; |
||
158 | struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq; |
||
159 | char data[] = { |
||
160 | 1, 2, 3, 4, |
||
161 | 5, 6, 7, 8, |
||
162 | 9, 10, 11, 12, |
||
163 | 13, 14, 15, 16}; |
||
164 | u16_t data_len; |
||
165 | struct netif netif; |
||
166 | LWIP_UNUSED_ARG(_i); |
||
167 | |||
168 | /* initialize local vars */ |
||
169 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
170 | data_len = sizeof(data); |
||
171 | /* initialize counter struct */ |
||
172 | memset(&counters, 0, sizeof(counters)); |
||
173 | counters.expected_data_len = data_len; |
||
174 | counters.expected_data = data; |
||
175 | |||
176 | /* create and initialize the pcb */ |
||
177 | pcb = test_tcp_new_counters_pcb(&counters); |
||
178 | EXPECT_RET(pcb != NULL); |
||
179 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
180 | |||
181 | /* create segments */ |
||
182 | /* pinseq is sent as last segment! */ |
||
183 | pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK); |
||
184 | /* p1: 8 bytes before FIN */ |
||
185 | /* seqno: 8..16 */ |
||
186 | p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN); |
||
187 | /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */ |
||
188 | /* seqno: 4..11 */ |
||
189 | p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK); |
||
190 | /* p3: same as p2 but 2 bytes longer */ |
||
191 | /* seqno: 4..13 */ |
||
192 | p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK); |
||
193 | /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */ |
||
194 | /* seqno: 2..15 */ |
||
195 | p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK); |
||
196 | /* FIN, seqno 16 */ |
||
197 | p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN); |
||
198 | EXPECT(pinseq != NULL); |
||
199 | EXPECT(p_8_9 != NULL); |
||
200 | EXPECT(p_4_8 != NULL); |
||
201 | EXPECT(p_4_10 != NULL); |
||
202 | EXPECT(p_2_14 != NULL); |
||
203 | EXPECT(p_fin != NULL); |
||
204 | if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) { |
||
205 | /* pass the segment to tcp_input */ |
||
206 | test_tcp_input(p_8_9, &netif); |
||
207 | /* check if counters are as expected */ |
||
208 | EXPECT(counters.close_calls == 0); |
||
209 | EXPECT(counters.recv_calls == 0); |
||
210 | EXPECT(counters.recved_bytes == 0); |
||
211 | EXPECT(counters.err_calls == 0); |
||
212 | /* check ooseq queue */ |
||
213 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); |
||
214 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8); |
||
215 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */ |
||
216 | |||
217 | /* pass the segment to tcp_input */ |
||
218 | test_tcp_input(p_4_8, &netif); |
||
219 | /* check if counters are as expected */ |
||
220 | EXPECT(counters.close_calls == 0); |
||
221 | EXPECT(counters.recv_calls == 0); |
||
222 | EXPECT(counters.recved_bytes == 0); |
||
223 | EXPECT(counters.err_calls == 0); |
||
224 | /* check ooseq queue */ |
||
225 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); |
||
226 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4); |
||
227 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4); |
||
228 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); |
||
229 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ |
||
230 | |||
231 | /* pass the segment to tcp_input */ |
||
232 | test_tcp_input(p_4_10, &netif); |
||
233 | /* check if counters are as expected */ |
||
234 | EXPECT(counters.close_calls == 0); |
||
235 | EXPECT(counters.recv_calls == 0); |
||
236 | EXPECT(counters.recved_bytes == 0); |
||
237 | EXPECT(counters.err_calls == 0); |
||
238 | /* ooseq queue: unchanged */ |
||
239 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); |
||
240 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4); |
||
241 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4); |
||
242 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); |
||
243 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ |
||
244 | |||
245 | /* pass the segment to tcp_input */ |
||
246 | test_tcp_input(p_2_14, &netif); |
||
247 | /* check if counters are as expected */ |
||
248 | EXPECT(counters.close_calls == 0); |
||
249 | EXPECT(counters.recv_calls == 0); |
||
250 | EXPECT(counters.recved_bytes == 0); |
||
251 | EXPECT(counters.err_calls == 0); |
||
252 | /* check ooseq queue */ |
||
253 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); |
||
254 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); |
||
255 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ |
||
256 | |||
257 | /* pass the segment to tcp_input */ |
||
258 | test_tcp_input(p_fin, &netif); |
||
259 | /* check if counters are as expected */ |
||
260 | EXPECT(counters.close_calls == 0); |
||
261 | EXPECT(counters.recv_calls == 0); |
||
262 | EXPECT(counters.recved_bytes == 0); |
||
263 | EXPECT(counters.err_calls == 0); |
||
264 | /* ooseq queue: unchanged */ |
||
265 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); |
||
266 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); |
||
267 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ |
||
268 | |||
269 | /* pass the segment to tcp_input */ |
||
270 | test_tcp_input(pinseq, &netif); |
||
271 | /* check if counters are as expected */ |
||
272 | EXPECT(counters.close_calls == 1); |
||
273 | EXPECT(counters.recv_calls == 1); |
||
274 | EXPECT(counters.recved_bytes == data_len); |
||
275 | EXPECT(counters.err_calls == 0); |
||
276 | EXPECT(pcb->ooseq == NULL); |
||
277 | } |
||
278 | |||
279 | /* make sure the pcb is freed */ |
||
280 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
281 | tcp_abort(pcb); |
||
282 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
283 | } |
||
284 | END_TEST |
||
285 | |||
286 | |||
287 | /** create multiple segments and pass them to tcp_input in a wrong |
||
288 | * order to see if ooseq-caching works correctly |
||
289 | * FIN is received IN-SEQUENCE at the end */ |
||
290 | START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) |
||
291 | { |
||
292 | struct test_tcp_counters counters; |
||
293 | struct tcp_pcb* pcb; |
||
294 | struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN; |
||
295 | char data[] = { |
||
296 | 1, 2, 3, 4, |
||
297 | 5, 6, 7, 8, |
||
298 | 9, 10, 11, 12, |
||
299 | 13, 14, 15, 16}; |
||
300 | u16_t data_len; |
||
301 | struct netif netif; |
||
302 | LWIP_UNUSED_ARG(_i); |
||
303 | |||
304 | /* initialize local vars */ |
||
305 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
306 | data_len = sizeof(data); |
||
307 | /* initialize counter struct */ |
||
308 | memset(&counters, 0, sizeof(counters)); |
||
309 | counters.expected_data_len = data_len; |
||
310 | counters.expected_data = data; |
||
311 | |||
312 | /* create and initialize the pcb */ |
||
313 | pcb = test_tcp_new_counters_pcb(&counters); |
||
314 | EXPECT_RET(pcb != NULL); |
||
315 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
316 | |||
317 | /* create segments */ |
||
318 | /* p1: 7 bytes - 2 before FIN */ |
||
319 | /* seqno: 1..2 */ |
||
320 | p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK); |
||
321 | /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */ |
||
322 | /* seqno: 4..11 */ |
||
323 | p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK); |
||
324 | /* p3: same as p2 but 2 bytes longer and one byte more at the front */ |
||
325 | /* seqno: 3..13 */ |
||
326 | p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK); |
||
327 | /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */ |
||
328 | /* seqno: 2..13 */ |
||
329 | p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK); |
||
330 | /* pinseq is the first segment that is held back to create ooseq! */ |
||
331 | /* seqno: 0..3 */ |
||
332 | pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK); |
||
333 | /* p5: last byte before FIN */ |
||
334 | /* seqno: 15 */ |
||
335 | p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK); |
||
336 | /* p6: same as p5, should be ignored */ |
||
337 | p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK); |
||
338 | /* pinseqFIN: last 2 bytes plus FIN */ |
||
339 | /* only segment containing seqno 14 and FIN */ |
||
340 | pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN); |
||
341 | EXPECT(pinseq != NULL); |
||
342 | EXPECT(p_1_2 != NULL); |
||
343 | EXPECT(p_4_8 != NULL); |
||
344 | EXPECT(p_3_11 != NULL); |
||
345 | EXPECT(p_2_12 != NULL); |
||
346 | EXPECT(p_15_1 != NULL); |
||
347 | EXPECT(p_15_1a != NULL); |
||
348 | EXPECT(pinseqFIN != NULL); |
||
349 | if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL) |
||
350 | && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) { |
||
351 | /* pass the segment to tcp_input */ |
||
352 | test_tcp_input(p_1_2, &netif); |
||
353 | /* check if counters are as expected */ |
||
354 | EXPECT(counters.close_calls == 0); |
||
355 | EXPECT(counters.recv_calls == 0); |
||
356 | EXPECT(counters.recved_bytes == 0); |
||
357 | EXPECT(counters.err_calls == 0); |
||
358 | /* check ooseq queue */ |
||
359 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); |
||
360 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); |
||
361 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); |
||
362 | |||
363 | /* pass the segment to tcp_input */ |
||
364 | test_tcp_input(p_4_8, &netif); |
||
365 | /* check if counters are as expected */ |
||
366 | EXPECT(counters.close_calls == 0); |
||
367 | EXPECT(counters.recv_calls == 0); |
||
368 | EXPECT(counters.recved_bytes == 0); |
||
369 | EXPECT(counters.err_calls == 0); |
||
370 | /* check ooseq queue */ |
||
371 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); |
||
372 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); |
||
373 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); |
||
374 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4); |
||
375 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8); |
||
376 | |||
377 | /* pass the segment to tcp_input */ |
||
378 | test_tcp_input(p_3_11, &netif); |
||
379 | /* check if counters are as expected */ |
||
380 | EXPECT(counters.close_calls == 0); |
||
381 | EXPECT(counters.recv_calls == 0); |
||
382 | EXPECT(counters.recved_bytes == 0); |
||
383 | EXPECT(counters.err_calls == 0); |
||
384 | /* check ooseq queue */ |
||
385 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); |
||
386 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); |
||
387 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); |
||
388 | /* p_3_11 has removed p_4_8 from ooseq */ |
||
389 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3); |
||
390 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11); |
||
391 | |||
392 | /* pass the segment to tcp_input */ |
||
393 | test_tcp_input(p_2_12, &netif); |
||
394 | /* check if counters are as expected */ |
||
395 | EXPECT(counters.close_calls == 0); |
||
396 | EXPECT(counters.recv_calls == 0); |
||
397 | EXPECT(counters.recved_bytes == 0); |
||
398 | EXPECT(counters.err_calls == 0); |
||
399 | /* check ooseq queue */ |
||
400 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); |
||
401 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); |
||
402 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); |
||
403 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2); |
||
404 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12); |
||
405 | |||
406 | /* pass the segment to tcp_input */ |
||
407 | test_tcp_input(pinseq, &netif); |
||
408 | /* check if counters are as expected */ |
||
409 | EXPECT(counters.close_calls == 0); |
||
410 | EXPECT(counters.recv_calls == 1); |
||
411 | EXPECT(counters.recved_bytes == 14); |
||
412 | EXPECT(counters.err_calls == 0); |
||
413 | EXPECT(pcb->ooseq == NULL); |
||
414 | |||
415 | /* pass the segment to tcp_input */ |
||
416 | test_tcp_input(p_15_1, &netif); |
||
417 | /* check if counters are as expected */ |
||
418 | EXPECT(counters.close_calls == 0); |
||
419 | EXPECT(counters.recv_calls == 1); |
||
420 | EXPECT(counters.recved_bytes == 14); |
||
421 | EXPECT(counters.err_calls == 0); |
||
422 | /* check ooseq queue */ |
||
423 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); |
||
424 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15); |
||
425 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); |
||
426 | |||
427 | /* pass the segment to tcp_input */ |
||
428 | test_tcp_input(p_15_1a, &netif); |
||
429 | /* check if counters are as expected */ |
||
430 | EXPECT(counters.close_calls == 0); |
||
431 | EXPECT(counters.recv_calls == 1); |
||
432 | EXPECT(counters.recved_bytes == 14); |
||
433 | EXPECT(counters.err_calls == 0); |
||
434 | /* check ooseq queue: unchanged */ |
||
435 | EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); |
||
436 | EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15); |
||
437 | EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); |
||
438 | |||
439 | /* pass the segment to tcp_input */ |
||
440 | test_tcp_input(pinseqFIN, &netif); |
||
441 | /* check if counters are as expected */ |
||
442 | EXPECT(counters.close_calls == 1); |
||
443 | EXPECT(counters.recv_calls == 2); |
||
444 | EXPECT(counters.recved_bytes == data_len); |
||
445 | EXPECT(counters.err_calls == 0); |
||
446 | EXPECT(pcb->ooseq == NULL); |
||
447 | } |
||
448 | |||
449 | /* make sure the pcb is freed */ |
||
450 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
451 | tcp_abort(pcb); |
||
452 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
453 | } |
||
454 | END_TEST |
||
455 | |||
456 | static char data_full_wnd[TCP_WND + TCP_MSS]; |
||
457 | |||
458 | /** create multiple segments and pass them to tcp_input with the first segment missing |
||
459 | * to simulate overruning the rxwin with ooseq queueing enabled */ |
||
460 | START_TEST(test_tcp_recv_ooseq_overrun_rxwin) |
||
461 | { |
||
462 | #if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS |
||
463 | int i, k; |
||
464 | struct test_tcp_counters counters; |
||
465 | struct tcp_pcb* pcb; |
||
466 | struct pbuf *pinseq, *p_ovr; |
||
467 | struct netif netif; |
||
468 | int datalen = 0; |
||
469 | int datalen2; |
||
470 | |||
471 | for(i = 0; i < (int)sizeof(data_full_wnd); i++) { |
||
472 | data_full_wnd[i] = (char)i; |
||
473 | } |
||
474 | |||
475 | /* initialize local vars */ |
||
476 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
477 | /* initialize counter struct */ |
||
478 | memset(&counters, 0, sizeof(counters)); |
||
479 | counters.expected_data_len = TCP_WND; |
||
480 | counters.expected_data = data_full_wnd; |
||
481 | |||
482 | /* create and initialize the pcb */ |
||
483 | pcb = test_tcp_new_counters_pcb(&counters); |
||
484 | EXPECT_RET(pcb != NULL); |
||
485 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
486 | pcb->rcv_nxt = 0x8000; |
||
487 | |||
488 | /* create segments */ |
||
489 | /* pinseq is sent as last segment! */ |
||
490 | pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); |
||
491 | |||
492 | for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) { |
||
493 | int count, expected_datalen; |
||
494 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], |
||
495 | TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); |
||
496 | EXPECT_RET(p != NULL); |
||
497 | /* pass the segment to tcp_input */ |
||
498 | test_tcp_input(p, &netif); |
||
499 | /* check if counters are as expected */ |
||
500 | EXPECT(counters.close_calls == 0); |
||
501 | EXPECT(counters.recv_calls == 0); |
||
502 | EXPECT(counters.recved_bytes == 0); |
||
503 | EXPECT(counters.err_calls == 0); |
||
504 | /* check ooseq queue */ |
||
505 | count = tcp_oos_count(pcb); |
||
506 | EXPECT_OOSEQ(count == k+1); |
||
507 | datalen = tcp_oos_tcplen(pcb); |
||
508 | if (i + TCP_MSS < TCP_WND) { |
||
509 | expected_datalen = (k+1)*TCP_MSS; |
||
510 | } else { |
||
511 | expected_datalen = TCP_WND - TCP_MSS; |
||
512 | } |
||
513 | if (datalen != expected_datalen) { |
||
514 | EXPECT_OOSEQ(datalen == expected_datalen); |
||
515 | } |
||
516 | } |
||
517 | |||
518 | /* pass in one more segment, cleary overrunning the rxwin */ |
||
519 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); |
||
520 | EXPECT_RET(p_ovr != NULL); |
||
521 | /* pass the segment to tcp_input */ |
||
522 | test_tcp_input(p_ovr, &netif); |
||
523 | /* check if counters are as expected */ |
||
524 | EXPECT(counters.close_calls == 0); |
||
525 | EXPECT(counters.recv_calls == 0); |
||
526 | EXPECT(counters.recved_bytes == 0); |
||
527 | EXPECT(counters.err_calls == 0); |
||
528 | /* check ooseq queue */ |
||
529 | EXPECT_OOSEQ(tcp_oos_count(pcb) == k); |
||
530 | datalen2 = tcp_oos_tcplen(pcb); |
||
531 | EXPECT_OOSEQ(datalen == datalen2); |
||
532 | |||
533 | /* now pass inseq */ |
||
534 | test_tcp_input(pinseq, &netif); |
||
535 | EXPECT(pcb->ooseq == NULL); |
||
536 | |||
537 | /* make sure the pcb is freed */ |
||
538 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
539 | tcp_abort(pcb); |
||
540 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
541 | #endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */ |
||
542 | LWIP_UNUSED_ARG(_i); |
||
543 | } |
||
544 | END_TEST |
||
545 | |||
546 | /** similar to above test, except seqno starts near the max rxwin */ |
||
547 | START_TEST(test_tcp_recv_ooseq_overrun_rxwin_edge) |
||
548 | { |
||
549 | #if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS |
||
550 | int i, k; |
||
551 | struct test_tcp_counters counters; |
||
552 | struct tcp_pcb* pcb; |
||
553 | struct pbuf *pinseq, *p_ovr; |
||
554 | struct netif netif; |
||
555 | int datalen = 0; |
||
556 | int datalen2; |
||
557 | |||
558 | for(i = 0; i < (int)sizeof(data_full_wnd); i++) { |
||
559 | data_full_wnd[i] = (char)i; |
||
560 | } |
||
561 | |||
562 | /* initialize local vars */ |
||
563 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
564 | /* initialize counter struct */ |
||
565 | memset(&counters, 0, sizeof(counters)); |
||
566 | counters.expected_data_len = TCP_WND; |
||
567 | counters.expected_data = data_full_wnd; |
||
568 | |||
569 | /* create and initialize the pcb */ |
||
570 | pcb = test_tcp_new_counters_pcb(&counters); |
||
571 | EXPECT_RET(pcb != NULL); |
||
572 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
573 | pcb->rcv_nxt = 0xffffffff - (TCP_WND / 2); |
||
574 | |||
575 | /* create segments */ |
||
576 | /* pinseq is sent as last segment! */ |
||
577 | pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); |
||
578 | |||
579 | for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) { |
||
580 | int count, expected_datalen; |
||
581 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], |
||
582 | TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); |
||
583 | EXPECT_RET(p != NULL); |
||
584 | /* pass the segment to tcp_input */ |
||
585 | test_tcp_input(p, &netif); |
||
586 | /* check if counters are as expected */ |
||
587 | EXPECT(counters.close_calls == 0); |
||
588 | EXPECT(counters.recv_calls == 0); |
||
589 | EXPECT(counters.recved_bytes == 0); |
||
590 | EXPECT(counters.err_calls == 0); |
||
591 | /* check ooseq queue */ |
||
592 | count = tcp_oos_count(pcb); |
||
593 | EXPECT_OOSEQ(count == k+1); |
||
594 | datalen = tcp_oos_tcplen(pcb); |
||
595 | if (i + TCP_MSS < TCP_WND) { |
||
596 | expected_datalen = (k+1)*TCP_MSS; |
||
597 | } else { |
||
598 | expected_datalen = TCP_WND - TCP_MSS; |
||
599 | } |
||
600 | if (datalen != expected_datalen) { |
||
601 | EXPECT_OOSEQ(datalen == expected_datalen); |
||
602 | } |
||
603 | } |
||
604 | |||
605 | /* pass in one more segment, cleary overrunning the rxwin */ |
||
606 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); |
||
607 | EXPECT_RET(p_ovr != NULL); |
||
608 | /* pass the segment to tcp_input */ |
||
609 | test_tcp_input(p_ovr, &netif); |
||
610 | /* check if counters are as expected */ |
||
611 | EXPECT(counters.close_calls == 0); |
||
612 | EXPECT(counters.recv_calls == 0); |
||
613 | EXPECT(counters.recved_bytes == 0); |
||
614 | EXPECT(counters.err_calls == 0); |
||
615 | /* check ooseq queue */ |
||
616 | EXPECT_OOSEQ(tcp_oos_count(pcb) == k); |
||
617 | datalen2 = tcp_oos_tcplen(pcb); |
||
618 | EXPECT_OOSEQ(datalen == datalen2); |
||
619 | |||
620 | /* now pass inseq */ |
||
621 | test_tcp_input(pinseq, &netif); |
||
622 | EXPECT(pcb->ooseq == NULL); |
||
623 | |||
624 | /* make sure the pcb is freed */ |
||
625 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
626 | tcp_abort(pcb); |
||
627 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
628 | #endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */ |
||
629 | LWIP_UNUSED_ARG(_i); |
||
630 | } |
||
631 | END_TEST |
||
632 | |||
633 | START_TEST(test_tcp_recv_ooseq_max_bytes) |
||
634 | { |
||
635 | #if TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) |
||
636 | int i, k; |
||
637 | struct test_tcp_counters counters; |
||
638 | struct tcp_pcb* pcb; |
||
639 | struct pbuf *p_ovr; |
||
640 | struct netif netif; |
||
641 | int datalen = 0; |
||
642 | int datalen2; |
||
643 | |||
644 | for(i = 0; i < sizeof(data_full_wnd); i++) { |
||
645 | data_full_wnd[i] = (char)i; |
||
646 | } |
||
647 | |||
648 | /* initialize local vars */ |
||
649 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
650 | /* initialize counter struct */ |
||
651 | memset(&counters, 0, sizeof(counters)); |
||
652 | counters.expected_data_len = TCP_WND; |
||
653 | counters.expected_data = data_full_wnd; |
||
654 | |||
655 | /* create and initialize the pcb */ |
||
656 | pcb = test_tcp_new_counters_pcb(&counters); |
||
657 | EXPECT_RET(pcb != NULL); |
||
658 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
659 | pcb->rcv_nxt = 0x8000; |
||
660 | |||
661 | /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ |
||
662 | |||
663 | /* create segments and 'recv' them */ |
||
664 | for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) { |
||
665 | int count; |
||
666 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k], |
||
667 | TCP_MSS, k, 0, TCP_ACK); |
||
668 | EXPECT_RET(p != NULL); |
||
669 | EXPECT_RET(p->next == NULL); |
||
670 | /* pass the segment to tcp_input */ |
||
671 | test_tcp_input(p, &netif); |
||
672 | /* check if counters are as expected */ |
||
673 | EXPECT(counters.close_calls == 0); |
||
674 | EXPECT(counters.recv_calls == 0); |
||
675 | EXPECT(counters.recved_bytes == 0); |
||
676 | EXPECT(counters.err_calls == 0); |
||
677 | /* check ooseq queue */ |
||
678 | count = tcp_oos_pbuf_count(pcb); |
||
679 | EXPECT_OOSEQ(count == i); |
||
680 | datalen = tcp_oos_tcplen(pcb); |
||
681 | EXPECT_OOSEQ(datalen == (i * TCP_MSS)); |
||
682 | } |
||
683 | |||
684 | /* pass in one more segment, overrunning the limit */ |
||
685 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK); |
||
686 | EXPECT_RET(p_ovr != NULL); |
||
687 | /* pass the segment to tcp_input */ |
||
688 | test_tcp_input(p_ovr, &netif); |
||
689 | /* check if counters are as expected */ |
||
690 | EXPECT(counters.close_calls == 0); |
||
691 | EXPECT(counters.recv_calls == 0); |
||
692 | EXPECT(counters.recved_bytes == 0); |
||
693 | EXPECT(counters.err_calls == 0); |
||
694 | /* check ooseq queue (ensure the new segment was not accepted) */ |
||
695 | EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); |
||
696 | datalen2 = tcp_oos_tcplen(pcb); |
||
697 | EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS)); |
||
698 | |||
699 | /* make sure the pcb is freed */ |
||
700 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
701 | tcp_abort(pcb); |
||
702 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
703 | #endif /* TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ |
||
704 | LWIP_UNUSED_ARG(_i); |
||
705 | } |
||
706 | END_TEST |
||
707 | |||
708 | START_TEST(test_tcp_recv_ooseq_max_pbufs) |
||
709 | { |
||
710 | #if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) |
||
711 | int i; |
||
712 | struct test_tcp_counters counters; |
||
713 | struct tcp_pcb* pcb; |
||
714 | struct pbuf *p_ovr; |
||
715 | struct netif netif; |
||
716 | int datalen = 0; |
||
717 | int datalen2; |
||
718 | |||
719 | for(i = 0; i < sizeof(data_full_wnd); i++) { |
||
720 | data_full_wnd[i] = (char)i; |
||
721 | } |
||
722 | |||
723 | /* initialize local vars */ |
||
724 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
725 | /* initialize counter struct */ |
||
726 | memset(&counters, 0, sizeof(counters)); |
||
727 | counters.expected_data_len = TCP_WND; |
||
728 | counters.expected_data = data_full_wnd; |
||
729 | |||
730 | /* create and initialize the pcb */ |
||
731 | pcb = test_tcp_new_counters_pcb(&counters); |
||
732 | EXPECT_RET(pcb != NULL); |
||
733 | tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
734 | pcb->rcv_nxt = 0x8000; |
||
735 | |||
736 | /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ |
||
737 | |||
738 | /* create segments and 'recv' them */ |
||
739 | for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) { |
||
740 | int count; |
||
741 | struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i], |
||
742 | 1, i, 0, TCP_ACK); |
||
743 | EXPECT_RET(p != NULL); |
||
744 | EXPECT_RET(p->next == NULL); |
||
745 | /* pass the segment to tcp_input */ |
||
746 | test_tcp_input(p, &netif); |
||
747 | /* check if counters are as expected */ |
||
748 | EXPECT(counters.close_calls == 0); |
||
749 | EXPECT(counters.recv_calls == 0); |
||
750 | EXPECT(counters.recved_bytes == 0); |
||
751 | EXPECT(counters.err_calls == 0); |
||
752 | /* check ooseq queue */ |
||
753 | count = tcp_oos_pbuf_count(pcb); |
||
754 | EXPECT_OOSEQ(count == i); |
||
755 | datalen = tcp_oos_tcplen(pcb); |
||
756 | EXPECT_OOSEQ(datalen == i); |
||
757 | } |
||
758 | |||
759 | /* pass in one more segment, overrunning the limit */ |
||
760 | p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK); |
||
761 | EXPECT_RET(p_ovr != NULL); |
||
762 | /* pass the segment to tcp_input */ |
||
763 | test_tcp_input(p_ovr, &netif); |
||
764 | /* check if counters are as expected */ |
||
765 | EXPECT(counters.close_calls == 0); |
||
766 | EXPECT(counters.recv_calls == 0); |
||
767 | EXPECT(counters.recved_bytes == 0); |
||
768 | EXPECT(counters.err_calls == 0); |
||
769 | /* check ooseq queue (ensure the new segment was not accepted) */ |
||
770 | EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); |
||
771 | datalen2 = tcp_oos_tcplen(pcb); |
||
772 | EXPECT_OOSEQ(datalen2 == (i-1)); |
||
773 | |||
774 | /* make sure the pcb is freed */ |
||
775 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
776 | tcp_abort(pcb); |
||
777 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
778 | #endif /* TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ |
||
779 | LWIP_UNUSED_ARG(_i); |
||
780 | } |
||
781 | END_TEST |
||
782 | |||
783 | static void |
||
784 | check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls, |
||
785 | u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len) |
||
786 | { |
||
787 | int oos_len; |
||
788 | EXPECT(counters->close_calls == exp_close_calls); |
||
789 | EXPECT(counters->recv_calls == exp_rx_calls); |
||
790 | EXPECT(counters->recved_bytes == exp_rx_bytes); |
||
791 | EXPECT(counters->err_calls == exp_err_calls); |
||
792 | /* check that pbuf is queued in ooseq */ |
||
793 | EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count); |
||
794 | oos_len = tcp_oos_tcplen(pcb); |
||
795 | EXPECT_OOSEQ(exp_oos_len == oos_len); |
||
796 | } |
||
797 | |||
798 | /* this test uses 4 packets: |
||
799 | * - data (len=TCP_MSS) |
||
800 | * - FIN |
||
801 | * - data after FIN (len=1) (invalid) |
||
802 | * - 2nd FIN (invalid) |
||
803 | * |
||
804 | * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq |
||
805 | */ |
||
806 | static void test_tcp_recv_ooseq_double_FINs(int delay_packet) |
||
807 | { |
||
808 | int i, k; |
||
809 | struct test_tcp_counters counters; |
||
810 | struct tcp_pcb* pcb; |
||
811 | struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq; |
||
812 | struct netif netif; |
||
813 | u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0; |
||
814 | int first_dropped = 0xff; |
||
815 | |||
816 | for(i = 0; i < (int)sizeof(data_full_wnd); i++) { |
||
817 | data_full_wnd[i] = (char)i; |
||
818 | } |
||
819 | |||
820 | /* initialize local vars */ |
||
821 | test_tcp_init_netif(&netif, NULL, &test_local_ip, &test_netmask); |
||
822 | /* initialize counter struct */ |
||
823 | memset(&counters, 0, sizeof(counters)); |
||
824 | counters.expected_data_len = TCP_WND; |
||
825 | counters.expected_data = data_full_wnd; |
||
826 | |||
827 | /* create and initialize the pcb */ |
||
828 | pcb = test_tcp_new_counters_pcb(&counters); |
||
829 | EXPECT_RET(pcb != NULL); |
||
830 | tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT); |
||
831 | pcb->rcv_nxt = 0x8000; |
||
832 | |||
833 | /* create segments */ |
||
834 | p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); |
||
835 | p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN); |
||
836 | k = 1; |
||
837 | p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK); |
||
838 | p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN); |
||
839 | |||
840 | if(delay_packet & 1) { |
||
841 | /* drop normal data */ |
||
842 | first_dropped = 1; |
||
843 | } else { |
||
844 | /* send normal data */ |
||
845 | test_tcp_input(p, &netif); |
||
846 | exp_rx_calls++; |
||
847 | exp_rx_bytes += TCP_MSS; |
||
848 | } |
||
849 | /* check if counters are as expected */ |
||
850 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
851 | |||
852 | if(delay_packet & 2) { |
||
853 | /* drop FIN */ |
||
854 | if(first_dropped > 2) { |
||
855 | first_dropped = 2; |
||
856 | } |
||
857 | } else { |
||
858 | /* send FIN */ |
||
859 | test_tcp_input(p_normal_fin, &netif); |
||
860 | if (first_dropped < 2) { |
||
861 | /* already dropped packets, this one is ooseq */ |
||
862 | exp_oos_pbufs++; |
||
863 | exp_oos_tcplen++; |
||
864 | } else { |
||
865 | /* inseq */ |
||
866 | exp_close_calls++; |
||
867 | } |
||
868 | } |
||
869 | /* check if counters are as expected */ |
||
870 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
871 | |||
872 | if(delay_packet & 4) { |
||
873 | /* drop data-after-FIN */ |
||
874 | if(first_dropped > 3) { |
||
875 | first_dropped = 3; |
||
876 | } |
||
877 | } else { |
||
878 | /* send data-after-FIN */ |
||
879 | test_tcp_input(p_data_after_fin, &netif); |
||
880 | if (first_dropped < 3) { |
||
881 | /* already dropped packets, this one is ooseq */ |
||
882 | if (delay_packet & 2) { |
||
883 | /* correct FIN was ooseq */ |
||
884 | exp_oos_pbufs++; |
||
885 | exp_oos_tcplen += k; |
||
886 | } |
||
887 | } else { |
||
888 | /* inseq: no change */ |
||
889 | } |
||
890 | } |
||
891 | /* check if counters are as expected */ |
||
892 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
893 | |||
894 | if(delay_packet & 8) { |
||
895 | /* drop 2nd-FIN */ |
||
896 | if(first_dropped > 4) { |
||
897 | first_dropped = 4; |
||
898 | } |
||
899 | } else { |
||
900 | /* send 2nd-FIN */ |
||
901 | test_tcp_input(p_2nd_fin_ooseq, &netif); |
||
902 | if (first_dropped < 3) { |
||
903 | /* already dropped packets, this one is ooseq */ |
||
904 | if (delay_packet & 2) { |
||
905 | /* correct FIN was ooseq */ |
||
906 | exp_oos_pbufs++; |
||
907 | exp_oos_tcplen++; |
||
908 | } |
||
909 | } else { |
||
910 | /* inseq: no change */ |
||
911 | } |
||
912 | } |
||
913 | /* check if counters are as expected */ |
||
914 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
915 | |||
916 | if(delay_packet & 1) { |
||
917 | /* dropped normal data before */ |
||
918 | test_tcp_input(p, &netif); |
||
919 | exp_rx_calls++; |
||
920 | exp_rx_bytes += TCP_MSS; |
||
921 | if((delay_packet & 2) == 0) { |
||
922 | /* normal FIN was NOT delayed */ |
||
923 | exp_close_calls++; |
||
924 | exp_oos_pbufs = exp_oos_tcplen = 0; |
||
925 | } |
||
926 | } |
||
927 | /* check if counters are as expected */ |
||
928 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
929 | |||
930 | if(delay_packet & 2) { |
||
931 | /* dropped normal FIN before */ |
||
932 | test_tcp_input(p_normal_fin, &netif); |
||
933 | exp_close_calls++; |
||
934 | exp_oos_pbufs = exp_oos_tcplen = 0; |
||
935 | } |
||
936 | /* check if counters are as expected */ |
||
937 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
938 | |||
939 | if(delay_packet & 4) { |
||
940 | /* dropped data-after-FIN before */ |
||
941 | test_tcp_input(p_data_after_fin, &netif); |
||
942 | } |
||
943 | /* check if counters are as expected */ |
||
944 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
945 | |||
946 | if(delay_packet & 8) { |
||
947 | /* dropped 2nd-FIN before */ |
||
948 | test_tcp_input(p_2nd_fin_ooseq, &netif); |
||
949 | } |
||
950 | /* check if counters are as expected */ |
||
951 | check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); |
||
952 | |||
953 | /* check that ooseq data has been dumped */ |
||
954 | EXPECT(pcb->ooseq == NULL); |
||
955 | |||
956 | /* make sure the pcb is freed */ |
||
957 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1); |
||
958 | tcp_abort(pcb); |
||
959 | EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); |
||
960 | } |
||
961 | |||
962 | /** create multiple segments and pass them to tcp_input with the first segment missing |
||
963 | * to simulate overruning the rxwin with ooseq queueing enabled */ |
||
964 | #define FIN_TEST(name, num) \ |
||
965 | START_TEST(name) \ |
||
966 | { \ |
||
967 | LWIP_UNUSED_ARG(_i); \ |
||
968 | test_tcp_recv_ooseq_double_FINs(num); \ |
||
969 | } \ |
||
970 | END_TEST |
||
971 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0) |
||
972 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1) |
||
973 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2) |
||
974 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3) |
||
975 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4) |
||
976 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5) |
||
977 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6) |
||
978 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7) |
||
979 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8) |
||
980 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9) |
||
981 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10) |
||
982 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11) |
||
983 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12) |
||
984 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13) |
||
985 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14) |
||
986 | FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15) |
||
987 | |||
988 | |||
989 | /** Create the suite including all tests for this module */ |
||
990 | Suite * |
||
991 | tcp_oos_suite(void) |
||
992 | { |
||
993 | testfunc tests[] = { |
||
994 | TESTFUNC(test_tcp_recv_ooseq_FIN_OOSEQ), |
||
995 | TESTFUNC(test_tcp_recv_ooseq_FIN_INSEQ), |
||
996 | TESTFUNC(test_tcp_recv_ooseq_overrun_rxwin), |
||
997 | TESTFUNC(test_tcp_recv_ooseq_overrun_rxwin_edge), |
||
998 | TESTFUNC(test_tcp_recv_ooseq_max_bytes), |
||
999 | TESTFUNC(test_tcp_recv_ooseq_max_pbufs), |
||
1000 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_0), |
||
1001 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_1), |
||
1002 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_2), |
||
1003 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_3), |
||
1004 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_4), |
||
1005 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_5), |
||
1006 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_6), |
||
1007 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_7), |
||
1008 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_8), |
||
1009 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_9), |
||
1010 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_10), |
||
1011 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_11), |
||
1012 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_12), |
||
1013 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_13), |
||
1014 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_14), |
||
1015 | TESTFUNC(test_tcp_recv_ooseq_double_FIN_15) |
||
1016 | }; |
||
1017 | return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(testfunc), tcp_oos_setup, tcp_oos_teardown); |
||
1018 | } |