1 #include "test_tcp_oos.h"
3 #include "lwip/tcp_impl.h"
4 #include "lwip/stats.h"
5 #include "tcp_helper.h"
7 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
8 #error "This tests needs TCP- and MEMP-statistics enabled"
11 #error "This tests needs TCP_QUEUE_OOSEQ enabled"
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
19 #if CHECK_SEGMENTS_ON_OOSEQ
20 #define EXPECT_OOSEQ(x) EXPECT(x)
22 #define EXPECT_OOSEQ(x)
25 /* helper functions */
27 /** Get the numbers of segments on the ooseq list */
28 static int tcp_oos_count(struct tcp_pcb* pcb)
31 struct tcp_seg* seg = pcb->ooseq;
39 /** Get the seqno of a segment (by index) on the ooseq list
41 * @param pcb the pcb to check for ooseq segments
42 * @param seg_index index of the segment on the ooseq list
43 * @return seqno of the segment
46 tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
49 struct tcp_seg* seg = pcb->ooseq;
51 /* then check the actual segment */
53 if(num == seg_index) {
54 return seg->tcphdr->seqno;
63 /** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list
65 * @param pcb the pcb to check for ooseq segments
66 * @param seg_index index of the segment on the ooseq list
67 * @return tcplen of the segment
70 tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
73 struct tcp_seg* seg = pcb->ooseq;
75 /* then check the actual segment */
77 if(num == seg_index) {
78 return TCP_TCPLEN(seg);
87 /** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list
89 * @param pcb the pcb to check for ooseq segments
90 * @return tcplen of all segment
93 tcp_oos_tcplen(struct tcp_pcb* pcb)
96 struct tcp_seg* seg = pcb->ooseq;
98 /* then check the actual segment */
100 len += TCP_TCPLEN(seg);
106 /* Setup/teardown functions */
115 tcp_oos_teardown(void)
124 /** create multiple segments and pass them to tcp_input in a wrong
125 * order to see if ooseq-caching works correctly
126 * FIN is received in out-of-sequence segments only */
127 START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
129 struct test_tcp_counters counters;
131 struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
137 ip_addr_t remote_ip, local_ip;
139 u16_t remote_port = 0x100, local_port = 0x101;
143 /* initialize local vars */
144 memset(&netif, 0, sizeof(netif));
145 IP4_ADDR(&local_ip, 192, 168, 1, 1);
146 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
147 data_len = sizeof(data);
148 /* initialize counter struct */
149 memset(&counters, 0, sizeof(counters));
150 counters.expected_data_len = data_len;
151 counters.expected_data = data;
153 /* create and initialize the pcb */
154 pcb = test_tcp_new_counters_pcb(&counters);
155 EXPECT_RET(pcb != NULL);
156 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
158 /* create segments */
159 /* pinseq is sent as last segment! */
160 pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
161 /* p1: 8 bytes before FIN */
163 p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN);
164 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
166 p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
167 /* p3: same as p2 but 2 bytes longer */
169 p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
170 /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
172 p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
174 p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN);
175 EXPECT(pinseq != NULL);
176 EXPECT(p_8_9 != NULL);
177 EXPECT(p_4_8 != NULL);
178 EXPECT(p_4_10 != NULL);
179 EXPECT(p_2_14 != NULL);
180 EXPECT(p_fin != NULL);
181 if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
182 /* pass the segment to tcp_input */
183 test_tcp_input(p_8_9, &netif);
184 /* check if counters are as expected */
185 EXPECT(counters.close_calls == 0);
186 EXPECT(counters.recv_calls == 0);
187 EXPECT(counters.recved_bytes == 0);
188 EXPECT(counters.err_calls == 0);
189 /* check ooseq queue */
190 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
191 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
192 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
194 /* pass the segment to tcp_input */
195 test_tcp_input(p_4_8, &netif);
196 /* check if counters are as expected */
197 EXPECT(counters.close_calls == 0);
198 EXPECT(counters.recv_calls == 0);
199 EXPECT(counters.recved_bytes == 0);
200 EXPECT(counters.err_calls == 0);
201 /* check ooseq queue */
202 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
203 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
204 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
205 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
206 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
208 /* pass the segment to tcp_input */
209 test_tcp_input(p_4_10, &netif);
210 /* check if counters are as expected */
211 EXPECT(counters.close_calls == 0);
212 EXPECT(counters.recv_calls == 0);
213 EXPECT(counters.recved_bytes == 0);
214 EXPECT(counters.err_calls == 0);
215 /* ooseq queue: unchanged */
216 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
217 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
218 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
219 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
220 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
222 /* pass the segment to tcp_input */
223 test_tcp_input(p_2_14, &netif);
224 /* check if counters are as expected */
225 EXPECT(counters.close_calls == 0);
226 EXPECT(counters.recv_calls == 0);
227 EXPECT(counters.recved_bytes == 0);
228 EXPECT(counters.err_calls == 0);
229 /* check ooseq queue */
230 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
231 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
232 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
234 /* pass the segment to tcp_input */
235 test_tcp_input(p_fin, &netif);
236 /* check if counters are as expected */
237 EXPECT(counters.close_calls == 0);
238 EXPECT(counters.recv_calls == 0);
239 EXPECT(counters.recved_bytes == 0);
240 EXPECT(counters.err_calls == 0);
241 /* ooseq queue: unchanged */
242 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
243 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
244 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
246 /* pass the segment to tcp_input */
247 test_tcp_input(pinseq, &netif);
248 /* check if counters are as expected */
249 EXPECT(counters.close_calls == 1);
250 EXPECT(counters.recv_calls == 1);
251 EXPECT(counters.recved_bytes == data_len);
252 EXPECT(counters.err_calls == 0);
253 EXPECT(pcb->ooseq == NULL);
256 /* make sure the pcb is freed */
257 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
259 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
264 /** create multiple segments and pass them to tcp_input in a wrong
265 * order to see if ooseq-caching works correctly
266 * FIN is received IN-SEQUENCE at the end */
267 START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
269 struct test_tcp_counters counters;
271 struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
277 ip_addr_t remote_ip, local_ip;
279 u16_t remote_port = 0x100, local_port = 0x101;
283 /* initialize local vars */
284 memset(&netif, 0, sizeof(netif));
285 IP4_ADDR(&local_ip, 192, 168, 1, 1);
286 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
287 data_len = sizeof(data);
288 /* initialize counter struct */
289 memset(&counters, 0, sizeof(counters));
290 counters.expected_data_len = data_len;
291 counters.expected_data = data;
293 /* create and initialize the pcb */
294 pcb = test_tcp_new_counters_pcb(&counters);
295 EXPECT_RET(pcb != NULL);
296 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
298 /* create segments */
299 /* p1: 7 bytes - 2 before FIN */
301 p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK);
302 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
304 p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
305 /* p3: same as p2 but 2 bytes longer and one byte more at the front */
307 p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
308 /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
310 p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
311 /* pinseq is the first segment that is held back to create ooseq! */
313 pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
314 /* p5: last byte before FIN */
316 p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
317 /* p6: same as p5, should be ignored */
318 p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
319 /* pinseqFIN: last 2 bytes plus FIN */
320 /* only segment containing seqno 14 and FIN */
321 pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
322 EXPECT(pinseq != NULL);
323 EXPECT(p_1_2 != NULL);
324 EXPECT(p_4_8 != NULL);
325 EXPECT(p_3_11 != NULL);
326 EXPECT(p_2_12 != NULL);
327 EXPECT(p_15_1 != NULL);
328 EXPECT(p_15_1a != NULL);
329 EXPECT(pinseqFIN != NULL);
330 if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
331 && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
332 /* pass the segment to tcp_input */
333 test_tcp_input(p_1_2, &netif);
334 /* check if counters are as expected */
335 EXPECT(counters.close_calls == 0);
336 EXPECT(counters.recv_calls == 0);
337 EXPECT(counters.recved_bytes == 0);
338 EXPECT(counters.err_calls == 0);
339 /* check ooseq queue */
340 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
341 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
342 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
344 /* pass the segment to tcp_input */
345 test_tcp_input(p_4_8, &netif);
346 /* check if counters are as expected */
347 EXPECT(counters.close_calls == 0);
348 EXPECT(counters.recv_calls == 0);
349 EXPECT(counters.recved_bytes == 0);
350 EXPECT(counters.err_calls == 0);
351 /* check ooseq queue */
352 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
353 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
354 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
355 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
356 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
358 /* pass the segment to tcp_input */
359 test_tcp_input(p_3_11, &netif);
360 /* check if counters are as expected */
361 EXPECT(counters.close_calls == 0);
362 EXPECT(counters.recv_calls == 0);
363 EXPECT(counters.recved_bytes == 0);
364 EXPECT(counters.err_calls == 0);
365 /* check ooseq queue */
366 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
367 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
368 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
369 /* p_3_11 has removed p_4_8 from ooseq */
370 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
371 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
373 /* pass the segment to tcp_input */
374 test_tcp_input(p_2_12, &netif);
375 /* check if counters are as expected */
376 EXPECT(counters.close_calls == 0);
377 EXPECT(counters.recv_calls == 0);
378 EXPECT(counters.recved_bytes == 0);
379 EXPECT(counters.err_calls == 0);
380 /* check ooseq queue */
381 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
382 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
383 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
384 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
385 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
387 /* pass the segment to tcp_input */
388 test_tcp_input(pinseq, &netif);
389 /* check if counters are as expected */
390 EXPECT(counters.close_calls == 0);
391 EXPECT(counters.recv_calls == 1);
392 EXPECT(counters.recved_bytes == 14);
393 EXPECT(counters.err_calls == 0);
394 EXPECT(pcb->ooseq == NULL);
396 /* pass the segment to tcp_input */
397 test_tcp_input(p_15_1, &netif);
398 /* check if counters are as expected */
399 EXPECT(counters.close_calls == 0);
400 EXPECT(counters.recv_calls == 1);
401 EXPECT(counters.recved_bytes == 14);
402 EXPECT(counters.err_calls == 0);
403 /* check ooseq queue */
404 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
405 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
406 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
408 /* pass the segment to tcp_input */
409 test_tcp_input(p_15_1a, &netif);
410 /* check if counters are as expected */
411 EXPECT(counters.close_calls == 0);
412 EXPECT(counters.recv_calls == 1);
413 EXPECT(counters.recved_bytes == 14);
414 EXPECT(counters.err_calls == 0);
415 /* check ooseq queue: unchanged */
416 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
417 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
418 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
420 /* pass the segment to tcp_input */
421 test_tcp_input(pinseqFIN, &netif);
422 /* check if counters are as expected */
423 EXPECT(counters.close_calls == 1);
424 EXPECT(counters.recv_calls == 2);
425 EXPECT(counters.recved_bytes == data_len);
426 EXPECT(counters.err_calls == 0);
427 EXPECT(pcb->ooseq == NULL);
430 /* make sure the pcb is freed */
431 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
433 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
437 static char data_full_wnd[TCP_WND];
439 /** create multiple segments and pass them to tcp_input with the first segment missing
440 * to simulate overruning the rxwin with ooseq queueing enabled */
441 START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
444 struct test_tcp_counters counters;
446 struct pbuf *pinseq, *p_ovr;
447 ip_addr_t remote_ip, local_ip;
448 u16_t remote_port = 0x100, local_port = 0x101;
454 for(i = 0; i < sizeof(data_full_wnd); i++) {
455 data_full_wnd[i] = (char)i;
458 /* initialize local vars */
459 memset(&netif, 0, sizeof(netif));
460 IP4_ADDR(&local_ip, 192, 168, 1, 1);
461 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
462 /* initialize counter struct */
463 memset(&counters, 0, sizeof(counters));
464 counters.expected_data_len = TCP_WND;
465 counters.expected_data = data_full_wnd;
467 /* create and initialize the pcb */
468 pcb = test_tcp_new_counters_pcb(&counters);
469 EXPECT_RET(pcb != NULL);
470 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
471 pcb->rcv_nxt = 0x8000;
473 /* create segments */
474 /* pinseq is sent as last segment! */
475 pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
477 for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
478 int count, expected_datalen;
479 struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
480 TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
481 EXPECT_RET(p != NULL);
482 /* pass the segment to tcp_input */
483 test_tcp_input(p, &netif);
484 /* check if counters are as expected */
485 EXPECT(counters.close_calls == 0);
486 EXPECT(counters.recv_calls == 0);
487 EXPECT(counters.recved_bytes == 0);
488 EXPECT(counters.err_calls == 0);
489 /* check ooseq queue */
490 count = tcp_oos_count(pcb);
491 EXPECT_OOSEQ(count == k+1);
492 datalen = tcp_oos_tcplen(pcb);
493 if (i + TCP_MSS < TCP_WND) {
494 expected_datalen = (k+1)*TCP_MSS;
496 expected_datalen = TCP_WND - TCP_MSS;
498 if (datalen != expected_datalen) {
499 EXPECT_OOSEQ(datalen == expected_datalen);
503 /* pass in one more segment, cleary overrunning the rxwin */
504 p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
505 EXPECT_RET(p_ovr != NULL);
506 /* pass the segment to tcp_input */
507 test_tcp_input(p_ovr, &netif);
508 /* check if counters are as expected */
509 EXPECT(counters.close_calls == 0);
510 EXPECT(counters.recv_calls == 0);
511 EXPECT(counters.recved_bytes == 0);
512 EXPECT(counters.err_calls == 0);
513 /* check ooseq queue */
514 EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
515 datalen2 = tcp_oos_tcplen(pcb);
516 EXPECT_OOSEQ(datalen == datalen2);
519 test_tcp_input(pinseq, &netif);
520 EXPECT(pcb->ooseq == NULL);
522 /* make sure the pcb is freed */
523 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
525 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
530 check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls,
531 u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len)
534 EXPECT(counters->close_calls == exp_close_calls);
535 EXPECT(counters->recv_calls == exp_rx_calls);
536 EXPECT(counters->recved_bytes == exp_rx_bytes);
537 EXPECT(counters->err_calls == exp_err_calls);
538 /* check that pbuf is queued in ooseq */
539 EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count);
540 oos_len = tcp_oos_tcplen(pcb);
541 EXPECT_OOSEQ(exp_oos_len == oos_len);
544 /* this test uses 4 packets:
545 * - data (len=TCP_MSS)
547 * - data after FIN (len=1) (invalid)
548 * - 2nd FIN (invalid)
550 * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
552 static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
555 struct test_tcp_counters counters;
557 struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq;
558 ip_addr_t remote_ip, local_ip;
559 u16_t remote_port = 0x100, local_port = 0x101;
561 u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0;
562 int first_dropped = 0xff;
563 int last_dropped = 0;
565 for(i = 0; i < sizeof(data_full_wnd); i++) {
566 data_full_wnd[i] = (char)i;
569 /* initialize local vars */
570 memset(&netif, 0, sizeof(netif));
571 IP4_ADDR(&local_ip, 192, 168, 1, 1);
572 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
573 /* initialize counter struct */
574 memset(&counters, 0, sizeof(counters));
575 counters.expected_data_len = TCP_WND;
576 counters.expected_data = data_full_wnd;
578 /* create and initialize the pcb */
579 pcb = test_tcp_new_counters_pcb(&counters);
580 EXPECT_RET(pcb != NULL);
581 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
582 pcb->rcv_nxt = 0x8000;
584 /* create segments */
585 p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
586 p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN);
588 p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK);
589 p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN);
591 if(delay_packet & 1) {
592 /* drop normal data */
596 /* send normal data */
597 test_tcp_input(p, &netif);
599 exp_rx_bytes += TCP_MSS;
601 /* check if counters are as expected */
602 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
604 if(delay_packet & 2) {
606 if(first_dropped > 2) {
612 test_tcp_input(p_normal_fin, &netif);
613 if (first_dropped < 2) {
614 /* already dropped packets, this one is ooseq */
622 /* check if counters are as expected */
623 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
625 if(delay_packet & 4) {
626 /* drop data-after-FIN */
627 if(first_dropped > 3) {
632 /* send data-after-FIN */
633 test_tcp_input(p_data_after_fin, &netif);
634 if (first_dropped < 3) {
635 /* already dropped packets, this one is ooseq */
636 if (delay_packet & 2) {
637 /* correct FIN was ooseq */
642 /* inseq: no change */
645 /* check if counters are as expected */
646 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
648 if(delay_packet & 8) {
650 if(first_dropped > 4) {
656 test_tcp_input(p_2nd_fin_ooseq, &netif);
657 if (first_dropped < 3) {
658 /* already dropped packets, this one is ooseq */
659 if (delay_packet & 2) {
660 /* correct FIN was ooseq */
665 /* inseq: no change */
668 /* check if counters are as expected */
669 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
671 if(delay_packet & 1) {
672 /* dropped normal data before */
673 test_tcp_input(p, &netif);
675 exp_rx_bytes += TCP_MSS;
676 if((delay_packet & 2) == 0) {
677 /* normal FIN was NOT delayed */
679 exp_oos_pbufs = exp_oos_tcplen = 0;
682 /* check if counters are as expected */
683 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
685 if(delay_packet & 2) {
686 /* dropped normal FIN before */
687 test_tcp_input(p_normal_fin, &netif);
689 exp_oos_pbufs = exp_oos_tcplen = 0;
691 /* check if counters are as expected */
692 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
694 if(delay_packet & 4) {
695 /* dropped data-after-FIN before */
696 test_tcp_input(p_data_after_fin, &netif);
698 /* check if counters are as expected */
699 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
701 if(delay_packet & 8) {
702 /* dropped 2nd-FIN before */
703 test_tcp_input(p_2nd_fin_ooseq, &netif);
705 /* check if counters are as expected */
706 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
708 /* check that ooseq data has been dumped */
709 EXPECT(pcb->ooseq == NULL);
711 /* make sure the pcb is freed */
712 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
714 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
717 /** create multiple segments and pass them to tcp_input with the first segment missing
718 * to simulate overruning the rxwin with ooseq queueing enabled */
719 #define FIN_TEST(name, num) \
722 LWIP_UNUSED_ARG(_i); \
723 test_tcp_recv_ooseq_double_FINs(num); \
726 FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0)
727 FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1)
728 FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2)
729 FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3)
730 FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4)
731 FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5)
732 FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6)
733 FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7)
734 FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8)
735 FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9)
736 FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10)
737 FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11)
738 FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12)
739 FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13)
740 FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14)
741 FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15)
744 /** Create the suite including all tests for this module */
749 test_tcp_recv_ooseq_FIN_OOSEQ,
750 test_tcp_recv_ooseq_FIN_INSEQ,
751 test_tcp_recv_ooseq_overrun_rxwin,
752 test_tcp_recv_ooseq_double_FIN_0,
753 test_tcp_recv_ooseq_double_FIN_1,
754 test_tcp_recv_ooseq_double_FIN_2,
755 test_tcp_recv_ooseq_double_FIN_3,
756 test_tcp_recv_ooseq_double_FIN_4,
757 test_tcp_recv_ooseq_double_FIN_5,
758 test_tcp_recv_ooseq_double_FIN_6,
759 test_tcp_recv_ooseq_double_FIN_7,
760 test_tcp_recv_ooseq_double_FIN_8,
761 test_tcp_recv_ooseq_double_FIN_9,
762 test_tcp_recv_ooseq_double_FIN_10,
763 test_tcp_recv_ooseq_double_FIN_11,
764 test_tcp_recv_ooseq_double_FIN_12,
765 test_tcp_recv_ooseq_double_FIN_13,
766 test_tcp_recv_ooseq_double_FIN_14,
767 test_tcp_recv_ooseq_double_FIN_15
769 return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);