SAMV71 Xplained Ultra Software Package 1.0

test_tcp_oos.c

00001 #include "test_tcp_oos.h"
00002 
00003 #include "lwip/tcp_impl.h"
00004 #include "lwip/stats.h"
00005 #include "tcp_helper.h"
00006 
00007 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
00008 #error "This tests needs TCP- and MEMP-statistics enabled"
00009 #endif
00010 #if !TCP_QUEUE_OOSEQ
00011 #error "This tests needs TCP_QUEUE_OOSEQ enabled"
00012 #endif
00013 
00014 /** CHECK_SEGMENTS_ON_OOSEQ:
00015  * 1: check count, seqno and len of segments on pcb->ooseq (strict)
00016  * 0: only check that bytes are received in correct order (less strict) */
00017 #define CHECK_SEGMENTS_ON_OOSEQ 1
00018 
00019 #if CHECK_SEGMENTS_ON_OOSEQ
00020 #define EXPECT_OOSEQ(x) EXPECT(x)
00021 #else
00022 #define EXPECT_OOSEQ(x)
00023 #endif
00024 
00025 /* helper functions */
00026 
00027 /** Get the numbers of segments on the ooseq list */
00028 static int tcp_oos_count(struct tcp_pcb* pcb)
00029 {
00030   int num = 0;
00031   struct tcp_seg* seg = pcb->ooseq;
00032   while(seg != NULL) {
00033     num++;
00034     seg = seg->next;
00035   }
00036   return num;
00037 }
00038 
00039 /** Get the numbers of pbufs on the ooseq list */
00040 static int tcp_oos_pbuf_count(struct tcp_pcb* pcb)
00041 {
00042   int num = 0;
00043   struct tcp_seg* seg = pcb->ooseq;
00044   while(seg != NULL) {
00045     num += pbuf_clen(seg->p);
00046     seg = seg->next;
00047   }
00048   return num;
00049 }
00050 
00051 /** Get the seqno of a segment (by index) on the ooseq list
00052  *
00053  * @param pcb the pcb to check for ooseq segments
00054  * @param seg_index index of the segment on the ooseq list
00055  * @return seqno of the segment
00056  */
00057 static u32_t
00058 tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
00059 {
00060   int num = 0;
00061   struct tcp_seg* seg = pcb->ooseq;
00062 
00063   /* then check the actual segment */
00064   while(seg != NULL) {
00065     if(num == seg_index) {
00066       return seg->tcphdr->seqno;
00067     }
00068     num++;
00069     seg = seg->next;
00070   }
00071   fail();
00072   return 0;
00073 }
00074 
00075 /** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list
00076  *
00077  * @param pcb the pcb to check for ooseq segments
00078  * @param seg_index index of the segment on the ooseq list
00079  * @return tcplen of the segment
00080  */
00081 static int
00082 tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
00083 {
00084   int num = 0;
00085   struct tcp_seg* seg = pcb->ooseq;
00086 
00087   /* then check the actual segment */
00088   while(seg != NULL) {
00089     if(num == seg_index) {
00090       return TCP_TCPLEN(seg);
00091     }
00092     num++;
00093     seg = seg->next;
00094   }
00095   fail();
00096   return -1;
00097 }
00098 
00099 /** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list
00100  *
00101  * @param pcb the pcb to check for ooseq segments
00102  * @return tcplen of all segment
00103  */
00104 static int
00105 tcp_oos_tcplen(struct tcp_pcb* pcb)
00106 {
00107   int len = 0;
00108   struct tcp_seg* seg = pcb->ooseq;
00109 
00110   /* then check the actual segment */
00111   while(seg != NULL) {
00112     len += TCP_TCPLEN(seg);
00113     seg = seg->next;
00114   }
00115   return len;
00116 }
00117 
00118 /* Setup/teardown functions */
00119 
00120 static void
00121 tcp_oos_setup(void)
00122 {
00123   tcp_remove_all();
00124 }
00125 
00126 static void
00127 tcp_oos_teardown(void)
00128 {
00129   tcp_remove_all();
00130 }
00131 
00132 
00133 
00134 /* Test functions */
00135 
00136 /** create multiple segments and pass them to tcp_input in a wrong
00137  * order to see if ooseq-caching works correctly
00138  * FIN is received in out-of-sequence segments only */
00139 START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
00140 {
00141   struct test_tcp_counters counters;
00142   struct tcp_pcb* pcb;
00143   struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
00144   char data[] = {
00145      1,  2,  3,  4,
00146      5,  6,  7,  8,
00147      9, 10, 11, 12,
00148     13, 14, 15, 16};
00149   ip_addr_t remote_ip, local_ip;
00150   u16_t data_len;
00151   u16_t remote_port = 0x100, local_port = 0x101;
00152   struct netif netif;
00153   LWIP_UNUSED_ARG(_i);
00154 
00155   /* initialize local vars */
00156   memset(&netif, 0, sizeof(netif));
00157   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00158   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00159   data_len = sizeof(data);
00160   /* initialize counter struct */
00161   memset(&counters, 0, sizeof(counters));
00162   counters.expected_data_len = data_len;
00163   counters.expected_data = data;
00164 
00165   /* create and initialize the pcb */
00166   pcb = test_tcp_new_counters_pcb(&counters);
00167   EXPECT_RET(pcb != NULL);
00168   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00169 
00170   /* create segments */
00171   /* pinseq is sent as last segment! */
00172   pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
00173   /* p1: 8 bytes before FIN */
00174   /*     seqno: 8..16 */
00175   p_8_9  = tcp_create_rx_segment(pcb, &data[8],  8, 8, 0, TCP_ACK|TCP_FIN);
00176   /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
00177   /*     seqno: 4..11 */
00178   p_4_8  = tcp_create_rx_segment(pcb, &data[4],  8, 4, 0, TCP_ACK);
00179   /* p3: same as p2 but 2 bytes longer */
00180   /*     seqno: 4..13 */
00181   p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
00182   /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
00183   /*     seqno: 2..15 */
00184   p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
00185   /* FIN, seqno 16 */
00186   p_fin  = tcp_create_rx_segment(pcb,     NULL,  0,16, 0, TCP_ACK|TCP_FIN);
00187   EXPECT(pinseq != NULL);
00188   EXPECT(p_8_9 != NULL);
00189   EXPECT(p_4_8 != NULL);
00190   EXPECT(p_4_10 != NULL);
00191   EXPECT(p_2_14 != NULL);
00192   EXPECT(p_fin != NULL);
00193   if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
00194     /* pass the segment to tcp_input */
00195     test_tcp_input(p_8_9, &netif);
00196     /* check if counters are as expected */
00197     EXPECT(counters.close_calls == 0);
00198     EXPECT(counters.recv_calls == 0);
00199     EXPECT(counters.recved_bytes == 0);
00200     EXPECT(counters.err_calls == 0);
00201     /* check ooseq queue */
00202     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00203     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
00204     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
00205 
00206     /* pass the segment to tcp_input */
00207     test_tcp_input(p_4_8, &netif);
00208     /* check if counters are as expected */
00209     EXPECT(counters.close_calls == 0);
00210     EXPECT(counters.recv_calls == 0);
00211     EXPECT(counters.recved_bytes == 0);
00212     EXPECT(counters.err_calls == 0);
00213     /* check ooseq queue */
00214     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00215     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
00216     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
00217     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
00218     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
00219 
00220     /* pass the segment to tcp_input */
00221     test_tcp_input(p_4_10, &netif);
00222     /* check if counters are as expected */
00223     EXPECT(counters.close_calls == 0);
00224     EXPECT(counters.recv_calls == 0);
00225     EXPECT(counters.recved_bytes == 0);
00226     EXPECT(counters.err_calls == 0);
00227     /* ooseq queue: unchanged */
00228     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00229     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
00230     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
00231     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
00232     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
00233 
00234     /* pass the segment to tcp_input */
00235     test_tcp_input(p_2_14, &netif);
00236     /* check if counters are as expected */
00237     EXPECT(counters.close_calls == 0);
00238     EXPECT(counters.recv_calls == 0);
00239     EXPECT(counters.recved_bytes == 0);
00240     EXPECT(counters.err_calls == 0);
00241     /* check ooseq queue */
00242     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00243     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
00244     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
00245 
00246     /* pass the segment to tcp_input */
00247     test_tcp_input(p_fin, &netif);
00248     /* check if counters are as expected */
00249     EXPECT(counters.close_calls == 0);
00250     EXPECT(counters.recv_calls == 0);
00251     EXPECT(counters.recved_bytes == 0);
00252     EXPECT(counters.err_calls == 0);
00253     /* ooseq queue: unchanged */
00254     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00255     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
00256     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
00257 
00258     /* pass the segment to tcp_input */
00259     test_tcp_input(pinseq, &netif);
00260     /* check if counters are as expected */
00261     EXPECT(counters.close_calls == 1);
00262     EXPECT(counters.recv_calls == 1);
00263     EXPECT(counters.recved_bytes == data_len);
00264     EXPECT(counters.err_calls == 0);
00265     EXPECT(pcb->ooseq == NULL);
00266   }
00267 
00268   /* make sure the pcb is freed */
00269   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00270   tcp_abort(pcb);
00271   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00272 }
00273 END_TEST
00274 
00275 
00276 /** create multiple segments and pass them to tcp_input in a wrong
00277  * order to see if ooseq-caching works correctly
00278  * FIN is received IN-SEQUENCE at the end */
00279 START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
00280 {
00281   struct test_tcp_counters counters;
00282   struct tcp_pcb* pcb;
00283   struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
00284   char data[] = {
00285      1,  2,  3,  4,
00286      5,  6,  7,  8,
00287      9, 10, 11, 12,
00288     13, 14, 15, 16};
00289   ip_addr_t remote_ip, local_ip;
00290   u16_t data_len;
00291   u16_t remote_port = 0x100, local_port = 0x101;
00292   struct netif netif;
00293   LWIP_UNUSED_ARG(_i);
00294 
00295   /* initialize local vars */
00296   memset(&netif, 0, sizeof(netif));
00297   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00298   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00299   data_len = sizeof(data);
00300   /* initialize counter struct */
00301   memset(&counters, 0, sizeof(counters));
00302   counters.expected_data_len = data_len;
00303   counters.expected_data = data;
00304 
00305   /* create and initialize the pcb */
00306   pcb = test_tcp_new_counters_pcb(&counters);
00307   EXPECT_RET(pcb != NULL);
00308   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00309 
00310   /* create segments */
00311   /* p1: 7 bytes - 2 before FIN */
00312   /*     seqno: 1..2 */
00313   p_1_2  = tcp_create_rx_segment(pcb, &data[1],  2, 1, 0, TCP_ACK);
00314   /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
00315   /*     seqno: 4..11 */
00316   p_4_8  = tcp_create_rx_segment(pcb, &data[4],  8, 4, 0, TCP_ACK);
00317   /* p3: same as p2 but 2 bytes longer and one byte more at the front */
00318   /*     seqno: 3..13 */
00319   p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
00320   /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
00321   /*     seqno: 2..13 */
00322   p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
00323   /* pinseq is the first segment that is held back to create ooseq! */
00324   /*     seqno: 0..3 */
00325   pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
00326   /* p5: last byte before FIN */
00327   /*     seqno: 15 */
00328   p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
00329   /* p6: same as p5, should be ignored */
00330   p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
00331   /* pinseqFIN: last 2 bytes plus FIN */
00332   /*     only segment containing seqno 14 and FIN */
00333   pinseqFIN = tcp_create_rx_segment(pcb,  &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
00334   EXPECT(pinseq != NULL);
00335   EXPECT(p_1_2 != NULL);
00336   EXPECT(p_4_8 != NULL);
00337   EXPECT(p_3_11 != NULL);
00338   EXPECT(p_2_12 != NULL);
00339   EXPECT(p_15_1 != NULL);
00340   EXPECT(p_15_1a != NULL);
00341   EXPECT(pinseqFIN != NULL);
00342   if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
00343     && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
00344     /* pass the segment to tcp_input */
00345     test_tcp_input(p_1_2, &netif);
00346     /* check if counters are as expected */
00347     EXPECT(counters.close_calls == 0);
00348     EXPECT(counters.recv_calls == 0);
00349     EXPECT(counters.recved_bytes == 0);
00350     EXPECT(counters.err_calls == 0);
00351     /* check ooseq queue */
00352     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00353     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00354     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
00355 
00356     /* pass the segment to tcp_input */
00357     test_tcp_input(p_4_8, &netif);
00358     /* check if counters are as expected */
00359     EXPECT(counters.close_calls == 0);
00360     EXPECT(counters.recv_calls == 0);
00361     EXPECT(counters.recved_bytes == 0);
00362     EXPECT(counters.err_calls == 0);
00363     /* check ooseq queue */
00364     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00365     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00366     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
00367     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
00368     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
00369 
00370     /* pass the segment to tcp_input */
00371     test_tcp_input(p_3_11, &netif);
00372     /* check if counters are as expected */
00373     EXPECT(counters.close_calls == 0);
00374     EXPECT(counters.recv_calls == 0);
00375     EXPECT(counters.recved_bytes == 0);
00376     EXPECT(counters.err_calls == 0);
00377     /* check ooseq queue */
00378     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00379     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00380     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
00381     /* p_3_11 has removed p_4_8 from ooseq */
00382     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
00383     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
00384 
00385     /* pass the segment to tcp_input */
00386     test_tcp_input(p_2_12, &netif);
00387     /* check if counters are as expected */
00388     EXPECT(counters.close_calls == 0);
00389     EXPECT(counters.recv_calls == 0);
00390     EXPECT(counters.recved_bytes == 0);
00391     EXPECT(counters.err_calls == 0);
00392     /* check ooseq queue */
00393     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00394     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00395     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
00396     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
00397     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
00398 
00399     /* pass the segment to tcp_input */
00400     test_tcp_input(pinseq, &netif);
00401     /* check if counters are as expected */
00402     EXPECT(counters.close_calls == 0);
00403     EXPECT(counters.recv_calls == 1);
00404     EXPECT(counters.recved_bytes == 14);
00405     EXPECT(counters.err_calls == 0);
00406     EXPECT(pcb->ooseq == NULL);
00407 
00408     /* pass the segment to tcp_input */
00409     test_tcp_input(p_15_1, &netif);
00410     /* check if counters are as expected */
00411     EXPECT(counters.close_calls == 0);
00412     EXPECT(counters.recv_calls == 1);
00413     EXPECT(counters.recved_bytes == 14);
00414     EXPECT(counters.err_calls == 0);
00415     /* check ooseq queue */
00416     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00417     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
00418     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
00419 
00420     /* pass the segment to tcp_input */
00421     test_tcp_input(p_15_1a, &netif);
00422     /* check if counters are as expected */
00423     EXPECT(counters.close_calls == 0);
00424     EXPECT(counters.recv_calls == 1);
00425     EXPECT(counters.recved_bytes == 14);
00426     EXPECT(counters.err_calls == 0);
00427     /* check ooseq queue: unchanged */
00428     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00429     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
00430     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
00431 
00432     /* pass the segment to tcp_input */
00433     test_tcp_input(pinseqFIN, &netif);
00434     /* check if counters are as expected */
00435     EXPECT(counters.close_calls == 1);
00436     EXPECT(counters.recv_calls == 2);
00437     EXPECT(counters.recved_bytes == data_len);
00438     EXPECT(counters.err_calls == 0);
00439     EXPECT(pcb->ooseq == NULL);
00440   }
00441 
00442   /* make sure the pcb is freed */
00443   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00444   tcp_abort(pcb);
00445   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00446 }
00447 END_TEST
00448 
00449 static char data_full_wnd[TCP_WND];
00450 
00451 /** create multiple segments and pass them to tcp_input with the first segment missing
00452  * to simulate overruning the rxwin with ooseq queueing enabled */
00453 START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
00454 {
00455 #if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS
00456   int i, k;
00457   struct test_tcp_counters counters;
00458   struct tcp_pcb* pcb;
00459   struct pbuf *pinseq, *p_ovr;
00460   ip_addr_t remote_ip, local_ip;
00461   u16_t remote_port = 0x100, local_port = 0x101;
00462   struct netif netif;
00463   int datalen = 0;
00464   int datalen2;
00465 
00466   for(i = 0; i < sizeof(data_full_wnd); i++) {
00467     data_full_wnd[i] = (char)i;
00468   }
00469 
00470   /* initialize local vars */
00471   memset(&netif, 0, sizeof(netif));
00472   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00473   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00474   /* initialize counter struct */
00475   memset(&counters, 0, sizeof(counters));
00476   counters.expected_data_len = TCP_WND;
00477   counters.expected_data = data_full_wnd;
00478 
00479   /* create and initialize the pcb */
00480   pcb = test_tcp_new_counters_pcb(&counters);
00481   EXPECT_RET(pcb != NULL);
00482   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00483   pcb->rcv_nxt = 0x8000;
00484 
00485   /* create segments */
00486   /* pinseq is sent as last segment! */
00487   pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0],  TCP_MSS, 0, 0, TCP_ACK);
00488 
00489   for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) {
00490     int count, expected_datalen;
00491     struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)],
00492                                            TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
00493     EXPECT_RET(p != NULL);
00494     /* pass the segment to tcp_input */
00495     test_tcp_input(p, &netif);
00496     /* check if counters are as expected */
00497     EXPECT(counters.close_calls == 0);
00498     EXPECT(counters.recv_calls == 0);
00499     EXPECT(counters.recved_bytes == 0);
00500     EXPECT(counters.err_calls == 0);
00501     /* check ooseq queue */
00502     count = tcp_oos_count(pcb);
00503     EXPECT_OOSEQ(count == k+1);
00504     datalen = tcp_oos_tcplen(pcb);
00505     if (i + TCP_MSS < TCP_WND) {
00506       expected_datalen = (k+1)*TCP_MSS;
00507     } else {
00508       expected_datalen = TCP_WND - TCP_MSS;
00509     }
00510     if (datalen != expected_datalen) {
00511       EXPECT_OOSEQ(datalen == expected_datalen);
00512     }
00513   }
00514 
00515   /* pass in one more segment, cleary overrunning the rxwin */
00516   p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
00517   EXPECT_RET(p_ovr != NULL);
00518   /* pass the segment to tcp_input */
00519   test_tcp_input(p_ovr, &netif);
00520   /* check if counters are as expected */
00521   EXPECT(counters.close_calls == 0);
00522   EXPECT(counters.recv_calls == 0);
00523   EXPECT(counters.recved_bytes == 0);
00524   EXPECT(counters.err_calls == 0);
00525   /* check ooseq queue */
00526   EXPECT_OOSEQ(tcp_oos_count(pcb) == k);
00527   datalen2 = tcp_oos_tcplen(pcb);
00528   EXPECT_OOSEQ(datalen == datalen2);
00529 
00530   /* now pass inseq */
00531   test_tcp_input(pinseq, &netif);
00532   EXPECT(pcb->ooseq == NULL);
00533 
00534   /* make sure the pcb is freed */
00535   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00536   tcp_abort(pcb);
00537   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00538 #endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */
00539   LWIP_UNUSED_ARG(_i);
00540 }
00541 END_TEST
00542 
00543 START_TEST(test_tcp_recv_ooseq_max_bytes)
00544 {
00545 #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))
00546   int i, k;
00547   struct test_tcp_counters counters;
00548   struct tcp_pcb* pcb;
00549   struct pbuf *p_ovr;
00550   ip_addr_t remote_ip, local_ip;
00551   u16_t remote_port = 0x100, local_port = 0x101;
00552   struct netif netif;
00553   int datalen = 0;
00554   int datalen2;
00555 
00556   for(i = 0; i < sizeof(data_full_wnd); i++) {
00557     data_full_wnd[i] = (char)i;
00558   }
00559 
00560   /* initialize local vars */
00561   memset(&netif, 0, sizeof(netif));
00562   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00563   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00564   /* initialize counter struct */
00565   memset(&counters, 0, sizeof(counters));
00566   counters.expected_data_len = TCP_WND;
00567   counters.expected_data = data_full_wnd;
00568 
00569   /* create and initialize the pcb */
00570   pcb = test_tcp_new_counters_pcb(&counters);
00571   EXPECT_RET(pcb != NULL);
00572   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00573   pcb->rcv_nxt = 0x8000;
00574 
00575   /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
00576 
00577   /* create segments and 'recv' them */
00578   for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) {
00579     int count;
00580     struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k],
00581                                            TCP_MSS, k, 0, TCP_ACK);
00582     EXPECT_RET(p != NULL);
00583     EXPECT_RET(p->next == NULL);
00584     /* pass the segment to tcp_input */
00585     test_tcp_input(p, &netif);
00586     /* check if counters are as expected */
00587     EXPECT(counters.close_calls == 0);
00588     EXPECT(counters.recv_calls == 0);
00589     EXPECT(counters.recved_bytes == 0);
00590     EXPECT(counters.err_calls == 0);
00591     /* check ooseq queue */
00592     count = tcp_oos_pbuf_count(pcb);
00593     EXPECT_OOSEQ(count == i);
00594     datalen = tcp_oos_tcplen(pcb);
00595     EXPECT_OOSEQ(datalen == (i * TCP_MSS));
00596   }
00597 
00598   /* pass in one more segment, overrunning the limit */
00599   p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK);
00600   EXPECT_RET(p_ovr != NULL);
00601   /* pass the segment to tcp_input */
00602   test_tcp_input(p_ovr, &netif);
00603   /* check if counters are as expected */
00604   EXPECT(counters.close_calls == 0);
00605   EXPECT(counters.recv_calls == 0);
00606   EXPECT(counters.recved_bytes == 0);
00607   EXPECT(counters.err_calls == 0);
00608   /* check ooseq queue (ensure the new segment was not accepted) */
00609   EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
00610   datalen2 = tcp_oos_tcplen(pcb);
00611   EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS));
00612 
00613   /* make sure the pcb is freed */
00614   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00615   tcp_abort(pcb);
00616   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00617 #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)) */
00618   LWIP_UNUSED_ARG(_i);
00619 }
00620 END_TEST
00621 
00622 START_TEST(test_tcp_recv_ooseq_max_pbufs)
00623 {
00624 #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))
00625   int i;
00626   struct test_tcp_counters counters;
00627   struct tcp_pcb* pcb;
00628   struct pbuf *p_ovr;
00629   ip_addr_t remote_ip, local_ip;
00630   u16_t remote_port = 0x100, local_port = 0x101;
00631   struct netif netif;
00632   int datalen = 0;
00633   int datalen2;
00634 
00635   for(i = 0; i < sizeof(data_full_wnd); i++) {
00636     data_full_wnd[i] = (char)i;
00637   }
00638 
00639   /* initialize local vars */
00640   memset(&netif, 0, sizeof(netif));
00641   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00642   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00643   /* initialize counter struct */
00644   memset(&counters, 0, sizeof(counters));
00645   counters.expected_data_len = TCP_WND;
00646   counters.expected_data = data_full_wnd;
00647 
00648   /* create and initialize the pcb */
00649   pcb = test_tcp_new_counters_pcb(&counters);
00650   EXPECT_RET(pcb != NULL);
00651   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00652   pcb->rcv_nxt = 0x8000;
00653 
00654   /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */
00655 
00656   /* create segments and 'recv' them */
00657   for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) {
00658     int count;
00659     struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i],
00660                                            1, i, 0, TCP_ACK);
00661     EXPECT_RET(p != NULL);
00662     EXPECT_RET(p->next == NULL);
00663     /* pass the segment to tcp_input */
00664     test_tcp_input(p, &netif);
00665     /* check if counters are as expected */
00666     EXPECT(counters.close_calls == 0);
00667     EXPECT(counters.recv_calls == 0);
00668     EXPECT(counters.recved_bytes == 0);
00669     EXPECT(counters.err_calls == 0);
00670     /* check ooseq queue */
00671     count = tcp_oos_pbuf_count(pcb);
00672     EXPECT_OOSEQ(count == i);
00673     datalen = tcp_oos_tcplen(pcb);
00674     EXPECT_OOSEQ(datalen == i);
00675   }
00676 
00677   /* pass in one more segment, overrunning the limit */
00678   p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK);
00679   EXPECT_RET(p_ovr != NULL);
00680   /* pass the segment to tcp_input */
00681   test_tcp_input(p_ovr, &netif);
00682   /* check if counters are as expected */
00683   EXPECT(counters.close_calls == 0);
00684   EXPECT(counters.recv_calls == 0);
00685   EXPECT(counters.recved_bytes == 0);
00686   EXPECT(counters.err_calls == 0);
00687   /* check ooseq queue (ensure the new segment was not accepted) */
00688   EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1));
00689   datalen2 = tcp_oos_tcplen(pcb);
00690   EXPECT_OOSEQ(datalen2 == (i-1));
00691 
00692   /* make sure the pcb is freed */
00693   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00694   tcp_abort(pcb);
00695   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00696 #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)) */
00697   LWIP_UNUSED_ARG(_i);
00698 }
00699 END_TEST
00700 
00701 static void
00702 check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls,
00703                   u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len)
00704 {
00705   int oos_len;
00706   EXPECT(counters->close_calls == exp_close_calls);
00707   EXPECT(counters->recv_calls == exp_rx_calls);
00708   EXPECT(counters->recved_bytes == exp_rx_bytes);
00709   EXPECT(counters->err_calls == exp_err_calls);
00710   /* check that pbuf is queued in ooseq */
00711   EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count);
00712   oos_len = tcp_oos_tcplen(pcb);
00713   EXPECT_OOSEQ(exp_oos_len == oos_len);
00714 }
00715 
00716 /* this test uses 4 packets:
00717  * - data (len=TCP_MSS)
00718  * - FIN
00719  * - data after FIN (len=1) (invalid)
00720  * - 2nd FIN (invalid)
00721  *
00722  * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq
00723  */
00724 static void test_tcp_recv_ooseq_double_FINs(int delay_packet)
00725 {
00726   int i, k;
00727   struct test_tcp_counters counters;
00728   struct tcp_pcb* pcb;
00729   struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq;
00730   ip_addr_t remote_ip, local_ip;
00731   u16_t remote_port = 0x100, local_port = 0x101;
00732   struct netif netif;
00733   u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0;
00734   int first_dropped = 0xff;
00735   int last_dropped = 0;
00736 
00737   for(i = 0; i < sizeof(data_full_wnd); i++) {
00738     data_full_wnd[i] = (char)i;
00739   }
00740 
00741   /* initialize local vars */
00742   memset(&netif, 0, sizeof(netif));
00743   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00744   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00745   /* initialize counter struct */
00746   memset(&counters, 0, sizeof(counters));
00747   counters.expected_data_len = TCP_WND;
00748   counters.expected_data = data_full_wnd;
00749 
00750   /* create and initialize the pcb */
00751   pcb = test_tcp_new_counters_pcb(&counters);
00752   EXPECT_RET(pcb != NULL);
00753   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00754   pcb->rcv_nxt = 0x8000;
00755 
00756   /* create segments */
00757   p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK);
00758   p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN);
00759   k = 1;
00760   p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK);
00761   p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN);
00762 
00763   if(delay_packet & 1) {
00764     /* drop normal data */
00765     first_dropped = 1;
00766     last_dropped = 1;
00767   } else {
00768     /* send normal data */
00769     test_tcp_input(p, &netif);
00770     exp_rx_calls++;
00771     exp_rx_bytes += TCP_MSS;
00772   }
00773   /* check if counters are as expected */
00774   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00775 
00776   if(delay_packet & 2) {
00777     /* drop FIN */
00778     if(first_dropped > 2) {
00779       first_dropped = 2;
00780     }
00781     last_dropped = 2;
00782   } else {
00783     /* send FIN */
00784     test_tcp_input(p_normal_fin, &netif);
00785     if (first_dropped < 2) {
00786       /* already dropped packets, this one is ooseq */
00787       exp_oos_pbufs++;
00788       exp_oos_tcplen++;
00789     } else {
00790       /* inseq */
00791       exp_close_calls++;
00792     }
00793   }
00794   /* check if counters are as expected */
00795   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00796 
00797   if(delay_packet & 4) {
00798     /* drop data-after-FIN */
00799     if(first_dropped > 3) {
00800       first_dropped = 3;
00801     }
00802     last_dropped = 3;
00803   } else {
00804     /* send data-after-FIN */
00805     test_tcp_input(p_data_after_fin, &netif);
00806     if (first_dropped < 3) {
00807       /* already dropped packets, this one is ooseq */
00808       if (delay_packet & 2) {
00809         /* correct FIN was ooseq */
00810         exp_oos_pbufs++;
00811         exp_oos_tcplen += k;
00812       }
00813     } else {
00814       /* inseq: no change */
00815     }
00816   }
00817   /* check if counters are as expected */
00818   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00819 
00820   if(delay_packet & 8) {
00821     /* drop 2nd-FIN */
00822     if(first_dropped > 4) {
00823       first_dropped = 4;
00824     }
00825     last_dropped = 4;
00826   } else {
00827     /* send 2nd-FIN */
00828     test_tcp_input(p_2nd_fin_ooseq, &netif);
00829     if (first_dropped < 3) {
00830       /* already dropped packets, this one is ooseq */
00831       if (delay_packet & 2) {
00832         /* correct FIN was ooseq */
00833         exp_oos_pbufs++;
00834         exp_oos_tcplen++;
00835       }
00836     } else {
00837       /* inseq: no change */
00838     }
00839   }
00840   /* check if counters are as expected */
00841   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00842 
00843   if(delay_packet & 1) {
00844     /* dropped normal data before */
00845     test_tcp_input(p, &netif);
00846     exp_rx_calls++;
00847     exp_rx_bytes += TCP_MSS;
00848     if((delay_packet & 2) == 0) {
00849       /* normal FIN was NOT delayed */
00850       exp_close_calls++;
00851       exp_oos_pbufs = exp_oos_tcplen = 0;
00852     }
00853   }
00854   /* check if counters are as expected */
00855   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00856 
00857   if(delay_packet & 2) {
00858     /* dropped normal FIN before */
00859     test_tcp_input(p_normal_fin, &netif);
00860     exp_close_calls++;
00861     exp_oos_pbufs = exp_oos_tcplen = 0;
00862   }
00863   /* check if counters are as expected */
00864   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00865 
00866   if(delay_packet & 4) {
00867     /* dropped data-after-FIN before */
00868     test_tcp_input(p_data_after_fin, &netif);
00869   }
00870   /* check if counters are as expected */
00871   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00872 
00873   if(delay_packet & 8) {
00874     /* dropped 2nd-FIN before */
00875     test_tcp_input(p_2nd_fin_ooseq, &netif);
00876   }
00877   /* check if counters are as expected */
00878   check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen);
00879 
00880   /* check that ooseq data has been dumped */
00881   EXPECT(pcb->ooseq == NULL);
00882 
00883   /* make sure the pcb is freed */
00884   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00885   tcp_abort(pcb);
00886   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00887 }
00888 
00889 /** create multiple segments and pass them to tcp_input with the first segment missing
00890  * to simulate overruning the rxwin with ooseq queueing enabled */
00891 #define FIN_TEST(name, num) \
00892   START_TEST(name) \
00893   { \
00894     LWIP_UNUSED_ARG(_i); \
00895     test_tcp_recv_ooseq_double_FINs(num); \
00896   } \
00897   END_TEST
00898 FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0)
00899 FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1)
00900 FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2)
00901 FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3)
00902 FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4)
00903 FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5)
00904 FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6)
00905 FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7)
00906 FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8)
00907 FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9)
00908 FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10)
00909 FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11)
00910 FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12)
00911 FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13)
00912 FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14)
00913 FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15)
00914 
00915 
00916 /** Create the suite including all tests for this module */
00917 Suite *
00918 tcp_oos_suite(void)
00919 {
00920   TFun tests[] = {
00921     test_tcp_recv_ooseq_FIN_OOSEQ,
00922     test_tcp_recv_ooseq_FIN_INSEQ,
00923     test_tcp_recv_ooseq_overrun_rxwin,
00924     test_tcp_recv_ooseq_max_bytes,
00925     test_tcp_recv_ooseq_max_pbufs,
00926     test_tcp_recv_ooseq_double_FIN_0,
00927     test_tcp_recv_ooseq_double_FIN_1,
00928     test_tcp_recv_ooseq_double_FIN_2,
00929     test_tcp_recv_ooseq_double_FIN_3,
00930     test_tcp_recv_ooseq_double_FIN_4,
00931     test_tcp_recv_ooseq_double_FIN_5,
00932     test_tcp_recv_ooseq_double_FIN_6,
00933     test_tcp_recv_ooseq_double_FIN_7,
00934     test_tcp_recv_ooseq_double_FIN_8,
00935     test_tcp_recv_ooseq_double_FIN_9,
00936     test_tcp_recv_ooseq_double_FIN_10,
00937     test_tcp_recv_ooseq_double_FIN_11,
00938     test_tcp_recv_ooseq_double_FIN_12,
00939     test_tcp_recv_ooseq_double_FIN_13,
00940     test_tcp_recv_ooseq_double_FIN_14,
00941     test_tcp_recv_ooseq_double_FIN_15
00942   };
00943   return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
00944 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines