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 numbers of pbufs on the ooseq list */
40 static int tcp_oos_pbuf_count(struct tcp_pcb
* pcb
)
43 struct tcp_seg
* seg
= pcb
->ooseq
;
45 num
+= pbuf_clen(seg
->p
);
51 /** Get the seqno of a segment (by index) on the ooseq list
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
58 tcp_oos_seg_seqno(struct tcp_pcb
* pcb
, int seg_index
)
61 struct tcp_seg
* seg
= pcb
->ooseq
;
63 /* then check the actual segment */
65 if(num
== seg_index
) {
66 return seg
->tcphdr
->seqno
;
75 /** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list
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
82 tcp_oos_seg_tcplen(struct tcp_pcb
* pcb
, int seg_index
)
85 struct tcp_seg
* seg
= pcb
->ooseq
;
87 /* then check the actual segment */
89 if(num
== seg_index
) {
90 return TCP_TCPLEN(seg
);
99 /** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list
101 * @param pcb the pcb to check for ooseq segments
102 * @return tcplen of all segment
105 tcp_oos_tcplen(struct tcp_pcb
* pcb
)
108 struct tcp_seg
* seg
= pcb
->ooseq
;
110 /* then check the actual segment */
112 len
+= TCP_TCPLEN(seg
);
118 /* Setup/teardown functions */
127 tcp_oos_teardown(void)
131 netif_default
= NULL
;
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
)
143 struct test_tcp_counters counters
;
145 struct pbuf
*p_8_9
, *p_4_8
, *p_4_10
, *p_2_14
, *p_fin
, *pinseq
;
151 ip_addr_t remote_ip
, local_ip
, netmask
;
153 u16_t remote_port
= 0x100, local_port
= 0x101;
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
;
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
);
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 */
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) */
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 */
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 */
188 p_2_14
= tcp_create_rx_segment(pcb
, &data
[2], 14, 2, 0, TCP_ACK
);
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 */
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 */
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 */
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 */
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 */
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
);
272 /* make sure the pcb is freed */
273 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
275 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 0);
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
)
285 struct test_tcp_counters counters
;
287 struct pbuf
*p_1_2
, *p_4_8
, *p_3_11
, *p_2_12
, *p_15_1
, *p_15_1a
, *pinseq
, *pinseqFIN
;
293 ip_addr_t remote_ip
, local_ip
, netmask
;
295 u16_t remote_port
= 0x100, local_port
= 0x101;
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
;
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
);
316 /* create segments */
317 /* p1: 7 bytes - 2 before FIN */
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) */
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 */
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 */
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! */
331 pinseq
= tcp_create_rx_segment(pcb
, &data
[0], 4, 0, 0, TCP_ACK
);
332 /* p5: last byte before FIN */
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);
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);
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);
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);
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
);
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);
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);
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
);
448 /* make sure the pcb is freed */
449 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
451 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 0);
455 static char data_full_wnd
[TCP_WND
];
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
)
461 #if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
463 struct test_tcp_counters counters
;
465 struct pbuf
*pinseq
, *p_ovr
;
466 ip_addr_t remote_ip
, local_ip
, netmask
;
467 u16_t remote_port
= 0x100, local_port
= 0x101;
472 for(i
= 0; i
< sizeof(data_full_wnd
); i
++) {
473 data_full_wnd
[i
] = (char)i
;
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
;
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;
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
);
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
;
516 expected_datalen
= TCP_WND
- TCP_MSS
;
518 if (datalen
!= expected_datalen
) {
519 EXPECT_OOSEQ(datalen
== expected_datalen
);
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
);
539 test_tcp_input(pinseq
, &netif
);
540 EXPECT(pcb
->ooseq
== NULL
);
542 /* make sure the pcb is freed */
543 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
545 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 0);
546 #endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
551 START_TEST(test_tcp_recv_ooseq_max_bytes
)
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))
555 struct test_tcp_counters counters
;
558 ip_addr_t remote_ip
, local_ip
, netmask
;
559 u16_t remote_port
= 0x100, local_port
= 0x101;
564 for(i
= 0; i
< sizeof(data_full_wnd
); i
++) {
565 data_full_wnd
[i
] = (char)i
;
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
;
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;
585 /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
587 /* create segments and 'recv' them */
588 for(k
= 1, i
= 1; k
< TCP_OOSEQ_MAX_BYTES
; k
+= TCP_MSS
, i
++) {
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
));
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
));
623 /* make sure the pcb is freed */
624 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
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)) */
632 START_TEST(test_tcp_recv_ooseq_max_pbufs
)
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))
636 struct test_tcp_counters counters
;
639 ip_addr_t remote_ip
, local_ip
, netmask
;
640 u16_t remote_port
= 0x100, local_port
= 0x101;
645 for(i
= 0; i
< sizeof(data_full_wnd
); i
++) {
646 data_full_wnd
[i
] = (char)i
;
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
;
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;
666 /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
668 /* create segments and 'recv' them */
669 for(i
= 1; i
<= TCP_OOSEQ_MAX_PBUFS
; i
++) {
671 struct pbuf
*p
= tcp_create_rx_segment(pcb
, &data_full_wnd
[i
],
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
);
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));
704 /* make sure the pcb is freed */
705 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
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)) */
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
)
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
);
728 /* this test uses 4 packets:
729 * - data (len=TCP_MSS)
731 * - data after FIN (len=1) (invalid)
732 * - 2nd FIN (invalid)
734 * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
736 static void test_tcp_recv_ooseq_double_FINs(int delay_packet
)
739 struct test_tcp_counters counters
;
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;
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;
749 for(i
= 0; i
< sizeof(data_full_wnd
); i
++) {
750 data_full_wnd
[i
] = (char)i
;
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
;
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;
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
);
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
);
777 if(delay_packet
& 1) {
778 /* drop normal data */
782 /* send normal data */
783 test_tcp_input(p
, &netif
);
785 exp_rx_bytes
+= TCP_MSS
;
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
);
790 if(delay_packet
& 2) {
792 if(first_dropped
> 2) {
798 test_tcp_input(p_normal_fin
, &netif
);
799 if (first_dropped
< 2) {
800 /* already dropped packets, this one is ooseq */
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
);
811 if(delay_packet
& 4) {
812 /* drop data-after-FIN */
813 if(first_dropped
> 3) {
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 */
828 /* inseq: no change */
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
);
834 if(delay_packet
& 8) {
836 if(first_dropped
> 4) {
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 */
851 /* inseq: no change */
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
);
857 if(delay_packet
& 1) {
858 /* dropped normal data before */
859 test_tcp_input(p
, &netif
);
861 exp_rx_bytes
+= TCP_MSS
;
862 if((delay_packet
& 2) == 0) {
863 /* normal FIN was NOT delayed */
865 exp_oos_pbufs
= exp_oos_tcplen
= 0;
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
);
871 if(delay_packet
& 2) {
872 /* dropped normal FIN before */
873 test_tcp_input(p_normal_fin
, &netif
);
875 exp_oos_pbufs
= exp_oos_tcplen
= 0;
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
);
880 if(delay_packet
& 4) {
881 /* dropped data-after-FIN before */
882 test_tcp_input(p_data_after_fin
, &netif
);
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
);
887 if(delay_packet
& 8) {
888 /* dropped 2nd-FIN before */
889 test_tcp_input(p_2nd_fin_ooseq
, &netif
);
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
);
894 /* check that ooseq data has been dumped */
895 EXPECT(pcb
->ooseq
== NULL
);
897 /* make sure the pcb is freed */
898 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 1);
900 EXPECT(lwip_stats
.memp
[MEMP_TCP_PCB
].used
== 0);
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) \
908 LWIP_UNUSED_ARG(_i); \
909 test_tcp_recv_ooseq_double_FINs(num); \
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)
930 /** Create the suite including all tests for this module */
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
957 return create_suite("TCP_OOS", tests
, sizeof(tests
)/sizeof(TFun
), tcp_oos_setup
, tcp_oos_teardown
);