Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_tcp.c Source File

test_tcp.c

00001 #include "test_tcp.h"
00002 
00003 #include "lwip/priv/tcp_priv.h"
00004 #include "lwip/stats.h"
00005 #include "tcp_helper.h"
00006 #include "lwip/inet_chksum.h"
00007 
00008 #ifdef _MSC_VER
00009 #pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */
00010 #endif
00011 
00012 #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS
00013 #error "This tests needs TCP- and MEMP-statistics enabled"
00014 #endif
00015 #if TCP_SND_BUF <= TCP_WND
00016 #error "This tests needs TCP_SND_BUF to be > TCP_WND"
00017 #endif
00018 
00019 /* used with check_seqnos() */
00020 #define SEQNO1 (0xFFFFFF00 - TCP_MSS)
00021 #define ISS    6510
00022 static u32_t seqnos[] = {
00023     SEQNO1,
00024     SEQNO1 + (1 * TCP_MSS),
00025     SEQNO1 + (2 * TCP_MSS),
00026     SEQNO1 + (3 * TCP_MSS),
00027     SEQNO1 + (4 * TCP_MSS),
00028     SEQNO1 + (5 * TCP_MSS) };
00029 
00030 static u8_t test_tcp_timer;
00031 
00032 /* our own version of tcp_tmr so we can reset fast/slow timer state */
00033 static void
00034 test_tcp_tmr(void)
00035 {
00036   tcp_fasttmr();
00037   if (++test_tcp_timer & 1) {
00038     tcp_slowtmr();
00039   }
00040 }
00041 
00042 /* Setups/teardown functions */
00043 static struct netif *old_netif_list;
00044 static struct netif *old_netif_default;
00045 
00046 static void
00047 tcp_setup(void)
00048 {
00049   struct tcp_pcb dummy_pcb; /* we need this for tcp_next_iss() only */
00050 
00051   old_netif_list = netif_list;
00052   old_netif_default = netif_default;
00053   netif_list = NULL;
00054   netif_default = NULL;
00055   /* reset iss to default (6510) */
00056   tcp_ticks = 0;
00057   tcp_ticks = 0 - (tcp_next_iss(&dummy_pcb) - 6510);
00058   tcp_next_iss(&dummy_pcb);
00059   tcp_ticks = 0;
00060 
00061   test_tcp_timer = 0;
00062   tcp_remove_all();
00063   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
00064 }
00065 
00066 static void
00067 tcp_teardown(void)
00068 {
00069   netif_list = NULL;
00070   netif_default = NULL;
00071   tcp_remove_all();
00072   /* restore netif_list for next tests (e.g. loopif) */
00073   netif_list = old_netif_list;
00074   netif_default = old_netif_default;
00075   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
00076 }
00077 
00078 
00079 /* Test functions */
00080 
00081 /** Call tcp_new() and tcp_abort() and test memp stats */
00082 START_TEST(test_tcp_new_abort)
00083 {
00084   struct tcp_pcb* pcb;
00085   LWIP_UNUSED_ARG(_i);
00086 
00087   fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00088 
00089   pcb = tcp_new();
00090   fail_unless(pcb != NULL);
00091   if (pcb != NULL) {
00092     fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00093     tcp_abort(pcb);
00094     fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00095   }
00096 }
00097 END_TEST
00098 
00099 /** Call tcp_new() and tcp_abort() and test memp stats */
00100 START_TEST(test_tcp_listen_passive_open)
00101 {
00102   struct tcp_pcb *pcb, *pcbl;
00103   struct tcp_pcb_listen *lpcb;
00104   struct netif netif;
00105   struct test_tcp_txcounters txcounters;
00106   struct test_tcp_counters counters;
00107   struct pbuf *p;
00108   ip_addr_t src_addr;
00109   err_t err;
00110   LWIP_UNUSED_ARG(_i);
00111 
00112   fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00113 
00114   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00115   /* initialize counter struct */
00116   memset(&counters, 0, sizeof(counters));
00117 
00118   pcb = tcp_new();
00119   EXPECT_RET(pcb != NULL);
00120   err = tcp_bind(pcb, &netif.ip_addr, 1234);
00121   EXPECT(err == ERR_OK);
00122   pcbl = tcp_listen(pcb);
00123   EXPECT_RET(pcbl != NULL);
00124   EXPECT_RET(pcbl != pcb);
00125   lpcb = (struct tcp_pcb_listen *)pcbl;
00126 
00127   ip_addr_set_ip4_u32_val(src_addr, lwip_htonl(lwip_ntohl(ip_addr_get_ip4_u32(&lpcb->local_ip)) + 1));
00128 
00129   /* check correct syn packet */
00130   p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345,
00131     lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN);
00132   EXPECT(p != NULL);
00133   if (p != NULL) {
00134     /* pass the segment to tcp_input */
00135     test_tcp_input(p, &netif);
00136     /* check if counters are as expected */
00137     EXPECT(txcounters.num_tx_calls == 1);
00138   }
00139 
00140   /* check syn packet with short length */
00141   p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345,
00142     lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN);
00143   EXPECT(p != NULL);
00144   EXPECT(p->next == NULL);
00145   if ((p != NULL) && (p->next == NULL)) {
00146     p->len -= 2;
00147     p->tot_len -= 2;
00148     /* pass the segment to tcp_input */
00149     test_tcp_input(p, &netif);
00150     /* check if counters are as expected */
00151     EXPECT(txcounters.num_tx_calls == 1);
00152   }
00153 
00154   tcp_close(pcbl);
00155 }
00156 END_TEST
00157 
00158 /** Create an ESTABLISHED pcb and check if receive callback is called */
00159 START_TEST(test_tcp_recv_inseq)
00160 {
00161   struct test_tcp_counters counters;
00162   struct tcp_pcb* pcb;
00163   struct pbuf* p;
00164   char data[] = {1, 2, 3, 4};
00165   u16_t data_len;
00166   struct netif netif;
00167   struct test_tcp_txcounters txcounters;
00168   LWIP_UNUSED_ARG(_i);
00169 
00170   /* initialize local vars */
00171   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00172   data_len = sizeof(data);
00173   /* initialize counter struct */
00174   memset(&counters, 0, sizeof(counters));
00175   counters.expected_data_len = data_len;
00176   counters.expected_data = data;
00177 
00178   /* create and initialize the pcb */
00179   pcb = test_tcp_new_counters_pcb(&counters);
00180   EXPECT_RET(pcb != NULL);
00181   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00182 
00183   /* create a segment */
00184   p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
00185   EXPECT(p != NULL);
00186   if (p != NULL) {
00187     /* pass the segment to tcp_input */
00188     test_tcp_input(p, &netif);
00189     /* check if counters are as expected */
00190     EXPECT(counters.close_calls == 0);
00191     EXPECT(counters.recv_calls == 1);
00192     EXPECT(counters.recved_bytes == data_len);
00193     EXPECT(counters.err_calls == 0);
00194   }
00195 
00196   /* make sure the pcb is freed */
00197   EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00198   tcp_abort(pcb);
00199   EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00200 }
00201 END_TEST
00202 
00203 /** Create an ESTABLISHED pcb and check if receive callback is called if a segment
00204  * overlapping rcv_nxt is received */
00205 START_TEST(test_tcp_recv_inseq_trim)
00206 {
00207   struct test_tcp_counters counters;
00208   struct tcp_pcb* pcb;
00209   struct pbuf* p;
00210   char data[PBUF_POOL_BUFSIZE*2];
00211   u16_t data_len;
00212   struct netif netif;
00213   struct test_tcp_txcounters txcounters;
00214   const u32_t new_data_len = 40;
00215   LWIP_UNUSED_ARG(_i);
00216 
00217   /* initialize local vars */
00218   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00219   data_len = sizeof(data);
00220   memset(data, 0, sizeof(data));
00221   /* initialize counter struct */
00222   memset(&counters, 0, sizeof(counters));
00223   counters.expected_data_len = data_len;
00224   counters.expected_data = data;
00225 
00226   /* create and initialize the pcb */
00227   pcb = test_tcp_new_counters_pcb(&counters);
00228   EXPECT_RET(pcb != NULL);
00229   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00230 
00231   /* create a segment (with an overlapping/old seqno so that the new data begins in the 2nd pbuf) */
00232   p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, (u32_t)(0-(data_len-new_data_len)), 0, 0);
00233   EXPECT(p != NULL);
00234   if (p != NULL) {
00235     EXPECT(p->next != NULL);
00236     if (p->next != NULL) {
00237       EXPECT(p->next->next != NULL);
00238     }
00239   }
00240   if ((p != NULL) && (p->next != NULL) && (p->next->next != NULL)) {
00241     /* pass the segment to tcp_input */
00242     test_tcp_input(p, &netif);
00243     /* check if counters are as expected */
00244     EXPECT(counters.close_calls == 0);
00245     EXPECT(counters.recv_calls == 1);
00246     EXPECT(counters.recved_bytes == new_data_len);
00247     EXPECT(counters.err_calls == 0);
00248   }
00249 
00250   /* make sure the pcb is freed */
00251   EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00252   tcp_abort(pcb);
00253   EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00254 }
00255 END_TEST
00256 
00257 static err_t test_tcp_recv_expect1byte(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err);
00258 
00259 static err_t
00260 test_tcp_recv_expectclose(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
00261 {
00262   EXPECT_RETX(pcb != NULL, ERR_OK);
00263   EXPECT_RETX(err == ERR_OK, ERR_OK);
00264   LWIP_UNUSED_ARG(arg);
00265 
00266   if (p != NULL) {
00267     fail();
00268   } else {
00269     /* correct: FIN received; close our end, too */
00270     err_t err2 = tcp_close(pcb);
00271     fail_unless(err2 == ERR_OK);
00272     /* set back to some other rx function, just to not get here again */
00273     tcp_recv(pcb, test_tcp_recv_expect1byte);
00274   }
00275   return ERR_OK;
00276 }
00277 
00278 static err_t
00279 test_tcp_recv_expect1byte(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err)
00280 {
00281   EXPECT_RETX(pcb != NULL, ERR_OK);
00282   EXPECT_RETX(err == ERR_OK, ERR_OK);
00283   LWIP_UNUSED_ARG(arg);
00284 
00285   if (p != NULL) {
00286     if ((p->len == 1) && (p->tot_len == 1)) {
00287       tcp_recv(pcb, test_tcp_recv_expectclose);
00288     } else {
00289       fail();
00290     }
00291     pbuf_free(p);
00292   } else {
00293     fail();
00294   }
00295   return ERR_OK;
00296 }
00297 
00298 START_TEST(test_tcp_passive_close)
00299 {
00300   struct test_tcp_counters counters;
00301   struct tcp_pcb* pcb;
00302   struct pbuf* p;
00303   char data = 0x0f;
00304   struct netif netif;
00305   struct test_tcp_txcounters txcounters;
00306   LWIP_UNUSED_ARG(_i);
00307 
00308   /* initialize local vars */
00309   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00310 
00311   /* initialize counter struct */
00312   memset(&counters, 0, sizeof(counters));
00313   counters.expected_data_len = 1;
00314   counters.expected_data = &data;
00315 
00316   /* create and initialize the pcb */
00317   pcb = test_tcp_new_counters_pcb(&counters);
00318   EXPECT_RET(pcb != NULL);
00319   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00320 
00321   /* create a segment without data */
00322   p = tcp_create_rx_segment(pcb, &data, 1, 0, 0, TCP_FIN);
00323   EXPECT(p != NULL);
00324   if (p != NULL) {
00325     tcp_recv(pcb, test_tcp_recv_expect1byte);
00326     /* pass the segment to tcp_input */
00327     test_tcp_input(p, &netif);
00328   }
00329   /* don't free the pcb here (part of the test!) */
00330 }
00331 END_TEST
00332 
00333 START_TEST(test_tcp_active_abort)
00334 {
00335   struct test_tcp_counters counters;
00336   struct tcp_pcb* pcb;
00337   char data = 0x0f;
00338   struct netif netif;
00339   struct test_tcp_txcounters txcounters;
00340   LWIP_UNUSED_ARG(_i);
00341 
00342   memset(&txcounters, 0, sizeof(txcounters));
00343 
00344   /* initialize local vars */
00345   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00346 
00347   /* initialize counter struct */
00348   memset(&counters, 0, sizeof(counters));
00349   counters.expected_data_len = 1;
00350   counters.expected_data = &data;
00351 
00352   /* create and initialize the pcb */
00353   pcb = test_tcp_new_counters_pcb(&counters);
00354   EXPECT_RET(pcb != NULL);
00355   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00356 
00357   /* abort the pcb */
00358   EXPECT_RET(txcounters.num_tx_calls == 0);
00359   txcounters.copy_tx_packets = 1;
00360   tcp_abort(pcb);
00361   txcounters.copy_tx_packets = 0;
00362   EXPECT(txcounters.num_tx_calls == 1);
00363   EXPECT(txcounters.num_tx_bytes == 40U);
00364   EXPECT(txcounters.tx_packets != NULL);
00365   if (txcounters.tx_packets != NULL) {
00366     u16_t ret;
00367     struct tcp_hdr tcphdr;
00368     ret = pbuf_copy_partial(txcounters.tx_packets, &tcphdr, 20, 20);
00369     EXPECT(ret == 20);
00370     EXPECT(tcphdr.dest == PP_HTONS(TEST_REMOTE_PORT));
00371     EXPECT(tcphdr.src == PP_HTONS(TEST_LOCAL_PORT));
00372     pbuf_free(txcounters.tx_packets);
00373     txcounters.tx_packets = NULL;
00374   }
00375 
00376   /* don't free the pcb here (part of the test!) */
00377 }
00378 END_TEST
00379 
00380 /** Check that we handle malformed tcp headers, and discard the pbuf(s) */
00381 START_TEST(test_tcp_malformed_header)
00382 {
00383   struct test_tcp_counters counters;
00384   struct tcp_pcb* pcb;
00385   struct pbuf* p;
00386   char data[] = {1, 2, 3, 4};
00387   u16_t data_len, chksum;
00388   struct netif netif;
00389   struct test_tcp_txcounters txcounters;
00390   struct tcp_hdr *hdr;
00391   LWIP_UNUSED_ARG(_i);
00392 
00393   /* initialize local vars */
00394   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00395   data_len = sizeof(data);
00396   /* initialize counter struct */
00397   memset(&counters, 0, sizeof(counters));
00398   counters.expected_data_len = data_len;
00399   counters.expected_data = data;
00400 
00401   /* create and initialize the pcb */
00402   pcb = test_tcp_new_counters_pcb(&counters);
00403   EXPECT_RET(pcb != NULL);
00404   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00405 
00406   /* create a segment */
00407   p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
00408 
00409   pbuf_header(p, -(s16_t)sizeof(struct ip_hdr));
00410 
00411   hdr = (struct tcp_hdr *)p->payload;
00412   TCPH_HDRLEN_FLAGS_SET(hdr, 15, 0x3d1);
00413 
00414   hdr->chksum = 0;
00415 
00416   chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
00417                              &test_remote_ip, &test_local_ip);
00418 
00419   hdr->chksum = chksum;
00420 
00421   pbuf_header(p, sizeof(struct ip_hdr));
00422 
00423   EXPECT(p != NULL);
00424   EXPECT(p->next == NULL);
00425   if (p != NULL) {
00426     /* pass the segment to tcp_input */
00427     test_tcp_input(p, &netif);
00428     /* check if counters are as expected */
00429     EXPECT(counters.close_calls == 0);
00430     EXPECT(counters.recv_calls == 0);
00431     EXPECT(counters.recved_bytes == 0);
00432     EXPECT(counters.err_calls == 0);
00433   }
00434 
00435   /* make sure the pcb is freed */
00436   EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00437   tcp_abort(pcb);
00438   EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00439 }
00440 END_TEST
00441 
00442 
00443 /** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
00444  * At the end, send more data. */
00445 START_TEST(test_tcp_fast_retx_recover)
00446 {
00447   struct netif netif;
00448   struct test_tcp_txcounters txcounters;
00449   struct test_tcp_counters counters;
00450   struct tcp_pcb* pcb;
00451   struct pbuf* p;
00452   char data1[] = { 1,  2,  3,  4};
00453   char data2[] = { 5,  6,  7,  8};
00454   char data3[] = { 9, 10, 11, 12};
00455   char data4[] = {13, 14, 15, 16};
00456   char data5[] = {17, 18, 19, 20};
00457   char data6[TCP_MSS] = {21, 22, 23, 24};
00458   err_t err;
00459   LWIP_UNUSED_ARG(_i);
00460 
00461   /* initialize local vars */
00462   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00463   memset(&counters, 0, sizeof(counters));
00464 
00465   /* create and initialize the pcb */
00466   pcb = test_tcp_new_counters_pcb(&counters);
00467   EXPECT_RET(pcb != NULL);
00468   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00469   pcb->mss = TCP_MSS;
00470   /* disable initial congestion window (we don't send a SYN here...) */
00471   pcb->cwnd = pcb->snd_wnd;
00472 
00473   /* send data1 */
00474   err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY);
00475   EXPECT_RET(err == ERR_OK);
00476   err = tcp_output(pcb);
00477   EXPECT_RET(err == ERR_OK);
00478   EXPECT_RET(txcounters.num_tx_calls == 1);
00479   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
00480   memset(&txcounters, 0, sizeof(txcounters));
00481  /* "recv" ACK for data1 */
00482   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
00483   EXPECT_RET(p != NULL);
00484   test_tcp_input(p, &netif);
00485   EXPECT_RET(txcounters.num_tx_calls == 0);
00486   EXPECT_RET(pcb->unacked == NULL);
00487   /* send data2 */
00488   err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY);
00489   EXPECT_RET(err == ERR_OK);
00490   err = tcp_output(pcb);
00491   EXPECT_RET(err == ERR_OK);
00492   EXPECT_RET(txcounters.num_tx_calls == 1);
00493   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
00494   memset(&txcounters, 0, sizeof(txcounters));
00495   /* duplicate ACK for data1 (data2 is lost) */
00496   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00497   EXPECT_RET(p != NULL);
00498   test_tcp_input(p, &netif);
00499   EXPECT_RET(txcounters.num_tx_calls == 0);
00500   EXPECT_RET(pcb->dupacks == 1);
00501   /* send data3 */
00502   err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
00503   EXPECT_RET(err == ERR_OK);
00504   err = tcp_output(pcb);
00505   EXPECT_RET(err == ERR_OK);
00506   /* nagle enabled, no tx calls */
00507   EXPECT_RET(txcounters.num_tx_calls == 0);
00508   EXPECT_RET(txcounters.num_tx_bytes == 0);
00509   memset(&txcounters, 0, sizeof(txcounters));
00510   /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */
00511   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00512   EXPECT_RET(p != NULL);
00513   test_tcp_input(p, &netif);
00514   EXPECT_RET(txcounters.num_tx_calls == 0);
00515   EXPECT_RET(pcb->dupacks == 2);
00516   /* queue data4, don't send it (unsent-oversize is != 0) */
00517   err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
00518   EXPECT_RET(err == ERR_OK);
00519   /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */
00520   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00521   EXPECT_RET(p != NULL);
00522   test_tcp_input(p, &netif);
00523   /*EXPECT_RET(txcounters.num_tx_calls == 1);*/
00524   EXPECT_RET(pcb->dupacks == 3);
00525   memset(&txcounters, 0, sizeof(txcounters));
00526   /* @todo: check expected data?*/
00527   
00528   /* send data5, not output yet */
00529   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00530   EXPECT_RET(err == ERR_OK);
00531   /*err = tcp_output(pcb);
00532   EXPECT_RET(err == ERR_OK);*/
00533   EXPECT_RET(txcounters.num_tx_calls == 0);
00534   EXPECT_RET(txcounters.num_tx_bytes == 0);
00535   memset(&txcounters, 0, sizeof(txcounters));
00536   {
00537     int i = 0;
00538     do
00539     {
00540       err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
00541       i++;
00542     }while(err == ERR_OK);
00543     EXPECT_RET(err != ERR_OK);
00544   }
00545   err = tcp_output(pcb);
00546   EXPECT_RET(err == ERR_OK);
00547   /*EXPECT_RET(txcounters.num_tx_calls == 0);
00548   EXPECT_RET(txcounters.num_tx_bytes == 0);*/
00549   memset(&txcounters, 0, sizeof(txcounters));
00550 
00551   /* send even more data */
00552   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00553   EXPECT_RET(err == ERR_OK);
00554   err = tcp_output(pcb);
00555   EXPECT_RET(err == ERR_OK);
00556   /* ...and even more data */
00557   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00558   EXPECT_RET(err == ERR_OK);
00559   err = tcp_output(pcb);
00560   EXPECT_RET(err == ERR_OK);
00561   /* ...and even more data */
00562   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00563   EXPECT_RET(err == ERR_OK);
00564   err = tcp_output(pcb);
00565   EXPECT_RET(err == ERR_OK);
00566   /* ...and even more data */
00567   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00568   EXPECT_RET(err == ERR_OK);
00569   err = tcp_output(pcb);
00570   EXPECT_RET(err == ERR_OK);
00571 
00572   /* send ACKs for data2 and data3 */
00573   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK);
00574   EXPECT_RET(p != NULL);
00575   test_tcp_input(p, &netif);
00576   /*EXPECT_RET(txcounters.num_tx_calls == 0);*/
00577 
00578   /* ...and even more data */
00579   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00580   EXPECT_RET(err == ERR_OK);
00581   err = tcp_output(pcb);
00582   EXPECT_RET(err == ERR_OK);
00583   /* ...and even more data */
00584   err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY);
00585   EXPECT_RET(err == ERR_OK);
00586   err = tcp_output(pcb);
00587   EXPECT_RET(err == ERR_OK);
00588 
00589 #if 0
00590   /* create expected segment */
00591   p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0);
00592   EXPECT_RET(p != NULL);
00593   if (p != NULL) {
00594     /* pass the segment to tcp_input */
00595     test_tcp_input(p, &netif);
00596     /* check if counters are as expected */
00597     EXPECT_RET(counters.close_calls == 0);
00598     EXPECT_RET(counters.recv_calls == 1);
00599     EXPECT_RET(counters.recved_bytes == data_len);
00600     EXPECT_RET(counters.err_calls == 0);
00601   }
00602 #endif
00603   /* make sure the pcb is freed */
00604   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00605   tcp_abort(pcb);
00606   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00607 }
00608 END_TEST
00609 
00610 static u8_t tx_data[TCP_WND*2];
00611 
00612 static void
00613 check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected)
00614 {
00615   struct tcp_seg *s = segs;
00616   int i;
00617   for (i = 0; i < num_expected; i++, s = s->next) {
00618     EXPECT_RET(s != NULL);
00619     EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i]));
00620   }
00621   EXPECT(s == NULL);
00622 }
00623 
00624 /** Send data with sequence numbers that wrap around the u32_t range.
00625  * Then, provoke fast retransmission by duplicate ACKs and check that all
00626  * segment lists are still properly sorted. */
00627 START_TEST(test_tcp_fast_rexmit_wraparound)
00628 {
00629   struct netif netif;
00630   struct test_tcp_txcounters txcounters;
00631   struct test_tcp_counters counters;
00632   struct tcp_pcb* pcb;
00633   struct pbuf* p;
00634   err_t err;
00635   size_t i;
00636   u16_t sent_total = 0;
00637   LWIP_UNUSED_ARG(_i);
00638 
00639   for (i = 0; i < sizeof(tx_data); i++) {
00640     tx_data[i] = (u8_t)i;
00641   }
00642 
00643   /* initialize local vars */
00644   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00645   memset(&counters, 0, sizeof(counters));
00646 
00647   /* create and initialize the pcb */
00648   tcp_ticks = SEQNO1 - ISS;
00649   pcb = test_tcp_new_counters_pcb(&counters);
00650   EXPECT_RET(pcb != NULL);
00651   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00652   pcb->mss = TCP_MSS;
00653   /* disable initial congestion window (we don't send a SYN here...) */
00654   pcb->cwnd = 2*TCP_MSS;
00655   /* start in congestion advoidance */
00656   pcb->ssthresh = pcb->cwnd;
00657 
00658   /* send 6 mss-sized segments */
00659   for (i = 0; i < 6; i++) {
00660     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
00661     EXPECT_RET(err == ERR_OK);
00662     sent_total += TCP_MSS;
00663   }
00664   check_seqnos(pcb->unsent, 6, seqnos);
00665   EXPECT(pcb->unacked == NULL);
00666   err = tcp_output(pcb);
00667   EXPECT(txcounters.num_tx_calls == 2);
00668   EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
00669   memset(&txcounters, 0, sizeof(txcounters));
00670 
00671   check_seqnos(pcb->unacked, 2, seqnos);
00672   check_seqnos(pcb->unsent, 4, &seqnos[2]);
00673 
00674   /* ACK the first segment */
00675   p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
00676   test_tcp_input(p, &netif);
00677   /* ensure this didn't trigger a retransmission. Only one
00678   segment should be transmitted because cwnd opened up by
00679   TCP_MSS and a fraction since we are in congestion avoidance */
00680   EXPECT(txcounters.num_tx_calls == 1);
00681   EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
00682   memset(&txcounters, 0, sizeof(txcounters));
00683   check_seqnos(pcb->unacked, 2, &seqnos[1]);
00684   check_seqnos(pcb->unsent, 3, &seqnos[3]);
00685 
00686   /* 3 dupacks */
00687   EXPECT(pcb->dupacks == 0);
00688   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00689   test_tcp_input(p, &netif);
00690   EXPECT(txcounters.num_tx_calls == 0);
00691   EXPECT(pcb->dupacks == 1);
00692   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00693   test_tcp_input(p, &netif);
00694   EXPECT(txcounters.num_tx_calls == 0);
00695   EXPECT(pcb->dupacks == 2);
00696   /* 3rd dupack -> fast rexmit */
00697   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00698   test_tcp_input(p, &netif);
00699   EXPECT(pcb->dupacks == 3);
00700   EXPECT(txcounters.num_tx_calls == 4);
00701   memset(&txcounters, 0, sizeof(txcounters));
00702   EXPECT(pcb->unsent == NULL);
00703   check_seqnos(pcb->unacked, 5, &seqnos[1]);
00704 
00705   /* make sure the pcb is freed */
00706   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00707   tcp_abort(pcb);
00708   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00709 }
00710 END_TEST
00711 
00712 /** Send data with sequence numbers that wrap around the u32_t range.
00713  * Then, provoke RTO retransmission and check that all
00714  * segment lists are still properly sorted. */
00715 START_TEST(test_tcp_rto_rexmit_wraparound)
00716 {
00717   struct netif netif;
00718   struct test_tcp_txcounters txcounters;
00719   struct test_tcp_counters counters;
00720   struct tcp_pcb* pcb;
00721   struct tcp_pcb dummy_pcb_for_iss; /* we need this for tcp_next_iss() only */
00722   err_t err;
00723   size_t i;
00724   u16_t sent_total = 0;
00725   LWIP_UNUSED_ARG(_i);
00726 
00727   for (i = 0; i < sizeof(tx_data); i++) {
00728     tx_data[i] = (u8_t)i;
00729   }
00730 
00731   /* initialize local vars */
00732   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00733   memset(&counters, 0, sizeof(counters));
00734 
00735   /* create and initialize the pcb */
00736   tcp_ticks = 0;
00737   tcp_ticks = 0 - tcp_next_iss(&dummy_pcb_for_iss);
00738   tcp_ticks = SEQNO1 - tcp_next_iss(&dummy_pcb_for_iss);
00739   pcb = test_tcp_new_counters_pcb(&counters);
00740   EXPECT_RET(pcb != NULL);
00741   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00742   pcb->mss = TCP_MSS;
00743   /* disable initial congestion window (we don't send a SYN here...) */
00744   pcb->cwnd = 2*TCP_MSS;
00745 
00746   /* send 6 mss-sized segments */
00747   for (i = 0; i < 6; i++) {
00748     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
00749     EXPECT_RET(err == ERR_OK);
00750     sent_total += TCP_MSS;
00751   }
00752   check_seqnos(pcb->unsent, 6, seqnos);
00753   EXPECT(pcb->unacked == NULL);
00754   err = tcp_output(pcb);
00755   EXPECT(txcounters.num_tx_calls == 2);
00756   EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
00757   memset(&txcounters, 0, sizeof(txcounters));
00758 
00759   check_seqnos(pcb->unacked, 2, seqnos);
00760   check_seqnos(pcb->unsent, 4, &seqnos[2]);
00761 
00762   /* call the tcp timer some times */
00763   for (i = 0; i < 10; i++) {
00764     test_tcp_tmr();
00765     EXPECT(txcounters.num_tx_calls == 0);
00766   }
00767   /* 11th call to tcp_tmr: RTO rexmit fires */
00768   test_tcp_tmr();
00769   EXPECT(txcounters.num_tx_calls == 1);
00770   check_seqnos(pcb->unacked, 1, seqnos);
00771   check_seqnos(pcb->unsent, 5, &seqnos[1]);
00772 
00773   /* fake greater cwnd */
00774   pcb->cwnd = pcb->snd_wnd;
00775   /* send more data */
00776   err = tcp_output(pcb);
00777   EXPECT(err == ERR_OK);
00778   /* check queues are sorted */
00779   EXPECT(pcb->unsent == NULL);
00780   check_seqnos(pcb->unacked, 6, seqnos);
00781 
00782   /* make sure the pcb is freed */
00783   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00784   tcp_abort(pcb);
00785   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00786 }
00787 END_TEST
00788 
00789 /** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data.
00790  * At the end, send more data. */
00791 static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent)
00792 {
00793   struct netif netif;
00794   struct test_tcp_txcounters txcounters;
00795   struct test_tcp_counters counters;
00796   struct tcp_pcb* pcb;
00797   struct pbuf *p;
00798   err_t err;
00799   size_t i;
00800   u16_t sent_total;
00801   u8_t expected = 0xFE;
00802 
00803   for (i = 0; i < sizeof(tx_data); i++) {
00804     u8_t d = (u8_t)i;
00805     if (d == 0xFE) {
00806       d = 0xF0;
00807     }
00808     tx_data[i] = d;
00809   }
00810   if (zero_window_probe_from_unsent) {
00811     tx_data[TCP_WND] = expected;
00812   } else {
00813     tx_data[0] = expected;
00814   }
00815 
00816   /* initialize local vars */
00817   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00818   memset(&counters, 0, sizeof(counters));
00819 
00820   /* create and initialize the pcb */
00821   pcb = test_tcp_new_counters_pcb(&counters);
00822   EXPECT_RET(pcb != NULL);
00823   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00824   pcb->mss = TCP_MSS;
00825   /* disable initial congestion window (we don't send a SYN here...) */
00826   pcb->cwnd = pcb->snd_wnd;
00827 
00828   /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */
00829   sent_total = 0;
00830   if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) {
00831     u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS;
00832     err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY);
00833     EXPECT_RET(err == ERR_OK);
00834     err = tcp_output(pcb);
00835     EXPECT_RET(err == ERR_OK);
00836     EXPECT(txcounters.num_tx_calls == 1);
00837     EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U);
00838     memset(&txcounters, 0, sizeof(txcounters));
00839     sent_total += initial_data_len;
00840   }
00841   for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) {
00842     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
00843     EXPECT_RET(err == ERR_OK);
00844     err = tcp_output(pcb);
00845     EXPECT_RET(err == ERR_OK);
00846     EXPECT(txcounters.num_tx_calls == 1);
00847     EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
00848     memset(&txcounters, 0, sizeof(txcounters));
00849   }
00850   EXPECT(sent_total == (TCP_WND - TCP_MSS));
00851 
00852   /* now ACK the packet before the first */
00853   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK);
00854   test_tcp_input(p, &netif);
00855   /* ensure this didn't trigger a retransmission */
00856   EXPECT(txcounters.num_tx_calls == 0);
00857   EXPECT(txcounters.num_tx_bytes == 0);
00858 
00859   EXPECT(pcb->persist_backoff == 0);
00860   /* send the last packet, now a complete window has been sent */
00861   err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
00862   sent_total += TCP_MSS;
00863   EXPECT_RET(err == ERR_OK);
00864   err = tcp_output(pcb);
00865   EXPECT_RET(err == ERR_OK);
00866   EXPECT(txcounters.num_tx_calls == 1);
00867   EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
00868   memset(&txcounters, 0, sizeof(txcounters));
00869   EXPECT(pcb->persist_backoff == 0);
00870 
00871   if (zero_window_probe_from_unsent) {
00872     /* ACK all data but close the TX window */
00873     p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0);
00874     test_tcp_input(p, &netif);
00875     /* ensure this didn't trigger any transmission */
00876     EXPECT(txcounters.num_tx_calls == 0);
00877     EXPECT(txcounters.num_tx_bytes == 0);
00878     /* window is completely full, but persist timer is off since send buffer is empty */
00879     EXPECT(pcb->snd_wnd == 0);
00880     EXPECT(pcb->persist_backoff == 0);
00881   }
00882 
00883   /* send one byte more (out of window) -> persist timer starts */
00884   err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY);
00885   EXPECT_RET(err == ERR_OK);
00886   err = tcp_output(pcb);
00887   EXPECT_RET(err == ERR_OK);
00888   EXPECT(txcounters.num_tx_calls == 0);
00889   EXPECT(txcounters.num_tx_bytes == 0);
00890   memset(&txcounters, 0, sizeof(txcounters));
00891   if (!zero_window_probe_from_unsent) {
00892     /* no persist timer unless a zero window announcement has been received */
00893     EXPECT(pcb->persist_backoff == 0);
00894   } else {
00895     EXPECT(pcb->persist_backoff == 1);
00896 
00897     /* call tcp_timer some more times to let persist timer count up */
00898     for (i = 0; i < 4; i++) {
00899       test_tcp_tmr();
00900       EXPECT(txcounters.num_tx_calls == 0);
00901       EXPECT(txcounters.num_tx_bytes == 0);
00902     }
00903 
00904     /* this should trigger the zero-window-probe */
00905     txcounters.copy_tx_packets = 1;
00906     test_tcp_tmr();
00907     txcounters.copy_tx_packets = 0;
00908     EXPECT(txcounters.num_tx_calls == 1);
00909     EXPECT(txcounters.num_tx_bytes == 1 + 40U);
00910     EXPECT(txcounters.tx_packets != NULL);
00911     if (txcounters.tx_packets != NULL) {
00912       u8_t sent;
00913       u16_t ret;
00914       ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U);
00915       EXPECT(ret == 1);
00916       EXPECT(sent == expected);
00917     }
00918     if (txcounters.tx_packets != NULL) {
00919       pbuf_free(txcounters.tx_packets);
00920       txcounters.tx_packets = NULL;
00921     }
00922   }
00923 
00924   /* make sure the pcb is freed */
00925   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
00926   tcp_abort(pcb);
00927   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
00928 }
00929 
00930 START_TEST(test_tcp_tx_full_window_lost_from_unsent)
00931 {
00932   LWIP_UNUSED_ARG(_i);
00933   test_tcp_tx_full_window_lost(1);
00934 }
00935 END_TEST
00936 
00937 START_TEST(test_tcp_tx_full_window_lost_from_unacked)
00938 {
00939   LWIP_UNUSED_ARG(_i);
00940   test_tcp_tx_full_window_lost(0);
00941 }
00942 END_TEST
00943 
00944 /** Send data, provoke retransmission and then add data to a segment
00945  * that already has been sent before. */
00946 START_TEST(test_tcp_retx_add_to_sent)
00947 {
00948   struct netif netif;
00949   struct test_tcp_txcounters txcounters;
00950   struct test_tcp_counters counters;
00951   struct tcp_pcb* pcb;
00952   struct pbuf* p;
00953   char data1a[] = {  1,  2,  3};
00954   char data1b[] = {  4};
00955   char data2a[] = {  5,  6,  7,  8};
00956   char data2b[] = {  5,  6,  7};
00957   char data3[] = {  9, 10, 11, 12, 12};
00958   char data4[] = { 13, 14, 15, 16,17};
00959   err_t err;
00960   int i;
00961   LWIP_UNUSED_ARG(_i);
00962 
00963   /* initialize local vars */
00964   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
00965   memset(&counters, 0, sizeof(counters));
00966 
00967   /* create and initialize the pcb */
00968   pcb = test_tcp_new_counters_pcb(&counters);
00969   EXPECT_RET(pcb != NULL);
00970   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
00971   pcb->mss = TCP_MSS;
00972   /* disable initial congestion window (we don't send a SYN here...) */
00973   pcb->cwnd = pcb->snd_wnd;
00974 
00975   /* send data1 */
00976   err = tcp_write(pcb, data1a, sizeof(data1a), TCP_WRITE_FLAG_COPY);
00977   EXPECT_RET(err == ERR_OK);
00978   err = tcp_write(pcb, data1b, sizeof(data1b), TCP_WRITE_FLAG_COPY);
00979   EXPECT_RET(err == ERR_OK);
00980   err = tcp_output(pcb);
00981   EXPECT_RET(err == ERR_OK);
00982   EXPECT_RET(txcounters.num_tx_calls == 1);
00983   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1a) + sizeof(data1b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
00984   memset(&txcounters, 0, sizeof(txcounters));
00985  /* "recv" ACK for data1 */
00986   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK);
00987   EXPECT_RET(p != NULL);
00988   test_tcp_input(p, &netif);
00989   EXPECT_RET(txcounters.num_tx_calls == 0);
00990   EXPECT_RET(pcb->unacked == NULL);
00991   /* send data2 */
00992   err = tcp_write(pcb, data2a, sizeof(data2a), TCP_WRITE_FLAG_COPY);
00993   EXPECT_RET(err == ERR_OK);
00994   err = tcp_write(pcb, data2b, sizeof(data2b), TCP_WRITE_FLAG_COPY);
00995   EXPECT_RET(err == ERR_OK);
00996   err = tcp_output(pcb);
00997   EXPECT_RET(err == ERR_OK);
00998   EXPECT_RET(txcounters.num_tx_calls == 1);
00999   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2a) + sizeof(data2b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
01000   memset(&txcounters, 0, sizeof(txcounters));
01001   /* send data3 */
01002   err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY);
01003   EXPECT_RET(err == ERR_OK);
01004   err = tcp_output(pcb);
01005   EXPECT_RET(err == ERR_OK);
01006   EXPECT_RET(txcounters.num_tx_calls == 0);
01007   EXPECT_RET(txcounters.num_tx_bytes == 0);
01008   memset(&txcounters, 0, sizeof(txcounters));
01009 
01010   /* data3 not sent yet (nagle) */
01011   EXPECT_RET(pcb->unacked != NULL);
01012   EXPECT_RET(pcb->unsent != NULL);
01013 
01014   /* disable nagle for this test so data to sent segment can be added below... */
01015   tcp_nagle_disable(pcb);
01016 
01017   /* call the tcp timer some times */
01018   for (i = 0; i < 20; i++) {
01019     test_tcp_tmr();
01020     if (txcounters.num_tx_calls != 0) {
01021       break;
01022     }
01023   }
01024   /* data3 sent */
01025   EXPECT_RET(txcounters.num_tx_calls == 1);
01026   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data3) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
01027   EXPECT_RET(pcb->unacked != NULL);
01028   EXPECT_RET(pcb->unsent == NULL);
01029   memset(&txcounters, 0, sizeof(txcounters));
01030 
01031   tcp_nagle_enable(pcb);
01032 
01033   /* call the tcp timer some times */
01034   for (i = 0; i < 20; i++) {
01035     test_tcp_tmr();
01036     if (txcounters.num_tx_calls != 0) {
01037       break;
01038     }
01039   }
01040   /* RTO: rexmit of data2 */
01041   EXPECT_RET(txcounters.num_tx_calls == 1);
01042   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2a) + sizeof(data2b) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
01043   EXPECT_RET(pcb->unacked != NULL);
01044   EXPECT_RET(pcb->unsent != NULL);
01045   memset(&txcounters, 0, sizeof(txcounters));
01046 
01047   /* send data4 */
01048   err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY);
01049   EXPECT_RET(err == ERR_OK);
01050   /* disable nagle for this test so data to transmit without further ACKs... */
01051   tcp_nagle_disable(pcb);
01052   err = tcp_output(pcb);
01053   EXPECT_RET(err == ERR_OK);
01054   /* nagle enabled, no tx calls */
01055   EXPECT_RET(txcounters.num_tx_calls == 1);
01056   EXPECT_RET(txcounters.num_tx_bytes == sizeof(data3) + sizeof(data4) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr));
01057   memset(&txcounters, 0, sizeof(txcounters));
01058   /* make sure the pcb is freed */
01059   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
01060   tcp_abort(pcb);
01061   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
01062 }
01063 END_TEST
01064 
01065 START_TEST(test_tcp_rto_tracking)
01066 {
01067   struct netif netif;
01068   struct test_tcp_txcounters txcounters;
01069   struct test_tcp_counters counters;
01070   struct tcp_pcb* pcb;
01071   struct pbuf* p;
01072   err_t err;
01073   size_t i;
01074   u16_t sent_total = 0;
01075   LWIP_UNUSED_ARG(_i);
01076 
01077   for (i = 0; i < sizeof(tx_data); i++) {
01078     tx_data[i] = (u8_t)i;
01079   }
01080 
01081   /* initialize local vars */
01082   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
01083   memset(&counters, 0, sizeof(counters));
01084 
01085   /* create and initialize the pcb */
01086   tcp_ticks = SEQNO1 - ISS;
01087   pcb = test_tcp_new_counters_pcb(&counters);
01088   EXPECT_RET(pcb != NULL);
01089   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
01090   pcb->mss = TCP_MSS;
01091   /* Set congestion window large enough to send all our segments */
01092   pcb->cwnd = 5*TCP_MSS;
01093 
01094   /* send 5 mss-sized segments */
01095   for (i = 0; i < 5; i++) {
01096     err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
01097     EXPECT_RET(err == ERR_OK);
01098     sent_total += TCP_MSS;
01099   }
01100   check_seqnos(pcb->unsent, 5, seqnos);
01101   EXPECT(pcb->unacked == NULL);
01102   err = tcp_output(pcb);
01103   EXPECT(txcounters.num_tx_calls == 5);
01104   EXPECT(txcounters.num_tx_bytes == 5 * (TCP_MSS + 40U));
01105   memset(&txcounters, 0, sizeof(txcounters));
01106   /* Check all 5 are in-flight */
01107   EXPECT(pcb->unsent == NULL);
01108   check_seqnos(pcb->unacked, 5, seqnos);
01109 
01110   /* Force us into retransmisson timeout */
01111   while (!(pcb->flags & TF_RTO)) {
01112     test_tcp_tmr();
01113   }
01114   /* Ensure 4 remaining segments are back on unsent, ready for retransmission */
01115   check_seqnos(pcb->unsent, 4, &seqnos[1]);
01116   /* Ensure 1st segment is on unacked (already retransmitted) */
01117   check_seqnos(pcb->unacked, 1, seqnos);
01118   EXPECT(txcounters.num_tx_calls == 1);
01119   EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U);
01120   memset(&txcounters, 0, sizeof(txcounters));
01121   /* Ensure rto_end points to next byte */
01122   EXPECT(pcb->rto_end == seqnos[5]);
01123   EXPECT(pcb->rto_end == pcb->snd_nxt);
01124   /* Check cwnd was reset */
01125   EXPECT(pcb->cwnd == pcb->mss);
01126 
01127   /* Add another segment to send buffer which is outside of RTO */
01128   err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY);
01129   EXPECT_RET(err == ERR_OK);
01130   sent_total += TCP_MSS;
01131   check_seqnos(pcb->unsent, 5, &seqnos[1]);
01132   /* Ensure no new data was sent */
01133   EXPECT(txcounters.num_tx_calls == 0);
01134   EXPECT(txcounters.num_tx_bytes == 0);
01135   EXPECT(pcb->rto_end == pcb->snd_nxt);
01136 
01137   /* ACK first segment */
01138   p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK);
01139   test_tcp_input(p, &netif);
01140   /* Next two retranmissions should go out, due to cwnd in slow start */
01141   EXPECT(txcounters.num_tx_calls == 2);
01142   EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U));
01143   memset(&txcounters, 0, sizeof(txcounters));
01144   check_seqnos(pcb->unacked, 2, &seqnos[1]);
01145   check_seqnos(pcb->unsent, 3, &seqnos[3]);
01146   /* RTO should still be marked */
01147   EXPECT(pcb->flags & TF_RTO);
01148   /* cwnd should have only grown by 1 MSS */
01149   EXPECT(pcb->cwnd == (tcpwnd_size_t)(2 * pcb->mss));
01150   /* Ensure no new data was sent */
01151   EXPECT(pcb->rto_end == pcb->snd_nxt);
01152 
01153   /* ACK the next two segments */
01154   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 2*TCP_MSS, TCP_ACK);
01155   test_tcp_input(p, &netif);
01156   /* Final 2 retransmissions and 1 new data should go out */
01157   EXPECT(txcounters.num_tx_calls == 3);
01158   EXPECT(txcounters.num_tx_bytes == 3 * (TCP_MSS + 40U));
01159   memset(&txcounters, 0, sizeof(txcounters));
01160   check_seqnos(pcb->unacked, 3, &seqnos[3]);
01161   EXPECT(pcb->unsent == NULL);
01162   /* RTO should still be marked */
01163   EXPECT(pcb->flags & TF_RTO);
01164   /* cwnd should have only grown by 1 MSS */
01165   EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
01166   /* snd_nxt should have been advanced past rto_end */
01167   EXPECT(TCP_SEQ_GT(pcb->snd_nxt, pcb->rto_end));
01168 
01169   /* ACK the next two segments, finishing our RTO, leaving new segment unacked */
01170   p = tcp_create_rx_segment(pcb, NULL, 0, 0, 2*TCP_MSS, TCP_ACK);
01171   test_tcp_input(p, &netif);
01172   EXPECT(!(pcb->flags & TF_RTO));
01173   check_seqnos(pcb->unacked, 1, &seqnos[5]);
01174   /* We should be in ABC congestion avoidance, so no change in cwnd */
01175   EXPECT(pcb->cwnd == (tcpwnd_size_t)(3 * pcb->mss));
01176   EXPECT(pcb->cwnd >= pcb->ssthresh);
01177   /* Ensure ABC congestion avoidance is tracking bytes acked */
01178   EXPECT(pcb->bytes_acked == (tcpwnd_size_t)(2 * pcb->mss));
01179 
01180   /* make sure the pcb is freed */
01181   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
01182   tcp_abort(pcb);
01183   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
01184 }
01185 END_TEST
01186 
01187 static void test_tcp_rto_timeout_impl(int link_down)
01188 {
01189   struct netif netif;
01190   struct test_tcp_txcounters txcounters;
01191   struct test_tcp_counters counters;
01192   struct tcp_pcb *pcb, *cur;
01193   err_t err;
01194   size_t i;
01195   const size_t max_wait_ctr = 1024 * 1024;
01196 
01197   /* Setup data for a single segment */
01198   for (i = 0; i < TCP_MSS; i++) {
01199     tx_data[i] = (u8_t)i;
01200   }
01201 
01202   /* initialize local vars */
01203   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
01204   memset(&counters, 0, sizeof(counters));
01205 
01206   /* create and initialize the pcb */
01207   tcp_ticks = SEQNO1 - ISS;
01208   pcb = test_tcp_new_counters_pcb(&counters);
01209   EXPECT_RET(pcb != NULL);
01210   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
01211   pcb->mss = TCP_MSS;
01212   pcb->cwnd = TCP_MSS;
01213 
01214   /* send our segment */
01215   err = tcp_write(pcb, &tx_data[0], TCP_MSS, TCP_WRITE_FLAG_COPY);
01216   EXPECT_RET(err == ERR_OK);
01217   err = tcp_output(pcb);
01218   EXPECT(txcounters.num_tx_calls == 1);
01219   EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
01220   memset(&txcounters, 0, sizeof(txcounters));
01221 
01222   /* ensure no errors have been recorded */
01223   EXPECT(counters.err_calls == 0);
01224   EXPECT(counters.last_err == ERR_OK);
01225 
01226   /* Force us into retransmisson timeout */
01227    for (i = 0; !(pcb->flags & TF_RTO) && i < max_wait_ctr; i++) {
01228     test_tcp_tmr();
01229   }
01230    EXPECT(i < max_wait_ctr);
01231 
01232   /* check first rexmit */
01233   EXPECT(pcb->nrtx == 1);
01234   EXPECT(txcounters.num_tx_calls == 1);
01235   EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
01236 
01237   /* still no error expected */
01238   EXPECT(counters.err_calls == 0);
01239   EXPECT(counters.last_err == ERR_OK);
01240 
01241   if (link_down) {
01242     netif_set_link_down(&netif);
01243   }
01244 
01245   /* keep running the timer till we hit our maximum RTO */
01246   for (i = 0;  counters.last_err == ERR_OK && i < max_wait_ctr; i++) {
01247     test_tcp_tmr();
01248   }
01249   EXPECT(i < max_wait_ctr);
01250 
01251   /* check number of retransmissions */
01252   if (link_down) {
01253     EXPECT(txcounters.num_tx_calls == 1);
01254     EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
01255   } else {
01256     EXPECT(txcounters.num_tx_calls == TCP_MAXRTX);
01257     EXPECT(txcounters.num_tx_bytes == TCP_MAXRTX * (TCP_MSS + 40U));
01258   }
01259 
01260   /* check the connection (pcb) has been aborted */
01261   EXPECT(counters.err_calls == 1);
01262   EXPECT(counters.last_err == ERR_ABRT);
01263   /* check our pcb is no longer active */
01264   for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
01265     EXPECT(cur != pcb);
01266   }  
01267   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
01268 }
01269 
01270 START_TEST(test_tcp_rto_timeout)
01271 {
01272   LWIP_UNUSED_ARG(_i);
01273   test_tcp_rto_timeout_impl(0);
01274 }
01275 END_TEST
01276 
01277 START_TEST(test_tcp_rto_timeout_link_down)
01278 {
01279   LWIP_UNUSED_ARG(_i);
01280   test_tcp_rto_timeout_impl(1);
01281 }
01282 END_TEST
01283 
01284 static void test_tcp_rto_timeout_syn_sent_impl(int link_down)
01285 {
01286   struct netif netif;
01287   struct test_tcp_txcounters txcounters;
01288   struct test_tcp_counters counters;
01289   struct tcp_pcb *pcb, *cur;
01290   err_t err;
01291   size_t i;
01292   const size_t max_wait_ctr = 1024 * 1024;
01293   const u16_t tcp_syn_opts_len = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_MSS|TF_SEG_OPTS_WND_SCALE|TF_SEG_OPTS_SACK_PERM|TF_SEG_OPTS_TS);
01294 
01295   /* Setup data for a single segment */
01296   for (i = 0; i < TCP_MSS; i++) {
01297     tx_data[i] = (u8_t)i;
01298   }
01299 
01300   /* initialize local vars */
01301   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
01302   memset(&counters, 0, sizeof(counters));
01303 
01304   /* create and initialize the pcb */
01305   tcp_ticks = SEQNO1 - ISS;
01306   pcb = test_tcp_new_counters_pcb(&counters);
01307   EXPECT_RET(pcb != NULL);
01308   err = tcp_connect(pcb, &netif.gw, 123, NULL);
01309   EXPECT_RET(err == ERR_OK);
01310   EXPECT_RET(pcb->state == SYN_SENT);
01311   EXPECT(txcounters.num_tx_calls == 1);
01312   EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len);
01313 
01314   /* ensure no errors have been recorded */
01315   EXPECT(counters.err_calls == 0);
01316   EXPECT(counters.last_err == ERR_OK);
01317 
01318   txcounters.num_tx_calls = 0;
01319   txcounters.num_tx_bytes = 0;
01320 
01321   /* Force us into retransmisson timeout */
01322   for (i = 0; !(pcb->flags & TF_RTO) && i < max_wait_ctr; i++) {
01323     test_tcp_tmr();
01324   }
01325   EXPECT(i < max_wait_ctr);
01326 
01327   /* check first rexmit */
01328   EXPECT(pcb->nrtx == 1);
01329   EXPECT(txcounters.num_tx_calls == 1);
01330   EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len); /* 40: headers; >=: options */
01331 
01332   /* still no error expected */
01333   EXPECT(counters.err_calls == 0);
01334   EXPECT(counters.last_err == ERR_OK);
01335 
01336   if (link_down) {
01337     /* set link down and check what happens to the RTO counter */
01338     netif_set_link_down(&netif);
01339   }
01340 
01341   /* keep running the timer till we hit our maximum RTO */
01342   for (i = 0;  counters.last_err == ERR_OK && i < max_wait_ctr; i++) {
01343     test_tcp_tmr();
01344   }
01345   EXPECT(i < max_wait_ctr);
01346 
01347   /* check number of retransmissions */
01348   if (link_down) {
01349     EXPECT(txcounters.num_tx_calls == 1);
01350     EXPECT(txcounters.num_tx_bytes == 40U + tcp_syn_opts_len);
01351   } else {
01352     EXPECT(txcounters.num_tx_calls == TCP_SYNMAXRTX);
01353     EXPECT(txcounters.num_tx_bytes == TCP_SYNMAXRTX * (tcp_syn_opts_len + 40U));
01354   }
01355 
01356   /* check the connection (pcb) has been aborted */
01357   EXPECT(counters.err_calls == 1);
01358   EXPECT(counters.last_err == ERR_ABRT);
01359   /* check our pcb is no longer active */
01360   for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
01361     EXPECT(cur != pcb);
01362   }  
01363   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
01364 }
01365 
01366 START_TEST(test_tcp_rto_timeout_syn_sent)
01367 {
01368   LWIP_UNUSED_ARG(_i);
01369   test_tcp_rto_timeout_syn_sent_impl(0);
01370 }
01371 END_TEST
01372 
01373 START_TEST(test_tcp_rto_timeout_syn_sent_link_down)
01374 {
01375   LWIP_UNUSED_ARG(_i);
01376   test_tcp_rto_timeout_syn_sent_impl(1);
01377 }
01378 END_TEST
01379 
01380 static void test_tcp_zwp_timeout_impl(int link_down)
01381 {
01382   struct netif netif;
01383   struct test_tcp_txcounters txcounters;
01384   struct test_tcp_counters counters;
01385   struct tcp_pcb *pcb, *cur;
01386   struct pbuf* p;
01387   err_t err;
01388   size_t i;
01389 
01390   /* Setup data for two segments */
01391   for (i = 0; i < 2*TCP_MSS; i++) {
01392     tx_data[i] = (u8_t)i;
01393   }
01394 
01395   /* initialize local vars */
01396   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
01397   memset(&counters, 0, sizeof(counters));
01398 
01399   /* create and initialize the pcb */
01400   tcp_ticks = SEQNO1 - ISS;
01401   pcb = test_tcp_new_counters_pcb(&counters);
01402   EXPECT_RET(pcb != NULL);
01403   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
01404   pcb->mss = TCP_MSS;
01405   pcb->cwnd = TCP_MSS;
01406 
01407   /* send first segment */
01408   err = tcp_write(pcb, &tx_data[0], TCP_MSS, TCP_WRITE_FLAG_COPY);
01409   EXPECT(err == ERR_OK);
01410   err = tcp_output(pcb);
01411   EXPECT(err == ERR_OK);
01412   
01413   /* verify segment is in-flight */
01414   EXPECT(pcb->unsent == NULL);
01415   check_seqnos(pcb->unacked, 1, seqnos);
01416   EXPECT(txcounters.num_tx_calls == 1);
01417   EXPECT(txcounters.num_tx_bytes == 1 * (TCP_MSS + 40U));
01418   memset(&txcounters, 0, sizeof(txcounters));
01419 
01420   /* ACK the segment and close the TX window */
01421   p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK, 0);
01422   test_tcp_input(p, &netif);
01423   EXPECT(pcb->unacked == NULL);
01424   EXPECT(pcb->unsent == NULL);
01425   /* send buffer empty, persist should be off */
01426   EXPECT(pcb->persist_backoff == 0);
01427   EXPECT(pcb->snd_wnd == 0);
01428 
01429   /* send second segment, should be buffered */
01430   err = tcp_write(pcb, &tx_data[TCP_MSS], TCP_MSS, TCP_WRITE_FLAG_COPY);
01431   EXPECT(err == ERR_OK);
01432   err = tcp_output(pcb);
01433   EXPECT(err == ERR_OK);
01434 
01435   /* ensure it is buffered and persist timer started */
01436   EXPECT(pcb->unacked == NULL);
01437   check_seqnos(pcb->unsent, 1, &seqnos[1]);
01438   EXPECT(txcounters.num_tx_calls == 0);
01439   EXPECT(txcounters.num_tx_bytes == 0);
01440   EXPECT(pcb->persist_backoff == 1);
01441 
01442   /* ensure no errors have been recorded */
01443   EXPECT(counters.err_calls == 0);
01444   EXPECT(counters.last_err == ERR_OK);
01445 
01446   /* run timer till first probe */
01447   EXPECT(pcb->persist_probe == 0);
01448   while (pcb->persist_probe == 0) {
01449     test_tcp_tmr();
01450   }
01451   EXPECT(txcounters.num_tx_calls == 1);
01452   EXPECT(txcounters.num_tx_bytes == (1 + 40U));
01453   memset(&txcounters, 0, sizeof(txcounters));
01454 
01455   /* respond to probe with remote's current SEQ, ACK, and zero-window */
01456   p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, 0, TCP_ACK, 0);
01457   test_tcp_input(p, &netif);
01458   /* ensure zero-window is still active, but probe count reset */
01459   EXPECT(pcb->persist_backoff > 1);
01460   EXPECT(pcb->persist_probe == 0);
01461   EXPECT(pcb->snd_wnd == 0);
01462 
01463   /* ensure no errors have been recorded */
01464   EXPECT(counters.err_calls == 0);
01465   EXPECT(counters.last_err == ERR_OK);
01466 
01467   if (link_down) {
01468     netif_set_link_down(&netif);
01469   }
01470 
01471   /* now run the timer till we hit our maximum probe count */
01472   while (counters.last_err == ERR_OK) {
01473     test_tcp_tmr();
01474   }
01475 
01476   if (link_down) {
01477     EXPECT(txcounters.num_tx_calls == 0);
01478     EXPECT(txcounters.num_tx_bytes == 0);
01479   } else {
01480     /* check maximum number of 1 byte probes were sent */
01481     EXPECT(txcounters.num_tx_calls == TCP_MAXRTX);
01482     EXPECT(txcounters.num_tx_bytes == TCP_MAXRTX * (1 + 40U));
01483   }
01484 
01485   /* check the connection (pcb) has been aborted */
01486   EXPECT(counters.err_calls == 1);
01487   EXPECT(counters.last_err == ERR_ABRT);
01488   /* check our pcb is no longer active */
01489   for (cur = tcp_active_pcbs; cur != NULL; cur = cur->next) {
01490     EXPECT(cur != pcb);
01491   }  
01492   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
01493 }
01494 
01495 START_TEST(test_tcp_zwp_timeout)
01496 {
01497   LWIP_UNUSED_ARG(_i);
01498   test_tcp_zwp_timeout_impl(0);
01499 }
01500 END_TEST
01501 
01502 START_TEST(test_tcp_zwp_timeout_link_down)
01503 {
01504   LWIP_UNUSED_ARG(_i);
01505   test_tcp_zwp_timeout_impl(1);
01506 }
01507 END_TEST
01508 
01509 START_TEST(test_tcp_persist_split)
01510 {
01511   struct netif netif;
01512   struct test_tcp_txcounters txcounters;
01513   struct test_tcp_counters counters;
01514   struct tcp_pcb *pcb;
01515   struct pbuf* p;
01516   err_t err;
01517   size_t i;
01518   LWIP_UNUSED_ARG(_i);
01519 
01520   /* Setup data for four segments */
01521   for (i = 0; i < 4 * TCP_MSS; i++) {
01522     tx_data[i] = (u8_t)i;
01523   }
01524 
01525   /* initialize local vars */
01526   test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask);
01527   memset(&counters, 0, sizeof(counters));
01528 
01529   /* create and initialize the pcb */
01530   tcp_ticks = SEQNO1 - ISS;
01531   pcb = test_tcp_new_counters_pcb(&counters);
01532   EXPECT_RET(pcb != NULL);
01533   tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
01534   pcb->mss = TCP_MSS;
01535   /* set window to three segments */
01536   pcb->cwnd = 3 * TCP_MSS;
01537   pcb->snd_wnd = 3 * TCP_MSS;
01538   pcb->snd_wnd_max = 3 * TCP_MSS;
01539 
01540   /* send four segments. Fourth should stay buffered and is a 3/4 MSS segment to
01541      get coverage on the oversized segment case */
01542   err = tcp_write(pcb, &tx_data[0], (3 * TCP_MSS) + (TCP_MSS - (TCP_MSS / 4)), TCP_WRITE_FLAG_COPY);
01543   EXPECT(err == ERR_OK);
01544   err = tcp_output(pcb);
01545   EXPECT(err == ERR_OK);
01546 
01547   /* verify 3 segments are in-flight */
01548   EXPECT(pcb->unacked != NULL);
01549   check_seqnos(pcb->unacked, 3, seqnos);
01550   EXPECT(txcounters.num_tx_calls == 3);
01551   EXPECT(txcounters.num_tx_bytes == 3 * (TCP_MSS + 40U));
01552   memset(&txcounters, 0, sizeof(txcounters));
01553   /* verify 4th segment is on unsent */
01554   EXPECT(pcb->unsent != NULL);
01555   EXPECT(pcb->unsent->len == TCP_MSS - (TCP_MSS / 4));
01556   check_seqnos(pcb->unsent, 1, &seqnos[3]);
01557 #if TCP_OVERSIZE
01558   EXPECT(pcb->unsent_oversize == TCP_MSS / 4);
01559 #if TCP_OVERSIZE_DBGCHECK
01560   EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
01561 #endif /* TCP_OVERSIZE_DBGCHECK */
01562 #endif /* TCP_OVERSIZE */
01563 
01564   /* ACK the 3 segments and update the window to only 1/2 TCP_MSS.
01565      4th segment should stay on unsent because it's bigger than 1/2 MSS */
01566   p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, 3 * TCP_MSS, TCP_ACK, TCP_MSS / 2);
01567   test_tcp_input(p, &netif);
01568   EXPECT(pcb->unacked == NULL);
01569   EXPECT(pcb->snd_wnd == TCP_MSS / 2);
01570   EXPECT(pcb->unsent != NULL);
01571   check_seqnos(pcb->unsent, 1, &seqnos[3]);
01572   EXPECT(txcounters.num_tx_calls == 0);
01573   EXPECT(txcounters.num_tx_bytes == 0);
01574   /* persist timer should be started since 4th segment is stuck waiting on snd_wnd */
01575   EXPECT(pcb->persist_backoff == 1);
01576 
01577   /* ensure no errors have been recorded */
01578   EXPECT(counters.err_calls == 0);
01579   EXPECT(counters.last_err == ERR_OK);
01580 
01581   /* call tcp_timer some more times to let persist timer count up */
01582     for (i = 0; i < 4; i++) {
01583       test_tcp_tmr();
01584       EXPECT(txcounters.num_tx_calls == 0);
01585       EXPECT(txcounters.num_tx_bytes == 0);
01586     }
01587 
01588   /* this should be the first timer shot, which should split the
01589    * segment and send a runt (of the remaining window size) */
01590   txcounters.copy_tx_packets = 1;
01591   test_tcp_tmr();
01592   txcounters.copy_tx_packets = 0;
01593   /* persist will be disabled as RTO timer takes over */
01594   EXPECT(pcb->persist_backoff == 0);
01595   EXPECT(txcounters.num_tx_calls == 1);
01596   EXPECT(txcounters.num_tx_bytes == ((TCP_MSS /2) + 40U));
01597   /* verify 1/2 MSS segment sent, 1/4 MSS still buffered */
01598   EXPECT(pcb->unsent != NULL);
01599   EXPECT(pcb->unsent->len == TCP_MSS / 4);
01600   EXPECT(pcb->unacked != NULL);
01601   EXPECT(pcb->unacked->len == TCP_MSS / 2);
01602 #if TCP_OVERSIZE
01603   /* verify there is no oversized remaining since during the
01604      segment split, the remainder pbuf is always the exact length */
01605   EXPECT(pcb->unsent_oversize == 0);
01606 #if TCP_OVERSIZE_DBGCHECK
01607   /* Split segment already transmitted, should be at 0 */
01608   EXPECT(pcb->unacked->oversize_left == 0);
01609   /* Remainder segement should match pcb value (which is 0) */
01610   EXPECT(pcb->unsent->oversize_left == pcb->unsent_oversize);
01611 #endif /* TCP_OVERSIZE_DBGCHECK */
01612 #endif /* TCP_OVERSIZE */
01613 
01614   /* verify first half segment */
01615   EXPECT(txcounters.tx_packets != NULL);
01616   if (txcounters.tx_packets != NULL) {
01617     u8_t sent[TCP_MSS / 2];
01618     u16_t ret;
01619     ret = pbuf_copy_partial(txcounters.tx_packets, &sent, TCP_MSS / 2, 40U);
01620     EXPECT(ret == TCP_MSS / 2);
01621     EXPECT(memcmp(sent, &tx_data[3 * TCP_MSS], TCP_MSS / 2) == 0);
01622   }
01623   if (txcounters.tx_packets != NULL) {
01624     pbuf_free(txcounters.tx_packets);
01625     txcounters.tx_packets = NULL;
01626   }
01627   memset(&txcounters, 0, sizeof(txcounters));
01628 
01629   /* ACK the half segment, leave window at half segment */
01630   p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_MSS / 2, TCP_ACK, TCP_MSS / 2);
01631   txcounters.copy_tx_packets = 1;
01632   test_tcp_input(p, &netif);
01633   txcounters.copy_tx_packets = 0;
01634   /* ensure remaining segment was sent */
01635   EXPECT(txcounters.num_tx_calls == 1);
01636   EXPECT(txcounters.num_tx_bytes == ((TCP_MSS / 4) + 40U));
01637   EXPECT(pcb->unsent == NULL);
01638   EXPECT(pcb->unacked != NULL);
01639   EXPECT(pcb->unacked->len == TCP_MSS / 4);
01640   EXPECT(pcb->snd_wnd == TCP_MSS / 2);
01641 
01642   /* verify remainder segment */
01643   EXPECT(txcounters.tx_packets != NULL);
01644   if (txcounters.tx_packets != NULL) {
01645     u8_t sent[TCP_MSS / 4];
01646     u16_t ret;
01647     ret = pbuf_copy_partial(txcounters.tx_packets, &sent, TCP_MSS / 4, 40U);
01648     EXPECT(ret == TCP_MSS / 4);
01649     EXPECT(memcmp(sent, &tx_data[(3 * TCP_MSS) + TCP_MSS / 2], TCP_MSS / 4) == 0);
01650   }
01651   if (txcounters.tx_packets != NULL) {
01652     pbuf_free(txcounters.tx_packets);
01653     txcounters.tx_packets = NULL;
01654   }
01655 
01656   /* ensure no errors have been recorded */
01657   EXPECT(counters.err_calls == 0);
01658   EXPECT(counters.last_err == ERR_OK);
01659 
01660   /* make sure the pcb is freed */
01661   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
01662   tcp_abort(pcb);
01663   EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);
01664 }
01665 END_TEST
01666 
01667 /** Create the suite including all tests for this module */
01668 Suite *
01669 tcp_suite(void)
01670 {
01671   testfunc tests[] = {
01672     TESTFUNC(test_tcp_new_abort),
01673     TESTFUNC(test_tcp_listen_passive_open),
01674     TESTFUNC(test_tcp_recv_inseq),
01675     TESTFUNC(test_tcp_recv_inseq_trim),
01676     TESTFUNC(test_tcp_passive_close),
01677     TESTFUNC(test_tcp_active_abort),
01678     TESTFUNC(test_tcp_malformed_header),
01679     TESTFUNC(test_tcp_fast_retx_recover),
01680     TESTFUNC(test_tcp_fast_rexmit_wraparound),
01681     TESTFUNC(test_tcp_rto_rexmit_wraparound),
01682     TESTFUNC(test_tcp_tx_full_window_lost_from_unacked),
01683     TESTFUNC(test_tcp_tx_full_window_lost_from_unsent),
01684     TESTFUNC(test_tcp_retx_add_to_sent),
01685     TESTFUNC(test_tcp_rto_tracking),
01686     TESTFUNC(test_tcp_rto_timeout),
01687     TESTFUNC(test_tcp_rto_timeout_link_down),
01688     TESTFUNC(test_tcp_rto_timeout_syn_sent),
01689     TESTFUNC(test_tcp_rto_timeout_syn_sent_link_down),
01690     TESTFUNC(test_tcp_zwp_timeout),
01691     TESTFUNC(test_tcp_zwp_timeout_link_down),
01692     TESTFUNC(test_tcp_persist_split)
01693   };
01694   return create_suite("TCP", tests, sizeof(tests)/sizeof(testfunc), tcp_setup, tcp_teardown);
01695 }