]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/blob - test/unit/tcp/test_tcp_oos.c
c62dc1789175002d9e02b378231fc5c8e923144f
[pes-rpp/rpp-lwip.git] / 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 seqno of a segment (by index) on the ooseq list
40  *
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
44  */
45 static u32_t
46 tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
47 {
48   int num = 0;
49   struct tcp_seg* seg = pcb->ooseq;
50
51   /* then check the actual segment */
52   while(seg != NULL) {
53     if(num == seg_index) {
54       return seg->tcphdr->seqno;
55     }
56     num++;
57     seg = seg->next;
58   }
59   fail();
60   return 0;
61 }
62
63 /** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list
64  *
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
68  */
69 static int
70 tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
71 {
72   int num = 0;
73   struct tcp_seg* seg = pcb->ooseq;
74
75   /* then check the actual segment */
76   while(seg != NULL) {
77     if(num == seg_index) {
78       return TCP_TCPLEN(seg);
79     }
80     num++;
81     seg = seg->next;
82   }
83   fail();
84   return -1;
85 }
86
87 /** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list
88  *
89  * @param pcb the pcb to check for ooseq segments
90  * @return tcplen of all segment
91  */
92 static int
93 tcp_oos_tcplen(struct tcp_pcb* pcb)
94 {
95   int len = 0;
96   struct tcp_seg* seg = pcb->ooseq;
97
98   /* then check the actual segment */
99   while(seg != NULL) {
100     len += TCP_TCPLEN(seg);
101     seg = seg->next;
102   }
103   return len;
104 }
105
106 /* Setup/teardown functions */
107
108 static void
109 tcp_oos_setup(void)
110 {
111   tcp_remove_all();
112 }
113
114 static void
115 tcp_oos_teardown(void)
116 {
117   tcp_remove_all();
118 }
119
120
121
122 /* Test functions */
123
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)
128 {
129   struct test_tcp_counters counters;
130   struct tcp_pcb* pcb;
131   struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
132   char data[] = {
133      1,  2,  3,  4,
134      5,  6,  7,  8,
135      9, 10, 11, 12,
136     13, 14, 15, 16};
137   ip_addr_t remote_ip, local_ip;
138   u16_t data_len;
139   u16_t remote_port = 0x100, local_port = 0x101;
140   struct netif netif;
141   LWIP_UNUSED_ARG(_i);
142
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;
152
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);
157
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 */
162   /*     seqno: 8..16 */
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) */
165   /*     seqno: 4..11 */
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 */
168   /*     seqno: 4..13 */
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 */
171   /*     seqno: 2..15 */
172   p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
173   /* FIN, seqno 16 */
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 */
193
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 */
207
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 */
221
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 */
233
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 */
245
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);
254   }
255
256   /* make sure the pcb is freed */
257   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
258   tcp_abort(pcb);
259   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
260 }
261 END_TEST
262
263
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)
268 {
269   struct test_tcp_counters counters;
270   struct tcp_pcb* pcb;
271   struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
272   char data[] = {
273      1,  2,  3,  4,
274      5,  6,  7,  8,
275      9, 10, 11, 12,
276     13, 14, 15, 16};
277   ip_addr_t remote_ip, local_ip;
278   u16_t data_len;
279   u16_t remote_port = 0x100, local_port = 0x101;
280   struct netif netif;
281   LWIP_UNUSED_ARG(_i);
282
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;
292
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);
297
298   /* create segments */
299   /* p1: 7 bytes - 2 before FIN */
300   /*     seqno: 1..2 */
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) */
303   /*     seqno: 4..11 */
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 */
306   /*     seqno: 3..13 */
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 */
309   /*     seqno: 2..13 */
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! */
312   /*     seqno: 0..3 */
313   pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
314   /* p5: last byte before FIN */
315   /*     seqno: 15 */
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);
343
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);
357
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);
372
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);
386
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);
395
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);
407
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);
419
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);
428   }
429
430   /* make sure the pcb is freed */
431   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
432   tcp_abort(pcb);
433   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
434 }
435 END_TEST
436
437 static char data_full_wnd[TCP_WND];
438
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)
442 {
443   int i, k;
444   struct test_tcp_counters counters;
445   struct tcp_pcb* pcb;
446   struct pbuf *pinseq, *p_ovr;
447   ip_addr_t remote_ip, local_ip;
448   u16_t remote_port = 0x100, local_port = 0x101;
449   struct netif netif;
450   int datalen = 0;
451   int datalen2;
452   LWIP_UNUSED_ARG(_i);
453
454   for(i = 0; i < sizeof(data_full_wnd); i++) {
455     data_full_wnd[i] = (char)i;
456   }
457
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;
466
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;
472
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);
476
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;
495     } else {
496       expected_datalen = TCP_WND - TCP_MSS;
497     }
498     if (datalen != expected_datalen) {
499       EXPECT_OOSEQ(datalen == expected_datalen);
500     }
501   }
502
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);
517
518   /* now pass inseq */
519   test_tcp_input(pinseq, &netif);
520   EXPECT(pcb->ooseq == NULL);
521
522   /* make sure the pcb is freed */
523   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
524   tcp_abort(pcb);
525   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
526 }
527 END_TEST
528
529 static void
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)
532 {
533   int 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);
542 }
543
544 /* this test uses 4 packets:
545  * - data (len=TCP_MSS)
546  * - FIN
547  * - data after FIN (len=1) (invalid)
548  * - 2nd FIN (invalid)
549  *
550  * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
551  */
552 static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
553 {
554   int i, k;
555   struct test_tcp_counters counters;
556   struct tcp_pcb* pcb;
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;
560   struct netif netif;
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;
564
565   for(i = 0; i < sizeof(data_full_wnd); i++) {
566     data_full_wnd[i] = (char)i;
567   }
568
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;
577
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;
583
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);
587   k = 1;
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);
590
591   if(delay_packet & 1) {
592     /* drop normal data */
593     first_dropped = 1;
594     last_dropped = 1;
595   } else {
596     /* send normal data */
597     test_tcp_input(p, &netif);
598     exp_rx_calls++;
599     exp_rx_bytes += TCP_MSS;
600   }
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);
603
604   if(delay_packet & 2) {
605     /* drop FIN */
606     if(first_dropped > 2) {
607       first_dropped = 2;
608     }
609     last_dropped = 2;
610   } else {
611     /* send FIN */
612     test_tcp_input(p_normal_fin, &netif);
613     if (first_dropped < 2) {
614       /* already dropped packets, this one is ooseq */
615       exp_oos_pbufs++;
616       exp_oos_tcplen++;
617     } else {
618       /* inseq */
619       exp_close_calls++;
620     }
621   }
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);
624
625   if(delay_packet & 4) {
626     /* drop data-after-FIN */
627     if(first_dropped > 3) {
628       first_dropped = 3;
629     }
630     last_dropped = 3;
631   } else {
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 */
638         exp_oos_pbufs++;
639         exp_oos_tcplen += k;
640       }
641     } else {
642       /* inseq: no change */
643     }
644   }
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);
647
648   if(delay_packet & 8) {
649     /* drop 2nd-FIN */
650     if(first_dropped > 4) {
651       first_dropped = 4;
652     }
653     last_dropped = 4;
654   } else {
655     /* send 2nd-FIN */
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 */
661         exp_oos_pbufs++;
662         exp_oos_tcplen++;
663       }
664     } else {
665       /* inseq: no change */      
666     }
667   }
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);
670
671   if(delay_packet & 1) {
672     /* dropped normal data before */
673     test_tcp_input(p, &netif);
674     exp_rx_calls++;
675     exp_rx_bytes += TCP_MSS;
676     if((delay_packet & 2) == 0) {
677       /* normal FIN was NOT delayed */
678       exp_close_calls++;
679       exp_oos_pbufs = exp_oos_tcplen = 0;
680     }
681   }
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);
684
685   if(delay_packet & 2) {
686     /* dropped normal FIN before */
687     test_tcp_input(p_normal_fin, &netif);
688     exp_close_calls++;
689     exp_oos_pbufs = exp_oos_tcplen = 0;
690   }
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);
693
694   if(delay_packet & 4) {
695     /* dropped data-after-FIN before */
696     test_tcp_input(p_data_after_fin, &netif);
697   }
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);
700
701   if(delay_packet & 8) {
702     /* dropped 2nd-FIN before */
703     test_tcp_input(p_2nd_fin_ooseq, &netif);
704   }
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);
707
708   /* check that ooseq data has been dumped */
709   EXPECT(pcb->ooseq == NULL);
710
711   /* make sure the pcb is freed */
712   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
713   tcp_abort(pcb);
714   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
715 }
716
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) \
720   START_TEST(name) \
721   { \
722     LWIP_UNUSED_ARG(_i); \
723     test_tcp_recv_ooseq_double_FINs(num); \
724   } \
725   END_TEST
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)
742
743
744 /** Create the suite including all tests for this module */
745 Suite *
746 tcp_oos_suite(void)
747 {
748   TFun tests[] = {
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
768   };
769   return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
770 }