So far we know different ways to encode 0 and 1 onto low and signals, and
we know techniques to figure out when frames start and end.
One problem we still need to solve is how to handle bit errors in frames.
As we saw many of the frame formats of last day either had checksums or CRCs
(cyclic redundancy checks). These are used to detect errors in frames.
There are two ways one could handle bit errors in frames: (1) One can use an error detecting code. Then if an error is detected one resends the frame. (2) One can use an error correcting code which provided not too many bits are messed up allows one to determine which bit to fix.
We look at three error detecting codes: two-dimensional parity (used by BISYNC), checksums, and CRC (used by HDLC, DDCMP, Ethernet, and Token rings).
Two Dimensional Parity
We will describe 2D PARITY in the context BISYNC, which used IBMs old 7-bit character encoding EBCDIC.
First, after every 7 bits we count the number of 1's we saw in those seven bits. If this was odd we output a 1; otherwise a 0.
For example, if we see 0101001, we would output a 1.
This last bit is called a parity bit.
Adding parities for each 7-bit sequence we want to send, would be called doing a 1D-parity check. This can detect any odd number of errors in the 7+1 bit sequence.
In BISYNC, after every sixth 7 (data) + 1 (parity) = 8 bit sequences, we send a parity row. We first imagine we have a 6 row by 8 column rectangle, and for each column calculate its parity and write it to that column of the parity row.
This is stronger than a 1D parity set-up in that we can detect any odd number of erros in either rows or columns. However, we now have 14 redundant bits for every 42 bits of data.
Internet Checksum Algorithm
This algorithm is used at the internet/network layer; whereas, the other two detection algorithms we will consider are at the data link layer.
As in practice most errors are caught in the data link layer the detection needed at this higher layer does not have to be as strong.
The checksum algorithm views data as a sequence of 16-bit integers.
The checksum maintains a sum of the integers seen in the frame as calculated using 1-complement arithmetic.
Let x > 0 be a 16 bit number whose high bit is off.
The ones complement of x is x; the ones complement of -x is the bit pattern obtained by inverting each bit of x.
As an example, for 1's complement on 4 bit numbers, the number 5 would be 0101 and the number
-5 is 1010. Similarly, 3 would by 0011 and -3 would be 1100.
If we add -5 + -3 in 4-bit 1's complement, we first add the two numbers to get
a 5-bit number 10110 where the high order bit is the so called carry bit. We strip any carry
bit to get 0110, and if the carry bit was on we increment the result to get 0111, which is -8.
Cyclic Redundancy Check Codes
These are also known as polynomial codes.
A k-bit frame is viewed as specifying the coefficients of a degree k-1 polynomials.
For example 101 code 1x2 +1x0.
Polynomials can be added mod 2, they can also be multiplied and divided.
In a CRC code, both sender can receiver agree on on a generator polynomial G(x) which has both its high and low order coefficient 1.
We assume the message m has length > deg(G)=r.
Let M(x) be the polynomial of the message.
To compute a checksum for a message we (1) Compute xrM(x), (the bit sequence of this polynomial is that of M(x) shifted over r bits). (2) Divide xrM(x) by G(x) to get a remainder R(x). (3) Send the coefficients of T(x) = xrM(x)-R(x).
More on CRC codes.
Notice T(x) is divisible by G(x).
Suppose T(x)+E(x) arrives.
Then (T(x) +E(x))/G(x) = E(x)/G(x).
The only way an error is undetected is if this value is 0.
If there was a single bit error then E(x)=xi for some i which can't be divisible by G(x). So any single bit error will be detected.
If there are two errors then E(x)= xi+ xj where i>j. So E(x)= xj(xi-j +1). So this error will be detected provided that G(x) does not divide xk+1 for any k up to i-j.
There are some low degree polynomials that will give this protection to very long frames. For instance, x15+ x14+1 does not divide xk +1 for any k below 32768.
If E(X) contains an odd number of terms (hence errors), then it cannot have x+1 as a factor mod 2, so if x+1 is a factor of G(x) we can catch these errors.
To see this suppose E(x)=(x+1)Q(x) had an odd number of terms. Then E(1)=(1+1)Q(1) = 0 mod 2. On the other hand substituting 1 for an odd number of terms should give 1 mod 2.
CRC codes with r check bits will detect all burst errors of length ≤ r. Such an error would look like xi(xk +xk-1 + .. +x0). If G(x) has a x0 term, it will not have an xi factor, so if the degree of the parenthesized expression if less than G(x), the remainder won't be 0.
So at this point let's assume we can detect if there is an error in our frame.
How can the sender know if the frame arrived to the receiver correctly?
This is usually accomplished using two mechanisms: acknowledgments (ACKs) and timeouts.
The receiver can send a special control frame (a frame without data but whose header contains control information) ACKing the receipt of the data frame.
If the sender does not receive the ACK frame within a timeout period it retransmits the frame.
This strategy of using ACKs and timeouts is called ARQ (automatic repeat request).
We next look at several ARQ algorithms.
Stop and Wait
In the stop and wait protocol, the sender sends a frame, then waits for an acknowledgement of the frame
before transmitting the next frame. If the acknowledgment takes too long. Then the sender resends the frame.
There are four possible scenarios that could occur with this algorithm for a given frame:
The frame arrives okay and is acknowledged okay. This is the happy case.
The frame does not arrive okay. After the timeout period, the frame is re-sent and this time it is acknowledged. This is situation might cause problems (similar to the item below).
The frame arrives okay but the ACK frame is lost. The timeout then happens, the frame is re-sent and it is acknowledged
correctly. Even this is still pretty happy.
The frame arrives okay but the ACK frame is sent but it arrives to the sender after the timeout period. So the sender has
already re-sent the frame. This might be bad. How does the receiver know the re-sent frame is not the next frame?
To avoid the problem of situation 4, typically a 1-bit control sequence is used in the header of frames sent and in the acknowledgment
frame. Each time the Sender sends, it adds 1 to this sequence number mod 2. The receiver's ACK frame should say in its header the sequence
number being acknowledged.
The Drawback of Stop and Wait
The main problem with stop and wait is that it doesn't make efficient use of the bandwidth resources.
To see this suppose one had a 1.5Mbps link with a 45ms RTT.
Suppose the frame size is 1KB. Since only one frame can be sent per RTT, implies our effective bit
rate is (1024 * 8)/.045 = 182 Kbps -- only 1/8 of the total channel bandwidth.
We would like somehow to be able to send 8 frames before have to send an acknowledgment.
Sliding Window -- the Sender
In the sliding window protocol, the sender assigns a sequence number SeqNum to each frame. For now we'll assume that this number could be any natural number
(even though it will eventually be implemented with some fixed number of bits).
The sender also has:
a sender window size (SWS) -- the maximum number of unacknowledged frames that the sender can transmit. We will choose
the SWS to try to keep the pipe as full as possible.
a last acknowledgment received (LAR) -- the sequence number of the last frame acknowledged.
a last frame sent (LFS) -- the sequence number of the last frame sent.
The sender maintains that LFS - LAR ≤ SWS.
The sender has a buffer of size SWS which could hold all of the frames which might not yet be acknowledged.
The sender has a timer for each frame that has not been acknowledged, and re-sends a frame if its timer goes off.
An acknowledgment from the receiver of a sequence number will now be a promise from the receiver that all smaller
sequence numbers have been received. So when the sender gets an acknowledgement it checks if the number is between
LAR and LFS, if it is, it sets LAR to this number -- all of the frames less than this are viewed as acknowledged.
Sliding Window -- the Receiver
Meanwhile, the receiver also maintains three variables:
a receive window size (RWS) -- maximum number of out of order frame the receiver is willing to receive.
a largest acceptable frame (LAF) -- the highest sequence number that the receiver is currently will to accept.
a last frame received (LFR) -- the sequence number of last frame received.
The receiver maintains that LAF - LFR ≤ RWS.
When a frame with SeqNum arrives, the receiver checks if SeqNum ≤ LFR or SeqNum ≤ LAF. If so the frame is out of the
receiver's window and is discarded.
If the frame is in the receiver window, it is accepted.
The receiver ACKs the frame with sequence number SeqNumToAck, which denotes the largest sequence number not yet
acknowledged, such that all frames less than or equal to it have been received.
The receiver then sets LFR =SeqNumToAck and LAF = LFR + RWS.
More Sliding Window
Suppose LFR=5, and RWS =4. So LAF = 9.
If frames 7 and 8 are received, they will be buffered because they are within the receiver window. However, no ACK need to be sent
yet because frame 6 has not yet arrived.
Frame 7 and 8 are said to be out of order.
When frame 6 arrives (it might have come later because it had a problem and had to be resent), LFR is set to 8 (this is also the sequence number ACK'd) and LAF is set to 12.
Suppose frame 6 had been lost, then a timeout would occur. The amount of data in transit decrease because, the sender cannot
advance his window. So in this situation the pipe might no longer be full.
One way to mitigate against this problem is when frame 7 arrives, the receiver sends a negative acknowledgement (NAK) for frame 6. This might
get back to the sender before its timeout expires and so would allow the sender to re-send more quickly. This, of course, adds complexity to the receiver.
Another technique is to use selective acknowledgments. The receiver could acknowledge exactly those frames it receives, rather than the highest number frame received in order. This add considerable complexity though to the implementation.
The sending window size, SWS, is selected according to how many frames we want to have outstanding on the link at a given time. It is set to how many frames fit in a given delay * bandwidth product.
The RWS can be set to whatever the receiver wants. When RWS=1 the receiver does not buffer any out of order frames. When RWS=SWS, the receiver can buffer any of the frames the sender transmits. Setting RWS > SWS doesn't help since its impossible for more than SWS frames to arrive out of order.
Finite Sequence Numbers
Let's assume now that sequence numbers are bounded to values less than some number MaxSeqNum.
If the sequence number gets to MaxSeqNum - 1, the next sequence number is 0.
How big does MaxSeqNum have to be so that we don't have to worry about two different incarnations
of the same sequence number?
Obviously, we want SWS < MaxSeqNum.
If RWS=1, then MaxSeqNum = SWS + 1 will work.
If SWS=RWS, SWS+1 does not work. Consider SWS=RWS=7, then if the sender sends 0..6 which are received by the
receiver but all the ACKs are lost. Then the receiver is expecting frames 7,0..5. The sender timesout and resends
0..6 are some of these are confused for new frames.
It turns out in this case the correct answers is SWS < (MaxSeqNum +1 )/2
Frame Order and Flow Control
The sliding window protocol is one of the best-known computer networking algorithms. It actually can be used to
support three different roles:
To deliver frames reliably across an unreliable link.
To preserve the order in which frame are transmitted.
To make sure that the receiver can slow down a sender who is transmitting too fast. (flow control)
Concurrent Logical Channels
The data link layer in the ARPANET used an interesting alternative to the sliding window protocol.
This protocol did not address order preservation or flow control.
ARPANET supported the ability to multiplex several logical channels onto a single point-to-point link and
then ran stop-and-wait for each of these channels. This idea was referred to as the support for
concurrent logical channels.
ARPANET supported 8 logical channels over each ground link and 16 over satellite links. Each channel had a
3 bit state, a boolean for whether the channel was busy, a 1-bit sequence number to use for the next frame, and the
next sequence number to expect.
When one wanted to send a frame one used the first non-busy channel.
Ethernet
Ethernet is the most popular local area network (LAN) technology.
It was developed at Xerox PARC in the mid-1970s.
It makes use of a LAN technology known as carrier sense, multiple access with collision detection (CSMA/CD)
Multiple nodes can send and receive data over a shared Ethernet link. This is what multiple access means.
Carrier sense means that all nodes can distinguish between an idle link and if someone is talking (a busy link).
Collision detection means that a node listens as it transmits and can detect when a frame it is transmitting
is interfered with by another frame from another node.
The technology that Ethernet uses was original worked out for an early packet radio network called Aloha developed
at the University of Hawaii.
Both systems had to solve the problem of how to use a shared resource fairly and efficiently. i.e., we need to
figure out who can transmit when.
DEC, Intel, and Xerox defined a 10 Mbps Ethernet standard in 1978, and this formed the basis for the IEEE 802.3 standard.
This standard was later extended to include 100Mbps (Fast) Ethernet and 1000Mbps (Gigabit) Ethernet.
We will over the next class describe how Ethernet works.