ReactOS 0.4.15-dev-7704-gc07eb9f
test_tcp_oos.c
Go to the documentation of this file.
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
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
28static 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
40static 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
57static u32_t
58tcp_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
81static int
82tcp_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
104static int
105tcp_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
120static void
122{
124}
125
126static void
128{
130}
131
132
133
134/* Test functions */
135
139START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
140{
142 struct tcp_pcb* pcb;
143 struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
144 char data[] = {
145 1, 2, 3, 4,
146 5, 6, 7, 8,
147 9, 10, 11, 12,
148 13, 14, 15, 16};
149 ip_addr_t remote_ip, local_ip;
150 u16_t data_len;
151 u16_t remote_port = 0x100, local_port = 0x101;
152 struct netif netif;
153 LWIP_UNUSED_ARG(_i);
154
155 /* initialize local vars */
156 memset(&netif, 0, sizeof(netif));
157 IP4_ADDR(&local_ip, 192, 168, 1, 1);
158 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
159 data_len = sizeof(data);
160 /* initialize counter struct */
161 memset(&counters, 0, sizeof(counters));
162 counters.expected_data_len = data_len;
163 counters.expected_data = data;
164
165 /* create and initialize the pcb */
167 EXPECT_RET(pcb != NULL);
168 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
169
170 /* create segments */
171 /* pinseq is sent as last segment! */
172 pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
173 /* p1: 8 bytes before FIN */
174 /* seqno: 8..16 */
175 p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN);
176 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
177 /* seqno: 4..11 */
178 p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
179 /* p3: same as p2 but 2 bytes longer */
180 /* seqno: 4..13 */
181 p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
182 /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
183 /* seqno: 2..15 */
184 p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
185 /* FIN, seqno 16 */
186 p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN);
187 EXPECT(pinseq != NULL);
188 EXPECT(p_8_9 != NULL);
189 EXPECT(p_4_8 != NULL);
190 EXPECT(p_4_10 != NULL);
191 EXPECT(p_2_14 != NULL);
192 EXPECT(p_fin != NULL);
193 if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
194 /* pass the segment to tcp_input */
195 test_tcp_input(p_8_9, &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) == 1);
203 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
204 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
205
206 /* pass the segment to tcp_input */
207 test_tcp_input(p_4_8, &netif);
208 /* check if counters are as expected */
209 EXPECT(counters.close_calls == 0);
210 EXPECT(counters.recv_calls == 0);
211 EXPECT(counters.recved_bytes == 0);
212 EXPECT(counters.err_calls == 0);
213 /* check ooseq queue */
214 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
215 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
216 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
217 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
218 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
219
220 /* pass the segment to tcp_input */
221 test_tcp_input(p_4_10, &netif);
222 /* check if counters are as expected */
223 EXPECT(counters.close_calls == 0);
224 EXPECT(counters.recv_calls == 0);
225 EXPECT(counters.recved_bytes == 0);
226 EXPECT(counters.err_calls == 0);
227 /* ooseq queue: unchanged */
228 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
229 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
230 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
231 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
232 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
233
234 /* pass the segment to tcp_input */
235 test_tcp_input(p_2_14, &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 /* check ooseq queue */
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 */
245
246 /* pass the segment to tcp_input */
247 test_tcp_input(p_fin, &netif);
248 /* check if counters are as expected */
249 EXPECT(counters.close_calls == 0);
250 EXPECT(counters.recv_calls == 0);
251 EXPECT(counters.recved_bytes == 0);
252 EXPECT(counters.err_calls == 0);
253 /* ooseq queue: unchanged */
254 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
255 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
256 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
257
258 /* pass the segment to tcp_input */
259 test_tcp_input(pinseq, &netif);
260 /* check if counters are as expected */
261 EXPECT(counters.close_calls == 1);
262 EXPECT(counters.recv_calls == 1);
263 EXPECT(counters.recved_bytes == data_len);
264 EXPECT(counters.err_calls == 0);
265 EXPECT(pcb->ooseq == NULL);
266 }
267
268 /* make sure the pcb is freed */
269 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
270 tcp_abort(pcb);
271 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
272}
273END_TEST
274
275
279START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
280{
282 struct tcp_pcb* pcb;
283 struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
284 char data[] = {
285 1, 2, 3, 4,
286 5, 6, 7, 8,
287 9, 10, 11, 12,
288 13, 14, 15, 16};
289 ip_addr_t remote_ip, local_ip;
290 u16_t data_len;
291 u16_t remote_port = 0x100, local_port = 0x101;
292 struct netif netif;
293 LWIP_UNUSED_ARG(_i);
294
295 /* initialize local vars */
296 memset(&netif, 0, sizeof(netif));
297 IP4_ADDR(&local_ip, 192, 168, 1, 1);
298 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
299 data_len = sizeof(data);
300 /* initialize counter struct */
301 memset(&counters, 0, sizeof(counters));
302 counters.expected_data_len = data_len;
303 counters.expected_data = data;
304
305 /* create and initialize the pcb */
307 EXPECT_RET(pcb != NULL);
308 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
309
310 /* create segments */
311 /* p1: 7 bytes - 2 before FIN */
312 /* seqno: 1..2 */
313 p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK);
314 /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
315 /* seqno: 4..11 */
316 p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
317 /* p3: same as p2 but 2 bytes longer and one byte more at the front */
318 /* seqno: 3..13 */
319 p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
320 /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
321 /* seqno: 2..13 */
322 p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
323 /* pinseq is the first segment that is held back to create ooseq! */
324 /* seqno: 0..3 */
325 pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
326 /* p5: last byte before FIN */
327 /* seqno: 15 */
328 p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
329 /* p6: same as p5, should be ignored */
330 p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
331 /* pinseqFIN: last 2 bytes plus FIN */
332 /* only segment containing seqno 14 and FIN */
333 pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
334 EXPECT(pinseq != NULL);
335 EXPECT(p_1_2 != NULL);
336 EXPECT(p_4_8 != NULL);
337 EXPECT(p_3_11 != NULL);
338 EXPECT(p_2_12 != NULL);
339 EXPECT(p_15_1 != NULL);
340 EXPECT(p_15_1a != NULL);
341 EXPECT(pinseqFIN != NULL);
342 if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
343 && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
344 /* pass the segment to tcp_input */
345 test_tcp_input(p_1_2, &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) == 1);
353 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
354 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
355
356 /* pass the segment to tcp_input */
357 test_tcp_input(p_4_8, &netif);
358 /* check if counters are as expected */
359 EXPECT(counters.close_calls == 0);
360 EXPECT(counters.recv_calls == 0);
361 EXPECT(counters.recved_bytes == 0);
362 EXPECT(counters.err_calls == 0);
363 /* check ooseq queue */
364 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
365 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
366 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
367 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
368 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
369
370 /* pass the segment to tcp_input */
371 test_tcp_input(p_3_11, &netif);
372 /* check if counters are as expected */
373 EXPECT(counters.close_calls == 0);
374 EXPECT(counters.recv_calls == 0);
375 EXPECT(counters.recved_bytes == 0);
376 EXPECT(counters.err_calls == 0);
377 /* check ooseq queue */
378 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
379 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
380 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
381 /* p_3_11 has removed p_4_8 from ooseq */
382 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
383 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
384
385 /* pass the segment to tcp_input */
386 test_tcp_input(p_2_12, &netif);
387 /* check if counters are as expected */
388 EXPECT(counters.close_calls == 0);
389 EXPECT(counters.recv_calls == 0);
390 EXPECT(counters.recved_bytes == 0);
391 EXPECT(counters.err_calls == 0);
392 /* check ooseq queue */
393 EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
394 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
395 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
396 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
397 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
398
399 /* pass the segment to tcp_input */
400 test_tcp_input(pinseq, &netif);
401 /* check if counters are as expected */
402 EXPECT(counters.close_calls == 0);
403 EXPECT(counters.recv_calls == 1);
404 EXPECT(counters.recved_bytes == 14);
405 EXPECT(counters.err_calls == 0);
406 EXPECT(pcb->ooseq == NULL);
407
408 /* pass the segment to tcp_input */
409 test_tcp_input(p_15_1, &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 */
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);
419
420 /* pass the segment to tcp_input */
421 test_tcp_input(p_15_1a, &netif);
422 /* check if counters are as expected */
423 EXPECT(counters.close_calls == 0);
424 EXPECT(counters.recv_calls == 1);
425 EXPECT(counters.recved_bytes == 14);
426 EXPECT(counters.err_calls == 0);
427 /* check ooseq queue: unchanged */
428 EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
429 EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
430 EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
431
432 /* pass the segment to tcp_input */
433 test_tcp_input(pinseqFIN, &netif);
434 /* check if counters are as expected */
435 EXPECT(counters.close_calls == 1);
436 EXPECT(counters.recv_calls == 2);
437 EXPECT(counters.recved_bytes == data_len);
438 EXPECT(counters.err_calls == 0);
439 EXPECT(pcb->ooseq == NULL);
440 }
441
442 /* make sure the pcb is freed */
443 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
444 tcp_abort(pcb);
445 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
446}
447END_TEST
448
450
453START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
454{
455#if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
456 int i, k;
458 struct tcp_pcb* pcb;
459 struct pbuf *pinseq, *p_ovr;
460 ip_addr_t remote_ip, local_ip;
461 u16_t remote_port = 0x100, local_port = 0x101;
462 struct netif netif;
463 int datalen = 0;
464 int datalen2;
465
466 for(i = 0; i < sizeof(data_full_wnd); i++) {
467 data_full_wnd[i] = (char)i;
468 }
469
470 /* initialize local vars */
471 memset(&netif, 0, sizeof(netif));
472 IP4_ADDR(&local_ip, 192, 168, 1, 1);
473 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
474 /* initialize counter struct */
475 memset(&counters, 0, sizeof(counters));
476 counters.expected_data_len = TCP_WND;
477 counters.expected_data = data_full_wnd;
478
479 /* create and initialize the pcb */
481 EXPECT_RET(pcb != NULL);
482 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
483 pcb->rcv_nxt = 0x8000;
484
485 /* create segments */
486 /* pinseq is sent as last segment! */
487 pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
488
489 for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
490 int count, expected_datalen;
491 struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
492 TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
493 EXPECT_RET(p != NULL);
494 /* pass the segment to tcp_input */
496 /* check if counters are as expected */
497 EXPECT(counters.close_calls == 0);
498 EXPECT(counters.recv_calls == 0);
499 EXPECT(counters.recved_bytes == 0);
500 EXPECT(counters.err_calls == 0);
501 /* check ooseq queue */
502 count = tcp_oos_count(pcb);
503 EXPECT_OOSEQ(count == k+1);
504 datalen = tcp_oos_tcplen(pcb);
505 if (i + TCP_MSS < TCP_WND) {
506 expected_datalen = (k+1)*TCP_MSS;
507 } else {
508 expected_datalen = TCP_WND - TCP_MSS;
509 }
510 if (datalen != expected_datalen) {
511 EXPECT_OOSEQ(datalen == expected_datalen);
512 }
513 }
514
515 /* pass in one more segment, cleary overrunning the rxwin */
516 p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
517 EXPECT_RET(p_ovr != NULL);
518 /* pass the segment to tcp_input */
519 test_tcp_input(p_ovr, &netif);
520 /* check if counters are as expected */
521 EXPECT(counters.close_calls == 0);
522 EXPECT(counters.recv_calls == 0);
523 EXPECT(counters.recved_bytes == 0);
524 EXPECT(counters.err_calls == 0);
525 /* check ooseq queue */
527 datalen2 = tcp_oos_tcplen(pcb);
528 EXPECT_OOSEQ(datalen == datalen2);
529
530 /* now pass inseq */
531 test_tcp_input(pinseq, &netif);
532 EXPECT(pcb->ooseq == NULL);
533
534 /* make sure the pcb is freed */
535 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
536 tcp_abort(pcb);
537 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
538#endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
539 LWIP_UNUSED_ARG(_i);
540}
541END_TEST
542
543START_TEST(test_tcp_recv_ooseq_max_bytes)
544{
545#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))
546 int i, k;
548 struct tcp_pcb* pcb;
549 struct pbuf *p_ovr;
550 ip_addr_t remote_ip, local_ip;
551 u16_t remote_port = 0x100, local_port = 0x101;
552 struct netif netif;
553 int datalen = 0;
554 int datalen2;
555
556 for(i = 0; i < sizeof(data_full_wnd); i++) {
557 data_full_wnd[i] = (char)i;
558 }
559
560 /* initialize local vars */
561 memset(&netif, 0, sizeof(netif));
562 IP4_ADDR(&local_ip, 192, 168, 1, 1);
563 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
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 */
571 EXPECT_RET(pcb != NULL);
572 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
573 pcb->rcv_nxt = 0x8000;
574
575 /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
576
577 /* create segments and 'recv' them */
578 for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) {
579 int count;
580 struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k],
581 TCP_MSS, k, 0, TCP_ACK);
582 EXPECT_RET(p != NULL);
583 EXPECT_RET(p->next == NULL);
584 /* pass the segment to tcp_input */
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 */
593 EXPECT_OOSEQ(count == i);
594 datalen = tcp_oos_tcplen(pcb);
596 }
597
598 /* pass in one more segment, overrunning the limit */
599 p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK);
600 EXPECT_RET(p_ovr != NULL);
601 /* pass the segment to tcp_input */
602 test_tcp_input(p_ovr, &netif);
603 /* check if counters are as expected */
604 EXPECT(counters.close_calls == 0);
605 EXPECT(counters.recv_calls == 0);
606 EXPECT(counters.recved_bytes == 0);
607 EXPECT(counters.err_calls == 0);
608 /* check ooseq queue (ensure the new segment was not accepted) */
609 EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
610 datalen2 = tcp_oos_tcplen(pcb);
611 EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS));
612
613 /* make sure the pcb is freed */
614 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
615 tcp_abort(pcb);
616 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
617#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)) */
618 LWIP_UNUSED_ARG(_i);
619}
620END_TEST
621
622START_TEST(test_tcp_recv_ooseq_max_pbufs)
623{
624#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))
625 int i;
627 struct tcp_pcb* pcb;
628 struct pbuf *p_ovr;
629 ip_addr_t remote_ip, local_ip;
630 u16_t remote_port = 0x100, local_port = 0x101;
631 struct netif netif;
632 int datalen = 0;
633 int datalen2;
634
635 for(i = 0; i < sizeof(data_full_wnd); i++) {
636 data_full_wnd[i] = (char)i;
637 }
638
639 /* initialize local vars */
640 memset(&netif, 0, sizeof(netif));
641 IP4_ADDR(&local_ip, 192, 168, 1, 1);
642 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
643 /* initialize counter struct */
644 memset(&counters, 0, sizeof(counters));
645 counters.expected_data_len = TCP_WND;
646 counters.expected_data = data_full_wnd;
647
648 /* create and initialize the pcb */
650 EXPECT_RET(pcb != NULL);
651 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
652 pcb->rcv_nxt = 0x8000;
653
654 /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
655
656 /* create segments and 'recv' them */
657 for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) {
658 int count;
659 struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i],
660 1, i, 0, TCP_ACK);
661 EXPECT_RET(p != NULL);
662 EXPECT_RET(p->next == NULL);
663 /* pass the segment to tcp_input */
665 /* check if counters are as expected */
666 EXPECT(counters.close_calls == 0);
667 EXPECT(counters.recv_calls == 0);
668 EXPECT(counters.recved_bytes == 0);
669 EXPECT(counters.err_calls == 0);
670 /* check ooseq queue */
672 EXPECT_OOSEQ(count == i);
673 datalen = tcp_oos_tcplen(pcb);
675 }
676
677 /* pass in one more segment, overrunning the limit */
678 p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK);
679 EXPECT_RET(p_ovr != NULL);
680 /* pass the segment to tcp_input */
681 test_tcp_input(p_ovr, &netif);
682 /* check if counters are as expected */
683 EXPECT(counters.close_calls == 0);
684 EXPECT(counters.recv_calls == 0);
685 EXPECT(counters.recved_bytes == 0);
686 EXPECT(counters.err_calls == 0);
687 /* check ooseq queue (ensure the new segment was not accepted) */
688 EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
689 datalen2 = tcp_oos_tcplen(pcb);
690 EXPECT_OOSEQ(datalen2 == (i-1));
691
692 /* make sure the pcb is freed */
693 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
694 tcp_abort(pcb);
695 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
696#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)) */
697 LWIP_UNUSED_ARG(_i);
698}
699END_TEST
700
701static void
702check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls,
703 u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len)
704{
705 int oos_len;
706 EXPECT(counters->close_calls == exp_close_calls);
707 EXPECT(counters->recv_calls == exp_rx_calls);
708 EXPECT(counters->recved_bytes == exp_rx_bytes);
709 EXPECT(counters->err_calls == exp_err_calls);
710 /* check that pbuf is queued in ooseq */
711 EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count);
712 oos_len = tcp_oos_tcplen(pcb);
713 EXPECT_OOSEQ(exp_oos_len == oos_len);
714}
715
716/* this test uses 4 packets:
717 * - data (len=TCP_MSS)
718 * - FIN
719 * - data after FIN (len=1) (invalid)
720 * - 2nd FIN (invalid)
721 *
722 * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
723 */
724static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
725{
726 int i, k;
728 struct tcp_pcb* pcb;
729 struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq;
730 ip_addr_t remote_ip, local_ip;
731 u16_t remote_port = 0x100, local_port = 0x101;
732 struct netif netif;
733 u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0;
734 int first_dropped = 0xff;
735 int last_dropped = 0;
736
737 for(i = 0; i < sizeof(data_full_wnd); i++) {
738 data_full_wnd[i] = (char)i;
739 }
740
741 /* initialize local vars */
742 memset(&netif, 0, sizeof(netif));
743 IP4_ADDR(&local_ip, 192, 168, 1, 1);
744 IP4_ADDR(&remote_ip, 192, 168, 1, 2);
745 /* initialize counter struct */
746 memset(&counters, 0, sizeof(counters));
747 counters.expected_data_len = TCP_WND;
748 counters.expected_data = data_full_wnd;
749
750 /* create and initialize the pcb */
752 EXPECT_RET(pcb != NULL);
753 tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
754 pcb->rcv_nxt = 0x8000;
755
756 /* create segments */
757 p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
758 p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN);
759 k = 1;
760 p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK);
761 p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN);
762
763 if(delay_packet & 1) {
764 /* drop normal data */
765 first_dropped = 1;
766 last_dropped = 1;
767 } else {
768 /* send normal data */
770 exp_rx_calls++;
771 exp_rx_bytes += TCP_MSS;
772 }
773 /* check if counters are as expected */
774 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
775
776 if(delay_packet & 2) {
777 /* drop FIN */
778 if(first_dropped > 2) {
779 first_dropped = 2;
780 }
781 last_dropped = 2;
782 } else {
783 /* send FIN */
784 test_tcp_input(p_normal_fin, &netif);
785 if (first_dropped < 2) {
786 /* already dropped packets, this one is ooseq */
787 exp_oos_pbufs++;
788 exp_oos_tcplen++;
789 } else {
790 /* inseq */
791 exp_close_calls++;
792 }
793 }
794 /* check if counters are as expected */
795 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
796
797 if(delay_packet & 4) {
798 /* drop data-after-FIN */
799 if(first_dropped > 3) {
800 first_dropped = 3;
801 }
802 last_dropped = 3;
803 } else {
804 /* send data-after-FIN */
805 test_tcp_input(p_data_after_fin, &netif);
806 if (first_dropped < 3) {
807 /* already dropped packets, this one is ooseq */
808 if (delay_packet & 2) {
809 /* correct FIN was ooseq */
810 exp_oos_pbufs++;
811 exp_oos_tcplen += k;
812 }
813 } else {
814 /* inseq: no change */
815 }
816 }
817 /* check if counters are as expected */
818 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
819
820 if(delay_packet & 8) {
821 /* drop 2nd-FIN */
822 if(first_dropped > 4) {
823 first_dropped = 4;
824 }
825 last_dropped = 4;
826 } else {
827 /* send 2nd-FIN */
828 test_tcp_input(p_2nd_fin_ooseq, &netif);
829 if (first_dropped < 3) {
830 /* already dropped packets, this one is ooseq */
831 if (delay_packet & 2) {
832 /* correct FIN was ooseq */
833 exp_oos_pbufs++;
834 exp_oos_tcplen++;
835 }
836 } else {
837 /* inseq: no change */
838 }
839 }
840 /* check if counters are as expected */
841 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
842
843 if(delay_packet & 1) {
844 /* dropped normal data before */
846 exp_rx_calls++;
847 exp_rx_bytes += TCP_MSS;
848 if((delay_packet & 2) == 0) {
849 /* normal FIN was NOT delayed */
850 exp_close_calls++;
851 exp_oos_pbufs = exp_oos_tcplen = 0;
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 & 2) {
858 /* dropped normal FIN before */
859 test_tcp_input(p_normal_fin, &netif);
860 exp_close_calls++;
861 exp_oos_pbufs = exp_oos_tcplen = 0;
862 }
863 /* check if counters are as expected */
864 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
865
866 if(delay_packet & 4) {
867 /* dropped data-after-FIN before */
868 test_tcp_input(p_data_after_fin, &netif);
869 }
870 /* check if counters are as expected */
871 check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
872
873 if(delay_packet & 8) {
874 /* dropped 2nd-FIN before */
875 test_tcp_input(p_2nd_fin_ooseq, &netif);
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 /* check that ooseq data has been dumped */
881 EXPECT(pcb->ooseq == NULL);
882
883 /* make sure the pcb is freed */
884 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
885 tcp_abort(pcb);
886 EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
887}
888
891#define FIN_TEST(name, num) \
892 START_TEST(name) \
893 { \
894 LWIP_UNUSED_ARG(_i); \
895 test_tcp_recv_ooseq_double_FINs(num); \
896 } \
897 END_TEST
898FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0)
899FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1)
900FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2)
901FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3)
902FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4)
903FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5)
904FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6)
905FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7)
906FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8)
907FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9)
908FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10)
909FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11)
910FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12)
911FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13)
912FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14)
913FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15)
914
915
917Suite *
919{
920 TFun tests[] = {
921 test_tcp_recv_ooseq_FIN_OOSEQ,
922 test_tcp_recv_ooseq_FIN_INSEQ,
923 test_tcp_recv_ooseq_overrun_rxwin,
924 test_tcp_recv_ooseq_max_bytes,
925 test_tcp_recv_ooseq_max_pbufs,
926 test_tcp_recv_ooseq_double_FIN_0,
927 test_tcp_recv_ooseq_double_FIN_1,
928 test_tcp_recv_ooseq_double_FIN_2,
929 test_tcp_recv_ooseq_double_FIN_3,
930 test_tcp_recv_ooseq_double_FIN_4,
931 test_tcp_recv_ooseq_double_FIN_5,
932 test_tcp_recv_ooseq_double_FIN_6,
933 test_tcp_recv_ooseq_double_FIN_7,
934 test_tcp_recv_ooseq_double_FIN_8,
935 test_tcp_recv_ooseq_double_FIN_9,
936 test_tcp_recv_ooseq_double_FIN_10,
937 test_tcp_recv_ooseq_double_FIN_11,
938 test_tcp_recv_ooseq_double_FIN_12,
939 test_tcp_recv_ooseq_double_FIN_13,
940 test_tcp_recv_ooseq_double_FIN_14,
941 test_tcp_recv_ooseq_double_FIN_15
942 };
943 return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
944}
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
#define START_TEST(x)
Definition: atltest.h:75
#define NULL
Definition: types.h:112
unsigned char
Definition: typeof.h:29
unsigned long u32_t
Definition: cc.h:25
unsigned short u16_t
Definition: cc.h:24
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLuint * counters
Definition: glext.h:11114
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TCP_WND
Definition: lwipopts.h:67
#define TCP_MSS
Definition: lwipopts.h:65
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition: ip_addr.h:139
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1031
static Suite * create_suite(const char *name, TFun *tests, size_t num_tests, SFun setup, SFun teardown)
Definition: lwip_check.h:20
#define EXPECT(x)
Definition: lwip_check.h:11
#define EXPECT_RET(x)
Definition: lwip_check.h:12
static struct test_info tests[]
int k
Definition: mpi.c:3369
#define TCP_OOSEQ_MAX_PBUFS
Definition: opt.h:1019
#define TCP_OOSEQ_MAX_BYTES
Definition: opt.h:1011
u8_t pbuf_clen(struct pbuf *p)
Definition: pbuf.c:704
#define memset(x, y, z)
Definition: compat.h:39
Definition: netif.h:136
Definition: pbuf.h:79
void test_tcp_input(struct pbuf *p, struct netif *inp)
Definition: tcp_helper.c:238
struct pbuf * tcp_create_rx_segment(struct tcp_pcb *pcb, void *data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags)
Definition: tcp_helper.c:118
struct tcp_pcb * test_tcp_new_counters_pcb(struct test_tcp_counters *counters)
Definition: tcp_helper.c:223
void tcp_remove_all(void)
Definition: tcp_helper.c:28
static __inline void tcp_set_state(struct sock *sk, int state)
Definition: tcpcore.h:3256
static int tcp_oos_seg_tcplen(struct tcp_pcb *pcb, int seg_index)
Definition: test_tcp_oos.c:82
static END_TEST void check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls, u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len)
Definition: test_tcp_oos.c:702
static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
Definition: test_tcp_oos.c:724
#define FIN_TEST(name, num)
Definition: test_tcp_oos.c:891
Suite * tcp_oos_suite(void)
Definition: test_tcp_oos.c:918
static int tcp_oos_tcplen(struct tcp_pcb *pcb)
Definition: test_tcp_oos.c:105
static void tcp_oos_setup(void)
Definition: test_tcp_oos.c:121
static int tcp_oos_pbuf_count(struct tcp_pcb *pcb)
Definition: test_tcp_oos.c:40
static void tcp_oos_teardown(void)
Definition: test_tcp_oos.c:127
#define EXPECT_OOSEQ(x)
Definition: test_tcp_oos.c:20
static int tcp_oos_count(struct tcp_pcb *pcb)
Definition: test_tcp_oos.c:28
static u32_t tcp_oos_seg_seqno(struct tcp_pcb *pcb, int seg_index)
Definition: test_tcp_oos.c:58
static END_TEST char data_full_wnd[TCP_WND]
Definition: test_tcp_oos.c:449