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