mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-06 22:44:38 +08:00
BUG26301 and BUG26267: correct simultaneous close behaviour, and make
snd_nxt have the same meaning as in the RFCs.
This commit is contained in:
parent
aefeba3fc0
commit
c232edb83a
@ -1014,7 +1014,6 @@ tcp_alloc(u8_t prio)
|
|||||||
iss = tcp_next_iss();
|
iss = tcp_next_iss();
|
||||||
pcb->snd_wl2 = iss;
|
pcb->snd_wl2 = iss;
|
||||||
pcb->snd_nxt = iss;
|
pcb->snd_nxt = iss;
|
||||||
pcb->snd_max = iss;
|
|
||||||
pcb->lastack = iss;
|
pcb->lastack = iss;
|
||||||
pcb->snd_lbb = iss;
|
pcb->snd_lbb = iss;
|
||||||
pcb->tmr = tcp_ticks;
|
pcb->tmr = tcp_ticks;
|
||||||
|
@ -506,7 +506,6 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
struct tcp_seg *rseg;
|
struct tcp_seg *rseg;
|
||||||
u8_t acceptable = 0;
|
u8_t acceptable = 0;
|
||||||
err_t err;
|
err_t err;
|
||||||
u8_t accepted_inseq;
|
|
||||||
|
|
||||||
err = ERR_OK;
|
err = ERR_OK;
|
||||||
|
|
||||||
@ -527,7 +526,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
if (acceptable) {
|
if (acceptable) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
|
||||||
LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
|
LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
|
||||||
recv_flags = TF_RESET;
|
recv_flags |= TF_RESET;
|
||||||
pcb->flags &= ~TF_ACK_DELAY;
|
pcb->flags &= ~TF_ACK_DELAY;
|
||||||
return ERR_RST;
|
return ERR_RST;
|
||||||
} else {
|
} else {
|
||||||
@ -626,11 +625,11 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
old_cwnd = pcb->cwnd;
|
old_cwnd = pcb->cwnd;
|
||||||
/* If there was any data contained within this ACK,
|
/* If there was any data contained within this ACK,
|
||||||
* we'd better pass it on to the application as well. */
|
* we'd better pass it on to the application as well. */
|
||||||
accepted_inseq = tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
|
|
||||||
pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
|
pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
|
||||||
|
|
||||||
if ((flags & TCP_FIN) && accepted_inseq) {
|
if (recv_flags & TF_GOT_FIN) {
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
pcb->state = CLOSE_WAIT;
|
pcb->state = CLOSE_WAIT;
|
||||||
}
|
}
|
||||||
@ -649,16 +648,16 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
case CLOSE_WAIT:
|
case CLOSE_WAIT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ESTABLISHED:
|
case ESTABLISHED:
|
||||||
accepted_inseq = tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if ((flags & TCP_FIN) && accepted_inseq) { /* passive close */
|
if (recv_flags & TF_GOT_FIN) { /* passive close */
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
pcb->state = CLOSE_WAIT;
|
pcb->state = CLOSE_WAIT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIN_WAIT_1:
|
case FIN_WAIT_1:
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_FIN) {
|
if (recv_flags & TF_GOT_FIN) {
|
||||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
|
||||||
LWIP_DEBUGF(TCP_DEBUG,
|
LWIP_DEBUGF(TCP_DEBUG,
|
||||||
("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
@ -670,13 +669,13 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
pcb->state = CLOSING;
|
pcb->state = CLOSING;
|
||||||
}
|
}
|
||||||
} else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
} else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
|
||||||
pcb->state = FIN_WAIT_2;
|
pcb->state = FIN_WAIT_2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIN_WAIT_2:
|
case FIN_WAIT_2:
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_FIN) {
|
if (recv_flags & TF_GOT_FIN) {
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
tcp_pcb_purge(pcb);
|
tcp_pcb_purge(pcb);
|
||||||
@ -689,7 +688,6 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
tcp_ack_now(pcb);
|
|
||||||
tcp_pcb_purge(pcb);
|
tcp_pcb_purge(pcb);
|
||||||
TCP_RMV(&tcp_active_pcbs, pcb);
|
TCP_RMV(&tcp_active_pcbs, pcb);
|
||||||
pcb->state = TIME_WAIT;
|
pcb->state = TIME_WAIT;
|
||||||
@ -701,7 +699,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
/* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
|
/* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */
|
||||||
recv_flags = TF_CLOSED;
|
recv_flags |= TF_CLOSED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -755,8 +753,10 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
#if TCP_WND_DEBUG
|
#if TCP_WND_DEBUG
|
||||||
} else {
|
} else {
|
||||||
if (pcb->snd_wnd != tcphdr->wnd) {
|
if (pcb->snd_wnd != tcphdr->wnd) {
|
||||||
LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %"U32_F" snd_max %"U32_F" ackno %"U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
|
LWIP_DEBUGF(TCP_WND_DEBUG,
|
||||||
pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
|
("tcp_receive: no window update lastack %"U32_F" ackno %"
|
||||||
|
U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
|
||||||
|
pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
|
||||||
}
|
}
|
||||||
#endif /* TCP_WND_DEBUG */
|
#endif /* TCP_WND_DEBUG */
|
||||||
}
|
}
|
||||||
@ -803,7 +803,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",
|
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",
|
||||||
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
||||||
}
|
}
|
||||||
} else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
|
} else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
|
||||||
/* We come here when the ACK acknowledges new data. */
|
/* We come here when the ACK acknowledges new data. */
|
||||||
|
|
||||||
/* Reset the "IN Fast Retransmit" flag, since we are no longer
|
/* Reset the "IN Fast Retransmit" flag, since we are no longer
|
||||||
@ -897,10 +897,8 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
->unsent list after a retransmission, so these segments may
|
->unsent list after a retransmission, so these segments may
|
||||||
in fact have been sent once. */
|
in fact have been sent once. */
|
||||||
while (pcb->unsent != NULL &&
|
while (pcb->unsent != NULL &&
|
||||||
/*TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), ackno) &&
|
TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
|
||||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)*/
|
TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
|
||||||
TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max)
|
|
||||||
) {
|
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
|
||||||
ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
|
ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
|
||||||
TCP_TCPLEN(pcb->unsent)));
|
TCP_TCPLEN(pcb->unsent)));
|
||||||
@ -916,10 +914,6 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
LWIP_ASSERT("tcp_receive: valid queue length",
|
LWIP_ASSERT("tcp_receive: valid queue length",
|
||||||
pcb->unacked != NULL || pcb->unsent != NULL);
|
pcb->unacked != NULL || pcb->unsent != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcb->unsent != NULL) {
|
|
||||||
pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* End of ACK for new data processing. */
|
/* End of ACK for new data processing. */
|
||||||
|
|
||||||
@ -1081,13 +1075,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
#endif /* TCP_QUEUE_OOSEQ */
|
#endif /* TCP_QUEUE_OOSEQ */
|
||||||
|
|
||||||
tcplen = TCP_TCPLEN(&inseg);
|
tcplen = TCP_TCPLEN(&inseg);
|
||||||
|
pcb->rcv_nxt = seqno + tcplen;
|
||||||
/* First received FIN will be ACKed +1, on any successive (duplicate)
|
|
||||||
* FINs we are already in CLOSE_WAIT and have already done +1.
|
|
||||||
*/
|
|
||||||
if (pcb->state != CLOSE_WAIT) {
|
|
||||||
pcb->rcv_nxt += tcplen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the receiver's (our) window. */
|
/* Update the receiver's (our) window. */
|
||||||
if (pcb->rcv_wnd < tcplen) {
|
if (pcb->rcv_wnd < tcplen) {
|
||||||
@ -1116,7 +1104,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
|
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags |= TF_GOT_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCP_QUEUE_OOSEQ
|
#if TCP_QUEUE_OOSEQ
|
||||||
@ -1149,7 +1137,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
|
if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags |= TF_GOT_FIN;
|
||||||
if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
|
if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */
|
||||||
pcb->state = CLOSE_WAIT;
|
pcb->state = CLOSE_WAIT;
|
||||||
}
|
}
|
||||||
|
@ -60,12 +60,13 @@
|
|||||||
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
|
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
|
||||||
|
|
||||||
static struct tcp_hdr *
|
static struct tcp_hdr *
|
||||||
tcp_output_set_header(struct tcp_pcb *pcb, struct pbuf *p, int optlen)
|
tcp_output_set_header(struct tcp_pcb *pcb, struct pbuf *p, int optlen,
|
||||||
|
u32_t seqno_be /* already in network byte order */)
|
||||||
{
|
{
|
||||||
struct tcp_hdr *tcphdr = p->payload;
|
struct tcp_hdr *tcphdr = p->payload;
|
||||||
tcphdr->src = htons(pcb->local_port);
|
tcphdr->src = htons(pcb->local_port);
|
||||||
tcphdr->dest = htons(pcb->remote_port);
|
tcphdr->dest = htons(pcb->remote_port);
|
||||||
tcphdr->seqno = htonl(pcb->snd_nxt);
|
tcphdr->seqno = seqno_be;
|
||||||
tcphdr->ackno = htonl(pcb->rcv_nxt);
|
tcphdr->ackno = htonl(pcb->rcv_nxt);
|
||||||
TCPH_FLAGS_SET(tcphdr, TCP_ACK);
|
TCPH_FLAGS_SET(tcphdr, TCP_ACK);
|
||||||
tcphdr->wnd = htons(pcb->rcv_ann_wnd);
|
tcphdr->wnd = htons(pcb->rcv_ann_wnd);
|
||||||
@ -456,7 +457,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
struct tcp_hdr *tcphdr;
|
struct tcp_hdr *tcphdr;
|
||||||
struct tcp_seg *seg, *useg;
|
struct tcp_seg *seg, *useg;
|
||||||
u32_t wnd;
|
u32_t wnd, snd_nxt;
|
||||||
#if TCP_CWND_DEBUG
|
#if TCP_CWND_DEBUG
|
||||||
s16_t i = 0;
|
s16_t i = 0;
|
||||||
#endif /* TCP_CWND_DEBUG */
|
#endif /* TCP_CWND_DEBUG */
|
||||||
@ -503,7 +504,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
/* remove ACK flags from the PCB, as we send an empty ACK now */
|
/* remove ACK flags from the PCB, as we send an empty ACK now */
|
||||||
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
||||||
|
|
||||||
tcphdr = tcp_output_set_header(pcb, p, optlen);
|
tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt));
|
||||||
|
|
||||||
/* NB. MSS option is only sent on SYNs, so ignore it here */
|
/* NB. MSS option is only sent on SYNs, so ignore it here */
|
||||||
#if LWIP_TCP_TIMESTAMPS
|
#if LWIP_TCP_TIMESTAMPS
|
||||||
@ -583,9 +584,9 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcp_output_segment(seg, pcb);
|
tcp_output_segment(seg, pcb);
|
||||||
pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
|
snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
|
||||||
if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
|
if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
|
||||||
pcb->snd_max = pcb->snd_nxt;
|
pcb->snd_nxt = snd_nxt;
|
||||||
}
|
}
|
||||||
/* put segment on unacknowledged list if length > 0 */
|
/* put segment on unacknowledged list if length > 0 */
|
||||||
if (TCP_TCPLEN(seg) > 0) {
|
if (TCP_TCPLEN(seg) > 0) {
|
||||||
@ -805,7 +806,6 @@ tcp_rexmit_rto(struct tcp_pcb *pcb)
|
|||||||
/* unacked queue is now empty */
|
/* unacked queue is now empty */
|
||||||
pcb->unacked = NULL;
|
pcb->unacked = NULL;
|
||||||
|
|
||||||
pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
|
|
||||||
/* increment number of retransmissions */
|
/* increment number of retransmissions */
|
||||||
++pcb->nrtx;
|
++pcb->nrtx;
|
||||||
|
|
||||||
@ -846,8 +846,6 @@ tcp_rexmit(struct tcp_pcb *pcb)
|
|||||||
seg->next = *cur_seg;
|
seg->next = *cur_seg;
|
||||||
*cur_seg = seg;
|
*cur_seg = seg;
|
||||||
|
|
||||||
pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
|
|
||||||
|
|
||||||
++pcb->nrtx;
|
++pcb->nrtx;
|
||||||
|
|
||||||
/* Don't take any rtt measurements after retransmitting. */
|
/* Don't take any rtt measurements after retransmitting. */
|
||||||
@ -889,9 +887,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
|||||||
LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
|
LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
|
||||||
(p->len >= sizeof(struct tcp_hdr)));
|
(p->len >= sizeof(struct tcp_hdr)));
|
||||||
|
|
||||||
tcphdr = tcp_output_set_header(pcb, p, 0);
|
tcphdr = tcp_output_set_header(pcb, p, 0, htonl(pcb->snd_nxt - 1));
|
||||||
|
|
||||||
tcphdr->seqno = htonl(pcb->snd_nxt - 1);
|
|
||||||
|
|
||||||
#if CHECKSUM_GEN_TCP
|
#if CHECKSUM_GEN_TCP
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
|
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
|
||||||
@ -957,9 +953,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
|||||||
LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
|
LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
|
||||||
(p->len >= sizeof(struct tcp_hdr)));
|
(p->len >= sizeof(struct tcp_hdr)));
|
||||||
|
|
||||||
tcphdr = tcp_output_set_header(pcb, p, 0);
|
tcphdr = tcp_output_set_header(pcb, p, 0, seg->tcphdr->seqno);
|
||||||
|
|
||||||
tcphdr->seqno = seg->tcphdr->seqno;
|
|
||||||
|
|
||||||
/* Copy in one byte from the head of the unacked queue */
|
/* Copy in one byte from the head of the unacked queue */
|
||||||
*((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
|
*((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
|
||||||
|
@ -338,12 +338,11 @@ struct tcp_pcb {
|
|||||||
u16_t ssthresh;
|
u16_t ssthresh;
|
||||||
|
|
||||||
/* sender variables */
|
/* sender variables */
|
||||||
u32_t snd_nxt, /* next seqno to be sent */
|
u32_t snd_nxt; /* next new seqno to be sent */
|
||||||
snd_max; /* Highest seqno sent. */
|
|
||||||
u16_t snd_wnd; /* sender window */
|
u16_t snd_wnd; /* sender window */
|
||||||
u32_t snd_wl1, snd_wl2, /* Sequence and acknowledgement numbers of last
|
u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
|
||||||
window update. */
|
window update. */
|
||||||
snd_lbb; /* Sequence number of next byte to be buffered. */
|
u32_t snd_lbb; /* Sequence number of next byte to be buffered. */
|
||||||
|
|
||||||
u16_t acked;
|
u16_t acked;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user