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