117#ifdef LWIP_HOOK_FILENAME
118#include LWIP_HOOK_FILENAME
121#ifndef TCP_LOCAL_PORT_RANGE_START
124#define TCP_LOCAL_PORT_RANGE_START 0xc000
125#define TCP_LOCAL_PORT_RANGE_END 0xffff
126#define TCP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START))
129#if LWIP_TCP_KEEPALIVE
130#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl)
131#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
133#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE
134#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
139#define INITIAL_MSS 536
141#define INITIAL_MSS TCP_MSS
159static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
163static const u8_t tcp_backoff[13] =
164{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
166static const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
171struct tcp_pcb *tcp_bound_pcbs;
173union tcp_listen_pcbs_t tcp_listen_pcbs;
176struct tcp_pcb *tcp_active_pcbs;
178struct tcp_pcb *tcp_tw_pcbs;
181struct tcp_pcb **
const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
182 &tcp_active_pcbs, &tcp_tw_pcbs
185u8_t tcp_active_pcbs_changed;
188static u8_t tcp_timer;
189static u8_t tcp_timer_ctr;
190static u16_t tcp_new_port(
void);
192static err_t tcp_close_shutdown_fin(
struct tcp_pcb *pcb);
193#if LWIP_TCP_PCB_NUM_EXT_ARGS
194static void tcp_ext_arg_invoke_callbacks_destroyed(
struct tcp_pcb_ext_args *ext_args);
204 tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
210tcp_free(
struct tcp_pcb *pcb)
212 LWIP_ASSERT(
"tcp_free: LISTEN", pcb->state != LISTEN);
213#if LWIP_TCP_PCB_NUM_EXT_ARGS
214 tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args);
221tcp_free_listen(
struct tcp_pcb *pcb)
223 LWIP_ASSERT(
"tcp_free_listen: !LISTEN", pcb->state != LISTEN);
224#if LWIP_TCP_PCB_NUM_EXT_ARGS
225 tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args);
239 if (++tcp_timer & 1) {
246#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
251tcp_remove_listener(
struct tcp_pcb *
list,
struct tcp_pcb_listen *lpcb)
258 if (pcb->listener == lpcb) {
259 pcb->listener =
NULL;
269tcp_listen_closed(
struct tcp_pcb *pcb)
271#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
274 LWIP_ASSERT(
"pcb->state == LISTEN", pcb->state == LISTEN);
276 tcp_remove_listener(*tcp_pcb_lists[
i], (
struct tcp_pcb_listen *)pcb);
282#if TCP_LISTEN_BACKLOG
294tcp_backlog_delayed(
struct tcp_pcb *pcb)
298 if ((pcb->flags & TF_BACKLOGPEND) == 0) {
299 if (pcb->listener !=
NULL) {
300 pcb->listener->accepts_pending++;
301 LWIP_ASSERT(
"accepts_pending != 0", pcb->listener->accepts_pending != 0);
302 tcp_set_flags(pcb, TF_BACKLOGPEND);
317tcp_backlog_accepted(
struct tcp_pcb *pcb)
321 if ((pcb->flags & TF_BACKLOGPEND) != 0) {
322 if (pcb->listener !=
NULL) {
323 LWIP_ASSERT(
"accepts_pending != 0", pcb->listener->accepts_pending != 0);
324 pcb->listener->accepts_pending--;
325 tcp_clear_flags(pcb, TF_BACKLOGPEND);
348tcp_close_shutdown(
struct tcp_pcb *pcb,
u8_t rst_on_unacked_data)
352 if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
353 if ((pcb->refused_data !=
NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) {
356 LWIP_ASSERT(
"pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
360 tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
361 pcb->local_port, pcb->remote_port);
366 if (tcp_input_pcb == pcb) {
368 tcp_trigger_input_pcb_close();
378 switch (pcb->state) {
387 if (pcb->local_port != 0) {
388 TCP_RMV(&tcp_bound_pcbs, pcb);
393 tcp_listen_closed(pcb);
394 tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
395 tcp_free_listen(pcb);
398 TCP_PCB_REMOVE_ACTIVE(pcb);
403 return tcp_close_shutdown_fin(pcb);
409tcp_close_shutdown_fin(
struct tcp_pcb *pcb)
414 switch (pcb->state) {
418 tcp_backlog_accepted(pcb);
420 pcb->state = FIN_WAIT_1;
427 pcb->state = FIN_WAIT_1;
434 pcb->state = LAST_ACK;
451 tcp_set_flags(pcb, TF_CLOSEPEND);
491 tcp_debug_print_state(pcb->state);
493 if (pcb->state != LISTEN) {
495 tcp_set_flags(pcb, TF_RXCLOSED);
498 return tcp_close_shutdown(pcb, 1);
515tcp_shutdown(
struct tcp_pcb *pcb,
int shut_rx,
int shut_tx)
521 if (pcb->state == LISTEN) {
526 tcp_set_flags(pcb, TF_RXCLOSED);
529 return tcp_close_shutdown(pcb, 1);
532 if (pcb->refused_data !=
NULL) {
534 pcb->refused_data =
NULL;
540 switch (pcb->state) {
544 return tcp_close_shutdown(pcb, (
u8_t)shut_rx);
563tcp_abandon(
struct tcp_pcb *pcb,
int reset)
576 LWIP_ASSERT(
"don't call tcp_abort/tcp_abandon for listen-pcbs",
577 pcb->state != LISTEN);
581 if (pcb->state == TIME_WAIT) {
582 tcp_pcb_remove(&tcp_tw_pcbs, pcb);
586 u16_t local_port = 0;
587 enum tcp_state last_state;
588 seqno = pcb->snd_nxt;
589 ackno = pcb->rcv_nxt;
593 errf_arg = pcb->callback_arg;
594 if (pcb->state == CLOSED) {
595 if (pcb->local_port != 0) {
597 TCP_RMV(&tcp_bound_pcbs, pcb);
601 local_port = pcb->local_port;
602 TCP_PCB_REMOVE_ACTIVE(pcb);
604 if (pcb->unacked !=
NULL) {
605 tcp_segs_free(pcb->unacked);
607 if (pcb->unsent !=
NULL) {
608 tcp_segs_free(pcb->unsent);
611 if (pcb->ooseq !=
NULL) {
612 tcp_segs_free(pcb->ooseq);
615 tcp_backlog_accepted(pcb);
618 tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
620 last_state = pcb->state;
622 TCP_EVENT_ERR(last_state, errf, errf_arg,
ERR_ABRT);
638tcp_abort(
struct tcp_pcb *pcb)
665 int max_pcb_list = NUM_TCP_PCB_LISTS;
666 struct tcp_pcb *cpcb;
667#if LWIP_IPV6 && LWIP_IPV6_SCOPES
675 if (ipaddr ==
NULL) {
676 ipaddr = IP4_ADDR_ANY;
684 LWIP_ERROR(
"tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED,
return ERR_VAL);
693 max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
697#if LWIP_IPV6 && LWIP_IPV6_SCOPES
702 if (
IP_IS_V6(ipaddr) && ip6_addr_lacks_zone(
ip_2_ip6(ipaddr), IP6_UNICAST)) {
705 ipaddr = &zoned_ipaddr;
710 port = tcp_new_port();
716 for (
i = 0;
i < max_pcb_list;
i++) {
717 for (cpcb = *tcp_pcb_lists[
i]; cpcb !=
NULL; cpcb = cpcb->
next) {
718 if (cpcb->local_port ==
port) {
747 pcb->local_port =
port;
748 TCP_REG(&tcp_bound_pcbs, pcb);
764tcp_bind_netif(
struct tcp_pcb *pcb,
const struct netif *
netif)
779tcp_accept_null(
void *
arg,
struct tcp_pcb *pcb,
err_t err)
826tcp_listen_with_backlog(
struct tcp_pcb *pcb,
u8_t backlog)
829 return tcp_listen_with_backlog_and_err(pcb, backlog,
NULL);
849tcp_listen_with_backlog_and_err(
struct tcp_pcb *pcb,
u8_t backlog,
err_t *
err)
851 struct tcp_pcb_listen *lpcb =
NULL;
859 LWIP_ERROR(
"tcp_listen_with_backlog_and_err: pcb already connected", pcb->state == CLOSED,
res =
ERR_CLSD;
goto done);
862 if (pcb->state == LISTEN) {
863 lpcb = (
struct tcp_pcb_listen *)pcb;
872 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb !=
NULL; lpcb = lpcb->
next) {
873 if ((lpcb->local_port == pcb->local_port) &&
874 ip_addr_eq(&lpcb->local_ip, &pcb->local_ip)) {
883 lpcb = (
struct tcp_pcb_listen *)
memp_malloc(MEMP_TCP_PCB_LISTEN);
888 lpcb->callback_arg = pcb->callback_arg;
889 lpcb->local_port = pcb->local_port;
890 lpcb->state = LISTEN;
891 lpcb->prio = pcb->prio;
892 lpcb->so_options = pcb->so_options;
893 lpcb->netif_idx = pcb->netif_idx;
894 lpcb->ttl = pcb->ttl;
895 lpcb->tos = pcb->tos;
897 lpcb->netif_hints.tci = pcb->netif_hints.tci;
899#if LWIP_IPV4 && LWIP_IPV6
903 if (pcb->local_port != 0) {
904 TCP_RMV(&tcp_bound_pcbs, pcb);
906#if LWIP_TCP_PCB_NUM_EXT_ARGS
908 memcpy(&lpcb->ext_args, &pcb->ext_args,
sizeof(pcb->ext_args));
912 lpcb->accept = tcp_accept_null;
914#if TCP_LISTEN_BACKLOG
915 lpcb->accepts_pending = 0;
916 tcp_backlog_set(lpcb, backlog);
918 TCP_REG(&tcp_listen_pcbs.pcbs, (
struct tcp_pcb *)lpcb);
924 return (
struct tcp_pcb *)lpcb;
934tcp_update_rcv_ann_wnd(
struct tcp_pcb *pcb)
936 u32_t new_right_edge;
939 new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
941 if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge +
LWIP_MIN((
TCP_WND / 2), pcb->mss))) {
943 pcb->rcv_ann_wnd = pcb->rcv_wnd;
944 return new_right_edge - pcb->rcv_ann_right_edge;
946 if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
949 pcb->rcv_ann_wnd = 0;
952 u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
954 LWIP_ASSERT(
"new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
956 pcb->rcv_ann_wnd = (tcpwnd_size_t)new_rcv_ann_wnd;
972tcp_recved(
struct tcp_pcb *pcb,
u16_t len)
975 tcpwnd_size_t rcv_wnd;
982 LWIP_ASSERT(
"don't call tcp_recved for listen-pcbs",
983 pcb->state != LISTEN);
985 rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd +
len);
986 if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) {
989 pcb->rcv_wnd = TCP_WND_MAX(pcb);
991 pcb->rcv_wnd = rcv_wnd;
994 wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
1006 len, pcb->rcv_wnd, (
u16_t)(TCP_WND_MAX(pcb) - pcb->rcv_wnd)));
1019 struct tcp_pcb *pcb;
1023 if (tcp_port == TCP_LOCAL_PORT_RANGE_END) {
1024 tcp_port = TCP_LOCAL_PORT_RANGE_START;
1027 for (
i = 0;
i < NUM_TCP_PCB_LISTS;
i++) {
1028 for (pcb = *tcp_pcb_lists[
i]; pcb !=
NULL; pcb = pcb->
next) {
1029 if (pcb->local_port == tcp_port) {
1031 if (
n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
1077 u16_t old_local_port;
1084 LWIP_ERROR(
"tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED,
return ERR_ISCONN);
1088 pcb->remote_port =
port;
1094 netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
1103 const ip_addr_t *local_ip = ip_netif_get_local_ip(
netif, ipaddr);
1104 if (local_ip ==
NULL) {
1110#if LWIP_IPV6 && LWIP_IPV6_SCOPES
1114 ip6_addr_lacks_zone(
ip_2_ip6(&pcb->remote_ip), IP6_UNICAST)) {
1115 ip6_addr_assign_zone(
ip_2_ip6(&pcb->remote_ip), IP6_UNICAST,
netif);
1119 old_local_port = pcb->local_port;
1120 if (pcb->local_port == 0) {
1121 pcb->local_port = tcp_new_port();
1122 if (pcb->local_port == 0) {
1130 struct tcp_pcb *cpcb;
1133 for (
i = 2;
i < NUM_TCP_PCB_LISTS;
i++) {
1134 for (cpcb = *tcp_pcb_lists[
i]; cpcb !=
NULL; cpcb = cpcb->
next) {
1135 if ((cpcb->local_port == pcb->local_port) &&
1136 (cpcb->remote_port ==
port) &&
1137 ip_addr_eq(&cpcb->local_ip, &pcb->local_ip) &&
1148 iss = tcp_next_iss(pcb);
1151 pcb->lastack = iss - 1;
1152 pcb->snd_wl2 = iss - 1;
1153 pcb->snd_lbb = iss - 1;
1156 pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(
TCP_WND);
1157 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
1161 pcb->mss = INITIAL_MSS;
1162#if TCP_CALCULATE_EFF_SEND_MSS
1163 pcb->mss = tcp_eff_send_mss_netif(pcb->mss,
netif, &pcb->remote_ip);
1166#if LWIP_CALLBACK_API
1176 pcb->state = SYN_SENT;
1177 if (old_local_port != 0) {
1178 TCP_RMV(&tcp_bound_pcbs, pcb);
1180 TCP_REG_ACTIVE(pcb);
1198 struct tcp_pcb *pcb, *prev;
1199 tcpwnd_size_t eff_wnd;
1212 pcb = tcp_active_pcbs;
1216 while (pcb !=
NULL) {
1218 LWIP_ASSERT(
"tcp_slowtmr: active pcb->state != CLOSED", pcb->state != CLOSED);
1219 LWIP_ASSERT(
"tcp_slowtmr: active pcb->state != LISTEN", pcb->state != LISTEN);
1220 LWIP_ASSERT(
"tcp_slowtmr: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
1221 if (pcb->last_timer == tcp_timer_ctr) {
1227 pcb->last_timer = tcp_timer_ctr;
1239 if (pcb->persist_backoff > 0) {
1240 LWIP_ASSERT(
"tcp_slowtimr: persist ticking with in-flight data", pcb->unacked ==
NULL);
1241 LWIP_ASSERT(
"tcp_slowtimr: persist ticking with empty send buffer", pcb->unsent !=
NULL);
1245 u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff - 1];
1246 if (pcb->persist_cnt < backoff_cnt) {
1249 if (pcb->persist_cnt >= backoff_cnt) {
1252 if (pcb->snd_wnd == 0) {
1253 if (tcp_zero_window_probe(pcb) !=
ERR_OK) {
1258 if (tcp_split_unsent_seg(pcb, (
u16_t)pcb->snd_wnd) ==
ERR_OK) {
1259 if (tcp_output(pcb) ==
ERR_OK) {
1266 pcb->persist_cnt = 0;
1267 if (pcb->persist_backoff <
sizeof(tcp_persist_backoff)) {
1268 pcb->persist_backoff++;
1275 if ((pcb->rtime >= 0) && (pcb->rtime < 0x7FFF)) {
1279 if (pcb->rtime >= pcb->rto) {
1282 " pcb->rto %"S16_F"\n",
1283 pcb->rtime, pcb->rto));
1287 if ((tcp_rexmit_rto_prepare(pcb) ==
ERR_OK) || ((pcb->unacked ==
NULL) && (pcb->unsent !=
NULL))) {
1290 if (pcb->state != SYN_SENT) {
1291 u8_t backoff_idx =
LWIP_MIN(pcb->nrtx,
sizeof(tcp_backoff) - 1);
1292 int calc_rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx];
1300 eff_wnd =
LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
1301 pcb->ssthresh = eff_wnd >> 1;
1302 if (pcb->ssthresh < (tcpwnd_size_t)(pcb->mss << 1)) {
1303 pcb->ssthresh = (tcpwnd_size_t)(pcb->mss << 1);
1305 pcb->cwnd = pcb->mss;
1307 " ssthresh %"TCPWNDSIZE_F
"\n",
1308 pcb->cwnd, pcb->ssthresh));
1309 pcb->bytes_acked = 0;
1313 tcp_rexmit_rto_commit(pcb);
1319 if (pcb->state == FIN_WAIT_2) {
1321 if (pcb->flags & TF_RXCLOSED) {
1324 if ((
u32_t)(tcp_ticks - pcb->tmr) >
1325 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
1334 ((pcb->state == ESTABLISHED) ||
1335 (pcb->state == CLOSE_WAIT))) {
1336 if ((
u32_t)(tcp_ticks - pcb->tmr) >
1337 (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) {
1344 }
else if ((
u32_t)(tcp_ticks - pcb->tmr) >
1345 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
1346 / TCP_SLOW_INTERVAL) {
1349 pcb->keep_cnt_sent++;
1358 if (pcb->ooseq !=
NULL &&
1359 (tcp_ticks - pcb->tmr >= (
u32_t)pcb->rto * TCP_OOSEQ_TIMEOUT)) {
1361 tcp_free_ooseq(pcb);
1366 if (pcb->state == SYN_RCVD) {
1367 if ((
u32_t)(tcp_ticks - pcb->tmr) >
1368 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
1375 if (pcb->state == LAST_ACK) {
1376 if ((
u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
1384 struct tcp_pcb *pcb2;
1385#if LWIP_CALLBACK_API
1386 tcp_err_fn err_fn = pcb->errf;
1389 enum tcp_state last_state;
1393 LWIP_ASSERT(
"tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
1394 prev->next = pcb->next;
1397 LWIP_ASSERT(
"tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
1398 tcp_active_pcbs = pcb->next;
1402 tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
1403 pcb->local_port, pcb->remote_port);
1406 err_arg = pcb->callback_arg;
1407 last_state = pcb->state;
1412 tcp_active_pcbs_changed = 0;
1413 TCP_EVENT_ERR(last_state, err_fn, err_arg,
ERR_ABRT);
1414 if (tcp_active_pcbs_changed) {
1415 goto tcp_slowtmr_start;
1424 if (prev->polltmr >= prev->pollinterval) {
1427 tcp_active_pcbs_changed = 0;
1428 TCP_EVENT_POLL(prev,
err);
1429 if (tcp_active_pcbs_changed) {
1430 goto tcp_slowtmr_start;
1444 while (pcb !=
NULL) {
1445 LWIP_ASSERT(
"tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
1449 if ((
u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
1455 struct tcp_pcb *pcb2;
1459 LWIP_ASSERT(
"tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
1460 prev->next = pcb->next;
1463 LWIP_ASSERT(
"tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
1464 tcp_tw_pcbs = pcb->next;
1485 struct tcp_pcb *pcb;
1490 pcb = tcp_active_pcbs;
1492 while (pcb !=
NULL) {
1493 if (pcb->last_timer != tcp_timer_ctr) {
1494 struct tcp_pcb *
next;
1495 pcb->last_timer = tcp_timer_ctr;
1497 if (pcb->flags & TF_ACK_DELAY) {
1501 tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
1504 if (pcb->flags & TF_CLOSEPEND) {
1506 tcp_clear_flags(pcb, TF_CLOSEPEND);
1507 tcp_close_shutdown_fin(pcb);
1513 if (pcb->refused_data !=
NULL) {
1514 tcp_active_pcbs_changed = 0;
1515 tcp_process_refused_data(pcb);
1516 if (tcp_active_pcbs_changed) {
1518 goto tcp_fasttmr_start;
1532 struct tcp_pcb *pcb;
1534 for (pcb = tcp_active_pcbs; pcb !=
NULL; pcb = pcb->
next) {
1535 if (pcb->flags & TF_NAGLEMEMERR) {
1543tcp_process_refused_data(
struct tcp_pcb *pcb)
1545#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
1551#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
1552 while (pcb->refused_data !=
NULL)
1556 u8_t refused_flags = pcb->refused_data->flags;
1559 struct pbuf *refused_data = pcb->refused_data;
1560#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
1561 pbuf_split_64k(refused_data, &rest);
1562 pcb->refused_data = rest;
1564 pcb->refused_data =
NULL;
1568 TCP_EVENT_RECV(pcb, refused_data,
ERR_OK,
err);
1578 if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
1581 TCP_EVENT_CLOSED(pcb,
err);
1594#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
1599 pcb->refused_data = refused_data;
1612tcp_segs_free(
struct tcp_seg *seg)
1614 while (seg !=
NULL) {
1615 struct tcp_seg *
next = seg->next;
1627tcp_seg_free(
struct tcp_seg *seg)
1630 if (seg->p !=
NULL) {
1648tcp_setprio(
struct tcp_pcb *pcb,
u8_t prio)
1666tcp_seg_copy(
struct tcp_seg *seg)
1668 struct tcp_seg *cseg;
1672 cseg = (
struct tcp_seg *)
memp_malloc(MEMP_TCP_SEG);
1682#if LWIP_CALLBACK_API
1695 tcp_recved(pcb,
p->tot_len);
1710tcp_kill_prio(
u8_t prio)
1712 struct tcp_pcb *pcb, *inactive;
1716 mprio =
LWIP_MIN(TCP_PRIO_MAX, prio);
1734 for (pcb = tcp_active_pcbs; pcb !=
NULL; pcb = pcb->
next) {
1736 if ((pcb->prio < mprio) ||
1738 ((pcb->prio == mprio) && ((
u32_t)(tcp_ticks - pcb->tmr) >= inactivity))) {
1739 inactivity = tcp_ticks - pcb->tmr;
1744 if (inactive !=
NULL) {
1746 (
void *)inactive, inactivity));
1747 tcp_abort(inactive);
1756tcp_kill_state(
enum tcp_state
state)
1758 struct tcp_pcb *pcb, *inactive;
1767 for (pcb = tcp_active_pcbs; pcb !=
NULL; pcb = pcb->
next) {
1768 if (pcb->state ==
state) {
1769 if ((
u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
1770 inactivity = tcp_ticks - pcb->tmr;
1775 if (inactive !=
NULL) {
1779 tcp_abandon(inactive, 0);
1788tcp_kill_timewait(
void)
1790 struct tcp_pcb *pcb, *inactive;
1796 for (pcb = tcp_tw_pcbs; pcb !=
NULL; pcb = pcb->
next) {
1797 if ((
u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
1798 inactivity = tcp_ticks - pcb->tmr;
1802 if (inactive !=
NULL) {
1804 (
void *)inactive, inactivity));
1805 tcp_abort(inactive);
1815tcp_handle_closepend(
void)
1817 struct tcp_pcb *pcb = tcp_active_pcbs;
1819 while (pcb !=
NULL) {
1820 struct tcp_pcb *
next = pcb->next;
1822 if (pcb->flags & TF_CLOSEPEND) {
1824 tcp_clear_flags(pcb, TF_CLOSEPEND);
1825 tcp_close_shutdown_fin(pcb);
1840 struct tcp_pcb *pcb;
1844 pcb = (
struct tcp_pcb *)
memp_malloc(MEMP_TCP_PCB);
1847 tcp_handle_closepend();
1851 tcp_kill_timewait();
1853 pcb = (
struct tcp_pcb *)
memp_malloc(MEMP_TCP_PCB);
1857 tcp_kill_state(LAST_ACK);
1859 pcb = (
struct tcp_pcb *)
memp_malloc(MEMP_TCP_PCB);
1863 tcp_kill_state(CLOSING);
1865 pcb = (
struct tcp_pcb *)
memp_malloc(MEMP_TCP_PCB);
1868 LWIP_DEBUGF(
TCP_DEBUG, (
"tcp_alloc: killing oldest connection with prio lower than %d\n", prio));
1869 tcp_kill_prio(prio);
1871 pcb = (
struct tcp_pcb *)
memp_malloc(MEMP_TCP_PCB);
1894 memset(pcb, 0,
sizeof(
struct tcp_pcb));
1899 pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(
TCP_WND);
1903 pcb->mss = INITIAL_MSS;
1910 pcb->tmr = tcp_ticks;
1911 pcb->last_timer = tcp_timer_ctr;
1921#if LWIP_CALLBACK_API
1922 pcb->recv = tcp_recv_null;
1926 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT;
1928#if LWIP_TCP_KEEPALIVE
1929 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
1930 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT;
1955 return tcp_alloc(TCP_PRIO_NORMAL);
1973 struct tcp_pcb *pcb;
1974 pcb = tcp_alloc(TCP_PRIO_NORMAL);
1975#if LWIP_IPV4 && LWIP_IPV6
1997tcp_arg(
struct tcp_pcb *pcb,
void *
arg)
2003 pcb->callback_arg =
arg;
2006#if LWIP_CALLBACK_API
2024 LWIP_ASSERT(
"invalid socket state for recv callback", pcb->state != LISTEN);
2040tcp_sent(
struct tcp_pcb *pcb, tcp_sent_fn
sent)
2044 LWIP_ASSERT(
"invalid socket state for sent callback", pcb->state != LISTEN);
2066tcp_err(
struct tcp_pcb *pcb, tcp_err_fn
err)
2070 LWIP_ASSERT(
"invalid socket state for err callback", pcb->state != LISTEN);
2089 if ((pcb !=
NULL) && (pcb->state == LISTEN)) {
2090 struct tcp_pcb_listen *lpcb = (
struct tcp_pcb_listen *)pcb;
2120 LWIP_ASSERT(
"invalid socket state for poll", pcb->state != LISTEN);
2122#if LWIP_CALLBACK_API
2137tcp_pcb_purge(
struct tcp_pcb *pcb)
2141 if (pcb->state != CLOSED &&
2142 pcb->state != TIME_WAIT &&
2143 pcb->state != LISTEN) {
2147 tcp_backlog_accepted(pcb);
2149 if (pcb->refused_data !=
NULL) {
2152 pcb->refused_data =
NULL;
2154 if (pcb->unsent !=
NULL) {
2157 if (pcb->unacked !=
NULL) {
2161 if (pcb->ooseq !=
NULL) {
2163 tcp_free_ooseq(pcb);
2171 tcp_segs_free(pcb->unsent);
2172 tcp_segs_free(pcb->unacked);
2173 pcb->unacked = pcb->unsent =
NULL;
2175 pcb->unsent_oversize = 0;
2187tcp_pcb_remove(
struct tcp_pcb **pcblist,
struct tcp_pcb *pcb)
2192 TCP_RMV(pcblist, pcb);
2197 if ((pcb->state != TIME_WAIT) &&
2198 (pcb->state != LISTEN) &&
2199 (pcb->flags & TF_ACK_DELAY)) {
2204 if (pcb->state != LISTEN) {
2212 pcb->state = CLOSED;
2214 pcb->local_port = 0;
2216 LWIP_ASSERT(
"tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
2225tcp_next_iss(
struct tcp_pcb *pcb)
2227#ifdef LWIP_HOOK_TCP_ISN
2229 return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port);
2231 static u32_t iss = 6510;
2241#if TCP_CALCULATE_EFF_SEND_MSS
2271 if (outif ==
NULL) {
2301 sendmss =
LWIP_MIN(sendmss, mss_s);
2309tcp_netif_ip_addr_changed_pcblist(
const ip_addr_t *old_addr,
struct tcp_pcb *pcb_list)
2311 struct tcp_pcb *pcb;
2314 LWIP_ASSERT(
"tcp_netif_ip_addr_changed_pcblist: invalid old_addr", old_addr !=
NULL);
2316 while (pcb !=
NULL) {
2321 && (!
IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip)))
2325 struct tcp_pcb *
next = pcb->next;
2343 struct tcp_pcb_listen *lpcb;
2346 tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs);
2347 tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs);
2351 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb !=
NULL; lpcb = lpcb->
next) {
2364tcp_debug_state_str(
enum tcp_state
s)
2375 *
addr = pcb->local_ip;
2378 *
port = pcb->local_port;
2382 *
addr = pcb->remote_ip;
2385 *
port = pcb->remote_port;
2396tcp_free_ooseq(
struct tcp_pcb *pcb)
2399 tcp_segs_free(pcb->ooseq);
2401#if LWIP_TCP_SACK_OUT
2402 memset(pcb->rcv_sacks, 0,
sizeof(pcb->rcv_sacks));
2408#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
2451tcp_debug_print_state(
enum tcp_state
s)
2495tcp_debug_print_pcbs(
void)
2497 struct tcp_pcb *pcb;
2498 struct tcp_pcb_listen *pcbl;
2501 for (pcb = tcp_active_pcbs; pcb !=
NULL; pcb = pcb->
next) {
2503 pcb->local_port, pcb->remote_port,
2504 pcb->snd_nxt, pcb->rcv_nxt));
2505 tcp_debug_print_state(pcb->state);
2509 for (pcbl = tcp_listen_pcbs.listen_pcbs; pcbl !=
NULL; pcbl = pcbl->
next) {
2511 tcp_debug_print_state(pcbl->state);
2515 for (pcb = tcp_tw_pcbs; pcb !=
NULL; pcb = pcb->
next) {
2517 pcb->local_port, pcb->remote_port,
2518 pcb->snd_nxt, pcb->rcv_nxt));
2519 tcp_debug_print_state(pcb->state);
2529 struct tcp_pcb *pcb;
2530 for (pcb = tcp_active_pcbs; pcb !=
NULL; pcb = pcb->
next) {
2531 LWIP_ASSERT(
"tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
2532 LWIP_ASSERT(
"tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
2533 LWIP_ASSERT(
"tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
2535 for (pcb = tcp_tw_pcbs; pcb !=
NULL; pcb = pcb->
next) {
2536 LWIP_ASSERT(
"tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
2542#if LWIP_TCP_PCB_NUM_EXT_ARGS
2560static u8_t tcp_ext_arg_id;
2581tcp_ext_arg_alloc_id(
void)
2588#if LWIP_TCP_PCB_NUM_EXT_ARGS >= 255
2589#error LWIP_TCP_PCB_NUM_EXT_ARGS
2604tcp_ext_arg_set_callbacks(
struct tcp_pcb *pcb,
u8_t id,
const struct tcp_ext_arg_callbacks *
const callbacks)
2623void tcp_ext_arg_set(
struct tcp_pcb *pcb,
u8_t id,
void *
arg)
2630 pcb->ext_args[
id].data =
arg;
2641void *tcp_ext_arg_get(
const struct tcp_pcb *pcb,
u8_t id)
2648 return pcb->ext_args[
id].data;
2655tcp_ext_arg_invoke_callbacks_destroyed(
struct tcp_pcb_ext_args *ext_args)
2663 ext_args[
i].callbacks->destroy((
u8_t)
i, ext_args[
i].
data);
2676tcp_ext_arg_invoke_callbacks_passive_open(
struct tcp_pcb_listen *lpcb,
struct tcp_pcb *cpcb)
2683 if (lpcb->ext_args[
i].callbacks !=
NULL) {
2684 if (lpcb->ext_args[
i].callbacks->passive_open !=
NULL) {
2685 err_t err = lpcb->ext_args[
i].callbacks->passive_open((
u8_t)
i, lpcb, cpcb);
STREAM tcp_recv(STREAM s, uint32 length)
RD_BOOL tcp_connect(char *server)
STREAM tcp_init(uint32 maxlen)
static int next_slot(PBTRFS_INFO BtrFsInfo, struct btrfs_disk_key *key, struct btrfs_path *path)
#define LWIP_ARRAYSIZE(x)
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
static const char *const tcp_state_str[]
#define LWIP_DEBUGF(debug, message)
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
#define ip_get_option(pcb, opt)
#define pcb_tci_init(pcb)
GLuint GLuint GLsizei GLenum type
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLenum const GLvoid * addr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
#define LWIP_ASSERT_CORE_LOCKED()
#define SMEMCPY(dst, src, len)
#define LWIP_TCP_PCB_NUM_EXT_ARGS
#define TCP_WND_UPDATE_THRESHOLD
#define LWIP_TCP_RTO_TIME
struct netif * netif_get_by_index(u8_t idx)
void pbuf_ref(struct pbuf *p)
void pbuf_cat(struct pbuf *h, struct pbuf *t)
u8_t pbuf_free(struct pbuf *p)
#define IP_IS_V6_VAL(ipaddr)
#define ip_addr_isany(ipaddr)
#define ip_addr_set(dest, src)
#define ip_addr_eq(addr1, addr2)
#define ip_addr_copy(dest, src)
#define IP_GET_TYPE(ipaddr)
#define IP_SET_TYPE_VAL(ipaddr, iptype)
#define IP_IS_V4_VAL(ipaddr)
#define ip_addr_debug_print_val(debug, ipaddr)
#define TCPH_HDRLEN(phdr)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
#define memcpy(s1, s2, n)
#define netif_get_index(netif)
#define PBUF_FLAG_TCP_FIN
static unsigned __int64 next
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
#define MIB2_STATS_INC(x)
#define MEMP_STATS_DEC(x, i)
void tcp_close(struct sock *sk, long timeout)
struct sock * tcp_accept(struct sock *sk, int flags, int *err)
void tcp_shutdown(struct sock *sk, int how)
void tcp_send_fin(struct sock *sk)
unsigned int tcp_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait)