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