Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 }
Generated on Tue Jul 12 2022 13:54:56 by
