uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test_tcp_oos.c
Go to the documentation of this file.
1 #include "test_tcp_oos.h"
2 
3 #include "lwip/tcp_impl.h"
4 #include "lwip/stats.h"
5 #include "tcp_helper.h"
6 
7 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
8 #error "This tests needs TCP- and MEMP-statistics enabled"
9 #endif
10 #if !TCP_QUEUE_OOSEQ
11 #error "This tests needs TCP_QUEUE_OOSEQ enabled"
12 #endif
13 
17 #define CHECK_SEGMENTS_ON_OOSEQ 1
18 
19 #if CHECK_SEGMENTS_ON_OOSEQ
20 #define EXPECT_OOSEQ(x) EXPECT(x)
21 #else
22 #define EXPECT_OOSEQ(x)
23 #endif
24 
25 /* helper functions */
26 
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 
45 static u32_t
46 tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
47 {
48  int num = 0;
49  struct tcp_seg* seg = pcb->ooseq;
50 
51  /* then check the actual segment */
52  while(seg != NULL) {
53  if(num == seg_index) {
54  return seg->tcphdr->seqno;
55  }
56  num++;
57  seg = seg->next;
58  }
59  fail();
60  return 0;
61 }
62 
69 static int
70 tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
71 {
72  int num = 0;
73  struct tcp_seg* seg = pcb->ooseq;
74 
75  /* then check the actual segment */
76  while(seg != NULL) {
77  if(num == seg_index) {
78  return TCP_TCPLEN(seg);
79  }
80  num++;
81  seg = seg->next;
82  }
83  fail();
84  return -1;
85 }
86 
92 static int
93 tcp_oos_tcplen(struct tcp_pcb* pcb)
94 {
95  int len = 0;
96  struct tcp_seg* seg = pcb->ooseq;
97 
98  /* then check the actual segment */
99  while(seg != NULL) {
100  len += TCP_TCPLEN(seg);
101  seg = seg->next;
102  }
103  return len;
104 }
105 
106 /* Setup/teardown functions */
107 
108 static void
109 tcp_oos_setup(void)
110 {
111  tcp_remove_all();
112 }
113 
114 static void
115 tcp_oos_teardown(void)
116 {
117  tcp_remove_all();
118 }
119 
120 
121 
122 /* Test functions */
123 
127 START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
128 {
129  struct test_tcp_counters counters;
130  struct tcp_pcb* pcb;
131  struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
132  char data[] = {
133  1, 2, 3, 4,
134  5, 6, 7, 8,
135  9, 10, 11, 12,
136  13, 14, 15, 16};
137  ip_addr_t remote_ip, local_ip;
138  u16_t data_len;
139  u16_t remote_port = 0x100, local_port = 0x101;
140  struct netif netif;
141  LWIP_UNUSED_ARG(_i);
142 
143  /* initialize local vars */
144  memset(&netif, 0, sizeof(netif));
145  IP4_ADDR(&local_ip, 192, 168, 1, 1);
146  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
147  data_len = sizeof(data);
148  /* initialize counter struct */
149  memset(&counters, 0, sizeof(counters));
150  counters.expected_data_len = data_len;
151  counters.expected_data = data;
152 
153  /* create and initialize the pcb */
154  pcb = test_tcp_new_counters_pcb(&counters);
155  EXPECT_RET(pcb != NULL);
156  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
157 
158  /* create segments */
159  /* pinseq is sent as last segment! */
160  pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
161  /* p1: 8 bytes before FIN */
162  /* seqno: 8..16 */
163  p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN);
164  /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
165  /* seqno: 4..11 */
166  p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
167  /* p3: same as p2 but 2 bytes longer */
168  /* seqno: 4..13 */
169  p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
170  /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
171  /* seqno: 2..15 */
172  p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
173  /* FIN, seqno 16 */
174  p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN);
175  EXPECT(pinseq != NULL);
176  EXPECT(p_8_9 != NULL);
177  EXPECT(p_4_8 != NULL);
178  EXPECT(p_4_10 != NULL);
179  EXPECT(p_2_14 != NULL);
180  EXPECT(p_fin != NULL);
181  if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
182  /* pass the segment to tcp_input */
183  tcp_input(p_8_9, &netif);
184  /* check if counters are as expected */
185  EXPECT(counters.close_calls == 0);
186  EXPECT(counters.recv_calls == 0);
187  EXPECT(counters.recved_bytes == 0);
188  EXPECT(counters.err_calls == 0);
189  /* check ooseq queue */
190  EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
191  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
192  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
193 
194  /* pass the segment to tcp_input */
195  tcp_input(p_4_8, &netif);
196  /* check if counters are as expected */
197  EXPECT(counters.close_calls == 0);
198  EXPECT(counters.recv_calls == 0);
199  EXPECT(counters.recved_bytes == 0);
200  EXPECT(counters.err_calls == 0);
201  /* check ooseq queue */
202  EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
203  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
204  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
205  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
206  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
207 
208  /* pass the segment to tcp_input */
209  tcp_input(p_4_10, &netif);
210  /* check if counters are as expected */
211  EXPECT(counters.close_calls == 0);
212  EXPECT(counters.recv_calls == 0);
213  EXPECT(counters.recved_bytes == 0);
214  EXPECT(counters.err_calls == 0);
215  /* ooseq queue: unchanged */
216  EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
217  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
218  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
219  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
220  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
221 
222  /* pass the segment to tcp_input */
223  tcp_input(p_2_14, &netif);
224  /* check if counters are as expected */
225  EXPECT(counters.close_calls == 0);
226  EXPECT(counters.recv_calls == 0);
227  EXPECT(counters.recved_bytes == 0);
228  EXPECT(counters.err_calls == 0);
229  /* check ooseq queue */
230  EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
231  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
232  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
233 
234  /* pass the segment to tcp_input */
235  tcp_input(p_fin, &netif);
236  /* check if counters are as expected */
237  EXPECT(counters.close_calls == 0);
238  EXPECT(counters.recv_calls == 0);
239  EXPECT(counters.recved_bytes == 0);
240  EXPECT(counters.err_calls == 0);
241  /* ooseq queue: unchanged */
242  EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
243  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
244  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
245 
246  /* pass the segment to tcp_input */
247  tcp_input(pinseq, &netif);
248  /* check if counters are as expected */
249  EXPECT(counters.close_calls == 1);
250  EXPECT(counters.recv_calls == 1);
251  EXPECT(counters.recved_bytes == data_len);
252  EXPECT(counters.err_calls == 0);
253  EXPECT(pcb->ooseq == NULL);
254  }
255 
256  /* make sure the pcb is freed */
257  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
258  tcp_abort(pcb);
259  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
260 }
261 END_TEST
262 
263 
267 START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
268 {
269  struct test_tcp_counters counters;
270  struct tcp_pcb* pcb;
271  struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
272  char data[] = {
273  1, 2, 3, 4,
274  5, 6, 7, 8,
275  9, 10, 11, 12,
276  13, 14, 15, 16};
277  ip_addr_t remote_ip, local_ip;
278  u16_t data_len;
279  u16_t remote_port = 0x100, local_port = 0x101;
280  struct netif netif;
281  LWIP_UNUSED_ARG(_i);
282 
283  /* initialize local vars */
284  memset(&netif, 0, sizeof(netif));
285  IP4_ADDR(&local_ip, 192, 168, 1, 1);
286  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
287  data_len = sizeof(data);
288  /* initialize counter struct */
289  memset(&counters, 0, sizeof(counters));
290  counters.expected_data_len = data_len;
291  counters.expected_data = data;
292 
293  /* create and initialize the pcb */
294  pcb = test_tcp_new_counters_pcb(&counters);
295  EXPECT_RET(pcb != NULL);
296  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
297 
298  /* create segments */
299  /* p1: 7 bytes - 2 before FIN */
300  /* seqno: 1..2 */
301  p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK);
302  /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
303  /* seqno: 4..11 */
304  p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK);
305  /* p3: same as p2 but 2 bytes longer and one byte more at the front */
306  /* seqno: 3..13 */
307  p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
308  /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
309  /* seqno: 2..13 */
310  p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
311  /* pinseq is the first segment that is held back to create ooseq! */
312  /* seqno: 0..3 */
313  pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK);
314  /* p5: last byte before FIN */
315  /* seqno: 15 */
316  p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
317  /* p6: same as p5, should be ignored */
318  p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
319  /* pinseqFIN: last 2 bytes plus FIN */
320  /* only segment containing seqno 14 and FIN */
321  pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
322  EXPECT(pinseq != NULL);
323  EXPECT(p_1_2 != NULL);
324  EXPECT(p_4_8 != NULL);
325  EXPECT(p_3_11 != NULL);
326  EXPECT(p_2_12 != NULL);
327  EXPECT(p_15_1 != NULL);
328  EXPECT(p_15_1a != NULL);
329  EXPECT(pinseqFIN != NULL);
330  if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
331  && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
332  /* pass the segment to tcp_input */
333  tcp_input(p_1_2, &netif);
334  /* check if counters are as expected */
335  EXPECT(counters.close_calls == 0);
336  EXPECT(counters.recv_calls == 0);
337  EXPECT(counters.recved_bytes == 0);
338  EXPECT(counters.err_calls == 0);
339  /* check ooseq queue */
340  EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
341  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
342  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
343 
344  /* pass the segment to tcp_input */
345  tcp_input(p_4_8, &netif);
346  /* check if counters are as expected */
347  EXPECT(counters.close_calls == 0);
348  EXPECT(counters.recv_calls == 0);
349  EXPECT(counters.recved_bytes == 0);
350  EXPECT(counters.err_calls == 0);
351  /* check ooseq queue */
352  EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
353  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
354  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
355  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
356  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
357 
358  /* pass the segment to tcp_input */
359  tcp_input(p_3_11, &netif);
360  /* check if counters are as expected */
361  EXPECT(counters.close_calls == 0);
362  EXPECT(counters.recv_calls == 0);
363  EXPECT(counters.recved_bytes == 0);
364  EXPECT(counters.err_calls == 0);
365  /* check ooseq queue */
366  EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
367  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
368  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
369  /* p_3_11 has removed p_4_8 from ooseq */
370  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
371  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
372 
373  /* pass the segment to tcp_input */
374  tcp_input(p_2_12, &netif);
375  /* check if counters are as expected */
376  EXPECT(counters.close_calls == 0);
377  EXPECT(counters.recv_calls == 0);
378  EXPECT(counters.recved_bytes == 0);
379  EXPECT(counters.err_calls == 0);
380  /* check ooseq queue */
381  EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
382  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
383  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
384  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
385  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
386 
387  /* pass the segment to tcp_input */
388  tcp_input(pinseq, &netif);
389  /* check if counters are as expected */
390  EXPECT(counters.close_calls == 0);
391  EXPECT(counters.recv_calls == 1);
392  EXPECT(counters.recved_bytes == 14);
393  EXPECT(counters.err_calls == 0);
394  EXPECT(pcb->ooseq == NULL);
395 
396  /* pass the segment to tcp_input */
397  tcp_input(p_15_1, &netif);
398  /* check if counters are as expected */
399  EXPECT(counters.close_calls == 0);
400  EXPECT(counters.recv_calls == 1);
401  EXPECT(counters.recved_bytes == 14);
402  EXPECT(counters.err_calls == 0);
403  /* check ooseq queue */
404  EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
405  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
406  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
407 
408  /* pass the segment to tcp_input */
409  tcp_input(p_15_1a, &netif);
410  /* check if counters are as expected */
411  EXPECT(counters.close_calls == 0);
412  EXPECT(counters.recv_calls == 1);
413  EXPECT(counters.recved_bytes == 14);
414  EXPECT(counters.err_calls == 0);
415  /* check ooseq queue: unchanged */
416  EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
417  EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
418  EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
419 
420  /* pass the segment to tcp_input */
421  tcp_input(pinseqFIN, &netif);
422  /* check if counters are as expected */
423  EXPECT(counters.close_calls == 1);
424  EXPECT(counters.recv_calls == 2);
425  EXPECT(counters.recved_bytes == data_len);
426  EXPECT(counters.err_calls == 0);
427  EXPECT(pcb->ooseq == NULL);
428  }
429 
430  /* make sure the pcb is freed */
431  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
432  tcp_abort(pcb);
433  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
434 }
435 END_TEST
436 
437 static char data_full_wnd[TCP_WND];
438 
441 START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
442 {
443  int i, k;
444  struct test_tcp_counters counters;
445  struct tcp_pcb* pcb;
446  struct pbuf *pinseq, *p_ovr;
447  ip_addr_t remote_ip, local_ip;
448  u16_t remote_port = 0x100, local_port = 0x101;
449  struct netif netif;
450  int datalen = 0;
451  int datalen2;
452  LWIP_UNUSED_ARG(_i);
453 
454  for(i = 0; i < sizeof(data_full_wnd); i++) {
455  data_full_wnd[i] = (char)i;
456  }
457 
458  /* initialize local vars */
459  memset(&netif, 0, sizeof(netif));
460  IP4_ADDR(&local_ip, 192, 168, 1, 1);
461  IP4_ADDR(&remote_ip, 192, 168, 1, 2);
462  /* initialize counter struct */
463  memset(&counters, 0, sizeof(counters));
464  counters.expected_data_len = TCP_WND;
465  counters.expected_data = data_full_wnd;
466 
467  /* create and initialize the pcb */
468  pcb = test_tcp_new_counters_pcb(&counters);
469  EXPECT_RET(pcb != NULL);
470  tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
471  pcb->rcv_nxt = 0x8000;
472 
473  /* create segments */
474  /* pinseq is sent as last segment! */
475  pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
476 
477  for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
478  int count, expected_datalen;
479  struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
480  TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
481  EXPECT(p != NULL);
482  /* pass the segment to tcp_input */
483  tcp_input(p, &netif);
484  /* check if counters are as expected */
485  EXPECT(counters.close_calls == 0);
486  EXPECT(counters.recv_calls == 0);
487  EXPECT(counters.recved_bytes == 0);
488  EXPECT(counters.err_calls == 0);
489  /* check ooseq queue */
490  count = tcp_oos_count(pcb);
491  EXPECT_OOSEQ(count == k+1);
492  datalen = tcp_oos_tcplen(pcb);
493  if (i + TCP_MSS < TCP_WND) {
494  expected_datalen = (k+1)*TCP_MSS;
495  } else {
496  expected_datalen = TCP_WND - TCP_MSS;
497  }
498  if (datalen != expected_datalen) {
499  EXPECT_OOSEQ(datalen == expected_datalen);
500  }
501  }
502 
503  /* pass in one more segment, cleary overrunning the rxwin */
504  p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
505  EXPECT(p_ovr != NULL);
506  /* pass the segment to tcp_input */
507  tcp_input(p_ovr, &netif);
508  /* check if counters are as expected */
509  EXPECT(counters.close_calls == 0);
510  EXPECT(counters.recv_calls == 0);
511  EXPECT(counters.recved_bytes == 0);
512  EXPECT(counters.err_calls == 0);
513  /* check ooseq queue */
514  EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
515  datalen2 = tcp_oos_tcplen(pcb);
516  EXPECT_OOSEQ(datalen == datalen2);
517 
518  /* now pass inseq */
519  tcp_input(pinseq, &netif);
520  EXPECT(pcb->ooseq == NULL);
521 
522  /* make sure the pcb is freed */
523  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
524  tcp_abort(pcb);
525  EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
526 }
527 END_TEST
528 
529 
531 Suite *
533 {
534  TFun tests[] = {
535  test_tcp_recv_ooseq_FIN_OOSEQ,
536  test_tcp_recv_ooseq_FIN_INSEQ,
537  test_tcp_recv_ooseq_overrun_rxwin,
538  };
539  return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
540 }