Lines Matching refs:pcb

75 static err_t tcp_process(struct tcp_pcb *pcb);
76 static void tcp_receive(struct tcp_pcb *pcb);
77 static void tcp_parseopt(struct tcp_pcb *pcb);
79 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
80 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
94 struct tcp_pcb *pcb, *prev;
170 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
171 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
172 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
173 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
174 if (pcb->remote_port == tcphdr->src &&
175 pcb->local_port == tcphdr->dest &&
176 ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
177 ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
182 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
184 prev->next = pcb->next;
185 pcb->next = tcp_active_pcbs;
186 tcp_active_pcbs = pcb;
188 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
191 prev = pcb;
194 if (pcb == NULL) {
197 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
198 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
199 if (pcb->remote_port == tcphdr->src &&
200 pcb->local_port == tcphdr->dest &&
201 ip_addr_cmp(&(pcb->remote_ip), &current_iphdr_src) &&
202 ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest)) {
207 tcp_timewait_input(pcb);
253 /* put this listening pcb at the head of the listening list */
271 if (pcb != NULL) {
275 tcp_debug_print_state(pcb->state);
293 if (pcb->refused_data != NULL) {
294 if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
295 ((pcb->refused_data != NULL) && (tcplen > 0))) {
296 /* pcb has been aborted or refused data is still refused and the new
303 tcp_input_pcb = pcb;
304 err = tcp_process(pcb);
306 and that the pcb has been freed. If so, we don't do anything. */
313 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
314 tcp_pcb_remove(&tcp_active_pcbs, pcb);
315 memp_free(MEMP_TCP_PCB, pcb);
319 if (!(pcb->flags & TF_RXCLOSED)) {
323 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
325 tcp_pcb_remove(&tcp_active_pcbs, pcb);
326 memp_free(MEMP_TCP_PCB, pcb);
332 if (pcb->acked > 0) {
333 TCP_EVENT_SENT(pcb, pcb->acked, err);
340 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
341 if (pcb->flags & TF_RXCLOSED) {
345 tcp_abort(pcb);
350 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
357 pcb->refused_data = recv_data;
358 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
365 if (pcb->refused_data != NULL) {
367 pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
371 if (pcb->rcv_wnd != TCP_WND) {
372 pcb->rcv_wnd++;
374 TCP_EVENT_CLOSED(pcb, err);
383 tcp_output(pcb);
386 tcp_debug_print_state(pcb->state);
391 /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()).
392 Below this line, 'pcb' may not be dereferenced! */
431 * @param pcb the tcp_pcb_listen for which a segment arrived
436 * @note the segment which arrived is saved in global variables, therefore only the pcb
440 tcp_listen_input(struct tcp_pcb_listen *pcb)
461 if (pcb->accepts_pending >= pcb->backlog) {
466 npcb = tcp_alloc(pcb->prio);
476 pcb->accepts_pending++;
480 npcb->local_port = pcb->local_port;
490 npcb->callback_arg = pcb->callback_arg;
492 npcb->accept = pcb->accept;
495 npcb->so_options = pcb->so_options & SOF_INHERITED;
523 * @param pcb the tcp_pcb for which a segment arrived
525 * @note the segment which arrived is saved in global variables, therefore only the pcb
529 tcp_timewait_input(struct tcp_pcb *pcb)
543 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
552 pcb->tmr = tcp_ticks;
557 pcb->flags |= TF_ACK_NOW;
558 return tcp_output(pcb);
567 * recv_data pointer in the pcb is set.
569 * @param pcb the tcp_pcb for which a segment arrived
571 * @note the segment which arrived is saved in global variables, therefore only the pcb
575 tcp_process(struct tcp_pcb *pcb)
586 if (pcb->state == SYN_SENT) {
587 if (ackno == pcb->snd_nxt) {
591 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
592 pcb->rcv_nxt+pcb->rcv_wnd)) {
599 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
601 pcb->flags &= ~TF_ACK_DELAY;
605 seqno, pcb->rcv_nxt));
607 seqno, pcb->rcv_nxt));
612 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
614 tcp_ack_now(pcb);
618 if ((pcb->flags & TF_RXCLOSED) == 0) {
620 pcb->tmr = tcp_ticks;
622 pcb->keep_cnt_sent = 0;
624 tcp_parseopt(pcb);
627 switch (pcb->state) {
629 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
630 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
633 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
634 pcb->snd_buf++;
635 pcb->rcv_nxt = seqno + 1;
636 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
637 pcb->lastack = ackno;
638 pcb->snd_wnd = tcphdr->wnd;
639 pcb->snd_wnd_max = tcphdr->wnd;
640 pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
641 pcb->state = ESTABLISHED;
644 pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
647 /* Set ssthresh again after changing pcb->mss (already set in tcp_connect
648 * but for the default value of pcb->mss) */
649 pcb->ssthresh = pcb->mss * 10;
651 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
652 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
653 --pcb->snd_queuelen;
654 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
655 rseg = pcb->unacked;
656 pcb->unacked = rseg->next;
661 if(pcb->unacked == NULL)
662 pcb->rtime = -1;
664 pcb->rtime = 0;
665 pcb->nrtx = 0;
670 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
674 tcp_ack_now(pcb);
686 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
688 pcb->state = ESTABLISHED;
691 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
694 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
700 tcp_abort(pcb);
704 old_cwnd = pcb->cwnd;
707 tcp_receive(pcb);
710 if (pcb->acked != 0) {
711 pcb->acked--;
714 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
717 tcp_ack_now(pcb);
718 pcb->state = CLOSE_WAIT;
725 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
727 tcp_rexmit(pcb);
733 tcp_receive(pcb);
735 tcp_ack_now(pcb);
736 pcb->state = CLOSE_WAIT;
740 tcp_receive(pcb);
742 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
745 tcp_ack_now(pcb);
746 tcp_pcb_purge(pcb);
747 TCP_RMV_ACTIVE(pcb);
748 pcb->state = TIME_WAIT;
749 TCP_REG(&tcp_tw_pcbs, pcb);
751 tcp_ack_now(pcb);
752 pcb->state = CLOSING;
754 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
755 pcb->state = FIN_WAIT_2;
759 tcp_receive(pcb);
762 tcp_ack_now(pcb);
763 tcp_pcb_purge(pcb);
764 TCP_RMV_ACTIVE(pcb);
765 pcb->state = TIME_WAIT;
766 TCP_REG(&tcp_tw_pcbs, pcb);
770 tcp_receive(pcb);
771 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
773 tcp_pcb_purge(pcb);
774 TCP_RMV_ACTIVE(pcb);
775 pcb->state = TIME_WAIT;
776 TCP_REG(&tcp_tw_pcbs, pcb);
780 tcp_receive(pcb);
781 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
783 /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
837 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
847 tcp_receive(struct tcp_pcb *pcb)
864 LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
867 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
870 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
871 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
872 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
873 pcb->snd_wnd = tcphdr->wnd;
876 if (pcb->snd_wnd_max < tcphdr->wnd) {
877 pcb->snd_wnd_max = tcphdr->wnd;
879 pcb->snd_wl1 = seqno;
880 pcb->snd_wl2 = ackno;
881 if (pcb->snd_wnd == 0) {
882 if (pcb->persist_backoff == 0) {
884 pcb->persist_cnt = 0;
885 pcb->persist_backoff = 1;
887 } else if (pcb->persist_backoff > 0) {
889 pcb->persist_backoff = 0;
891 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
894 if (pcb->snd_wnd != tcphdr->wnd) {
898 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
924 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
925 pcb->acked = 0;
929 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
931 if (pcb->rtime >= 0) {
933 if (pcb->lastack == ackno) {
935 if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
936 ++pcb->dupacks;
938 if (pcb->dupacks > 3) {
941 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
942 pcb->cwnd += pcb->mss;
944 } else if (pcb->dupacks == 3) {
946 tcp_rexmit_fast(pcb);
955 pcb->dupacks = 0;
957 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
963 if (pcb->flags & TF_INFR) {
964 pcb->flags &= ~TF_INFR;
965 pcb->cwnd = pcb->ssthresh;
969 pcb->nrtx = 0;
972 pcb->rto = (pcb->sa >> 3) + pcb->sv;
975 pcb->acked = (u16_t)(ackno - pcb->lastack);
977 pcb->snd_buf += pcb->acked;
980 pcb->dupacks = 0;
981 pcb->lastack = ackno;
985 if (pcb->state >= ESTABLISHED) {
986 if (pcb->cwnd < pcb->ssthresh) {
987 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
988 pcb->cwnd += pcb->mss;
990 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
992 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
993 if (new_cwnd > pcb->cwnd) {
994 pcb->cwnd = new_cwnd;
996 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
1001 pcb->unacked != NULL?
1002 ntohl(pcb->unacked->tcphdr->seqno): 0,
1003 pcb->unacked != NULL?
1004 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
1008 while (pcb->unacked != NULL &&
1009 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
1010 TCP_TCPLEN(pcb->unacked), ackno)) {
1011 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
1012 ntohl(pcb->unacked->tcphdr->seqno),
1013 ntohl(pcb->unacked->tcphdr->seqno) +
1014 TCP_TCPLEN(pcb->unacked)));
1016 next = pcb->unacked;
1017 pcb->unacked = pcb->unacked->next;
1019 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1020 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1022 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1023 pcb->acked--;
1026 pcb->snd_queuelen -= pbuf_clen(next->p);
1029 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
1030 if (pcb->snd_queuelen != 0) {
1031 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
1032 pcb->unsent != NULL);
1038 if(pcb->unacked == NULL)
1039 pcb->rtime = -1;
1041 pcb->rtime = 0;
1043 pcb->polltmr = 0;
1046 pcb->acked = 0;
1055 while (pcb->unsent != NULL &&
1056 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
1057 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
1058 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
1059 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
1060 TCP_TCPLEN(pcb->unsent)));
1062 next = pcb->unsent;
1063 pcb->unsent = pcb->unsent->next;
1065 if (pcb->unsent == NULL) {
1066 pcb->unsent_oversize = 0;
1069 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
1070 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
1072 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
1073 pcb->acked--;
1075 pcb->snd_queuelen -= pbuf_clen(next->p);
1077 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
1078 if (pcb->snd_queuelen != 0) {
1080 pcb->unacked != NULL || pcb->unsent != NULL);
1085 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
1086 pcb->rttest, pcb->rtseq, ackno));
1091 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1094 m = (s16_t)(tcp_ticks - pcb->rttest);
1100 m = m - (pcb->sa >> 3);
1101 pcb->sa += m;
1105 m = m - (pcb->sv >> 2);
1106 pcb->sv += m;
1107 pcb->rto = (pcb->sa >> 3) + pcb->sv;
1110 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
1112 pcb->rttest = 0;
1117 further unless the pcb already received a FIN.
1120 if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
1149 /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1150 if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/
1151 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
1172 off = pcb->rcv_nxt - seqno;
1198 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
1199 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1202 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
1207 tcp_ack_now(pcb);
1214 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1215 pcb->rcv_nxt + pcb->rcv_wnd - 1)){
1216 if (pcb->rcv_nxt == seqno) {
1222 if (tcplen > pcb->rcv_wnd) {
1226 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1233 inseg.len = pcb->rcv_wnd;
1240 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1246 if (pcb->ooseq != NULL) {
1253 while (pcb->ooseq != NULL) {
1254 struct tcp_seg *old_ooseq = pcb->ooseq;
1255 pcb->ooseq = pcb->ooseq->next;
1259 next = pcb->ooseq;
1290 pcb->ooseq = next;
1295 pcb->rcv_nxt = seqno + tcplen;
1298 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
1299 pcb->rcv_wnd -= tcplen;
1301 tcp_update_rcv_ann_wnd(pcb);
1327 while (pcb->ooseq != NULL &&
1328 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1330 cseg = pcb->ooseq;
1331 seqno = pcb->ooseq->tcphdr->seqno;
1333 pcb->rcv_nxt += TCP_TCPLEN(cseg);
1335 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1336 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1338 tcp_update_rcv_ann_wnd(pcb);
1353 if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
1354 pcb->state = CLOSE_WAIT;
1358 pcb->ooseq = cseg->next;
1365 tcp_ack(pcb);
1369 tcp_send_empty_ack(pcb);
1372 if (pcb->ooseq == NULL) {
1373 pcb->ooseq = tcp_seg_copy(&inseg);
1388 for(next = pcb->ooseq; next != NULL; next = next->next) {
1403 pcb->ooseq = cseg;
1423 pcb->ooseq = cseg;
1467 if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) {
1471 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1478 next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno;
1482 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1497 for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
1507 pcb->ooseq = NULL;
1520 tcp_send_empty_ack(pcb);
1525 /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
1526 TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/
1527 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
1528 tcp_ack_now(pcb);
1539 * @param pcb the tcp_pcb for which a segment arrived
1542 tcp_parseopt(struct tcp_pcb *pcb)
1578 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1594 pcb->ts_recent = ntohl(tsval);
1595 pcb->flags |= TF_TIMESTAMP;
1596 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
1597 pcb->ts_recent = ntohl(tsval);