Transport Layer

The transport layer is the one used most commonly by application programmers. A transport layer API can be uniform for a wide variety of applications whereas the underlying network technology might vary widely.

The transport layer entity (part of the kernel, separate networking process, maybe even hardware) sits on top of the network layer, using its services, but logically is in communication with the destination transport entity. Thus we have our first glimpse of the big picture, from the physical layer bit signals up to an application process.

Two hosts stacks and apps talking via them; logical and physical data flow.

By introducing the transport layer between the network layer and the application, you make efficient, robust communication possible in the event of problems in the subnets and WANs. Note that this isolation is still valuable even when you have a reliable, connection-oriented service offered by the network layer. When something goes wrong in the network (router crashes, bad routing, loss of line, etc) the transport layer entities can cope with the failure.

In order to get reliable and efficient use of the network for the application processes, the transport layer faces many of the same issues as the data link layer (flow control, error control, sequencing, etc). One big difference that makes these issues harder to deal with is the storage capacity of the subnet. Bits can't be stored on a wire between data link layers. But a store-and-forward packet switched network can keep packets around for some time, maybe after their associated timer has expired, before they are suddenly delivered.

The most common combination is an unreliable network layer with a reliable transport layer service offered to programmers. The programmers view in this case is a byte pipe between two processes on machines on the network.

Tanenbaum calls the units exchanged by the transport layer entities TPDU (transport protocol data units), to distinguish them from packets (network layer) and frames (data link layer) and bit streams (physical layer). TCP calls them segments.

Services offered

Reliable, connection-oriented

A minimal set of services offered by a reliable, connection-oriented transport layer would include a means of 1) waiting for a connection, 2) initiating a connection, 3) sending and receiving data, and 4) disconnecting.

Reliability is created by uniquely identifiying each segment. This allows for the detection of duplicates and the identification of missing segments.

Unreliable, connection-less (datagram)

A minimal set of services offered by a unreliable, connection-less transport layer includes only a means of sending and receiving data. Note how much simpler this is because of lack of connection.

Note the overloaded use of the term datagram. Here it is for a transport level service. In the network layer it refers to the philosophy of the network.

Effect of network layer services

How easy or hard it is to offer these services depends on the underlying network layer. For example, with an unreliable, best effort network layer, there is a lot of work to do in the transport layer to provide a reliable service. The unreliable service is trivial. This is the case with the Internet protocols.

With a reliable network, such as ATM, it is much easier to provide a reliable service, and doesn't make any sense to have an unreliable service. It is interesting to think about the wasted effort and space implicit in a reliable transport service built on top of a reliable network.

Addressing

In the same way that a single physical medium must be multiplexed at times, the protocol stack in a host must be multiplexed, or shared, by many application processes at once. This means the network layer address (e.g. IP address) isn't sufficient to identify the process using a transport layer connection (e.g. a socket). Tanenbaum calls these end point address TSAP (transport service access points). One way of seeing why a unique TSAP is necessary is to ask yourself the question, "to which process does a transport TPDU get delivered when it arrives?"

In the Internet suite the multiplexing of TCP segments is done by port numbers. Each process using a socket is given a unique (to that machine) port number. Then the combination of IP address + port number is a unique identifier for that process.

How does a client process know the TSAP of a server process? Some possibilities

  1. TSAPs are well-known, documented, static. Works ok for basic sorts of services that all servers provide. Example would be Internet well-known services (ports below 1024).
  2. A TSAP server runs on a well-known TSAP. A protocol is used for clients to query the TSAP server to find the TSAP given a name for the service. This is like a name server. The services are identified by string names, the name server returns the TSAP (e.g. a port number).
  3. A metaserver is used for the initial connection. The metaserver (server server, or super server) answers requests on many TSAPs, starts the proper server process, then gives the incoming connection to the new process. This also saves having to launch many infrequently used server processes. The Internet inetd is an example of this.

Connecting

The three-way handshake is a connection establishment protocol. Each host uses a different starting sequence number. Sequence numbers must uniquely identify packets, with no potential for duplication because of delaye packets. Consider three scenarios.
Host 1 sends CONN REQ containing sequence number x to host 2.
Host 2 sends ACCEPT to host 1 containing an ACK for x, and proposing sequence number y.
Host 1 sends first DATA TPDU numbered x, ACK for seq num y.

Host 1 selects x knowing that no other TPDUs numbered x can be outstanding. Similarly for host 2 and y.

Packet storage and duplicates

Reliability is made more difficult by the fact that packets can be stored in the network. A delayed packet may be duplicated by a host since its timer may expire causing a resend. What happens when a duplicate packet arrives? How does the receiver know it's a duplicate?

Delayed duplicates are bad for connecting since the initial request to connect may be delayed and duplicated.

The problem is more manageable if you can put a bound on the time which a packet can live in the network. There are three ways to achieve this:

Knowing an upper bound for the life of a packet in the network allows you to use sequence numbers and clocks to identify delayed duplicates. The sequence number for a packet is chosen based on a time-of-day clock (a counter that is regularly incremented). Rules are established for picking sequence numbers such that each transport entity can detect illegal sequence numbers. The sequence numbers must be large enough to ensure that no two outstanding TPDUs have the same sequence number.

Duplicate CONN REQ

A delayed duplicate CONN REQ containing sequence number x arrives to host 2.
Host 2 sends ACCEPT to host 1 containing an ACK for x, and proposing sequence number y.
Host 1 detects illegal seq num x being acknowledged, so REJECTs request.
Host 2 receives REJECT and figures out it was fooled by delayed duplicate, so drops any further effort.

Duplicate CONN REQ and DATA ACK

A delayed duplicate CONN REQ containing sequence number x arrives to host 2.
Host 2 sends ACCEPT to host 1 containing an ACK for x, and proposing sequence number y.
Host 2 receives a delayed duplicate DATA TPDU for x, with an ACK for seq num z. Host 2 knows this is bad since it proposed y, not z. Host 2 discards this TPDU.
Host 1 sends REJECT for the ACCEPT sent for the first duplicate, since it detects illegal sequence number x.
Host 2 receives REJECT and figures out it was fooled by delayed duplicate, so drops any further effort.

Disconnecting

Dropping connections isn't trivial either, as it turns out. An asymetric release means that either host can destroy the connection (like hanging up the telephone). But data can be lost since there is no coordination between parties, so data that is "in the pipe" is lost once the connection is destroyed. Symmetric release requires both parties to agree to a release. If both parties know they are done sending data, and agree, then no data is lost.

A famous problem deals with the failure of this sort of protocol. The problem is determining when the blue armies should attack the white army. If you substitue "drop connection" for "attack" you have the problem that interests us.

Two army problem

White army in valley. Blue arm in hills on either side of valley. White army can defeat either blue army in isolation, but blue armies together can defeat white army. How do the blue armies coordinate an attack on the white army? Their only communication is via messenging through the valley where messengers may be lost (i.e. an unreliable channel).

Blue army #1 sends message: attack at time X. Blue army #2 receives this message and sends an acknowledgment to it. Does the attack happen at time X? No, since blue army #2 can't know that it's ack was received. Adding an ack to the ack (three-way handshake) doesn't help, since now blue army #1 doesn't know if his ack to the ack got through, and if it didn't blue army #2 won't attack, so blue army #1 shouldn't attack either.

You can prove that no protocol can solve this problem. Suppose such a protocol existed. The last message sent is either essential or it is not. If it is not, it can be lost or dropped with no adverse affect. Drop all non-essential messages. Now all messages remaining are essential. What if the last message is lost? Since it is essential, the protocol fails. So we have a contradiction.

Timers are used in practice to make conclusions about when it is safe to drop connections. See TCP example.