4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TCP input process routines.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether the sequence number of the incoming segment is acceptable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Seg Pointer to the incoming segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 1 The sequence number is acceptable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 0 The sequence number is not acceptable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewReno fast recovery defined in RFC3782.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Seg Segment that triggers the fast recovery.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 1: Three duplicate ACKs and not in fast recovery
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 1A: Invoking fast retransmission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->Ssthresh = MAX (FlightSize >> 1, (UINT32) (2 * Tcb->SndMss));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 2: Entering fast retransmission
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpFastRecover: enter fast retransmission for TCB %p, recover point is %d\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // During fast recovery, execute Step 3, 4, 5 of RFC3782
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 3: Fast Recovery,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If this is a duplicated ACK, increse Cwnd by SMSS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 4 is skipped here only to be executed later
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // by TcpToSendData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpFastRecover: received another duplicated ACK (%d) for TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // New data is ACKed, check whether it is a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // full ACK or partial ACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 5 - Full ACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // deflate the congestion window, and exit fast recovery
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->CWnd = MIN (Tcb->Ssthresh, FlightSize + Tcb->SndMss);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpFastRecover: received a full ACK(%d) for TCB %p, exit fast recovery\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 5 - Partial ACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // fast retransmit the first unacknowledge field
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // , then deflate the CWnd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Deflate the CWnd by the amount of new data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ACKed by SEG.ACK. If more than one SMSS data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // is ACKed, add back SMSS byte to CWnd after
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpFastRecover: received a partial ACK(%d) for TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewReno fast loss recovery defined in RFC3792.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Seg Segment that triggers the fast loss recovery.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // New data is ACKed, check whether it is a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // full ACK or partial ACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Full ACK: exit the loss recovery.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpFastLossRecover: received a full ACK(%d) for TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Partial ACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // fast retransmit the first unacknowledge field.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpFastLossRecover: received a partial ACK(%d) for TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Compute the RTT as specified in RFC2988.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Measure Currently measured RTT in heartbeats.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 2.3: Compute the RTO for subsequent RTT measurement.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 2.2: compute the first RTT measure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->Rto = (Tcb->SRtt + MAX (8, 4 * Tcb->RttVar)) >> TCP_RTT_SHIFT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 2.4: Limit the RTO to at least 1 second
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Step 2.5: Limit the RTO to a maxium value that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // is at least 60 second
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpComputeRtt: new RTT for TCB %p computed SRTT: %d RTTVAR: %d RTO: %d\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Trim the data; SYN and FIN to fit into the window defined by Left and Right.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Nbuf The buffer that contains a received TCP segment without an IP header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Left The sequence number of the window's left edge.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Right The sequence number of the window's right edge.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the segment is completely out of window,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // truncate every thing, include SYN and FIN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LEQ (Seg->End, Left) || TCP_SEQ_LEQ (Right, Seg->Seq)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Adjust the buffer header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Adjust the urgent point
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Drop != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Adjust the buffer tail
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Drop != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Trim off the data outside the tcb's receive window.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Nbuf Pointer to the NET_BUF containing the received tcp segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpTrimSegment (Nbuf, Tcb->RcvNxt, Tcb->RcvWl2 + Tcb->RcvWnd);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the data and FIN flag, and check whether to deliver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync data to the socket layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 0 No error occurred to deliver data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval -1 An error condition occurred. The proper response is to reset the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // make sure there is some data queued,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and TCP is in a proper state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsListEmpty (&Tcb->RcvQue) || !TCP_CONNECTED (Tcb->State)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Deliver data to the socket layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // RFC793 Eighth step: process FIN in sequence
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The peer sends to us junky data after FIN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // reset the connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpDeliverData: data received after FIN from peer of TCB %p, reset connection\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpDeliverData: processing FIN from peer of TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_ACKED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // fall through
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpSetTimer (Tcb, TCP_TIMER_2MSL, Tcb->TimeWaitTimeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Connection closed immediately because app disables TIME_WAIT timer for %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The peer sends to us junk FIN byte. Discard
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the buffer then reset the connection
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't delay the ack if PUSH flag is on.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_URG) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Store the data into the reassemble queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Nbuf Pointer to the buffer containing the data to be queued.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fast path to process normal case. That is,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // no out-of-order segments are received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the point to insert the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LT (Seg->Seq, TCPSEG_NETBUF (Node)->Seq)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the current segment overlaps with the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // previous segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LT (Seg->Seq, TCPSEG_NETBUF (Node)->End)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LEQ (Seg->End, TCPSEG_NETBUF (Node)->End)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpTrimSegment (Nbuf, TCPSEG_NETBUF (Node)->End, Seg->End);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the segments after the insert point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LEQ (TCPSEG_NETBUF (Node)->End, Seg->End)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LT (TCPSEG_NETBUF (Node)->Seq, Seg->End)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LEQ (TCPSEG_NETBUF (Node)->Seq, Seg->Seq)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpTrimSegment (Nbuf, Seg->Seq, TCPSEG_NETBUF (Node)->Seq);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Adjust the send queue or the retransmit queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Ack The acknowledge seuqence number of the received segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove completely ACKed segments
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received TCP segments.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Nbuf Buffer that contains received a TCP segment without an IP header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Src Source address of the segment, or the peer's IP address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Dst Destination address of the segment, or the local end's IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Version IP_VERSION_4 indicates IP4 stack. IP_VERSION_6 indicates
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval 0 Segment processed successfully. It is either accepted or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync discarded. However, no connection is reset by the segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval -1 A connection is reset by the segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((Version == IP_VERSION_4) || (Version == IP_VERSION_6));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "TcpInput: received an mal-formated packet\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checksum = NetPseudoHeadChecksum (Src->Addr[0], Dst->Addr[0], 6, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Checksum = NetIp6PseudoHeadChecksum (&Src->v6, &Dst->v6, 6, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "TcpInput: received a checksum error packet\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "TcpInput: send reset because no TCB find\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // RFC1122 recommended reaction to illegal option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // (in fact, an illegal option length) is reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: reset the peer because of mal-format option for Tcb %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // From now on, the segment is headless
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufTrim (Nbuf, (Head->HeadLen << 2), NET_BUF_HEAD);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the segment in LISTEN state.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First step: Check RST
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: discard a reset segment for TCB %p in listening\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Second step: Check ACK.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Any ACK sent to TCP in LISTEN is reseted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: send reset because of segment with ACK for TCB %p in listening\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Third step: Check SYN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // create a child TCB to handle the data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: discard a segment because failed to clone a child for TCB%p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: create a child for TCB %p in listening\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // init the TCB structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First step: Check ACK bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Seg->Flag, TCP_FLG_ACK) && (Seg->Ack != Tcb->Iss + 1)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: send reset because of wrong ACK received for TCB %p in SYN_SENT\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Second step: Check RST bit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: connection reset by peer for TCB %p in SYN_SENT\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: discard a reset segment because of no ACK for TCB %p in SYN_SENT\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Third step: Check security and precedence. Skipped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fourth step: Check SYN. Pay attention to sitimulatous open
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: connection established for TCB %p in SYN_SENT\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Received a SYN segment without ACK, simultanous open.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: simultanous open for TCB %p in SYN_SENT\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process segment in SYN_RCVD or TCP_CONNECTED states
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clear probe timer since the RecvWindow is opened.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First step: Check whether SEG.SEQ is acceptable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: sequence acceptance test failed for segment of TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Second step: Check the RST
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_WARN, "TcpInput: connection reset for TCB %p\n", Tcb));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This TCB comes from either a LISTEN TCB,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // or active open TCB with simultanous open.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Do NOT signal user CONNECTION refused
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if it comes from a LISTEN TCB.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Trim the data and flags.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Third step: Check security and precedence, Ignored
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fourth step: Check the SYN bit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: connection reset because received extra SYN for TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fifth step: Check the ACK
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: segment discard because of no ACK for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Tcb->IpInfo->IpVersion == IP_VERSION_6 && Tcb->Tick == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcp6RefreshNeighbor (Tcb, Src, TCP6_KEEP_NEIGHBOR_TIME * TICKS_PER_SECOND);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LT (Tcb->SndUna, Seg->Ack) && TCP_SEQ_LEQ (Seg->Ack, Tcb->SndNxt)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->SndWndMax = MAX (Tcb->SndWnd, Tcb->SndWndMax);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: connection established for TCB %p in SYN_RCVD\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Continue the process as ESTABLISHED state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: send reset because of wrong ACK for TCB %p in SYN_RCVD\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: ignore the out-of-data ACK for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: discard segment for future ACK for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // From now on: SND.UNA <= SEG.ACK <= SND.NXT.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Option.Flag, TCP_OPTION_RCVD_TS)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // update TsRecent as specified in page 16 RFC1323.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // RcvWl2 equals to the variable "LastAckSent"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // defined there.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LEQ (Seg->Seq, Tcb->RcvWl2) && TCP_SEQ_LT (Tcb->RcvWl2, Seg->End)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpComputeRtt (Tcb, TCP_SUB_TIME (mTcpTick, Option.TSEcr));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RTT_ON)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Count duplicate acks.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Congestion avoidance, fast recovery and fast retransmission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((Tcb->CongestState == TCP_CONGEST_OPEN) && (Tcb->DupAck < 3)) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->CWnd += MAX (Tcb->SndMss * Tcb->SndMss / Tcb->CWnd, 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->CWnd = MIN (Tcb->CWnd, TCP_MAX_WIN << Tcb->SndWndScale);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_URG) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update window info
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ((Tcb->SndWl1 == Seg->Seq) && TCP_SEQ_LEQ (Tcb->SndWl2, Seg->Ack))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_SEQ_LT (Right, Tcb->SndWl2 + Tcb->SndWnd)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: peer shrinks the window for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Tcb->CongestState == TCP_CONGEST_RECOVER) && (TCP_SEQ_LT (Right, Tcb->Recover))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Tcb->CongestState == TCP_CONGEST_LOSS) && (TCP_SEQ_LT (Right, Tcb->LossRecover))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb->SndWndMax = MAX (Tcb->SndWnd, Tcb->SndWndMax);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_SENT) && (Tcb->SndUna == Tcb->SndNxt)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: local FIN is ACKed by peer for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Transit the state if proper.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_ACKED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpSetTimer (Tcb, TCP_TIMER_FINWAIT2, Tcb->FinWait2Timeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_ACKED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpSetTimer (Tcb, TCP_TIMER_2MSL, Tcb->TimeWaitTimeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Connection closed immediately because app disables TIME_WAIT timer for %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_ACKED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TcpSetTimer (Tcb, TCP_TIMER_2MSL, Tcb->TimeWaitTimeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "Connection closed immediately because app disables TIME_WAIT timer for %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Sixth step: Check the URG bit.update the Urg point
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if in TCP_CAN_RECV, otherwise, leave the RcvUp intact.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Seg->Flag, TCP_FLG_URG) && !TCP_FIN_RCVD (Tcb->State)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: received urgent data from peer for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_URG) && TCP_SEQ_GT (Urg, Tcb->RcvUp)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Seventh step: Process the segment data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: connection reset because data is lost for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TCP_LOCAL_CLOSED (Tcb->State) && (Nbuf->TotalSize != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "TcpInput: connection reset because data is lost for connected TCB %p\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Eighth step: check the FIN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This step is moved to TcpDeliverData. FIN will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // processed in sequence there. Check the comments in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the beginning of the file header for information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Tcb is a new child of the listening Parent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // commit it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW) || (Nbuf->TotalSize != 0))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Tcb is a child of Parent, and it doesn't survive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_WARN, "TcpInput: Discard a packet\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received ICMP error messages for TCP.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Nbuf The buffer that contains part of the TCP segment without an IP header
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync truncated from the ICMP error packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IcmpErr The ICMP error code interpreted from an ICMP error packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Src Source address of the ICMP error message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Dst Destination address of the ICMP error message.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Version IP_VERSION_4 indicates IP4 stack. IP_VERSION_6 indicates
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the sequence number.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(TCP_SEQ_LEQ (Tcb->SndUna, Seq) && TCP_SEQ_LT (Seq, Tcb->SndNxt))) {