ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_tcp_oos.c Source File

test_tcp_oos.c

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