SAMV71 Xplained Ultra Software Package 1.0

test_tcp_oos.c

00001 #include "test_tcp_oos.h"
00002 
00003 #include "lwip/tcp.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 seqno of a segment (by index) on the ooseq list
00040  *
00041  * @param pcb the pcb to check for ooseq segments
00042  * @param seg_index index of the segment on the ooseq list
00043  * @return seqno of the segment
00044  */
00045 static u32_t
00046 tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index)
00047 {
00048   int num = 0;
00049   struct tcp_seg* seg = pcb->ooseq;
00050 
00051   /* then check the actual segment */
00052   while(seg != NULL) {
00053     if(num == seg_index) {
00054       return seg->tcphdr->seqno;
00055     }
00056     num++;
00057     seg = seg->next;
00058   }
00059   fail();
00060   return 0;
00061 }
00062 
00063 /** Get the tcplen of a segment (by index) on the ooseq list
00064  *
00065  * @param pcb the pcb to check for ooseq segments
00066  * @param seg_index index of the segment on the ooseq list
00067  * @return tcplen of the segment
00068  */
00069 static int
00070 tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index)
00071 {
00072   int num = 0;
00073   struct tcp_seg* seg = pcb->ooseq;
00074 
00075   /* then check the actual segment */
00076   while(seg != NULL) {
00077     if(num == seg_index) {
00078       return TCP_TCPLEN(seg);
00079     }
00080     num++;
00081     seg = seg->next;
00082   }
00083   fail();
00084   return -1;
00085 }
00086 
00087 /* Setup/teardown functions */
00088 
00089 static void
00090 tcp_oos_setup(void)
00091 {
00092   tcp_remove_all();
00093 }
00094 
00095 static void
00096 tcp_oos_teardown(void)
00097 {
00098   tcp_remove_all();
00099 }
00100 
00101 
00102 
00103 /* Test functions */
00104 
00105 /** create multiple segments and pass them to tcp_input in a wrong
00106  * order to see if ooseq-caching works correctly
00107  * FIN is received in out-of-sequence segments only */
00108 START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
00109 {
00110   struct test_tcp_counters counters;
00111   struct tcp_pcb* pcb;
00112   struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq;
00113   char data[] = {
00114      1,  2,  3,  4,
00115      5,  6,  7,  8,
00116      9, 10, 11, 12,
00117     13, 14, 15, 16};
00118   struct ip_addr remote_ip, local_ip;
00119   u16_t data_len;
00120   u16_t remote_port = 0x100, local_port = 0x101;
00121   struct netif netif;
00122   LWIP_UNUSED_ARG(_i);
00123 
00124   /* initialize local vars */
00125   memset(&netif, 0, sizeof(netif));
00126   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00127   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00128   data_len = sizeof(data);
00129   /* initialize counter struct */
00130   memset(&counters, 0, sizeof(counters));
00131   counters.expected_data_len = data_len;
00132   counters.expected_data = data;
00133 
00134   /* create and initialize the pcb */
00135   pcb = test_tcp_new_counters_pcb(&counters);
00136   EXPECT_RET(pcb != NULL);
00137   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00138 
00139   /* create segments */
00140   /* pinseq is sent as last segment! */
00141   pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
00142   /* p1: 8 bytes before FIN */
00143   /*     seqno: 8..16 */
00144   p_8_9  = tcp_create_rx_segment(pcb, &data[8],  8, 8, 0, TCP_ACK|TCP_FIN);
00145   /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
00146   /*     seqno: 4..11 */
00147   p_4_8  = tcp_create_rx_segment(pcb, &data[4],  8, 4, 0, TCP_ACK);
00148   /* p3: same as p2 but 2 bytes longer */
00149   /*     seqno: 4..13 */
00150   p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK);
00151   /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */
00152   /*     seqno: 2..15 */
00153   p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK);
00154   /* FIN, seqno 16 */
00155   p_fin  = tcp_create_rx_segment(pcb,     NULL,  0,16, 0, TCP_ACK|TCP_FIN);
00156   EXPECT(pinseq != NULL);
00157   EXPECT(p_8_9 != NULL);
00158   EXPECT(p_4_8 != NULL);
00159   EXPECT(p_4_10 != NULL);
00160   EXPECT(p_2_14 != NULL);
00161   EXPECT(p_fin != NULL);
00162   if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
00163     /* pass the segment to tcp_input */
00164     tcp_input(p_8_9, &netif);
00165     /* check if counters are as expected */
00166     EXPECT(counters.close_calls == 0);
00167     EXPECT(counters.recv_calls == 0);
00168     EXPECT(counters.recved_bytes == 0);
00169     EXPECT(counters.err_calls == 0);
00170     /* check ooseq queue */
00171     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00172     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8);
00173     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
00174 
00175     /* pass the segment to tcp_input */
00176     tcp_input(p_4_8, &netif);
00177     /* check if counters are as expected */
00178     EXPECT(counters.close_calls == 0);
00179     EXPECT(counters.recv_calls == 0);
00180     EXPECT(counters.recved_bytes == 0);
00181     EXPECT(counters.err_calls == 0);
00182     /* check ooseq queue */
00183     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00184     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
00185     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
00186     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
00187     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
00188 
00189     /* pass the segment to tcp_input */
00190     tcp_input(p_4_10, &netif);
00191     /* check if counters are as expected */
00192     EXPECT(counters.close_calls == 0);
00193     EXPECT(counters.recv_calls == 0);
00194     EXPECT(counters.recved_bytes == 0);
00195     EXPECT(counters.err_calls == 0);
00196     /* ooseq queue: unchanged */
00197     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00198     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4);
00199     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4);
00200     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
00201     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
00202 
00203     /* pass the segment to tcp_input */
00204     tcp_input(p_2_14, &netif);
00205     /* check if counters are as expected */
00206     EXPECT(counters.close_calls == 0);
00207     EXPECT(counters.recv_calls == 0);
00208     EXPECT(counters.recved_bytes == 0);
00209     EXPECT(counters.err_calls == 0);
00210     /* check ooseq queue */
00211     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00212     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
00213     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
00214     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
00215     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
00216 
00217     /* pass the segment to tcp_input */
00218     tcp_input(p_fin, &netif);
00219     /* check if counters are as expected */
00220     EXPECT(counters.close_calls == 0);
00221     EXPECT(counters.recv_calls == 0);
00222     EXPECT(counters.recved_bytes == 0);
00223     EXPECT(counters.err_calls == 0);
00224     /* ooseq queue: unchanged */
00225     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00226     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2);
00227     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 6);
00228     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8);
00229     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
00230 
00231     /* pass the segment to tcp_input */
00232     tcp_input(pinseq, &netif);
00233     /* check if counters are as expected */
00234     EXPECT(counters.close_calls == 1);
00235     EXPECT(counters.recv_calls == 1);
00236     EXPECT(counters.recved_bytes == data_len);
00237     EXPECT(counters.err_calls == 0);
00238     EXPECT(pcb->ooseq == NULL);
00239   }
00240 
00241   /* make sure the pcb is freed */
00242   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00243   tcp_abort(pcb);
00244   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00245 }
00246 END_TEST
00247 
00248 
00249 /** create multiple segments and pass them to tcp_input in a wrong
00250  * order to see if ooseq-caching works correctly
00251  * FIN is received IN-SEQUENCE at the end */
00252 START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
00253 {
00254   struct test_tcp_counters counters;
00255   struct tcp_pcb* pcb;
00256   struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN;
00257   char data[] = {
00258      1,  2,  3,  4,
00259      5,  6,  7,  8,
00260      9, 10, 11, 12,
00261     13, 14, 15, 16};
00262   struct ip_addr remote_ip, local_ip;
00263   u16_t data_len;
00264   u16_t remote_port = 0x100, local_port = 0x101;
00265   struct netif netif;
00266   LWIP_UNUSED_ARG(_i);
00267 
00268   /* initialize local vars */
00269   memset(&netif, 0, sizeof(netif));
00270   IP4_ADDR(&local_ip, 192, 168, 1, 1);
00271   IP4_ADDR(&remote_ip, 192, 168, 1, 2);
00272   data_len = sizeof(data);
00273   /* initialize counter struct */
00274   memset(&counters, 0, sizeof(counters));
00275   counters.expected_data_len = data_len;
00276   counters.expected_data = data;
00277 
00278   /* create and initialize the pcb */
00279   pcb = test_tcp_new_counters_pcb(&counters);
00280   EXPECT_RET(pcb != NULL);
00281   tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port);
00282 
00283   /* create segments */
00284   /* p1: 7 bytes - 2 before FIN */
00285   /*     seqno: 1..2 */
00286   p_1_2  = tcp_create_rx_segment(pcb, &data[1],  2, 1, 0, TCP_ACK);
00287   /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */
00288   /*     seqno: 4..11 */
00289   p_4_8  = tcp_create_rx_segment(pcb, &data[4],  8, 4, 0, TCP_ACK);
00290   /* p3: same as p2 but 2 bytes longer and one byte more at the front */
00291   /*     seqno: 3..13 */
00292   p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK);
00293   /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */
00294   /*     seqno: 2..13 */
00295   p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK);
00296   /* pinseq is the first segment that is held back to create ooseq! */
00297   /*     seqno: 0..3 */
00298   pinseq = tcp_create_rx_segment(pcb, &data[0],  4, 0, 0, TCP_ACK);
00299   /* p5: last byte before FIN */
00300   /*     seqno: 15 */
00301   p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
00302   /* p6: same as p5, should be ignored */
00303   p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK);
00304   /* pinseqFIN: last 2 bytes plus FIN */
00305   /*     only segment containing seqno 14 and FIN */
00306   pinseqFIN = tcp_create_rx_segment(pcb,  &data[14], 2, 14, 0, TCP_ACK|TCP_FIN);
00307   EXPECT(pinseq != NULL);
00308   EXPECT(p_1_2 != NULL);
00309   EXPECT(p_4_8 != NULL);
00310   EXPECT(p_3_11 != NULL);
00311   EXPECT(p_2_12 != NULL);
00312   EXPECT(p_15_1 != NULL);
00313   EXPECT(p_15_1a != NULL);
00314   EXPECT(pinseqFIN != NULL);
00315   if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
00316     && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
00317     /* pass the segment to tcp_input */
00318     tcp_input(p_1_2, &netif);
00319     /* check if counters are as expected */
00320     EXPECT(counters.close_calls == 0);
00321     EXPECT(counters.recv_calls == 0);
00322     EXPECT(counters.recved_bytes == 0);
00323     EXPECT(counters.err_calls == 0);
00324     /* check ooseq queue */
00325     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00326     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00327     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
00328 
00329     /* pass the segment to tcp_input */
00330     tcp_input(p_4_8, &netif);
00331     /* check if counters are as expected */
00332     EXPECT(counters.close_calls == 0);
00333     EXPECT(counters.recv_calls == 0);
00334     EXPECT(counters.recved_bytes == 0);
00335     EXPECT(counters.err_calls == 0);
00336     /* check ooseq queue */
00337     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00338     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00339     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
00340     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4);
00341     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
00342 
00343     /* pass the segment to tcp_input */
00344     tcp_input(p_3_11, &netif);
00345     /* check if counters are as expected */
00346     EXPECT(counters.close_calls == 0);
00347     EXPECT(counters.recv_calls == 0);
00348     EXPECT(counters.recved_bytes == 0);
00349     EXPECT(counters.err_calls == 0);
00350     /* check ooseq queue */
00351     EXPECT_OOSEQ(tcp_oos_count(pcb) == 2);
00352     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00353     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
00354     /* p_3_11 has removed p_4_8 from ooseq */
00355     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3);
00356     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
00357 
00358     /* pass the segment to tcp_input */
00359     tcp_input(p_2_12, &netif);
00360     /* check if counters are as expected */
00361     EXPECT(counters.close_calls == 0);
00362     EXPECT(counters.recv_calls == 0);
00363     EXPECT(counters.recved_bytes == 0);
00364     EXPECT(counters.err_calls == 0);
00365     /* check ooseq queue */
00366     EXPECT_OOSEQ(tcp_oos_count(pcb) == 3);
00367     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1);
00368     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
00369     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2);
00370     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 1);
00371     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 2) == 3);
00372     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 2) == 11);
00373 
00374     /* pass the segment to tcp_input */
00375     tcp_input(pinseq, &netif);
00376     /* check if counters are as expected */
00377     EXPECT(counters.close_calls == 0);
00378     EXPECT(counters.recv_calls == 1);
00379     EXPECT(counters.recved_bytes == 14);
00380     EXPECT(counters.err_calls == 0);
00381     EXPECT(pcb->ooseq == NULL);
00382 
00383     /* pass the segment to tcp_input */
00384     tcp_input(p_15_1, &netif);
00385     /* check if counters are as expected */
00386     EXPECT(counters.close_calls == 0);
00387     EXPECT(counters.recv_calls == 1);
00388     EXPECT(counters.recved_bytes == 14);
00389     EXPECT(counters.err_calls == 0);
00390     /* check ooseq queue */
00391     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00392     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
00393     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
00394 
00395     /* pass the segment to tcp_input */
00396     tcp_input(p_15_1a, &netif);
00397     /* check if counters are as expected */
00398     EXPECT(counters.close_calls == 0);
00399     EXPECT(counters.recv_calls == 1);
00400     EXPECT(counters.recved_bytes == 14);
00401     EXPECT(counters.err_calls == 0);
00402     /* check ooseq queue: unchanged */
00403     EXPECT_OOSEQ(tcp_oos_count(pcb) == 1);
00404     EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15);
00405     EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
00406 
00407     /* pass the segment to tcp_input */
00408     tcp_input(pinseqFIN, &netif);
00409     /* check if counters are as expected */
00410     EXPECT(counters.close_calls == 1);
00411     EXPECT(counters.recv_calls == 2);
00412     EXPECT(counters.recved_bytes == data_len);
00413     EXPECT(counters.err_calls == 0);
00414     EXPECT(pcb->ooseq == NULL);
00415   }
00416 
00417   /* make sure the pcb is freed */
00418   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1);
00419   tcp_abort(pcb);
00420   EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0);
00421 }
00422 END_TEST
00423 
00424 /** Create the suite including all tests for this module */
00425 Suite *
00426 tcp_oos_suite(void)
00427 {
00428   TFun tests[] = {
00429     test_tcp_recv_ooseq_FIN_OOSEQ,
00430     test_tcp_recv_ooseq_FIN_INSEQ,
00431   };
00432   return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown);
00433 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines