The Data Link Layer protects the higher layers from the characteristics of the physical transmission medium, and takes the raw transmission facility and transforms it into a line that appears error free to the network layer. Moreover, included amongst its functions is the synchronisation of data and flow control - ensuring a fast transmitter does not send to a slow receiver. Another of the principal functions of this layer is to ensure that transmission errors are detected and to provide mechanisms from recovery from these - error control.
Data Link Layer

Services provided to the network layer

  • Data link connection - The provision of data link connections between two network entities
  • Data link service data units - In practice these are the frames of data exchanged over a data link connection
  • Error notification - If an unrecoverable error is detected, the Network Layer is informed
  • Flow control - The Network layer can dynamically control the rate at which it receives frames of data
  • Quality of service parameters - These are optionally selectable and include residual error rate and throughput.

Functions performed by the Data Link Layer

  • Set up and release of data link connections
  • Delimiting and synchronisation - This is essentially the framing function which organises bits (the physical service data units) into frames (the data link protocol data units)
  • Error detection - this function detects transmission, format and operational errors usually arising from deficiencies in the physical medium
  • Error recovery - This function attempts to recover from errors
  • Flow control

Services provided by the Data-link layer

Connectionless, unacknowledged

The simplest, fastest, lowest overhead service. Could be very useful for a reliable channel where most packets are delivered without errors. Puts the burden of error control on upper layers, which implicitly means that errors are unlikely. Good match to synchnronous data with lots of redundancy, like voice.

Connectionless, acknowledged

Like above, but each packet is acknowledged by the receiver, and the datalink layer makes sure each packet arrives. Good match for unreliable media like wireless. Still no guarantees about non-duplicated packets (which a lost ACK could cause).

Connection-oriented

Reliable bit-stream service for the network layer.

Framing

The physical layer deals with bit streams. It is the datalink layer that thinks in terms of packets or frames. Everything the datalink layer does is in the context of frames. Frames can be either bit or character oriented

Char oriented: SYN SYN <control chars><data chars><control chars>

Bit oriented: <flag><control chars><data field><control field><flag>

 

A big question for the receiving datalink layer is, how does it convert the stream of bits from the physical layer into a sequence of frames or packets? This issue is more complicated than it might seem. Some possible approaches:

size of frame (i.e. counting bits)

magic characters that mark the start/stop of frames

violations of the signalling scheme used in the physical layer

Error Control

Error control coding provides the means to protect data from errors. Data transferred from one place to the other has to be transferred reliably. Unfortunately, in many cases the physical link cannot guarantee that all bits will be transferred without errors. It is then the responsibility of the error control algorithm to detect those errors and in some cases correct them so upper layers will see an error free link

Error Detection

CRC

Parity isn't good at detecting burst errors, since a burst will corrupt a group of bits simultaneously. A group of check bits can be added to a frame by operating on all the data bits in the frame - polynomial code.

Treat bit strings as representations of polynomials with coefficients of 0, 1. A k-bit frame is a coeffiient list for a polynomial with k terms, xk-1 to x0, e.g. 110001 represents x5 + x4 + x0.

Sender and receiver agree on generator polynomial G(x), both high and low order bits of G(x) must be 1.To compute a checksum for m bits corresponding to the message M(x), the frame must be longer than G(x). We append a checksum to the frame so that the polynomial represented by the checksummed frame is divisible by G(x). The odds of a corrupt frame being also evenly divisible by G(x) are very small.

Checksum algorithm

  1. Let r be degree of G(x). Append r zero bits to the low order end of the frame, so it now contains m+r bits, and corresponds to the polynomial x^r * M(x).
  2. Divide G(x) into the bit string correspondingto x^r * M(x) using mod2 division.
  3. Subtract the remainder (which is always r or fewer bits) from the bit string corresponding to x^r * M(x) using mod2 subtraction. The result is the checksummed frame to be transmitted. Call its polynomial T(x).

Example

Polynomial arithmetic is done mod2, with no carries or borrows (this is just exclusive OR)

10011011 01010101

+11001010 -10101111

------------ ------------

01010001 11111010

Long division is also done modulo 2, "to go into" means having the same number of bits

frame: 1101011011

M(x): x9 + x8 + x6 + x4 + x4 + x1 + x0

G(x): x4 + x1 + x0, or the bit string: 10011

append 4 0 bits (multiply by x^4): 11010110110000

long division, modulo 2 subtraction, yields remainder of 1110

subtract

11010110110000

- 1110

-------------------------

transmit: 11010110111110

The checksum algorithm simply makes the transmitted frame be divisible by the generator polynomial. Doing this in decimal corresponds to

897 / 10 = 7

897 - 7 = 890

890 is evenly divisible by 10

Error Correction

If you have a feedback channel (not all communication situations allow for this) then you can get away with just detecting errors, have the receiver ask for retransmission. If you don't have a feedback channel (e.g. space probes) then you must use some form of feed forward control where redundancy allows both detection and correction of errors.

Most computer networking is concerned with error detection, since the amount of information added to do feedforward error correction can be large.

Total length of a transmission in bits is n = m + r (message + redundancy), where the codewords sent (distinct from the messages, remember) are n bits long.

Given two codewords, it is easy to say by how many bits they differ by (XOR and count the 1 bits). The number of bits that two codewords differ by is known as the Hamming distance. If two codewords are a Hamming distance d apart, it will require d single-bit errors to convert one to the other (corruption).

Most of the time when using m data bits we use all possible 2^m combinations. For example, the 7 bit ASCII code had 128 different symbols defined for it. It makes sense to use all possible combinations since to do otherwise decreases the inherent efficiency of the representation (i.e. you always send m bits, you might as well be able to communicate 2^m different symbols).

When you design a code that can be used to actually correct errors, and not just detect them, then you don't use all possible 2^n values in an n bit code. This "waste" represents redundancy which can be put to good use.

The Hamming distance of a code is the minimum Hamming distance between any two codewords of the code.

Detection: a code with a Hamming distance of d+1 can detect d single bit errors.

Correction: a code with Hamming distance of 2d+1 can correct d single bit errors.

Parity is a code with d=2, thus can detect single bit errors.

Simple correction example

Four valid codewords: 0000000000, 0000011111, 1111100000, 1111111111. Code size is n = 10 bits, so there are 2^n = 1024 possible codes that can be sent. Message size is m = 2 bits, or 2^2 = 4 possible messages that can be transmitted. What we lose: it takes 5 times as long to transmit any message compared to a non-coded message. What we gain: since the Hamming distance is 5 it means we can correct any possible 2 bit errors in a codeword. For example, if 00000 00111 is received, then 00000 11111 must have been transmitted, since it is the closest legal codeword.

Flow Control

Flow control is needed so that the receiver isn't overrun in time or buffer space by the sender. Flow control is independent of error control, but is made much more complicated by the possibilities of errors. The main goal of providing flow control is to insure that data is not lost by the sender sending too fast. The secondary goal is to use the channel as efficiently as possible. Important idea: length of a bit/frame. Depends on velocity of propogation and signalling rate. Matters when you talk about efficiency of protocols.

Stop & Wait

With this simple scheme, the sender can only have one frame outstanding, then it must wait for an ACK from the receiver. When the receiver receives an error free frame, it returns an ACK to the sender. When the sender receives an ACK it sends another frame.

The data frames from A to B are intermixed with the acknowlegement frames from A to B, since the communication is usually full-duplex. A field in the frame header can be used to distinguish data from ACK. This way ACKs get a free ride on the next outgoing data frame (piggybacking) which results in better use of the available channel bandwidth. How about if new frames do not arrive on time to piggyback the acknowlegement? (sender will time out) Use a timer in the receiver to time out and send separate acknowlegement frames when necessary.

Efficiency

H = number of header (overhead) bits per frame

D = number of data bits per frame

L = number of bits in a frame

(H + D) C = length of the channel

R = data rate in bits per second

v = velocity of propogation

Tframe = time to signal frame

Tproc = time to process frame in physical layer, pass to datalink layer

Tack = time to signal ACK

Tprop = time for first bit to travel from sender to receiver

Total time to send one frame and receive an ACK for it (draw a picture of this)

Ttotal = Tframe + Tproc + Tack + Tproc + 2Tprop

U = Tframe / Ttotal ~= Tframe / (Tframe + 2Tprop) since processing time is small and ACKs are short. = 1 / (1 + 2Tprop / Tframe)

Propogation delay is typically 2/3 speed of light, so Tprop = C / v and v = 2/3 * 3*10^8, where C is the distance between sender/receiver, and 3*10^8 is the speed of light in meters per second.

Tframe = L / R where L = length of frame in bits, and R is the data rate. So substituting we get

U = 1 / (1 + 2Rd/vL)

but we haven't accounted for the fact that a frame isn't all data, so in fact this utilization is reduced in proportion to the amount of header bits in a frame

U = D / L * { 1 / (1 + 2Rd/vL) } = {D / (H + D) } * { 1 / (1 + 2Rd/vL) }

if the headers are small relative to the data payload we can ignore this first term.

Experiment 1 - Short distances

utilization versus distance,for distance from 0 to 1000 meters

frame size = 1000 bits

speed = 2/3 speed of light

data rate = 10^2, 10^3, 10^4 bits/second (most eff to least eff)

Experiment 2 -Long distances

utilization versus distance, for distance from 0 to 5*10^6 meters

frame size = 1000 bits

speed = 2/3 speed of light

bit rate = 10^4, 10^5, 10^6 bits/second (results shown most eff to least eff)

When Tprop / Tframe is less than 1 (short links, low data rates) then efficiency of stop-and-wait is ok. For long links, but low data rates it is ok, but for very long links, even with low data rates it can be bad. The efficiency problems of Send&Wait are because only one packet can be in transit at a time, and that frame may be much smaller than the channel length.

What about errors?

When sender sends a frame, it starts a timer. If receiver receives a frame with errors or sender receives an ACK with errors, it is discarded. If sender does not receive an ACK, it times out and recsends the frame.

If an ACK is lost, or corrupted, then sender may send two copies of the same frame. To fix this we use a sequence number in packets. Receiver can simply discard duplicates that it receives. How many bits to use for sequence number? You only need 1 bit (sequence number 0 or 1) since there is only ambiguity arising between a packet and its predecessor or successor. In other words, there is only one frame at a time outstanding.

The timer must be sent to at least twice what the propogation delay is, or the sender will draw false conclusions about lost frames. Time is also wasted when the receiver gets a corrupted frame, as it must wait for the sender to timeout and resend. An improvement is possible by sending explicit acknowledgement of the receipt of bad frames: NAKs.

Efficiency is also reduced since frames with errors must be resent, wasting some of the capacity of the channel.

P1 = probability that a data frame is lost or corrupted

P2 = probability that an ACK is lost or corrupted

Prob of successful transmission = (1 - P1) * (1 - P2) assuming frame and ACK loss are independent events

Prob. of failed transmission = F = 1 - (1 - P1) * (1 - P2)

So your channel utilization is reduced by the probability you waste time sending frames that aren't successfully received and becomes U = {D / (H + D) } * {1 - F} * { 1 / (1 + 2Rd/vL)

Sliding Window Protocols

Efficiency can be 100% in the absence of errors, yet the sender won't overrun the receiver.

Essence of sliding window:

Some sort of maximum outstanding number of frames

Requires N buffers to hold outstanding frames

Receiver holds frames in a list, delivers in order to network layer.

Sender need not wait for an ACK to send the next frame, but must obey point 1.

You can view stop-and-wait as a sliding window protocol where the size of the window is 1. Since more than one frame can be outstanding at a time, each frame must be uniquely identified. A sequence number is used in the header of each frame to identify it. The size of the sequence number depends on how many frames can be outstanding (window size), and the way in which errors are handled.

Example of sliding window (Tannenbaum, 2nd ed, p 226) window of size 1, sequence number of 3 bits

 

Initial State first frame sent first frame received ack receive
Sender next frame 000

expects000

next is001

expects000

next is001

next is 001
Receiver expects 000 expects 000 expects 001 expects 001

If the size of the window was increased beyond 1, then the sender could transmit the 2nd frame immediately and the gap between expects and next would widen.

Efficiency

Calculate the length of the channel in terms of number of frames - this is the key parameter for sliding window.

number of bits in a meter of channel (bits/m) = data rate (bits/sec) / propogation speed (m/s)

length of a frame in meters = L (bits) / number of bits in a meter (bits/m) channel length in frames = d (m) / length of frame in meters (m) = d / ( L / R / v ) = d R / L v Since Tframe = L / R, and Tprop = d / v, then

channel length in frames = Tprop / Tframe Note that this term shows up in our efficiency for stop-and-wait protocol. If the channel is 10 frames long, and the send window is only 1 frame, then the maximum efficiency is 1/20, since it takes time equal to the sending of 20 frames to send and ACK just one frame.

In general, two modes to calculate efficiency for. The first is for when the sender is never idle waiting for an ACK. The sender can signal for a time Tframe*W, where W is the size of the sliding window. After that, the sender must wait for an ACK from the first frame, which will take Tframe + 2*Tprop to reach the sender. The sender will never be blocked if W* Tframe > Tframe + 2*Tprop, so the theoretical efficiency is 1.0, since the "pipeline" of transmission could always be full.

However, if W*Tframe < Tframe + 2*Tprop , then the sender will send W frames, then wait for an ACK, send 1 more frame, wait for an ACK, etc. This makes the steady-state efficiency

U = W Tframe / (Tframe + 2*Tprop) (since W Tframe is spent in useful signalling and the whole process repeats after Tframe + 2 Tprop when the first ACK is receive)

U = W / (1 + 2Tprop/ Tframe)

In other words, sliding window improves on stop-and-wait by the size of the window (or 100%, whichever U is smaller).

Errors in sliding window

How do you handle corrupt frames with a sliding window protocol? Two possible strategies: have the sender selectively resend the data that was corrupt, or just start back in the frame sequence from the first bad frame.

Selective retransmission

Sender detects out-of-sequence ACK and retransmits the unACKd frames. Or receiver sends a NAK and the bad frames are resent.

Example with frame error

  • error in frame N+1
  • receiver returns ACK for all correctly received frames (...,N-1, N, N+2, ...)
  • on receipt of ACK N+2, sender figures out that N+1 not received correctly ·
  • sender retransmits N+1, changes position in list, goes on

Example with error in ack N ·

  • sender receives ack N+1, resends frame N ·
  • receiver checks list, concludes that N is a duplicate, trashes ·
  • receiver acks duplicate frame

Requires 2W+1 sequence numbers for a window of W frames

Consider case where full window is sent, all acks lost - requires W buffer in the sender, W in the receiver.

If the probability of lost frames is high, and the frames can be large, then the space for buffers may be significant. That motivates the next strategy.

Go-back-N

Receiver detects receipt of an out-of-sequence frame and requests sender to retransmit all outstanding unACKd frames from the last correctly received frame.Or, the receiver sends a NAK to the primary when it first detects an out-of-sequence data frame. Thereafter the receiver discards all data frames until it receives the missing frame.

If an ACK is corrupted (say N and N+1), then the sender will infer from receipt of the ACK for N+2 that both N and N+1 were received correctly, and will take the N+2 ACK as sufficient for all three frames.

Since the receiver doesn't have to store frames out-of-sequence, it doesn't require much buffer space. Remember that it throws away the out-of-sequence frames it receives.

Requires W+1 sequence numbers for a window of W frames and W buffers in the sender, 1 in the receiver.

Go-Back-N handles duplicate (lost ACKs) frames easily by simply discarding them. Selective-Retransmission can only know to discard a duplicate by maintaining a history list of received frames.

Most data comm is full duplex, i.e. you have as much BW in one direction as you do in another. If you only use the reverse channel to send ACK/NAKs, then you will be wasting the BW of the reverse channel (low utilization). One idea is to piggy-back ACK/NAK traffic on the information frames that are flowing on the reverse channel.

Errors and efficiency

P1 = probability that a data frame is lost or corrupted

P2 = probability that an ACK is lost or corrupted

Prob of successful transmission = (1 - P1) * (1 - P2) assuming frame and ACK loss are independent events

Prob. of failed transmission

F = 1 - (1 - P1) * (1 - P2)

Assuming independent events, the probability that exactly k attempts are needed to get a frame transmitted is (1 - F) F^(k-1) i.e. one successful attempt and k-1 attempts

Now you can calculate the average number of transmission attempts to get the one frame through successfully:

N = sum of k from 1 to inf { k * (1-F)*F^(k-1) }

which is just the weighted average of all possible values for the number of times the frame must be sent and reduces to

N = 1 / (1 - F) and the number of re-transmission (i.e wasted channel capacity) is

N - 1 or Nr = N -1 = F / (1 - F)

SelectiveRetransmission

For W > 1 + 2 Tprop/Tframe the efficiency is reduced from 100% by the waste of failed transmissions

U = 1 * (1 - F) = 1 / N = 1 / (Nr + 1)

For W < 1 + 2 Tprop/Tframe the efficiency drops by the same amount, so

U = (1 - F) * { W / (1 + 2Tprop/ Tframe) } = {1 / (Nr + 1) } * {W / (1 + 2Tprop/ Tframe) }

GoBackN

The error handling is not as efficicient for GoBackN, since valid received frames are discarded