Please indicate the source: http://blog.csdn.net/gaoxiangnumber1
Welcome to my github: https://github.com/gaoxiangnumber1
18.1 Introduction
18.2 Connection Establishment and Termination
- To see what happens when a TCP connection is established and then terminated, we type the following command on the system svr4:
svr4 % telnet bsdi discard
Trying 192.82.148.3 ...
Connected to bsdi.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
- The telnet command establishes a TCP connection with the host bsdi on the port corresponding to the discard service(Section 1.12).
tcpdump Output
- Figure 18.1 shows the tcpdump output for the segments generated by this command.
- These seven TCP segments contain TCP headers only. For TCP segments, each output line begins with
source > destination: flags
where flags represents four of the six flag bits in the TCP header(the other two flag bits(ACK and URG) are printed specially). Figure 18.2 shows the five different characters that can appear in the flags output.
- Line 1:
1415531521:1415531521(0)
means the sequence number of the packet was 1415531521 and the number of data bytes was 0. tcpdump displays this by printing the starting sequence number, a colon, the implied ending sequence number, and the number of data bytes in parentheses.
- The implied ending sequence number is output only if
(1) the segment contains one or more bytes of data, or
(2) the SYN, FIN, or RST flag was on.
Lines 1, 2, 4, and 6 display this field because of the flag bits.
- Line 2:
ack 1415531522
shows the acknowledgment number. This is printed only if the ACK flag in the header is on.
- The field
win 4096
in every line of output shows the window size being advertised by the sender. Since we are not exchanging any data in this case, the window size never changes from its default of 4096.(Section 20.4.)
- The field
<mss 1024>
shows the maximum segment size(MSS) option specified by the sender. The sender does not want to receive TCP segments larger than this value.
Time Line
- Figure 18.3 shows the time line for this sequence of packets.
Connection Establishment Protocol
- The requesting end sends a SYN segment specifying the port number of the server that the client wants to connect to, and the client’s initial sequence number (1415531521 in this case). This is segment 1.
- The server responds with its own SYN segment containing the server’s initial sequence number(segment 2). The server also acknowledges the client’s SYN by ACK the client’s ISN plus one. A SYN consumes one sequence number.
- The client must acknowledge this SYN from the server by ACK the server’s ISN plus one(segment 3).
- The side that sends the first SYN is said to perform an active open. The other side, which receives this SYN and sends the next SYN, performs a passive open. In Section 18.8 we describe a simultaneous open where both sides can do an active open.
- When each end sends its SYN to establish the connection, it chooses an initial sequence number for that connection. The ISN should change over time so that each connection has a different ISN. The purpose in sequence numbers is to prevent packets that get delayed in the network from being delivered later and then misinterpreted as part of an existing connection.
- The 4.1 seconds gap between segments 3 and 4 is the time between establishing the connection and typing the quit command to telnet to terminate the connection.
Connection Termination Protocol
- Since a TCP connection is full-duplex, each direction must be shut down independently. The rule is that either end can send a FIN when it is done sending data. When a TCP receives a FIN, it must notify the application that the other end has terminated that direction of data flow. A TCP can still send data after receiving a FIN.
- We say that the end that first issues the close performs the active close and the other end performs the passive close. We’ll see in Section 18.9 how both ends can do an active close.
- Segment 4 in Figure 18.3 initiates the termination of the connection and is sent when the Telnet client closes its connection(i.e., when we type quit). This causes the client TCP to send a FIN, closing the flow of data from the client to the server.
- When the server receives the FIN, it sends back an ACK of the received sequence number plus one(segment 5). At this point the server’s TCP delivers an end-of-file to the application(the discard server). The server then closes its connection, causing its TCP to send a FIN(segment 6), which the client TCP must ACK by incrementing the received sequence number by one(segment 7).
- Figure 18.4. In this figure sending the FINs is caused by the applications closing their end of the connection, whereas the ACKs of these FINs are automatically generated by the TCP software.
Normal tcpdump Output
- The default tcpdump output shows the complete sequence numbers only on the SYN segments, and shows all following sequence numbers as relative offsets from the original sequence numbers.(To generate the output for Figure 18.1 we had to specify the -S option.) The normal tcpdump output corresponding to Figure 18.1 is shown in Figure 18.5.
18.3 Timeout of Connection Establishment
- There are several instances when the connection cannot be established. If the server host is down, Figure 18.6 shows the tcpdump output.
- To see how long the client’s TCP keeps retransmitting before giving up, we have to time the telnet command:
bsdi % date ; telnet svr4 discard ; date
Thu Sep 24 16:24:11 MST 1992
Trying 192.82.148.2...
telnet: Unable to connect to remote host: Connection timed out
Thu Sep 24 16:25:27 MST 1992
- The time difference is 76 seconds. Most Berkeley-derived systems set a time limit of 75 seconds on the establishment of a new connection.
First Timeout Period
- In Figure 18.6, the first timeout period is 5.8 seconds, close to 6 seconds, while the second period is almost exactly 24 seconds.
- BSD implementations of TCP run a timer that goes off every 500 ms. This 500-ms timer is used for various TCP timeouts. When we type in the telnet command, an initial 6-second timer is established(12 clock ticks), but it may expire anywhere between 5.5 and 6 seconds in the future. Figure 18.7 shows what’s happening.
- Although the timer is initialized to 12 ticks, the first decrement of the timer can occur between 0 and 500 ms after it is set. From that point on the timer is decremented about every 500 ms.(We use “about” because the time when TCP gets control every 500 ms can be preempted by other interrupts being handled by the kernel.) When that 6-second timer expires at the tick labeled 0 in Figure 18.7, the timer is reset for 24 seconds(48 ticks) in the future.
Type-of-Service Field
- In Figure 18.6, the notation
tos 0x10
is the type-of-service(TOS) field in the IP datagram(Figure 3.2).
18.4 Maximum Segment Size
- The maximum segment size(MSS) is the largest chunk of data that TCP will send to the other end. When a connection is established, each end can announce its MSS. The resulting IP datagram is normally 40 bytes larger: 20 bytes for the TCP header and 20 bytes for the IP header.
- When a connection is established, each end has the option of announcing the MSS it expects to receive.(An MSS option can only appear in a SYN segment.) If one end does not receive an MSS option from the other end, a default of 536 bytes is assumed.
- In general, the larger the MSS the better, until fragmentation occurs.(See Figures 24.3 and 24.4 for a counterexample.) A larger segment size allows more data to be sent in each segment, amortizing the cost of the IP and TCP headers.
- When TCP sends a SYN segment, it can send an MSS value up to the outgoing interface’s MTU, minus the size of the fixed TCP and IP headers. For an Ethernet this implies an MSS of up to 1460 bytes(1500 - 20 TCP header - 20 IP header).
- If the destination IP address is “nonlocal,” the MSS normally defaults to 536:
- A destination whose IP address has the same network ID and the same subnet ID as ours is local.
- A destination whose IP address has a different network ID from ours is nonlocal.
- A destination with the same network ID but different subnet ID could be either local or nonlocal.
- The MSS lets a host limit the size of datagrams that the other end sends, it also limit the size of the datagrams that this host sends, so avoid fragmentation when the host is connected to a network with a small MTU.
- Figure 18.8: host slip that has a SLIP link with an MTU of 296 to the router bsdi.
- We initiate a TCP connection from sun to slip and watch the segments using tcpdump. Figure 18.9 shows the connection establishment:
- Since the outgoing interface’s MTU is 296, even though sun announced an MSS of 1460, slip will never send more than 256 bytes of data, to avoid fragmentation. It’s OK for a system to send less than the MSS announced by the other end.
- This avoidance of fragmentation works only if either host is directly connected to a network with an MTU of less than 576. If both hosts are connected to Ethernets, and both announce an MSS of 536, but an intermediate network has an MTU of 296, fragmentation will occur. The only solution is to use the path MTU discovery(Section 24.2).
18.5 TCP Half-Close
- TCP allows one end of a connection to terminate its output, while receiving data from the other end. This is called a half-close. The sockets API supports the half-close: call
shutdown
with a second argument of 1, instead of calling close. Figure 18.10. Either end can initiate the half-close.
18.6 TCP State Transition Diagram
- Figure 18.12.
- The transition from LISTEN to SYN_SENT is legal but is not supported in Berkeley-derived implementations.
- The transition from SYN_RCVD to LISTEN is valid only if the SYN_RCVD state was entered from the LISTEN state(the normal scenario), not from the SYN_SENT state(a simultaneous open). This means if we perform a passive open(enter LISTEN), receive a SYN, send a SYN with an ACK(enter SYN_RCVD), and then receive a reset instead of an ACK, the end point returns to the LISTEN state and waits for another connection request to arrive.
2MSL Wait State
- The TIME_WAIT state is also called the 2MSL wait state. Implementation must choose a value for the maximum segment lifetime(MSL) that is the maximum amount of time any segment can exist in the network before being discarded. This time limit is bounded since TCP segments are transmitted as IP datagrams, and the IP datagram has the TTL field that limits its lifetime.
- RFC 793 specifies the MSL as 2 minutes. Common implementation values are 30 seconds, 1 minute, or 2 minutes. The real-world limit on the lifetime of the IP datagram is based on the number of hops, not a timer.
- Given the MSL value, the rule is that when TCP performs an active close and sends the final ACK, that connection must stay in the TIME_WAIT state for twice the MSL. This lets TCP resend the final ACK in case this ACK is lost(in which case the other end will time out and retransmit its final FIN).
- While the TCP connection is in the 2MSL wait, the socket pair
bsdi % sock -bl098 sun 6666
connected on 140.252.13.35.1098 to 140.252.13.33.6666
- It works: this is a violation of the TCP specification, but is supported by Berkeley-derived implementations. These implementations allow a new connection request to arrive for a connection that is in the TIME_WAIT state, if the new sequence number is greater than the final sequence number from the previous incarnation of this connection. In this case the ISN for the new incarnation is set to the final sequence number from the previous incarnation plus 128000. The appendix of RFC 1185 shows the pitfalls with this technique.
- This feature lets a client and server continually reuse the same port number at each end for successive incarnations of the same connection, but only if the server does the active close.
Quiet Time Concept
- The 2MSL wait provides protection against delayed segments from an earlier incarnation of a connection from being interpreted as part of a new connection that uses the same local and foreign IP addresses and port numbers. But this works only if a host with connections in the 2MSL wait does not crash.
- If a host with ports in the 2MSL wait crashes, reboots within MSL seconds, and immediately establishes new connections using the same local and foreign IP addresses and port numbers corresponding to the local ports that were in the 2MSL wait before the crash: delayed segments from the connections that existed before the crash can be misinterpreted as belonging to the new connections created after the reboot. This can happen regardless of how the initial sequence number is chosen after the reboot.
- To protect against this scenario, RFC 793 states that TCP should not create any connections for MSL seconds after rebooting. This is called the quiet time.
FIN WAIT 2 State
- In the FIN_WAIT_2 state we have sent our FIN and the other end has acknowledged it. Unless we have done a half-close, we are waiting for the application on the other end to recognize that it has received an end-of-file notification and close its end of the connection, which sends us a FIN. Only when the process at the other end does this close will our end move from the FIN_WAIT_2 to the TIME_WAIT state.
- This means our end of the connection can remain in this state forever. The other end is still in the CLOSE_WAIT state, and can remain there forever, until the application decides to issue its close.
- Berkeley-derived implementations prevent this infinite wait in the FIN_WAIT_2 state as follows. If the application that does the active close does a close, not a half-close, then a timer is set. If the connection is idle for 10 minutes plus 75 seconds, TCP moves the connection into the CLOSED state.
18.7 Reset Segments
- A reset is sent by TCP whenever a segment arrives that doesn’t appear correct for the connection specified by
bsdi % telnet: svr4 20000
Trying 140.252.13.34...
telnet: Unable to connect to remote host: Connection refused
- This error message is output by the Telnet client immediately. Figure 18.14 shows the packet exchange corresponding to this command.
-
- Because the ACK bit was not on in the arriving segment, the sequence number of the reset is set to 0.
- The acknowledgment number is set to the incoming ISN plus the number of data bytes in the segment. Though there is no data in the arriving segment, the SYN bit occupies 1 byte of sequence number space; so, the acknowledgment number in the reset is (ISN + data length(0) + 1(SYN bit)).
Aborting a Connection
- The normal way to terminate a connection is for one side to send a FIN. This is also called an orderly release since the FIN is sent after all previously queued data has been sent, and there is normally no loss of data. But we can abort a connection by sending a reset instead of a FIN. This is also called an abortive release.
- Aborting a connection provides two features to the application:
(1) any queued data is thrown away and the reset is sent immediately; and
(2) the receiver of the RST can tell that the other end did an abort instead of a normal close.
- The sockets API provides this capability by using the “linger on close” socket option (SO_LINGER). We specify the -L option with a linger time of 0. This causes the abort to be sent when the connection is closed, instead of the normal FIN.
bsdi % sock -L0 svr4 8888 #this is the client; server shown later
hello, world #type one line of input that's sent to other end
^D #type end-of-file character to terminate client
- Figure 18.15 shows the tcpdump output for this example. We have deleted all the window advertisements in this figure.
- Lines 1-3 show the normal connection establishment.
Line 4 sends the data line that we typed(12 characters plus the newline character).
Line 5 is the acknowledgment of the received data.
- Line 6 corresponds to our end-of-file character(Control-D) to terminate the client. Since we specified an abort instead of a normal close(the -L0 command-line option), the TCP on bsdi sends an RST RST segment that contains a sequence number and acknowledgment number.
- The receiver of the reset aborts the connection without acknowledging the RST and advises the application that the connection was reset. We get the following error on the server for this exchange:
svr4 % sock -s 8888 #run as server, listen on port 8888
hello, world #this is what the client sent over
read error: Connection reset by peer
- This server reads from the network and copies whatever it receives to standard output. It normally ends by receiving an end-of-file notification from its TCP, but here it receives an error when the RST arrives.
Detecting Half-Open Connections
- A TCP connection is said to be half-open if one end has closed or aborted the connection without the knowledge of the other end. This can happen any time one of the two hosts crashes. As long as there is no attempt to transfer data across a half-open connection, the end that’s still up won’t detect that the other end has crashed.
- Another cause of a half-open connection is when a client host is powered off, instead of terminating the client application and then shutting down the client host. If there was no data transfer going on when the host powered off, the server will never detect that the client disappeared. When the user powers on the PC and starts a new client, a new occurrence of the server is started on the server host. This can lead to many half-open TCP connections on the server host. In Chapter 23 there is a way for one end of a TCP connection to discover that the other end has disappeared using TCP’s keep-alive option.
-
- We execute the Telnet client on bsdi, connecting to the discard server on svr4.
- We type one line of input, and watch it go across with tcpdump, and then disconnect the Ethernet cable on the server’s host, and reboot the server host. This simulates the server host crashing.(We disconnect the Ethernet cable before rebooting the server to prevent it from sending a FIN out the open connections, which some TCPs do when they are shut down.)
- After the server has rebooted, we reconnect the cable, and try to send another line from the client to the server.
- Since the server’s TCP has rebooted and lost all memory of the connections that existed before it was rebooted, the receiver responds with a reset.
bsdi % telnet svr4 discard
Trying 140.252.13.34...
Connected to svr4.
Escape character is '^]'
hi there
another line
Connection closed by foreign host.
- Figure 18.16 shows the tcpdump output for this example. We have removed the window advertisements, the type-of-service information, and the MSS announcements.
- Lines 1-3 are the normal connection establishment.
Line 4 sends the line “hi there” to the discard server.
Line 5 is the acknowledgment.
- At this point we disconnect the Ethernet cable from svr4, reboot it, and reconnect the cable. This takes almost 190 seconds. We then type the next line of input to the client (“another line”) and when we type the return key the line is sent to the server(line 6).
- Since the server was rebooted, its ARP cache is empty, so an ARP request and reply are required(lines 7 and 8).
- The reset is sent in line 9. The client receives the reset and outputs that the connection was terminated by the foreign host.
18.8 Simultaneous Open
- Two applications may both perform an active open to each other at the same time. Each end transmit a SYN, and the SYNs pass each other on the network. It requires each end to have a local port number that is well known to the other end. This is called a simultaneous open.
- Figure 18.12. The rule for TCP is that only one connection results from this, not two. Both ends send a SYN at the same time, entering the SYN_SENT state. When each end receives the SYN, the state changes to SYN_RCVD, and each end resends the SYN and acknowledges the received SYN. When each end receives the SYN plus the ACK, the state changes to ESTABLISHED. Figure 18.17.
- One end(bsdi) assigns itself a local port of 8888(the -b command-line option) and performs an active open to port 7777 on the other host:
bsdi % sock -v -b8888 vangogh.cs.berkeley.edu 7777
connected on 140.252.13.35.8888 to 128.32.130.2.7777
TCP_MAXSEG = 512
hello, world #we type this line
and hi there #this line was typed on other end
connection closed by peer #this is output when FIN received
- The other end is started at about the same time, assigns itself a local port of 7777, and performs an active open to port 8888:
vangogh % sock -v -b7777 bsdi.edu 8888
connected on 128.32.130.2.7777 to 140.252.13.35.8888
TCP_MAXSEG = 512
hello, world #this is typed on the other end
and hi there #we type this line
^D #and then type our EOF character
- We specify the -v flag to verify the IP address and port numbers on each end of the connection. This flag prints the MSS used by each end of the connection. We type in one line on each end, which is sent to the other end and printed, to verify that both ends are indeed talking to each other.
- Figure 18.18. The two SYNs(lines 1 and 2) followed by the two SYNs with ACKs (lines 3 and 4). These perform the simultaneous open.
- Line 5 shows the input line “hello, world” going from bsdi to vangogh, with the acknowledgment in line 6. Lines 7 and 8 correspond to the line “and hi there” going in the other direction. Lines 9-12 show the normal connection termination.
18.9 Simultaneous Close
- TCP allows simultaneous close that both sides perform an active close. Both ends go from ESTABLISHED to FIN_WAIT_1 when the application issues the close. This causes both FINs to be sent, and they pass each other in the network. When the FIN is received, each end transitions from FIN_WAIT_1 to the CLOSING state, and each state sends its final ACK. When each end receives the final ACK, the state changes to TIME_WAIT. Figure 18.19.
18.10 TCP Options
- The TCP header can contain options. Figure 18.20 shows the format of the TCP options from RFC 793 and RFC 1323.
- Every option begins with a 1-byte kind that specifies the type of option. The options with a kind of 0 and 1 occupy a single byte. The other options have a len byte that follows the kind byte. The length is the total length, including the kind and len bytes.
- The no operation(NOP) option allows the sender to pad fields to a multiple of 4 bytes. If we initiate a TCP connection from a 4.4BSD system, the following TCP options are output by tcpdump on the initial SYN segment:
<mss 512,nop,wscale 0,nop,nop,timestamp 146647 0>
- The first NOP pad the 3-byte window scale option to a 4-byte boundary. The IO-byte timestamp option is preceded by two NOP to occupy 12 bytes, placing the two 4-byte timestamps onto 4-byte boundaries.
- Four other options are proposed with kinds of 4, 5, 6, and 7 called the selective-ACK and echo options. The T/TCP proposal for TCP transactions(Section 24.7) specifies three options with kinds of 11, 12, and 13.
18.11 TCP Server Design
- How are the port numbers handled when a server accepts a new connection request from a client?
What happens if multiple connection requests arrive at about the same time?
TCP Server Port Numbers
- We watch the Telnet server using the netstat command. The following output is on a system with no active Telnet connections.
sun % netstat -a -n -f inet
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp 0 0 *.23 *.* LISTEN
- -a reports all network end points.
-n prints IP addresses as dotted-decimal numbers and prints numeric port numbers.
-f inet option reports only TCP and UDP end points.
- The local address is .23( is also called the wildcard character) which means that an incoming connection request(i.e., a SYN) will be accepted on any local interface. If the host were multihomed, we could specify a single IP address for the local IP address(one of the host’s IP addresses), and only connections received on that interface would be accepted. Port 23 is the well-known port number for Telnet.
- We now start a Telnet client on the host slip(140.252.13.65) that connects to this server.
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp 0 0 140.252.13.33.23 140.252.13.65.1029 ESTABLISHED
tcp 0 0 *.23 *.* LISTEN
- The first line for port 23 is the ESTABLISHED connection. The local IP address corresponds to the interface on which the connection request arrived(the Ethernet interface, 140.252.13.33).
- The end point in the LISTEN state is used by the concurrent server to accept future connection requests.
- We now initiate another Telnet client from the same client(slip) to this server.
Proto Send-Q Recv-Q Local Address Foreign Address (state)
tcp 0 0 140.252.13.33.23 140.252.13.65.1030 ESTABLISHED
tcp 0 0 140.252.13.33.23 140.252.13.65.1029 ESTABLISHED
tcp 0 0 *.23 *.* LISTEN
- TCP demultiplexes incoming segments using four values
Proto Send-Q Recv-Q Local Address Foreign Address (state)
tcp 0 0 140.252.1.29.23 140.252.1.32.34603 ESTABLISHED
tcp 0 0 140.252.13.33.23 140.252.13.65.1030 ESTABLISHED
tcp 0 0 140.252.13.33.23 140.252.13.65.1029 ESTABLISHED
tcp 0 0 *.23 *.* LISTEN
- The local IP address of the first ESTABLISHED connection now corresponds to the interface address of SLIP link on the multihomed host sun(140.252.1.29).
Restricting Local IP Address
- What happens when the server sets its local IP address to one particular local interface address? If we specify an IP address to sock when we invoke it as a server, that IP address becomes the local IP address of the listening end point.
sun % sock -s 140.252.1.29 8888
restricts this server to connections arriving on the SLIP interface(140.252.1.29). The netstat output reflects this:
Proto Send-Q Recv-Q Local Address Foreign Address (state)
tcp 0 0 140.252.1.29.8888 *.* LISTEN
- If we connect to this server across the SLIP link, from the host solaris, it works.
Proto Send-Q Recv-Q Local Address Foreign Address (state)
tcp 0 0 140.252.1.29.8888 140.252.1.32.34614 ESTABLISHED
tcp 0 0 140.252.1.29.8888 *.* LISTEN
- But if we try to connect to this server from a host on the Ethernet(140.252.13), the connection request is not accepted by TCP. If we watch it with tcpdump, the SYN is responded to with an RST, Figure 18.21.
- The server application never sees the connection request since the rejection is done by the kernel’s TCP module based on the local IP address specified by the application.
Restricting Foreign IP Address
- Section 11.12: a UDP server can specify the foreign IP address and foreign port in addition to specifying the local IP address and local port.
- RFC 793 allow a server doing a passive open to have either a fully specified foreign socket(to wait for a particular client to issue an active open) or a unspecified foreign socket(to wait for any client). But most APIs don’t provide a way to do this. The server must leave the foreign socket unspecified, wait for the connection to arrive, and then examine the IP address and port number of the client.
- Figure 18.22 summarizes the three types of address bindings that a TCP server can establish for itself. The ordering of the three rows is the order that TCP applies when trying to determine which local end point receives an incoming connection request.
Incoming Connection Request Queue
- A concurrent server invokes a new process to handle each client, so the listening server should always be ready to handle the next incoming connection request.
How does TCP handle incoming connection requests while the listening server is creating a new process, or while the operating system is running other processes?
For Berkeley-derived implementations, the following rules apply:
- Each listening end point has a fixed length queue of connections that have been accepted by TCP(i.e., the three-way handshake is complete), but not yet accepted by the application.
- The application specifies a limit, called backlog, on this queue whose value must be belong to [0, 5].
Figure 18.23: the relationship between backlog and the real maximum number of queued connections. backlog specifies only the maximum number of queued connections for one listening end point, all of which have been accepted by TCP and are waiting to be accepted by the application. backlog has no effect on the maximum number of established connections allowed by the system, or on the number of clients that a concurrent server can handle concurrently.
- When a connection request arrives(i.e., the SYN segment), TCP check the current number of connections already queued for this listening end point, to see whether to accept the connection or not.
- If there is room on this listening end point’s queue for new connection, TCP ACKs the SYN and completes the connection. The server won’t see this new connection until the third segment of the three-way handshake is received.
The client may think the server is ready to receive data when the client’s active open completes successfully, before the server has been notified of the new connection. If this happens, the server’s TCP just queues the incoming data.
- If there is no room on the queue for the new connection, TCP ignores the received SYN with nothing sent back(i.e., no RST segment). If the server doesn’t accept some of the already accepted connections that have filled its queue to the limit, the client’s active open will eventually time out.
- We invoke sock with option(O) that tells it to pause after creating the listening end point, before accepting any connection requests. If we then invoke multiple clients during this pause period, it should cause the server’s queue of accepted connections to fill, and we can see what happens with tcpdump.
bsdi % sock -a -v -q1 -O30 7777
-q1 sets the backlog of the listening end point to 1, which for BSD should allow two pending connection requests(Figure 18.23).
-O30 causes the program to sleep for 30 seconds before accepting any client connections. This gives us 30 seconds to start some clients, to fill the queue. We’ll start four clients on the host sun.
- Figure 18.24.
- The first connection request from port 1090 is accepted(segments 1-3).
- The second connection request from port 1091 is also accepted(segments 4-6).
- Now, the server is still asleep, and has not accepted either connection yet. Everything has been done by the TCP module in the kernel. The two clients have returned successfully from their active opens.
- We start a third client in segment 7(port 1092), and a fourth in segment 8(port 1093). TCP ignores both SYNs since the queue for this listening end point is full. Both clients retransmit their SYNs in segments 9, 10, 11, 12, and 15.
- The fourth client’s third retransmission is accepted(segments 12-14) because the server’s 30-second pause is over, causing the server to remove the two connections that were accepted, emptying its queue.
The third client’s fourth retransmission is then accepted(segments 15-17).
- The fourth client connection(port 1093) is accepted by the server before the third client connection(port 1092) because of the timing interactions between the server’s 30-second pause and the client’s retransmissions.
- TCP ignores the incoming SYN when the queue is full and doesn’t respond with an RST because this is a soft error, not a hard error. By ignoring the SYN, the server forces the client TCP to retransmit the SYN later, hoping that the queue will then have room for the new connection.
18.12 Summary
Exercise 18.1
In Section 18.2 we said that the initial sequence number(ISN) normally starts at 1 and is incremented by 64000 every half-second and every time an active open is performed. This imply that the low-order three digits of the ISN would always be 001. But in Figure 18.3 these low-order three digits are 521 in each direction. What’s going on?
Exercise 18.2
In Figure 18.15 we typed 12 characters and saw 13 bytes sent by TCP. In Figure 18.16 we typed eight characters but TCP sent 10 bytes. Why was 1 byte added in the first case, but 2 bytes in the second case?
- In the first case we used sock program, by default it transmits the newline character as itself-the single ASCII character 012(octal).
- In the second case we used the Telnet client and it converts the Unix newline into two ASCII characters-a carriage return(octal 015) followed by a linefeed(octal 012).
Exercise 18.3
What’s the difference between a half-open connection and a half-closed connection?
- On a half-closed connection one end has sent a FIN and is waiting for either data or a FIN from the other end.
- A half-open connection is when one end crashes, unknown to the other end.
Exercise 18.4
If we start our sock program as a server, and then terminate it(without having a client connect to it), we can immediately restart the server. This implies that it doesn’t go through the 2MSL wait state. Explain this in terms of the state transition diagram.
- The 2MSL wait state is only entered for a connection that has gone through the ESTABLISHED state.
Exercise 18.5
In Section 18.6 we showed that a client cannot reuse the same local port number while that port is part of a connection in the 2MSL wait. But if we run our sock program twice in a row as a client, connecting to the daytime server, we can reuse the same local port number. Additionally, we’re able to create a new incarnation of a connection that should be in the 2MSL wait. What’s going on?
sun % sock -v bsdi daytime
connected on 140.252.13.33.1163 to 140.252.13.35.13
Wed Jul 7 07:54:51 1993
connection closed by peer
sun % sock -v -bll63 bsdi daytime reuse same local port number
connected on 140.252.13.33.1163 to 140.252.13.35.13
Wed Jul 707:55:01 1993
connection closed by peer
- First, the daytime server does the active close of the TCP connection after writing the time and date to the client. The client’s end of the connection goes through the passive close states that puts the socket pair in the TIME_WAIT state on the server, not the client.
- Next, Berkeley-derived implementations allow a new connection request to arrive for a socket pair currently in the TIME_WAIT state.
Exercise 18.6
At the end of Section 18.6 when describing the FIN_WAIT_2 state, we mentioned that many implementations move a connection from this state into the CLOSED state if the application did a complete close(not a half-close) after just over 11 minutes. If the other end(in the CLOSE_WAIT state) waited 12 minutes before issuing its close(i.e., sending its FIN), what would its TCP get in response to the FIN?
- A reset is sent in response to the FIN because the FIN arrived for a connection that was CLOSED.
Exercise 18.7
Which end of a telephone conversation does the active open, and which does the passive open? Are simultaneous opens allowed? Are simultaneous closes allowed?
Exercise 18.8
In Figure 18.6 we don’t see an ARP request or an ARP reply. Obviously the hardware address for host svr4 must be in the ARP cache on bsdi. What would change in this figure if this ARP cache entry was not present?
- We would only see ARP requests, not TCP SYN segments, but the ARP requests would have the same timing as in the figure.
Exercise 18.9
Explain the following tcpdump output. Compare it with Figure 18.13.
- The client’s ACK of the server’s SYN is combined with the first data segment from the client(line 3). This is legal under the rules of TCP. Next, the client sends its FIN(line 4) before waiting for the ACK of its data. This allows the server to acknowledge both the data and the FIN in line 5.
- This exchange(sending one segment of data from the client to the server) requires seven segments. The normal connection establishment and termination(Figure 18.13), along with a single data segment and its acknowledgment, requires nine segments.
Exercise 18.10
Why doesn’t the server in Figure 18.4 combine the ACK of the client’s FIN with its own FIN, reducing the number of segments to three?
- First, the server’s ACK of the client’s FIN is not delayed(delayed ACKs in Section 19.3) but sent as soon as the FIN arrives. It takes the application a while to receive the EOF and tell its TCP to close its end of the connection.
- Second, the server that receives the FIN does not have to close its end of the connection on receiving the FIN from the client. data can still be sent.
Exercise 18.11
In Figure 18.16 why is the sequence number of the RST 26368002?
- If an arriving segment that generates an RST has an ACK field, the sequence number of the RST is the arriving ACK field. The ACK value of 1 in line 6 is relative to the ISN of 26368001 in line 2.
Exercise 18.12
Does TCP’s querying the link layer for the MTU violate the spirit of layering?
Exercise 18.13
Assume in Figure 14.16 that each DNS query is issued using TCP instead of UDP. How many packets are exchanged?
Exercise 18.14
With an MSL of 120 seconds, what is the maximum at which a system can initiate new connections and then do an active close?
- The limit is about 268 connections per second: the maximum number of TCP port numbers(65536 -1024 = 64512, ignoring the well-known ports) divided by the TIME_WAIT state of 2MSL.
Exercise 18.15
Read RFC 793 to see what happens when an end point that is in the TIME_WAIT state receives a duplicate of the FIN that placed it into this state.
- The duplicate FIN is acknowledged and the 2MSL timer is restarted.
Exercise 18.16
Read RFC 793 to see what happens when an end point that is in the TIME_WAIT state receives an RST.
- The receipt of an RST while in the TIME_WAIT state causes the state to be prematurely terminated. This is called TIME_WAIT assassination. RFC 1337 discusses this in detail and shows the potential problems. The fix proposed by this RFC is to ignore RST segments while in the TIME_WAIT state.
Exercise 18.17
Read the Host Requirements RFC to obtain the definition of a half-duplex TCP close.
- It’s when the implementation does not support a half-close. Once the application causes a FIN to be sent, the application can no longer read from the connection.
Exercise 18.18
In Figure 1.8 we said that incoming TCP segments are demultiplexed based on the destination TCP port number. Is that correct?
- No. Incoming data segments are demultiplexed using the source IP address, source port number, destination IP address, and destination port number. For incoming connection requests we saw in Section 18.11 that a TCP server can normally prevent connections from being accepted based on the destination IP address.
Please indicate the source: http://blog.csdn.net/gaoxiangnumber1
Welcome to my github: https://github.com/gaoxiangnumber1