The Transmission Control Protocol (TCP)


As we have discussed so far, the IP protocol is a protocol that can be used to make a best-effort attempt to get a packet from one host to another, even when the hosts are on different networks. The Transmission Control Protocol uses IP but adds functionality that makes TCP a reliable, connection-oriented protocol. Whereas IP doesn't require any acknowledgment that a packet is ever received, TCP does. Whereas IP does no preliminary communication with the target system to set up any kind of session, TCP does. TCP builds on the functions that IP provides to create a session that can be used by applications for a reliable exchange of data. As stated earlier in this chapter, IP is similar to sending a letter in the mail. TCP can be compared to the "return receipt requested" function which acknowledges that the letter was received by someone at the destination address. One interesting difference, however, is that TCP doesn't necessarily need an acknowledgment for each packet sent. Instead, it is possible for a single acknowledgment to be sent in response to more than one IP packet.

TCP Provides a Reliable Connection-Oriented Session

Whereas IP provides a checksum mechanism in its header to ensure that the IP header is not corrupted during transit, the TCP protocol provides checksums on the data that is transmitted. TCP also has mechanisms that regulate the flow of data to avoid problems associated with congestion. TCP also uses sequence numbers in the TCP header so that IP packets can be reassembled in the correct order on the receiving end of the communication.

Examining TCP Header Information

Each layer in the TCP/IP protocol stack adds information to the data it receives from a layer above it. This process is usually called encapsulation, and the added data is usually called a header. The header information is significant only to the layer that adds it, and it is added as a message is passed down the stack and stripped off at the destination as the packet is passed back up the protocol stack. Some layers also add data at the end of the packet. This is called a trailer.

Earlier we looked at the makeup of the IP header. In Figure 24.6 you can see the layout of the TCP header. This header information is sometimes referred to as the TCP Protocol Data Unit.

Remember that TCP is responsible for establishing a reliable connection-oriented session between two applications across a network. TCP receives data (called messages) from layers above it in the protocol stack, adds its own header information, and then passes it to the IP layer, which then adds its own header information. The messages sent to TCP from applications up the stack are usually called a stream of data, because the amount of data can vary and is not limited to a set number of bytes. TCP takes these messages and, if they are too large to fit into a packet, breaks them into smaller segments and sends each segment in a separate packet. The TCP layer at the receiving end reassembles these messages before passing them up to an application.

Note

Don't confuse the fact that TCP can break up large messages into smaller units before it passes them to IP with the process of IP fragmentation. These are not the same thing. TCP processes messages from applications that use it and breaks up these messages into an appropriate size for the IP layer. The IP layer, on the local computer or on another device that is in the path the packet takes to reach its destination, can further fragment the IP packets. At the end, the IP packets are reassembled before being given to the TCP layer, which then reassembles any messages it might have chopped up before passing them up to the application.


Whereas most of the header information we looked at in the IP header was used for routing the packet through the Internet, the information in the TCP header is concerned with other issues, such as reliability of the connection and ordering of the messages being sent. The header fields for TCP include these:

  • Source port This 16-bit field is used to identify the port being used by the application that is sending the data. Ports are discussed in more detail later in this chapter.

  • Destination port This 16-bit field is used to identify the port to which the packet will be delivered on the receiving end of the connection.

  • Sequence number This 32-bit field is used to identify where a segment fits in the larger message when a message is broken into fragments for transmission.

  • Acknowledgment number This 32-bit field is used to indicate what the next sequence number should be. That is, this value is the next byte in the data stream that the receiver expects to receive from the sender.

  • Data offset This 4-bit field is used to specify the number of 32-bit words that make up the header. This field is used to calculate the start of the data portion of the packet.

  • Reserved These 6 bits were reserved for future use and, because they were never generally used, are supposed to be set to zeros.

  • URG flag When this bit is set to 1, the field titled Urgent Pointer will point to a section of the data portion of the packet that is flagged as "urgent."

  • ACK flag This is the acknowledgment bit. If it's set to 1, the packet is an acknowledgment. If it's set to 0, the packet is not an acknowledgment.

  • PSH flag If this bit is set to 1, it indicates a push function; otherwise, it is set to 0.

  • RST flag If this bit is set to 1, it is a signal that the connection is to be reset; otherwise, it is set to 0.

  • SYN flag If this bit is set to 1, it indicates that the sequence numbers are to be synchronized. If it's set to 0, the sequence numbers are not to be synchronized.

  • FIN flag If this bit is set to 1, it specifies that the sender is finished sending information; otherwise, it is set to 0.

  • Window This 16-bit field is used to specify how many blocks of data the receiving computer is able to accept at this time.

  • Checksum This 16-bit field is a calculated value used to verify the integrity of both the header and the data portions of the packet.

  • Urgent pointer If the URG flag is set, this 16-bit field points to the offset from the sequence number field into the data portion of the packet where the urgent data is stored. TCP does not use this field itself, but applications above TCP in the stack might do so.

  • Options This field can be of variable length and is similar to the Options field in the IP header. One function this field is used for is to specify the maximum segment size.

Because the Options field can vary, the header is padded with extra bits so that it will be a multiple of 32 bits.

The amount of information stored in the TCP header makes it possible to use the protocol for complex communications. TCP can implement error checking, flow control, and other necessary mechanisms to ensure reliable delivery of data throughout the network. However, because of the complexity of this header, hackers can use many different methods to manipulate the TCP protocol when trying to gain access to your network or otherwise cause you problems.

One interesting thing to note about the checksum field is that it is calculated based on three things:

  • The TCP header fields

  • The TCP data

  • Pseudo header information

The pseudo header information consists of the source and destination IP addresses, one byte set to all zeros, an 8-bit protocol field, and a 16-bit field that contains the length of the TCP segment. The address and protocol fields are duplicated from the IP packet, and the length field is redundant because it also is contained in the TCP header. Because the algorithm used to calculate the checksum is based on 16-bit words, the TCP packet may be padded with a zero byte for calculation purposes only. If the checksum field contains a value of zero, this indicates that no checksum was calculated by the sender. If by some chance the value of the checksum results in a value of zero, the checksum field is set to all 1s (65,535 decimal).

TCP Sessions

Because TCP is a connection-oriented protocol, the computers that want to communicate must first establish the conditions that will govern the session and set up the connection. TCP allows for twoway communicationthat is, it's a bidirectional, full-duplex connection. Both sides can send and receive data at the same time. To set up a connection, each side must "open" its side of the connection. On the server side this is called a passive open. The server application runs as a process on the server computer and listens for connection requests coming in for a certain port. For example, the Telnet server process typically listens for connections on port 23. By using both the IP address and a port number, the server process can uniquely identify each client that makes a connection request. Ports are discussed in more detail later in this chapter.

When a client computer wants to establish a connection to a server, it goes through a process known as an active open. The server is already listening for connection requests (passive open), but the client must initiate the actual connection process by sending a request to the port number of the server application it wants to use.

In Figure 24.7 (shown in the next section), the single-bit field named SYN is the "synchronization" bit. You also can see in Figure 24.7 another field titled ACK, for the acknowledgment bit. These 2 bits are very important and are used during the process of setting up a TCP/IP session so that a reliable connection can be established between two computers on the network.

Figure 24.7. TCP uses a three-way handshake to establish a connection.


Setting Up a TCP Session

A TCP/IP connection is made between two computers, using their addresses and, depending on the application using TCP, port numbers. The SYN and ACK bits in the TCP header are important components used to establish this initial connection.

The steps involved in setting up a TCP/IP connection appear in Figure 24.7 and are listed here:

1.

The client sends a TCP segment to the server with which it wants to establish a connection. The TCP header SYN field ("synchronize") is set indicating that it wants to synchronize sequence numbers so that further exchanges can be identified as belonging to this particular connection and so that the segments sent can be reassembled into the correct order and acknowledged. This first initial sequence number in the TCP header is set to an initial value chosen by the TCP software on the client computer. Additionally, the port-number field in the TCP header is set to a value of the port on the server to which the client wants to connect. Port numbers can be thought of as representing the application to which the computer wants to connect.

2.

When the server receives this segment, it returns a segment to the client with the SYN field set. The server's segment also contains an initial sequence number, which is chosen by its TCP software implementation. To show the client that it received the initial connection segment, the ACK bit is also set, and the acknowledgment field contains the client's initial sequence number, incremented by 1.

3.

The client, upon receiving this acknowledgment from the server, sends another segment to the server, acknowledging the server's initial sequence number. This is done in the same manner in which the server acknowledges the client's initial sequence number. The acknowledgment field contains the server's initial sequence number incremented by a value of 1.

During this exchange, the 16-bit acknowledgment field is incremented by 1. You might wonder why the acknowledging computer doesn't just send back the same sequence number it received from the sending computer. It increments the sequence number that it received to indicate the next sequence number it expects to receive from the sending computer. Thus, during each exchange of TCP segments, each side is telling the other side what it is expecting to get from the other side during the next transmission. The sequence numbers are used to indicate the next byte in the data stream that the receiving end of the connection expects to receive. Thus, when the actual data exchange begins to take place, the sequence numbers are not simply incremented by a value of 1, but instead they are set to the actual number of bytes received (offset from the initial sequence number chosen for the connection) plus 1.

Because three segments are used in this process, the connection setup is often referred to as a three-way handshake. In the last of these three steps the SYN bit is not set, because the segment is simply acknowledging the server's initial sequence number. Note also that port numbers are used to indicate the application for which the connection is being set up. TCP headers don't need to contain the source and destination IP addresses because that information is already stored in the IP datagram that encapsulates the TCP message.

The method used to choose values for the initial sequence number can vary from one implementation of TCP to another. However, there are two important points to understand about the sequence numbers:

  1. For each connection a client makes to another computer, the initial sequence number for each connection must be unique. If the same initial sequence number were used for every connection the client made to a single server, it would be impossible to differentiate between different connections of the same application (that is, port number) between the two machines. Although the IP address and port number can uniquely identify a computer, they can't uniquely identify multiple applications of the same process running on the same computer.

  2. Sequence numbers are incremented for each segment exchanged and are acknowledged by the receiver so that both sides can determine that segments are being delivered reliably and not getting lost in the network. However, it is not necessary that each and every segment be acknowledged with another segment. Using a technique called sliding windows (which we'll get to in a moment), TCP allows for a single acknowledgment of a number of segments.

In Figure 24.7 another field is also shown in the first two packets that are exchanged. The Maximum Segment Size (MSS) field in the TCP header indicates the maximum number of bytes of data that the sender wants to receive in each TCP segment. This value is used to help prevent fragmentation of the TCP segment as it travels through various network devices that might have different transmission frame sizes. This value applies only to the size of the data that the TCP segment carries, and does not include the bytes that make up the TCP and IP headers. You will see this field only during the connection setup. After the application data exchange begins, this field is not used. If the client or server does not put a value into this field during the connection setup, a default value, usually 536, is used.

Not shown in this figure is the TCP field that stores the window size. This field is used to help manage the connection after the application data exchange begins.

Managing the Session Connection

After a TCP session has been established between two computers, the application that uses TCP can begin to communicate with its counterpart on the other computer. TCP receives a stream of bytes (called a message) from an application and stores them in a buffer. When the buffer is full, or when the application indicates that it wants TCP to send the message to the destination computer, the bytes are assembled into a TCP segment with the necessary TCP header information, and the segment is passed to IP for transmission on the network.

Note

Although it is more efficient to send a large number of data bytes in a single TCP segment, some applications do not work well in this manner. For example, when Telnet is used, each keystroke the user enters must be sent to the remote Telnet server, acknowledged, and echoed back to the sender. This means that a TCP segment, and thus an IP datagram, can actually be sent for every single keystroke! When you consider the overhead involved in sending each datagram, this is a waste of valuable bandwidth. To help solve this problem, the Nagle Algorithm (as described in RFC 896) allows for small amounts of data (that is, single keystrokes) to accumulate in a buffer and not be sent until an acknowledgment is received for data previously sent. This means that, in practice, multiple keystrokes can be sent in a single packet instead of having to use a separate packet for each one. Because the speed (or bandwidth) of networks is increasing every year, the delay of buffering a few characters is usually unnoticeable by the user of the application.


Each transmission was acknowledged during the initial connection setup. This is not always the case when the actual exchange of data begins between two computers. Instead, there are several important mechanisms that TCP uses to manage a connection after it has been established. These include

  • TCP timers

  • Sliding windows

  • Retransmissions

When a segment is passed to the IP layer for transmission, a timer is set and a countdown starts. When this retransmission timer reaches zero with no acknowledgment, the sending computer assumes that the segment did not make it to its destination and retransmits the segment. This function requires that TCP keep data in a memory buffer until it is acknowledged.

During the connection setup, each side of the connection indicates to the other side the maximum amount of data it can buffer in memory. This is the window size. This value indicates how many TCP segments the computer can receive before an acknowledgment is required. For example, on a Windows 2000 client the default value for this field when using Ethernet for transmission is 12 segments.

Note

Because many applications used on networks are interactive, often a connection will not be a continuous exchange of data. Instead, as users interact with the client application, there are times when no data exchange is performed. To ensure that the connection is still validthat is, that both sides are still up and runningTCP uses a keepalive segment exchange to indicate that the connection is still being used. This segment consists of a TCP segment with the ACK bit set, but the segment contains no data. The sequence number field in the TCP header is set to a value of the current sequence number minus 1. The other end of the connection returns a segment that also has the ACK bit set, but in the acknowledgment number field the value is the next byte of data that the receiver expects from the sender. The keepalive timer is used to determine when a keepalive segment should be sent.

This keepalive function is not used by all TCP implementations. For example, in Windows 2000 it is disabled by default. However, an API (application programming interface) function can be used by programmers to activate this feature.


Another feature of TCP that helps to reduce the number of packets transmitted is the fact that the acknowledgment of received data does not have to travel in a packet separate from those that hold data. In other words, when sending data in a TCP segment to the remote computer, the sending computer also can use the ACK bit and the sequence number fields to acknowledge data that it has received from the remote computer. This is sometimes called a piggyback ACK because both data and an acknowledgment of data received travels in the same packet.

Having sliding windows also helps to reduce the number of packets transmitted by allowing a single acknowledgment to be sent for multiple segments. Instead of acknowledging every single segment that it receives, the receiver can send an acknowledgment that indicates the last byte received when it receives several contiguous segments in a short time. That is, the acknowledgment can be cumulative. Each end of the connection uses a send and receive buffer to store data received or waiting for transmission.

Remember that the application which uses TCP passes a stream of bytes to TCP or receives a stream of bytes from TCP, depending on the direction in which data is flowing at any particular point in time. The term sliding window refers to the fact that the receiving buffer can hold only so much data (the window size advertised by the receiving end). The amount of space available in the buffer can change over time, depending on the amount of time it takes for the application to accept the bytes from TCP and thus make more room in the buffer. The receiving end can use the window size TCP header field to tell the sender the number of bytes it can currently receive and store in its buffer. This window size is called the offered window size. That doesn't mean that the sender must send that amount of data, just that the receiver is ready to accept any number of data bytes, up to that size.

As you can see in Figure 24.8, the sender can calculate the amount of data it can send by comparing the window size offered, the bytes already sent and acknowledged, and the bytes that have been sent but not acknowledged. In this figure the window size offered by the receiver is 4 bytes. Because 2 bytes have already been sent and the window size is four, the sender can transmit 2 more bytes at this time. As bytes are acknowledged by the receiver, the left edge of the window slides toward the right, as shown in this figure. Depending on how well the receiving end of the connection is able to process incoming bytes, the offered window size can change, which in turn can affect the number of bytes that the sending end can transmit. As the buffer empties at the receiving end, a larger window size can be advertised and the right edge of the window slides toward the right.

Figure 24.8. The window size advertised by the receiver of TCP segments determines which bytes in the data stream the sender can transmit.


It also is possible that the buffer at the receiving end becomes full, and the sender is sent a window size that is now zero. The sender will not send any more segments until the window size is offered again at a value greater than zero.

Using this scheme, there are several things to keep in mind. First, the sender does not have to send an amount of data that is equal to the size of the offered window. It can send less. Second, the receiver does not have to wait until it has received data in the amount of the offered window before it sends an acknowledgment. Third, the window size is controlled, under most circumstances, by the receiving end of the connection.

In this example we have used a transmission that consists of only a few bytes at a time. For most TCP communications the amount of data, and the window size, is much larger.

Sliding windows tell the sender when and how much data it can transmit. When a connection is initially established, a technique called slow start is used to govern the amount of data that is sent, allowing it to increase to a point that the particular network will tolerate. When a connection has been in use for some time, congestion can occur and it might be necessary to slow down the rate at which segments are transmitted, by using a technique called the congestion avoidance algorithm. These two methods work together to control the flow of data during the connection.

Slow start means that when the transmitting side of a connection first transmits data, it does so by observing how fast it receives acknowledgments of data from the receiving end. A variable in the TCP software keeps track of the congestion window (cwnd), which is initially set to one segment. For each segment that is acknowledged, the cwnd variable is incremented. Then, the sender is allowed to send an amount of data up to the value of cwnd or the size of the offered window, whichever is the lower value. As you can see, the faster the receiving end acknowledges segments, the larger the cwnd variable becomes, and thus the more segments that the sender will be able to transmit (up to the offered window size). The offered window size enables the receiving end to control the amount of data that can be sent. The congestion window gives the sending end of the transmission control over how much data can be transmitted. Thus, both sides work together to throttle up data transmissions, starting off slowly, until the receiver is unable to buffer data at a faster rate or until network congestion forces the connection to operate at a slower rate.

The term slow start isn't actually an accurate way to describe what happens. In reality, the receiving end might acknowledge several segments, thus increasing the size of cwnd by more than one when it sends a single acknowledgment to account for multiple segments. This means that, instead of being incremented by one for each acknowledgment, cwnd can be incremented at a much faster rate. However, this method does allow for TCP to "test the waters," so to speak, to determine the rate at which data can be sent, up to the receiving end's capacity to buffer data and pass it up to the application on its end of the connection.

As packets make their way through the network, however, another problem can arise. In today's world, communications often take place between computers that reside on different networks that are connected by routers, and we find that, just like the freeway system, congestion can occur when too many computers are trying to send and receive data at the same time. When a router or another network connection device becomes a bottleneck, it can simply drop IP packetsremember that IP is an unreliable protocol. It is up to TCP to realize what is happening and to compensate for it by retransmitting unacknowledged segments.

The retransmission timer that we discussed earlier is used by the transmitting end of the connection to determine when a segment should be retransmitted. This value is recalculated over time, depending on the round-trip time it takes for a transmission to make it to the receiving end and an acknowledgment to get back to the transmitting side of the connection. The round-trip time can change over time, depending on the amount of data flowing through the network. Round-trip time also can change when the routes chosen by routers change, thus sending packets through a different path in the network that can take more or less time than previous transmissions.

Note

It is beyond the scope of this book to get into all the details of the calculations used to determine the round-trip time and thus the value of the retransmission timer. For more information, the reader is encouraged to read the RFCs that pertain to TCP/IP. A quick search on the Internet will give you a large list of RFCs that can provide some great nighttime reading if you have a hard time going to sleep. As mentioned earlier in this chapter, a good source for RFCs is www.rfc-editor.org.


The congestion avoidance algorithm is used to take care of situations in which the network becomes congested and packets are droppedthat is, they are not being acknowledged by the receiver. Although this algorithm is separate from the slow start technique, in practice they work together. In addition to the cwnd variable, another variable called the slow start threshold size (ssthresh) comes into play. This variable is initially set to 65,535 bytes when a connection is established. When congestion is detected, the value of this variable is set to half the currently offered window size, and the variable cwnd is set to the value of one maximum segment size (MSS)though this can vary from one implementation to another. In recent Microsoft operating systems including Windows 2000 and Windows XP, cwnd is set to the value of two times the MSS. The send window value then is set to the lower of the cwnd and the offered receive window size.

Based on which value is chosen, TCP segments are then sent. If the segments are acknowledged, cwnd is incremented. If the value of cwnd is lower than the value of ssthresh, a slow start is used. When the value of cwnd is equal to half the current offered window size from the receiving end of the transmission, congestion avoidance is used. Remember that the value of ssthresh can be used to determine this because it recorded the value of the offered window size (divided by two) that was in effect when congestion started.

During congestion avoidance, the value of cwnd is incremented by one cwnd for each acknowledgment receivedagain, this value might be different according to your particular TCP implementation. Thus, instead of a possible exponential increase that a slow start method would allow, congestion avoidance allows for a smaller increase in the value of cwnd. After all, if congestion is occurring, the last thing you want to do is quickly increase the rate of transmission. Instead, you want to throttle it up more slowly. So although slow start will increment cwnd by the number of segments acknowledged by a single acknowledgment, the congestion avoidance algorithm will increment cwnd by only one segment for each acknowledgment received, no matter how many segments are being acknowledged by the acknowledgment.

Other mechanisms are used for flow control in TCP, such as the fast recovery algorithm and the fast retransmit algorithm. Discussing these topics is beyond the scope of this book. The important thing to understand is that TCP does monitor and adjust its transmissions, from both sides of the connection, to try to get the maximum amount of data flowing without causing problems. It's a self-regulating protocol, you might say.

Ending a TCP Session

When the party's overthe application is finished sending data to another computerit tells TCP to close the connection from its side. Because the connection must be closed from each end, this is called a half-close. To fully close a TCP connection, four steps are required, as opposed to the threeway handshake method used to set up the connection. Four steps are required because TCP operates as a full-duplex connectionthat is, data can flow in both directions. Thus, each side needs to tell the other side of the connection that it has finished sending data and wants to close the connection.

For example, when the client application, such as Telnet, wants to close a connection, TCP sends a segment that has the FIN bit set in the TCP header to the remote computer. The remote computer must first acknowledge this FIN segment, and does so by sending a segment to the client that has the ACK bit set. Because the connection is full-duplex, the server TCP software informs the Telnet server application that the user application on the other end of the connection is finished. It then sends its own FIN segment to the client, which, as you can probably guess, sends an acknowledgment segment back to the server.

Although this is the general method used to close a TCP connection, another technique can be used in which one side sends a FIN segment, closing its data pipe, but the other side of the connection does not. Instead, it is possible for the other side to continue sending data until it is finished, at which time it sends the FIN segment and waits for an acknowledgment, which effectively closes the connection.

A good example of this method is the Unix rsh (remote shell) utility. This utility allows a user to execute a command on a remote server. Because Unix allows for the capability to redirect input (using the < operator), a user can use rsh to execute a command on a remote server, and use the < operator on the command line to redirect the input for the command from the command line to a file. In such a situation, the client's side of the connection sends the command to be executed to the remote server and then starts sending the data that is in the file. After the client's side of the connection finishes sending the data contained in the file to the remote server, it instructs TCP to close its side of the connection. Yet, at the other side of the connection, the data needs to be processed by the program invoked by the rsh command. When finished, the program on the remote server sends the data back to the client and then instructs TCP to close its side of the connection.

TCP Session Security Issues

Calling TCP a reliable protocol means that it uses an acknowledgment mechanism to ensure that the data is received at the remote computer intact. Reliable does not mean that TCP is a secure protocol. If that were so, there would be no need for firewalls! Although the connection setup and termination methods used to create a connection create a virtual circuit between the two computers, there are many ways to exploit TCP (and IP) to break into a computer. For example, every time a new connection is requested on a server (the receipt of a TCP segment with the SYN bit set), the computer sets aside data structures in memory to store information about the connection it is setting up. This requires a few CPU cycles and memory on the computer.

It should be obvious that an easy way to cause a "denial of service" attack against a computer is to simply send a large number of SYN segments to it in a short period. If the number of SYN segments and the rate at which they are sent exceed the capacity of the CPU or memory of the server, then, depending on the operating system and how the TCP/IP stack is implemented, the system might slow to a crawl or crash.

For more information about how the inner workings of TCP/IP and related protocols can be used maliciously, see Chapter 44, "Security Issues for Wide Area Networks." For information on how to protect yourself against these sorts of attacks, see Chapter 45.




Upgrading and Repairing Networks
Upgrading and Repairing Networks (5th Edition)
ISBN: 078973530X
EAN: 2147483647
Year: 2006
Pages: 411

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net