brian@sdcsvax.UCSD.EDU (Brian Kantor) (08/26/87)
indications for different SENDs, it might be appropriate for the [Page 47] September 1981 Transmission Control Protocol Functional Specification buffer address to be returned along with the coded response to the SEND request. TCP-to-user signals are discussed below, indicating the information which should be returned to the calling process. Receive Format: RECEIVE (local connection name, buffer address, byte count) -> byte count, urgent flag, push flag This command allocates a receiving buffer associated with the specified connection. If no OPEN precedes this command or the calling process is not authorized to use this connection, an error is returned. In the simplest implementation, control would not return to the calling program until either the buffer was filled, or some error occurred, but this scheme is highly subject to deadlocks. A more sophisticated implementation would permit several RECEIVEs to be outstanding at once. These would be filled as segments arrive. This strategy permits increased throughput at the cost of a more elaborate scheme (possibly asynchronous) to notify the calling program that a PUSH has been seen or a buffer filled. If enough data arrive to fill the buffer before a PUSH is seen, the PUSH flag will not be set in the response to the RECEIVE. The buffer will be filled with as much data as it can hold. If a PUSH is seen before the buffer is filled the buffer will be returned partially filled and PUSH indicated. If there is urgent data the user will have been informed as soon as it arrived via a TCP-to-user signal. The receiving user should thus be in "urgent mode". If the URGENT flag is on, additional urgent data remains. If the URGENT flag is off, this call to RECEIVE has returned all the urgent data, and the user may now leave "urgent mode". Note that data following the urgent pointer (non-urgent data) cannot be delivered to the user in the same buffer with preceeding urgent data unless the boundary is clearly marked for the user. To distinguish among several outstanding RECEIVEs and to take care of the case that a buffer is not completely filled, the return code is accompanied by both a buffer pointer and a byte count indicating the actual length of the data received. Alternative implementations of RECEIVE might have the TCP [Page 48] September 1981 Transmission Control Protocol Functional Specification allocate buffer storage, or the TCP might share a ring buffer with the user. Close Format: CLOSE (local connection name) This command causes the connection specified to be closed. If the connection is not open or the calling process is not authorized to use this connection, an error is returned. Closing connections is intended to be a graceful operation in the sense that outstanding SENDs will be transmitted (and retransmitted), as flow control permits, until all have been serviced. Thus, it should be acceptable to make several SEND calls, followed by a CLOSE, and expect all the data to be sent to the destination. It should also be clear that users should continue to RECEIVE on CLOSING connections, since the other side may be trying to transmit the last of its data. Thus, CLOSE means "I have no more to send" but does not mean "I will not receive any more." It may happen (if the user level protocol is not well thought out) that the closing side is unable to get rid of all its data before timing out. In this event, CLOSE turns into ABORT, and the closing TCP gives up. The user may CLOSE the connection at any time on his own initiative, or in response to various prompts from the TCP (e.g., remote close executed, transmission timeout exceeded, destination inaccessible). Because closing a connection requires communication with the foreign TCP, connections may remain in the closing state for a short time. Attempts to reopen the connection before the TCP replies to the CLOSE command will result in error responses. Close also implies push function. Status Format: STATUS (local connection name) -> status data This is an implementation dependent user command and could be excluded without adverse effect. Information returned would typically come from the TCB associated with the connection. This command returns a data block containing the following information: local socket, [Page 49] September 1981 Transmission Control Protocol Functional Specification foreign socket, local connection name, receive window, send window, connection state, number of buffers awaiting acknowledgment, number of buffers pending receipt, urgent state, precedence, security/compartment, and transmission timeout. Depending on the state of the connection, or on the implementation itself, some of this information may not be available or meaningful. If the calling process is not authorized to use this connection, an error is returned. This prevents unauthorized processes from gaining information about a connection. Abort Format: ABORT (local connection name) This command causes all pending SENDs and RECEIVES to be aborted, the TCB to be removed, and a special RESET message to be sent to the TCP on the other side of the connection. Depending on the implementation, users may receive abort indications for each outstanding SEND or RECEIVE, or may simply receive an ABORT-acknowledgment. TCP-to-User Messages It is assumed that the operating system environment provides a means for the TCP to asynchronously signal the user program. When the TCP does signal a user program, certain information is passed to the user. Often in the specification the information will be an error message. In other cases there will be information relating to the completion of processing a SEND or RECEIVE or other user call. The following information is provided: Local Connection Name Always Response String Always Buffer Address Send & Receive Byte count (counts bytes received) Receive Push flag Receive Urgent flag Receive [Page 50] September 1981 Transmission Control Protocol Functional Specification TCP/Lower-Level Interface The TCP calls on a lower level protocol module to actually send and receive information over a network. One case is that of the ARPA internetwork system where the lower level module is the Internet Protocol (IP) [2]. If the lower level protocol is IP it provides arguments for a type of service and for a time to live. TCP uses the following settings for these parameters: Type of Service = Precedence: routine, Delay: normal, Throughput: normal, Reliability: normal; or 00000000. Time to Live = one minute, or 00111100. Note that the assumed maximum segment lifetime is two minutes. Here we explicitly ask that a segment be destroyed if it cannot be delivered by the internet system within one minute. If the lower level is IP (or other protocol that provides this feature) and source routing is used, the interface must allow the route information to be communicated. This is especially important so that the source and destination addresses used in the TCP checksum be the originating source and ultimate destination. It is also important to preserve the return route to answer connection requests. Any lower level protocol will have to provide the source address, destination address, and protocol fields, and some way to determine the "TCP length", both to provide the functional equivlent service of IP and to be used in the TCP checksum. [Page 51] September 1981 Transmission Control Protocol Functional Specification 3.9. Event Processing The processing depicted in this section is an example of one possible implementation. Other implementations may have slightly different processing sequences, but they should differ from those in this section only in detail, not in substance. The activity of the TCP can be characterized as responding to events. The events that occur can be cast into three categories: user calls, arriving segments, and timeouts. This section describes the processing the TCP does in response to each of the events. In many cases the processing required depends on the state of the connection. Events that occur: User Calls OPEN SEND RECEIVE CLOSE ABORT STATUS Arriving Segments SEGMENT ARRIVES Timeouts USER TIMEOUT RETRANSMISSION TIMEOUT TIME-WAIT TIMEOUT The model of the TCP/user interface is that user commands receive an immediate return and possibly a delayed response via an event or pseudo interrupt. In the following descriptions, the term "signal" means cause a delayed response. Error responses are given as character strings. For example, user commands referencing connections that do not exist receive "error: connection not open". Please note in the following that all arithmetic on sequence numbers, acknowledgment numbers, windows, et cetera, is modulo 2**32 the size of the sequence number space. Also note that "=<" means less than or equal to (modulo 2**32). [Page 52] September 1981 Transmission Control Protocol Functional Specification A natural way to think about processing incoming segments is to imagine that they are first tested for proper sequence number (i.e., that their contents lie in the range of the expected "receive window" in the sequence number space) and then that they are generally queued and processed in sequence number order. When a segment overlaps other already received segments we reconstruct the segment to contain just the new data, and adjust the header fields to be consistent. Note that if no state change is mentioned the TCP stays in the same state. [Page 53] September 1981 Transmission Control Protocol Functional Specification OPEN Call OPEN Call CLOSED STATE (i.e., TCB does not exist) Create a new transmission control block (TCB) to hold connection state information. Fill in local socket identifier, foreign socket, precedence, security/compartment, and user timeout information. Note that some parts of the foreign socket may be unspecified in a passive OPEN and are to be filled in by the parameters of the incoming SYN segment. Verify the security and precedence requested are allowed for this user, if not return "error: precedence not allowed" or "error: security/compartment not allowed." If passive enter the LISTEN state and return. If active and the foreign socket is unspecified, return "error: foreign socket unspecified"; if active and the foreign socket is specified, issue a SYN segment. An initial send sequence number (ISS) is selected. A SYN segment of the form <SEQ=ISS><CTL=SYN> is sent. Set SND.UNA to ISS, SND.NXT to ISS+1, enter SYN-SENT state, and return. If the caller does not have access to the local socket specified, return "error: connection illegal for this process". If there is no room to create a new connection, return "error: insufficient resources". LISTEN STATE If active and the foreign socket is specified, then change the connection from passive to active, select an ISS. Send a SYN segment, set SND.UNA to ISS, SND.NXT to ISS+1. Enter SYN-SENT state. Data associated with SEND may be sent with SYN segment or queued for transmission after entering ESTABLISHED state. The urgent bit if requested in the command must be sent with the data segments sent as a result of this command. If there is no room to queue the request, respond with "error: insufficient resources". If Foreign socket was not specified, then return "error: foreign socket unspecified". [Page 54] September 1981 Transmission Control Protocol Functional Specification OPEN Call SYN-SENT STATE SYN-RECEIVED STATE ESTABLISHED STATE FIN-WAIT-1 STATE FIN-WAIT-2 STATE CLOSE-WAIT STATE CLOSING STATE LAST-ACK STATE TIME-WAIT STATE Return "error: connection already exists". [Page 55] September 1981 Transmission Control Protocol Functional Specification SEND Call SEND Call CLOSED STATE (i.e., TCB does not exist) If the user does not have access to such a connection, then return "error: connection illegal for this process". Otherwise, return "error: connection does not exist". LISTEN STATE If the foreign socket is specified, then change the connection from passive to active, select an ISS. Send a SYN segment, set SND.UNA to ISS, SND.NXT to ISS+1. Enter SYN-SENT state. Data associated with SEND may be sent with SYN segment or queued for transmission after entering ESTABLISHED state. The urgent bit if requested in the command must be sent with the data segments sent as a result of this command. If there is no room to queue the request, respond with "error: insufficient resources". If Foreign socket was not specified, then return "error: foreign socket unspecified". SYN-SENT STATE SYN-RECEIVED STATE Queue the data for transmission after entering ESTABLISHED state. If no space to queue, respond with "error: insufficient resources". ESTABLISHED STATE CLOSE-WAIT STATE Segmentize the buffer and send it with a piggybacked acknowledgment (acknowledgment value = RCV.NXT). If there is insufficient space to remember this buffer, simply return "error: insufficient resources". If the urgent flag is set, then SND.UP <- SND.NXT-1 and set the urgent pointer in the outgoing segments. [Page 56] September 1981 Transmission Control Protocol Functional Specification SEND Call FIN-WAIT-1 STATE FIN-WAIT-2 STATE CLOSING STATE LAST-ACK STATE TIME-WAIT STATE Return "error: connection closing" and do not service request. [Page 57] September 1981 Transmission Control Protocol Functional Specification RECEIVE Call RECEIVE Call CLOSED STATE (i.e., TCB does not exist) If the user does not have access to such a connection, return "error: connection illegal for this process". Otherwise return "error: connection does not exist". LISTEN STATE SYN-SENT STATE SYN-RECEIVED STATE Queue for processing after entering ESTABLISHED state. If there is no room to queue this request, respond with "error: insufficient resources". ESTABLISHED STATE FIN-WAIT-1 STATE FIN-WAIT-2 STATE If insufficient incoming segments are queued to satisfy the request, queue the request. If there is no queue space to remember the RECEIVE, respond with "error: insufficient resources". Reassemble queued incoming segments into receive buffer and return to user. Mark "push seen" (PUSH) if this is the case. If RCV.UP is in advance of the data currently being passed to the user notify the user of the presence of urgent data. When the TCP takes responsibility for delivering data to the user that fact must be communicated to the sender via an acknowledgment. The formation of such an acknowledgment is described below in the discussion of processing an incoming segment. [Page 58] September 1981 Transmission Control Protocol Functional Specification RECEIVE Call CLOSE-WAIT STATE Since the remote side has already sent FIN, RECEIVEs must be satisfied by text already on hand, but not yet delivered to the user. If no text is awaiting delivery, the RECEIVE will get a "error: connection closing" response. Otherwise, any remaining text can be used to satisfy the RECEIVE. CLOSING STATE LAST-ACK STATE TIME-WAIT STATE Return "error: connection closing". [Page 59] September 1981 Transmission Control Protocol Functional Specification CLOSE Call CLOSE Call CLOSED STATE (i.e., TCB does not exist) If the user does not have access to such a connection, return "error: connection illegal for this process". Otherwise, return "error: connection does not exist". LISTEN STATE Any outstanding RECEIVEs are returned with "error: closing" responses. Delete TCB, enter CLOSED state, and return. SYN-SENT STATE Delete the TCB and return "error: closing" responses to any queued SENDs, or RECEIVEs. SYN-RECEIVED STATE If no SENDs have been issued and there is no pending data to send, then form a FIN segment and send it, and enter FIN-WAIT-1 state; otherwise queue for processing after entering ESTABLISHED state. ESTABLISHED STATE Queue this until all preceding SENDs have been segmentized, then form a FIN segment and send it. In any case, enter FIN-WAIT-1 state. FIN-WAIT-1 STATE FIN-WAIT-2 STATE Strictly speaking, this is an error and should receive a "error: connection closing" response. An "ok" response would be acceptable, too, as long as a second FIN is not emitted (the first FIN may be retransmitted though). [Page 60] September 1981 Transmission Control Protocol Functional Specification CLOSE Call CLOSE-WAIT STATE Queue this request until all preceding SENDs have been segmentized; then send a FIN segment, enter CLOSING state. CLOSING STATE LAST-ACK STATE TIME-WAIT STATE Respond with "error: connection closing". [Page 61] September 1981 Transmission Control Protocol Functional Specification ABORT Call ABORT Call CLOSED STATE (i.e., TCB does not exist) If the user should not have access to such a connection, return "error: connection illegal for this process". Otherwise return "error: connection does not exist". LISTEN STATE Any outstanding RECEIVEs should be returned with "error: connection reset" responses. Delete TCB, enter CLOSED state, and return. SYN-SENT STATE All queued SENDs and RECEIVEs should be given "connection reset" notification, delete the TCB, enter CLOSED state, and return. SYN-RECEIVED STATE ESTABLISHED STATE FIN-WAIT-1 STATE FIN-WAIT-2 STATE CLOSE-WAIT STATE Send a reset segment: <SEQ=SND.NXT><CTL=RST> All queued SENDs and RECEIVEs should be given "connection reset" notification; all segments queued for transmission (except for the RST formed above) or retransmission should be flushed, delete the TCB, enter CLOSED state, and return. CLOSING STATE LAST-ACK STATE TIME-WAIT STATE Respond with "ok" and delete the TCB, enter CLOSED state, and return. [Page 62] September 1981 Transmission Control Protocol Functional Specification STATUS Call STATUS Call CLOSED STATE (i.e., TCB does not exist) If the user should not have access to such a connection, return "error: connection illegal for this process". Otherwise return "error: connection does not exist". LISTEN STATE Return "state = LISTEN", and the TCB pointer. SYN-SENT STATE Return "state = SYN-SENT", and the TCB pointer. SYN-RECEIVED STATE Return "state = SYN-RECEIVED", and the TCB pointer. ESTABLISHED STATE Return "state = ESTABLISHED", and the TCB pointer. FIN-WAIT-1 STATE Return "state = FIN-WAIT-1", and the TCB pointer. FIN-WAIT-2 STATE Return "state = FIN-WAIT-2", and the TCB pointer. CLOSE-WAIT STATE Return "state = CLOSE-WAIT", and the TCB pointer. CLOSING STATE Return "state = CLOSING", and the TCB pointer. LAST-ACK STATE Return "state = LAST-ACK", and the TCB pointer. [Page 63] September 1981 Transmission Control Protocol Functional Specification STATUS Call TIME-WAIT STATE Return "state = TIME-WAIT", and the TCB pointer. [Page 64] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES SEGMENT ARRIVES If the state is CLOSED (i.e., TCB does not exist) then all data in the incoming segment is discarded. An incoming segment containing a RST is discarded. An incoming segment not containing a RST causes a RST to be sent in response. The acknowledgment and sequence field values are selected to make the reset sequence acceptable to the TCP that sent the offending segment. If the ACK bit is off, sequence number zero is used, <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK> If the ACK bit is on, <SEQ=SEG.ACK><CTL=RST> Return. If the state is LISTEN then first check for an RST An incoming RST should be ignored. Return. second check for an ACK Any acknowledgment is bad if it arrives on a connection still in the LISTEN state. An acceptable reset segment should be formed for any arriving ACK-bearing segment. The RST should be formatted as follows: <SEQ=SEG.ACK><CTL=RST> Return. third check for a SYN If the SYN bit is set, check the security. If the security/compartment on the incoming segment does not exactly match the security/compartment in the TCB then send a reset and return. <SEQ=SEG.ACK><CTL=RST> [Page 65] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES If the SEG.PRC is greater than the TCB.PRC then if allowed by the user and the system set TCB.PRC<-SEG.PRC, if not allowed send a reset and return. <SEQ=SEG.ACK><CTL=RST> If the SEG.PRC is less than the TCB.PRC then continue. Set RCV.NXT to SEG.SEQ+1, IRS is set to SEG.SEQ and any other control or text should be queued for processing later. ISS should be selected and a SYN segment sent of the form: <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK> SND.NXT is set to ISS+1 and SND.UNA to ISS. The connection state should be changed to SYN-RECEIVED. Note that any other incoming control or data (combined with SYN) will be processed in the SYN-RECEIVED state, but processing of SYN and ACK should not be repeated. If the listen was not fully specified (i.e., the foreign socket was not fully specified), then the unspecified fields should be filled in now. fourth other text or control Any other control or text-bearing segment (not containing SYN) must have an ACK and thus would be discarded by the ACK processing. An incoming RST segment could not be valid, since it could not have been sent in response to anything sent by this incarnation of the connection. So you are unlikely to get here, but if you do, drop the segment, and return. If the state is SYN-SENT then first check the ACK bit If the ACK bit is set If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send a reset (unless the RST bit is set, if so drop the segment and return) <SEQ=SEG.ACK><CTL=RST> and discard the segment. Return. If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable. second check the RST bit [Page 66] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES If the RST bit is set If the ACK was acceptable then signal the user "error: connection reset", drop the segment, enter CLOSED state, delete TCB, and return. Otherwise (no ACK) drop the segment and return. third check the security and precedence If the security/compartment in the segment does not exactly match the security/compartment in the TCB, send a reset If there is an ACK <SEQ=SEG.ACK><CTL=RST> Otherwise <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK> If there is an ACK The precedence in the segment must match the precedence in the TCB, if not, send a reset <SEQ=SEG.ACK><CTL=RST> If there is no ACK If the precedence in the segment is higher than the precedence in the TCB then if allowed by the user and the system raise the precedence in the TCB to that in the segment, if not allowed to raise the prec then send a reset. <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK> If the precedence in the segment is lower than the precedence in the TCB continue. If a reset was sent, discard the segment and return. fourth check the SYN bit This step should be reached only if the ACK is ok, or there is no ACK, and it the segment did not contain a RST. If the SYN bit is on and the security/compartment and precedence [Page 67] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES are acceptable then, RCV.NXT is set to SEG.SEQ+1, IRS is set to SEG.SEQ. SND.UNA should be advanced to equal SEG.ACK (if there is an ACK), and any segments on the retransmission queue which are thereby acknowledged should be removed. If SND.UNA > ISS (our SYN has been ACKed), change the connection state to ESTABLISHED, form an ACK segment <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK> and send it. Data or controls which were queued for transmission may be included. If there are other controls or text in the segment then continue processing at the sixth step below where the URG bit is checked, otherwise return. Otherwise enter SYN-RECEIVED, form a SYN,ACK segment <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK> and send it. If there are other controls or text in the segment, queue them for processing after the ESTABLISHED state has been reached, return. fifth, if neither of the SYN or RST bits is set then drop the segment and return. [Page 68] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES Otherwise, first check sequence number SYN-RECEIVED STATE ESTABLISHED STATE FIN-WAIT-1 STATE FIN-WAIT-2 STATE CLOSE-WAIT STATE CLOSING STATE LAST-ACK STATE TIME-WAIT STATE Segments are processed in sequence. Initial tests on arrival are used to discard old duplicates, but further processing is done in SEG.SEQ order. If a segment's contents straddle the boundary between old and new, only the new parts should be processed. There are four cases for the acceptability test for an incoming segment: Segment Receive Test Length Window ------- ------- ------------------------------------------- 0 0 SEG.SEQ = RCV.NXT 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND >0 0 not acceptable >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND If the RCV.WND is zero, no segments will be acceptable, but special allowance should be made to accept valid ACKs, URGs and RSTs. If an incoming segment is not acceptable, an acknowledgment should be sent in reply (unless the RST bit is set, if so drop the segment and return): <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK> After sending the acknowledgment, drop the unacceptable segment and return. [Page 69] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES In the following it is assumed that the segment is the idealized segment that begins at RCV.NXT and does not exceed the window. One could tailor actual segments to fit this assumption by trimming off any portions that lie outside the window (including SYN and FIN), and only processing further if the segment then begins at RCV.NXT. Segments with higher begining sequence numbers may be held for later processing. second check the RST bit, SYN-RECEIVED STATE If the RST bit is set If this connection was initiated with a passive OPEN (i.e., came from the LISTEN state), then return this connection to LISTEN state and return. The user need not be informed. If this connection was initiated with an active OPEN (i.e., came from SYN-SENT state) then the connection was refused, signal the user "connection refused". In either case, all segments on the retransmission queue should be removed. And in the active OPEN case, enter the CLOSED state and delete the TCB, and return. ESTABLISHED FIN-WAIT-1 FIN-WAIT-2 CLOSE-WAIT If the RST bit is set then, any outstanding RECEIVEs and SEND should receive "reset" responses. All segment queues should be flushed. Users should also receive an unsolicited general "connection reset" signal. Enter the CLOSED state, delete the TCB, and return. CLOSING STATE LAST-ACK STATE TIME-WAIT If the RST bit is set then, enter the CLOSED state, delete the TCB, and return. [Page 70] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES third check security and precedence SYN-RECEIVED If the security/compartment and precedence in the segment do not exactly match the security/compartment and precedence in the TCB then send a reset, and return. ESTABLISHED STATE If the security/compartment and precedence in the segment do not exactly match the security/compartment and precedence in the TCB then send a reset, any outstanding RECEIVEs and SEND should receive "reset" responses. All segment queues should be flushed. Users should also receive an unsolicited general "connection reset" signal. Enter the CLOSED state, delete the TCB, and return. Note this check is placed following the sequence check to prevent a segment from an old connection between these ports with a different security or precedence from causing an abort of the current connection. fourth, check the SYN bit, SYN-RECEIVED ESTABLISHED STATE FIN-WAIT STATE-1 FIN-WAIT STATE-2 CLOSE-WAIT STATE CLOSING STATE LAST-ACK STATE TIME-WAIT STATE If the SYN is in the window it is an error, send a reset, any outstanding RECEIVEs and SEND should receive "reset" responses, all segment queues should be flushed, the user should also receive an unsolicited general "connection reset" signal, enter the CLOSED state, delete the TCB, and return. If the SYN is not in the window this step would not be reached and an ack would have been sent in the first step (sequence number check). [Page 71] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES fifth check the ACK field, if the ACK bit is off drop the segment and return if the ACK bit is on SYN-RECEIVED STATE If SND.UNA =< SEG.ACK =< SND.NXT then enter ESTABLISHED state and continue processing. If the segment acknowledgment is not acceptable, form a reset segment, <SEQ=SEG.ACK><CTL=RST> and send it. ESTABLISHED STATE If SND.UNA < SEG.ACK =< SND.NXT then, set SND.UNA <- SEG.ACK. Any segments on the retransmission queue which are thereby entirely acknowledged are removed. Users should receive positive acknowledgments for buffers which have been SENT and fully acknowledged (i.e., SEND buffer should be returned with "ok" response). If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. If the ACK acks something not yet sent (SEG.ACK > SND.NXT) then send an ACK, drop the segment, and return. If SND.UNA < SEG.ACK =< SND.NXT, the send window should be updated. If (SND.WL1 < SEG.SEQ or (SND.WL1 = SEG.SEQ and SND.WL2 =< SEG.ACK)), set SND.WND <- SEG.WND, set SND.WL1 <- SEG.SEQ, and set SND.WL2 <- SEG.ACK. Note that SND.WND is an offset from SND.UNA, that SND.WL1 records the sequence number of the last segment used to update SND.WND, and that SND.WL2 records the acknowledgment number of the last segment used to update SND.WND. The check here prevents using old segments to update the window. [Page 72] September 1981 Transmission Control Protocol Functional Specification SEGMENT ARRIVES FIN-WAIT-1 STATE In addition to the processing for the ESTABLISHED state, if our FIN is now acknowledged then enter FIN-WAIT-2 and continue processing in that state. FIN-WAIT-2 STATE In addition to the processing for the ESTABLISHED state, if the retransmission queue is empty, the user's CLOSE can be acknowledged ("ok") but do not delete the TCB.