Lines Matching defs:pcb

133 #define TCP_KEEP_DUR(pcb)   ((pcb)->keep_cnt * (pcb)->keep_intvl)
134 #define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
136 #define TCP_KEEP_DUR(pcb) TCP_MAXIDLE
137 #define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
195 static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb);
201 void set_tcp_pcb_net_group(struct tcp_pcb *pcb, struct net_group *group)
203 set_ippcb_net_group((struct ip_pcb *)pcb, group);
206 struct net_group *get_net_group_from_tcp_pcb(const struct tcp_pcb *pcb)
208 return get_net_group_from_ippcb((struct ip_pcb *)pcb);
222 /** Free a tcp pcb */
224 tcp_free(struct tcp_pcb *pcb)
226 LWIP_ASSERT("tcp_free: LISTEN", pcb->state != LISTEN);
228 tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args);
230 memp_free(MEMP_TCP_PCB, pcb);
233 /** Free a tcp listen pcb */
235 tcp_free_listen(struct tcp_pcb *pcb)
237 LWIP_ASSERT("tcp_free_listen: !LISTEN", pcb->state != LISTEN);
239 tcp_ext_arg_invoke_callbacks_destroyed(pcb->ext_args);
241 memp_free(MEMP_TCP_PCB_LISTEN, pcb);
264 tcp_set_timer_tick_by_persist(struct tcp_pcb *pcb, u32_t tick)
268 if (pcb->persist_backoff > 0) {
269 u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff - 1];
275 if (pcb->rtime >= 0) {
276 val = pcb->rto - pcb->rtime;
286 tcp_set_timer_tick_by_keepalive(struct tcp_pcb *pcb, u32_t tick)
290 if (ip_get_option(pcb, SOF_KEEPALIVE) &&
291 ((pcb->state == ESTABLISHED) ||
292 (pcb->state == CLOSE_WAIT))) {
293 u32_t idle = (pcb->keep_idle) / TCP_SLOW_INTERVAL;
294 if (pcb->keep_cnt_sent == 0) {
295 val = idle - (tcp_ticks - pcb->tmr);
297 val = (tcp_ticks - pcb->tmr) - idle;
298 idle = (TCP_KEEP_INTVL(pcb) / TCP_SLOW_INTERVAL);
309 static u32_t tcp_set_timer_tick_by_tcp_state(struct tcp_pcb *pcb, u32_t tick)
314 if (pcb->state == FIN_WAIT_2) {
316 if (pcb->flags & TF_RXCLOSED) {
323 if (pcb->state == SYN_RCVD) {
329 if (pcb->state == LAST_ACK) {
344 struct tcp_pcb *pcb = NULL;
347 pcb = tcp_active_pcbs;
348 while (pcb != NULL) {
349 if (((pcb->state == SYN_SENT) && (pcb->nrtx >= TCP_SYNMAXRTX)) ||
350 ((pcb->state == FIN_WAIT_1) || (pcb->state == CLOSING)) ||
351 (pcb->nrtx >= TCP_MAXRTX)) {
355 tick = tcp_set_timer_tick_by_persist(pcb, tick);
356 tick = tcp_set_timer_tick_by_keepalive(pcb, tick);
364 if (pcb->ooseq != NULL) {
369 tick = tcp_set_timer_tick_by_tcp_state(pcb, tick);
371 u8_t ret = poll_tcp_needed(pcb->callback_arg, pcb);
372 if ((pcb->poll != NULL) && (ret != 0)) {
375 pcb = pcb->next;
385 struct tcp_pcb *pcb = NULL;
387 pcb = tcp_active_pcbs;
388 while (pcb != NULL) {
390 if ((pcb->flags & TF_ACK_DELAY) ||
391 (pcb->flags & TF_CLOSEPEND) ||
392 (pcb->refused_data != NULL)
397 pcb = pcb->next;
405 /** Called when a listen pcb is closed. Iterates one pcb list and removes the
406 * closed listener pcb from pcb->listener if matching.
411 struct tcp_pcb *pcb;
415 for (pcb = list; pcb != NULL; pcb = pcb->next) {
416 if (pcb->listener == lpcb) {
417 pcb->listener = NULL;
423 /** Called when a listen pcb is closed. Iterates all pcb lists and removes the
424 * closed listener pcb from pcb->listener if matching.
427 tcp_listen_closed(struct tcp_pcb *pcb)
431 LWIP_ASSERT("pcb != NULL", pcb != NULL);
432 LWIP_ASSERT("pcb->state == LISTEN", pcb->state == LISTEN);
434 tcp_remove_listener(*tcp_pcb_lists[i], (struct tcp_pcb_listen *)pcb);
437 LWIP_UNUSED_ARG(pcb);
449 * @param pcb the connection pcb which is not fully accepted yet
452 tcp_backlog_delayed(struct tcp_pcb *pcb)
454 LWIP_ASSERT("pcb != NULL", pcb != NULL);
456 if ((pcb->flags & TF_BACKLOGPEND) == 0) {
457 if (pcb->listener != NULL) {
458 pcb->listener->accepts_pending++;
459 LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
460 tcp_set_flags(pcb, TF_BACKLOGPEND);
472 * @param pcb the connection pcb which is now fully accepted (or closed/aborted)
475 tcp_backlog_accepted(struct tcp_pcb *pcb)
477 LWIP_ASSERT("pcb != NULL", pcb != NULL);
479 if ((pcb->flags & TF_BACKLOGPEND) != 0) {
480 if (pcb->listener != NULL) {
481 LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0);
482 pcb->listener->accepts_pending--;
483 tcp_clear_flags(pcb, TF_BACKLOGPEND);
498 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
501 * @param pcb the tcp_pcb to close
503 * another err_t if closing failed and pcb is not freed
506 tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
508 LWIP_ASSERT("tcp_close_shutdown: invalid pcb", pcb != NULL);
510 if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
511 if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) {
514 LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
516 /* don't call tcp_abort here: we must not deallocate the pcb since
518 tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
519 pcb->local_port, pcb->remote_port);
521 tcp_pcb_purge(pcb);
522 TCP_RMV_ACTIVE(pcb);
523 /* Deallocate the pcb since we already sent a RST for it */
524 if (tcp_input_pcb == pcb) {
525 /* prevent using a deallocated pcb: free it from tcp_input later */
528 tcp_free(pcb);
534 /* - states which free the pcb are handled here,
536 switch (pcb->state) {
538 /* Closing a pcb in the CLOSED state might seem erroneous,
541 * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
542 * or for a pcb that has been used and then entered the CLOSED state
543 * is erroneous, but this should never happen as the pcb has in those cases
545 if (pcb->local_port != 0) {
546 TCP_RMV(&tcp_bound_pcbs, pcb);
548 tcp_free(pcb);
551 tcp_listen_closed(pcb);
552 tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
553 tcp_free_listen(pcb);
556 TCP_PCB_REMOVE_ACTIVE(pcb);
557 tcp_free(pcb);
561 return tcp_close_shutdown_fin(pcb);
567 tcp_close_shutdown_fin(struct tcp_pcb *pcb)
570 LWIP_ASSERT("pcb != NULL", pcb != NULL);
572 switch (pcb->state) {
574 err = tcp_send_fin(pcb);
576 tcp_backlog_accepted(pcb);
578 pcb->state = FIN_WAIT_1;
582 err = tcp_send_fin(pcb);
585 pcb->state = FIN_WAIT_1;
589 err = tcp_send_fin(pcb);
592 pcb->state = LAST_ACK;
606 tcp_output(pcb);
608 /* Mark this pcb for closing. Closing is retried from tcp_tmr. */
609 tcp_set_flags(pcb, TF_CLOSEPEND);
611 pcb should not be used any more as it will be freed soon via tcp_tmr.
613 actually freeing the pcb, either (it is left in closure states for
628 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
637 * @param pcb the tcp_pcb to close
639 * another err_t if closing failed and pcb is not freed
642 tcp_close(struct tcp_pcb *pcb)
646 LWIP_ERROR("tcp_close: invalid pcb", pcb != NULL, return ERR_ARG);
649 tcp_debug_print_state(pcb->state);
651 if (pcb->state != LISTEN) {
653 tcp_set_flags(pcb, TF_RXCLOSED);
656 return tcp_close_shutdown(pcb, 1);
666 * @param pcb PCB to shutdown
673 tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
677 LWIP_ERROR("tcp_shutdown: invalid pcb", pcb != NULL, return ERR_ARG);
679 if (pcb->state == LISTEN) {
684 tcp_set_flags(pcb, TF_RXCLOSED);
687 return tcp_close_shutdown(pcb, 1);
690 if (pcb->refused_data != NULL) {
691 pbuf_free(pcb->refused_data);
692 pcb->refused_data = NULL;
696 /* This can't happen twice since if it succeeds, the pcb's state is changed.
698 switch (pcb->state) {
702 return tcp_close_shutdown(pcb, (u8_t)shut_rx);
717 * @param pcb the tcp_pcb to abort
721 tcp_abandon(struct tcp_pcb *pcb, int reset)
731 LWIP_ERROR("tcp_abandon: invalid pcb", pcb != NULL, return);
733 /* pcb->state LISTEN not allowed here */
735 pcb->state != LISTEN);
739 if (pcb->state == TIME_WAIT) {
740 tcp_pcb_remove(&tcp_tw_pcbs, pcb);
741 tcp_free(pcb);
746 seqno = pcb->snd_nxt;
747 ackno = pcb->rcv_nxt;
749 errf = pcb->errf;
751 errf_arg = pcb->callback_arg;
752 if (pcb->state == CLOSED) {
753 if (pcb->local_port != 0) {
755 TCP_RMV(&tcp_bound_pcbs, pcb);
759 local_port = pcb->local_port;
760 TCP_PCB_REMOVE_ACTIVE(pcb);
762 if (pcb->unacked != NULL) {
763 tcp_segs_free(pcb->unacked);
765 if (pcb->unsent != NULL) {
766 tcp_segs_free(pcb->unsent);
769 if (pcb->ooseq != NULL) {
770 tcp_segs_free(pcb->ooseq);
773 tcp_backlog_accepted(pcb);
776 tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
778 last_state = pcb->state;
779 tcp_free(pcb);
787 * host. The pcb is deallocated. This function never fails.
793 * @param pcb the tcp pcb to abort
796 tcp_abort(struct tcp_pcb *pcb)
798 tcp_abandon(pcb, 1);
810 * @param pcb the tcp_pcb to bind (no check is done whether this pcb is
820 tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
840 LWIP_ERROR("tcp_bind: invalid pcb", pcb != NULL, return ERR_ARG);
842 LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
847 We do not dump TIME_WAIT pcb's; they can still be matched by incoming
850 if (ip_get_option(pcb, SOF_REUSEADDR)) {
877 if (cpcb->local_port == port && (get_net_group_from_tcp_pcb(pcb) == get_net_group_from_tcp_pcb(cpcb))) {
885 if (!ip_get_option(pcb, SOF_REUSEADDR) ||
904 || (IP_GET_TYPE(ipaddr) != IP_GET_TYPE(&pcb->local_ip))
907 ip_addr_set(&pcb->local_ip, ipaddr);
909 pcb->local_port = port;
910 TCP_REG(&tcp_bound_pcbs, pcb);
922 * @param pcb the tcp_pcb to bind.
926 tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif)
930 pcb->netif_idx = netif_get_index(netif);
932 pcb->netif_idx = NETIF_NO_INDEX;
941 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
946 LWIP_ASSERT("tcp_accept_null: invalid pcb", pcb != NULL);
948 tcp_abort(pcb);
961 * the tcp_accept() function will be called. The pcb has to be bound
972 * listening connection. If so, the memory associated with the pcb
979 * @param pcb the original tcp_pcb
988 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
991 return tcp_listen_with_backlog_and_err(pcb, backlog, NULL);
1001 * @param pcb the original tcp_pcb
1011 tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
1020 LWIP_ERROR("tcp_listen_with_backlog_and_err: invalid pcb", pcb != NULL, res = ERR_ARG; goto done);
1021 LWIP_ERROR("tcp_listen_with_backlog_and_err: pcb already connected", pcb->state == CLOSED, res = ERR_CLSD; goto done);
1024 if (pcb->state == LISTEN) {
1025 lpcb = (struct tcp_pcb_listen *)pcb;
1030 if (ip_get_option(pcb, SOF_REUSEADDR)) {
1031 /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage
1032 is declared (listen-/connection-pcb), we have to make sure now that
1035 if ((lpcb->local_port == pcb->local_port) &&
1036 ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
1051 set_tcp_pcb_net_group((struct tcp_pcb *)lpcb, get_net_group_from_tcp_pcb(pcb));
1053 lpcb->callback_arg = pcb->callback_arg;
1054 lpcb->local_port = pcb->local_port;
1056 lpcb->prio = pcb->prio;
1057 lpcb->so_options = pcb->so_options;
1058 lpcb->netif_idx = pcb->netif_idx;
1059 lpcb->ttl = pcb->ttl;
1060 lpcb->tos = pcb->tos;
1062 IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type);
1064 ip_addr_copy(lpcb->local_ip, pcb->local_ip);
1065 if (pcb->local_port != 0) {
1066 TCP_RMV(&tcp_bound_pcbs, pcb);
1069 /* copy over ext_args to listening pcb */
1070 memcpy(&lpcb->ext_args, &pcb->ext_args, sizeof(pcb->ext_args));
1072 tcp_free(pcb);
1096 tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
1100 LWIP_ASSERT("tcp_update_rcv_ann_wnd: invalid pcb", pcb != NULL);
1101 new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
1103 if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
1105 pcb->rcv_ann_wnd = pcb->rcv_wnd;
1106 return new_right_edge - pcb->rcv_ann_right_edge;
1108 if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
1111 pcb->rcv_ann_wnd = 0;
1114 u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
1118 pcb->rcv_ann_wnd = (tcpwnd_size_t)new_rcv_ann_wnd;
1130 * @param pcb the tcp_pcb for which data is read
1134 tcp_recved(struct tcp_pcb *pcb, u16_t len)
1141 LWIP_ERROR("tcp_recved: invalid pcb", pcb != NULL, return);
1143 /* pcb->state LISTEN not allowed here */
1145 pcb->state != LISTEN);
1147 rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len);
1148 if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) {
1151 pcb->rcv_wnd = TCP_WND_MAX(pcb);
1153 pcb->rcv_wnd = rcv_wnd;
1156 wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
1163 tcp_ack_now(pcb);
1164 tcp_output(pcb);
1168 len, pcb->rcv_wnd, (u16_t)(TCP_WND_MAX(pcb) - pcb->rcv_wnd)));
1181 struct tcp_pcb *pcb;
1190 for (pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
1191 if (pcb->local_port == tcp_port) {
1207 * Sets up the pcb to connect to the remote host and sends the
1216 * callback function of this pcb (registered with tcp_err, see below)
1223 * @param pcb the tcp_pcb used to establish the connection
1233 tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
1243 LWIP_ERROR("tcp_connect: invalid pcb", pcb != NULL, return ERR_ARG);
1246 LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
1249 struct net_group *group = get_net_group_from_tcp_pcb(pcb);
1253 ip_addr_set(&pcb->remote_ip, ipaddr);
1254 pcb->remote_port = port;
1256 if (pcb->netif_idx != NETIF_NO_INDEX) {
1258 netif = netif_get_by_index(pcb->netif_idx, group);
1260 netif = netif_get_by_index(pcb->netif_idx);
1265 netif = ip_route(&pcb->local_ip, &pcb->remote_ip, group);
1267 netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
1275 /* check if local IP has been assigned to pcb, if not, get one */
1276 if (ip_addr_isany(&pcb->local_ip)) {
1281 ip_addr_copy(pcb->local_ip, *local_ip);
1287 if (IP_IS_V6(&pcb->remote_ip) &&
1288 ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST)) {
1289 ip6_addr_assign_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST, netif);
1293 old_local_port = pcb->local_port;
1294 if (pcb->local_port == 0) {
1295 pcb->local_port = tcp_new_port();
1296 if (pcb->local_port == 0) {
1301 if (ip_get_option(pcb, SOF_REUSEADDR)) {
1309 if ((cpcb->local_port == pcb->local_port) &&
1311 ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
1322 iss = tcp_next_iss(pcb);
1323 pcb->rcv_nxt = 0;
1324 pcb->snd_nxt = iss;
1325 pcb->lastack = iss - 1;
1326 pcb->snd_wl2 = iss - 1;
1327 pcb->snd_lbb = iss - 1;
1330 pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
1331 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
1332 pcb->snd_wnd = TCP_WND;
1335 pcb->mss = INITIAL_MSS;
1337 pcb->mss = tcp_eff_send_mss_netif(pcb->mss, netif, &pcb->remote_ip);
1339 pcb->cwnd = 1;
1341 pcb->connected = connected;
1347 ret = tcp_enqueue_flags(pcb, TCP_SYN);
1350 pcb->state = SYN_SENT;
1352 TCP_RMV(&tcp_bound_pcbs, pcb);
1354 TCP_REG_ACTIVE(pcb);
1357 tcp_output(pcb);
1372 struct tcp_pcb *pcb, *prev;
1386 pcb = tcp_active_pcbs;
1387 if (pcb == NULL) {
1390 while (pcb != NULL) {
1391 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
1392 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
1393 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
1394 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
1395 if (pcb->last_timer == tcp_timer_ctr) {
1396 /* skip this pcb, we have already processed it */
1397 prev = pcb;
1398 pcb = pcb->next;
1401 pcb->last_timer = tcp_timer_ctr;
1406 if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) {
1409 } else if (pcb->nrtx >= TCP_MAXRTX) {
1413 if (pcb->persist_backoff > 0) {
1414 LWIP_ASSERT("tcp_slowtimr: persist ticking with in-flight data", pcb->unacked == NULL);
1415 LWIP_ASSERT("tcp_slowtimr: persist ticking with empty send buffer", pcb->unsent != NULL);
1416 if (pcb->persist_probe >= TCP_MAXRTX) {
1419 u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff - 1];
1420 if (pcb->persist_cnt < backoff_cnt) {
1421 pcb->persist_cnt++;
1423 if (pcb->persist_cnt >= backoff_cnt) {
1426 if (pcb->snd_wnd == 0) {
1427 if (tcp_zero_window_probe(pcb) != ERR_OK) {
1432 if (tcp_split_unsent_seg(pcb, (u16_t)pcb->snd_wnd) == ERR_OK) {
1433 if (tcp_output(pcb) == ERR_OK) {
1440 pcb->persist_cnt = 0;
1441 if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
1442 pcb->persist_backoff++;
1449 if ((pcb->rtime >= 0) && (pcb->rtime < 0x7FFF)) {
1450 ++pcb->rtime;
1453 if (pcb->rtime >= pcb->rto) {
1456 " pcb->rto %"S16_F"\n",
1457 pcb->rtime, pcb->rto));
1461 if ((tcp_rexmit_rto_prepare(pcb) == ERR_OK) || ((pcb->unacked == NULL) && (pcb->unsent != NULL))) {
1464 if (pcb->state != SYN_SENT) {
1465 u8_t backoff_idx = LWIP_MIN(pcb->nrtx, sizeof(tcp_backoff) - 1);
1466 int calc_rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx];
1467 pcb->rto = (s16_t)LWIP_MIN(calc_rto, 0x7FFF);
1471 pcb->rtime = 0;
1474 eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
1475 pcb->ssthresh = eff_wnd >> 1;
1476 if (pcb->ssthresh < (tcpwnd_size_t)(pcb->mss << 1)) {
1477 pcb->ssthresh = (tcpwnd_size_t)(pcb->mss << 1);
1479 pcb->cwnd = pcb->mss;
1482 pcb->cwnd, pcb->ssthresh));
1483 pcb->bytes_acked = 0;
1487 tcp_rexmit_rto_commit(pcb);
1493 if (pcb->state == FIN_WAIT_2) {
1495 if (pcb->flags & TF_RXCLOSED) {
1498 if ((u32_t)(tcp_ticks - pcb->tmr) >
1501 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
1507 if (ip_get_option(pcb, SOF_KEEPALIVE) &&
1508 ((pcb->state == ESTABLISHED) ||
1509 (pcb->state == CLOSE_WAIT))) {
1510 if ((u32_t)(tcp_ticks - pcb->tmr) >
1511 (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) {
1513 ip_addr_debug_print_val(TCP_DEBUG, pcb->remote_ip);
1518 } else if ((u32_t)(tcp_ticks - pcb->tmr) >
1519 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
1521 err = tcp_keepalive(pcb);
1523 pcb->keep_cnt_sent++;
1532 if (pcb->ooseq != NULL &&
1533 (tcp_ticks - pcb->tmr >= (u32_t)pcb->rto * TCP_OOSEQ_TIMEOUT)) {
1535 tcp_free_ooseq(pcb);
1540 if (pcb->state == SYN_RCVD) {
1541 if ((u32_t)(tcp_ticks - pcb->tmr) >
1544 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
1549 if (pcb->state == LAST_ACK) {
1550 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
1552 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
1560 tcp_err_fn err_fn = pcb->errf;
1564 tcp_pcb_purge(pcb);
1567 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
1568 prev->next = pcb->next;
1571 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
1572 tcp_active_pcbs = pcb->next;
1576 tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
1577 pcb->local_port, pcb->remote_port);
1580 err_arg = pcb->callback_arg;
1581 last_state = pcb->state;
1582 pcb2 = pcb;
1583 pcb = pcb->next;
1593 prev = pcb;
1594 pcb = pcb->next;
1617 pcb = tcp_tw_pcbs;
1618 while (pcb != NULL) {
1619 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
1623 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
1630 tcp_pcb_purge(pcb);
1633 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
1634 prev->next = pcb->next;
1637 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
1638 tcp_tw_pcbs = pcb->next;
1640 pcb2 = pcb;
1641 pcb = pcb->next;
1644 prev = pcb;
1645 pcb = pcb->next;
1659 struct tcp_pcb *pcb;
1664 pcb = tcp_active_pcbs;
1666 while (pcb != NULL) {
1667 if (pcb->last_timer != tcp_timer_ctr) {
1669 pcb->last_timer = tcp_timer_ctr;
1671 if (pcb->flags & TF_ACK_DELAY) {
1673 tcp_ack_now(pcb);
1674 tcp_output(pcb);
1675 tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
1678 if (pcb->flags & TF_CLOSEPEND) {
1680 tcp_clear_flags(pcb, TF_CLOSEPEND);
1681 tcp_close_shutdown_fin(pcb);
1684 next = pcb->next;
1687 if (pcb->refused_data != NULL) {
1689 tcp_process_refused_data(pcb);
1691 /* application callback has changed the pcb list: restart the loop */
1695 pcb = next;
1697 pcb = pcb->next;
1706 struct tcp_pcb *pcb;
1708 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1709 if (pcb->flags & TF_NAGLEMEMERR) {
1710 tcp_output(pcb);
1715 /** Pass pcb->refused_data to the recv callback */
1717 tcp_process_refused_data(struct tcp_pcb *pcb)
1723 LWIP_ERROR("tcp_process_refused_data: invalid pcb", pcb != NULL, return ERR_ARG);
1726 while (pcb->refused_data != NULL)
1730 u8_t refused_flags = pcb->refused_data->flags;
1731 /* set pcb->refused_data to NULL in case the callback frees it and then
1732 closes the pcb */
1733 struct pbuf *refused_data = pcb->refused_data;
1736 pcb->refused_data = rest;
1738 pcb->refused_data = NULL;
1742 TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
1752 if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
1753 pcb->rcv_wnd++;
1755 TCP_EVENT_CLOSED(pcb, err);
1761 /* if err == ERR_ABRT, 'pcb' is already deallocated */
1762 /* Drop incoming packets because pcb is "full" (only if the incoming
1764 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
1773 pcb->refused_data = refused_data;
1818 * @param pcb the tcp_pcb to manipulate
1822 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
1826 LWIP_ERROR("tcp_setprio: invalid pcb", pcb != NULL, return);
1828 pcb->prio = prio;
1859 * a recv callback for the pcb.
1862 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
1866 LWIP_ERROR("tcp_recv_null: invalid pcb", pcb != NULL, return ERR_ARG);
1869 tcp_recved(pcb, p->tot_len);
1872 return tcp_close(pcb);
1886 struct tcp_pcb *pcb, *inactive;
1908 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1910 if ((pcb->prio < mprio) ||
1912 ((pcb->prio == mprio) && ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity))) {
1913 inactivity = tcp_ticks - pcb->tmr;
1914 inactive = pcb;
1915 mprio = pcb->prio;
1932 struct tcp_pcb *pcb, *inactive;
1939 /* Go through the list of active pcbs and get the oldest pcb that is in state
1941 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
1942 if (pcb->state == state) {
1943 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
1944 inactivity = tcp_ticks - pcb->tmr;
1945 inactive = pcb;
1964 struct tcp_pcb *pcb, *inactive;
1969 /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */
1970 for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
1971 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
1972 inactivity = tcp_ticks - pcb->tmr;
1973 inactive = pcb;
1983 /* Called when allocating a pcb fails.
1985 * now send the FIN (which failed before), the pcb might be in a state that is
1991 struct tcp_pcb *pcb = tcp_active_pcbs;
1993 while (pcb != NULL) {
1994 struct tcp_pcb *next = pcb->next;
1996 if (pcb->flags & TF_CLOSEPEND) {
1998 tcp_clear_flags(pcb, TF_CLOSEPEND);
1999 tcp_close_shutdown_fin(pcb);
2001 pcb = next;
2008 * @param prio priority for the new pcb
2014 struct tcp_pcb *pcb;
2018 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
2019 if (pcb == NULL) {
2027 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
2028 if (pcb == NULL) {
2033 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
2034 if (pcb == NULL) {
2039 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
2040 if (pcb == NULL) {
2045 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
2046 if (pcb != NULL) {
2051 if (pcb != NULL) {
2056 if (pcb != NULL) {
2061 if (pcb != NULL) {
2066 if (pcb != NULL) {
2067 /* zero out the whole pcb, so there is no need to initialize members to zero */
2068 memset(pcb, 0, sizeof(struct tcp_pcb));
2069 pcb->prio = prio;
2070 pcb->snd_buf = TCP_SND_BUF;
2073 pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
2074 pcb->ttl = TCP_TTL;
2077 pcb->mss = INITIAL_MSS;
2078 pcb->rto = 3000 / TCP_SLOW_INTERVAL;
2079 pcb->sv = 3000 / TCP_SLOW_INTERVAL;
2080 pcb->rtime = -1;
2081 pcb->cwnd = 1;
2082 pcb->tmr = tcp_ticks;
2083 pcb->last_timer = tcp_timer_ctr;
2091 pcb->ssthresh = TCP_SND_BUF;
2094 pcb->recv = tcp_recv_null;
2098 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT;
2101 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
2102 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT;
2105 return pcb;
2112 * The pcb is not put on any list until binding using tcp_bind().
2113 * If memory is not available for creating the new pcb, NULL is returned.
2119 * to allocate a pcb with higher prio (@see tcp_kill_prio())
2133 * The pcb is not put on any list until binding using tcp_bind().
2144 struct tcp_pcb *pcb;
2145 pcb = tcp_alloc(TCP_PRIO_NORMAL);
2147 if (pcb != NULL) {
2148 IP_SET_TYPE_VAL(pcb->local_ip, type);
2149 IP_SET_TYPE_VAL(pcb->remote_ip, type);
2154 return pcb;
2160 * other callback functions. The "pcb" argument is the current TCP
2164 * @param pcb tcp_pcb to set the callback argument
2168 tcp_arg(struct tcp_pcb *pcb, void *arg)
2173 if (pcb != NULL) {
2174 pcb->callback_arg = arg;
2187 * @param pcb tcp_pcb to set the recv callback
2188 * @param recv callback function to call for this pcb when data is received
2191 tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
2194 if (pcb != NULL) {
2195 LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
2196 pcb->recv = recv;
2207 * @param pcb tcp_pcb to set the sent callback
2208 * @param sent callback function to call for this pcb when data is successfully sent
2211 tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
2214 if (pcb != NULL) {
2215 LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
2216 pcb->sent = sent;
2230 * @note The corresponding pcb is already freed when this callback is called!
2232 * @param pcb tcp_pcb to set the err callback
2233 * @param err callback function to call for this pcb when a fatal error
2237 tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
2240 if (pcb != NULL) {
2241 LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
2242 pcb->errf = err;
2252 * @param pcb tcp_pcb to set the accept callback
2253 * @param accept callback function to call for this pcb when LISTENing
2257 tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
2260 if ((pcb != NULL) && (pcb->state == LISTEN)) {
2261 struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen *)pcb;
2286 tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
2290 LWIP_ERROR("tcp_poll: invalid pcb", pcb != NULL, return);
2291 LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN);
2294 pcb->poll = poll;
2298 pcb->pollinterval = interval;
2303 * (pcb->ooseq, pcb->unsent and pcb->unacked are freed).
2305 * @param pcb tcp_pcb to purge. The pcb itself is not deallocated!
2308 tcp_pcb_purge(struct tcp_pcb *pcb)
2310 LWIP_ERROR("tcp_pcb_purge: invalid pcb", pcb != NULL, return);
2312 if (pcb->state != CLOSED &&
2313 pcb->state != TIME_WAIT &&
2314 pcb->state != LISTEN) {
2318 tcp_backlog_accepted(pcb);
2320 if (pcb->refused_data != NULL) {
2322 pbuf_free(pcb->refused_data);
2323 pcb->refused_data = NULL;
2325 if (pcb->unsent != NULL) {
2328 if (pcb->unacked != NULL) {
2332 if (pcb->ooseq != NULL) {
2334 tcp_free_ooseq(pcb);
2340 pcb->rtime = -1;
2342 tcp_segs_free(pcb->unsent);
2343 tcp_segs_free(pcb->unacked);
2344 pcb->unacked = pcb->unsent = NULL;
2346 pcb->unsent_oversize = 0;
2355 * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
2358 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
2360 LWIP_ASSERT("tcp_pcb_remove: invalid pcb", pcb != NULL);
2363 TCP_RMV(pcblist, pcb);
2365 tcp_pcb_purge(pcb);
2368 if ((pcb->state != TIME_WAIT) &&
2369 (pcb->state != LISTEN) &&
2370 (pcb->flags & TF_ACK_DELAY)) {
2371 tcp_ack_now(pcb);
2372 tcp_output(pcb);
2375 if (pcb->state != LISTEN) {
2376 LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
2377 LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
2379 LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
2383 pcb->state = CLOSED;
2384 /* reset the local port to prevent the pcb from being 'bound' */
2385 pcb->local_port = 0;
2396 tcp_next_iss(struct tcp_pcb *pcb)
2399 LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL);
2400 return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port);
2404 LWIP_ASSERT("tcp_next_iss: invalid pcb", pcb != NULL);
2405 LWIP_UNUSED_ARG(pcb);
2478 /** Helper function for tcp_netif_ip_addr_changed() that iterates a pcb list */
2482 struct tcp_pcb *pcb;
2483 pcb = pcb_list;
2487 while (pcb != NULL) {
2489 if (ip_addr_cmp(&pcb->local_ip, old_addr)
2492 && (!IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip)))
2496 struct tcp_pcb *next = pcb->next;
2497 LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
2498 tcp_abort(pcb);
2499 pcb = next;
2501 pcb = pcb->next;
2541 tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port)
2543 if (pcb) {
2546 *addr = pcb->local_ip;
2549 *port = pcb->local_port;
2553 *addr = pcb->remote_ip;
2556 *port = pcb->remote_port;
2567 tcp_free_ooseq(struct tcp_pcb *pcb)
2569 if (pcb->ooseq) {
2570 tcp_segs_free(pcb->ooseq);
2571 pcb->ooseq = NULL;
2573 memset(pcb->rcv_sacks, 0, sizeof(pcb->rcv_sacks));
2668 struct tcp_pcb *pcb;
2672 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
2674 pcb->local_port, pcb->remote_port,
2675 pcb->snd_nxt, pcb->rcv_nxt));
2676 tcp_debug_print_state(pcb->state);
2686 for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
2688 pcb->local_port, pcb->remote_port,
2689 pcb->snd_nxt, pcb->rcv_nxt));
2690 tcp_debug_print_state(pcb->state);
2700 struct tcp_pcb *pcb;
2701 for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
2702 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
2703 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
2704 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
2706 for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
2707 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
2717 * Additional data storage per tcp pcb\n
2720 * When LWIP_TCP_PCB_NUM_EXT_ARGS is > 0, every tcp pcb (including listen pcb)
2725 * deallocate memory when a pcb is deallocated (see struct @ref tcp_ext_arg_callbacks).
2728 * to store and load arguments from this index for a given pcb.
2739 * When @ref LWIP_TCP_PCB_NUM_EXT_ARGS is > 0, every tcp pcb (including listen pcb)
2744 * deallocate memory when a pcb is deallocated (see struct @ref tcp_ext_arg_callbacks).
2747 * to store and load arguments from this index for a given pcb.
2768 * Set callbacks for a given index of ext_args on the specified pcb.
2770 * @param pcb tcp_pcb for which to set the callback
2775 tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks)
2777 LWIP_ASSERT("pcb != NULL", pcb != NULL);
2783 pcb->ext_args[id].callbacks = callbacks;
2788 * Set data for a given index of ext_args on the specified pcb.
2790 * @param pcb tcp_pcb for which to set the data
2794 void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg)
2796 LWIP_ASSERT("pcb != NULL", pcb != NULL);
2801 pcb->ext_args[id].data = arg;
2806 * Set data for a given index of ext_args on the specified pcb.
2808 * @param pcb tcp_pcb for which to set the data
2812 void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id)
2814 LWIP_ASSERT("pcb != NULL", pcb != NULL);
2819 return pcb->ext_args[id].data;
2822 /** This function calls the "destroy" callback for all ext_args once a pcb is
2844 * pcb has not been called yet!