CSC 401 Data and Computer Communications Networks Transport Layer Principles of Reliable Data Transfer Sec 3.4 Prof. Lina Battestilli 2017 Fall
Transport Layer Chapter 3 Outline 3.1 Transport-layer Services 3.2 Multiplexing and Demultiplexing 3.3 Connectionless Transport: UDP 3.4 Principles of Reliable Data Transfer 3.5 Connection-oriented Transport: TCP segment structure, reliable data transfer, flow control, connection management 3.6 Principles of Congestion Control 3.7 TCP Congestion Control
Principles of reliable data transfer important in application, transport, link layers top-10 list of important networking topics!
Principles of reliable data transfer important in application, transport, link layers top-10 list of important networking topics! characteristics of unreliable channel will determine complexity of reliable data transfer protocol (rdt)
Principles of reliable data transfer characteristics of unreliable channel will determine complexity of reliable data transfer protocol (rdt)
The Interfaces for our Data Transfer Protocol rdt_send(): called from above, (e.g., by app.). Passed data to deliver to upper layer deliver_data(): called by rdt to deliver data to upper send side receive side udt_send(): called by rdt, to transfer packet over unreliable channel to rdt_rcv(): called when packet arrives on rcv-side of channel
Designing a Reliable Data Transfer protocol We will: incrementally develop, sides of a reliable data transfer protocol (rdt) consider only unidirectional data transfer but control info will flow on both directions! use finite state machines (FSM) to specify, event causing state transition actions taken on state transition state: when in this state next state uniquely determined by next event state 1 event actions state 2 state 3
Problem can send at a rate of 500 pkts/sec How to make the network reliable? can receive at a rate of 200 pkts/sec Sender should not send more packets than can process Receiver gives feedback Two basic approaches Stop and wait (one packet in flight) Pipelining (many packets in flight)
rdt1.0: reliable channel Underlying channel perfectly reliable no bit errors no loss of packets call from above rdt_send(data) packet = make_pkt(data) udt_send(packet) call from below rdt_rcv(packet) extract (packet,data) deliver_data(data) sends data into underlying channel receives data into underlying channel
rdt2.0: channel with bit errors Underlying channel may flip bits in packet checksum to detect bit errors The question: how to recover from errors: acknowledgements (ACKs): explicitly tells that pkt received OK negative acknowledgements (NAKs): explicitly tells that pkt had errors retransmits pkt on receipt of NAK new mechanisms in rdt2.0 (beyond rdt1.0): How do humans recover from errors error detection during conversation? feedback: control msgs (ACK,NAK) rcvr->
rdt2.0: channel with bit errors underlying channel may flip bits in packet checksum to detect bit errors The question: how to recover from errors: acknowledgements (ACKs): explicitly tells that pkt was received OK negative acknowledgements (NAKs): explicitly tells that pkt had errors retransmits pkt on receipt of NAK new mechanisms in rdt2.0 (extending rdt1.0): error detection: checksum feedback: control msgs (ACK,NAK) rcvr-> retransmission: -> rsvr
rdt2.0: FSM specification rdt_send(data) sndpkt = make_pkt(data, checksum) call from above ACK or NAK isack(rcvpkt) L isnak(rcvpkt) corrupt(rcvpkt) udt_send(nak) call from below notcorrupt(rcvpkt) extract(rcvpkt,data) deliver_data(data) udt_send(ack) 3-17
rdt2.0: operation with no errors rdt_send(data) snkpkt = make_pkt(data, checksum) call from above isack(rcvpkt) L ACK or NAK isnak(rcvpkt) corrupt(rcvpkt) udt_send(nak) call from below notcorrupt(rcvpkt) extract(rcvpkt,data) deliver_data(data) udt_send(ack)
rdt2.0: error scenario rdt_send(data) snkpkt = make_pkt(data, checksum) call from above isack(rcvpkt) L ACK or NAK isnak(rcvpkt) corrupt(rcvpkt) udt_send(nak) call from below Q: Are there any flaws with this protocol? notcorrupt(rcvpkt) extract(rcvpkt,data) deliver_data(data) udt_send(ack)
rdt2.0 has a flaw! What happens if ACK/NAK corrupted? doesn t know what happened at! Add a checksum for the ACK/NAK but what if ACK/NAK is lost? Can t just retransmit: possible duplicates! horse dog dog cat Receiver does NOT know if this is a retransmitted packet or or if dog was sent twice as part of the stream. Q: How to handle duplicates?
sending dog cat Duplicates Problem send dog corrupted ack So did the get dog? pkt1 dog pkt1 dog ack dog send ack rcv send dog rcv dog dog received dog cat Receiver did get dog send cat ack pkt2 cat send ack cat rcv Q: How to handle duplicates? 21
rdt2.0 ACK/NAK can be corrupted Handling Duplicates: retransmits current packet if ACK/NAK corrupted adds sequence number to each packet discards (doesn t deliver up to application) duplicate packet stop and wait protocol At most one packet in flight b/n & Sender sends one packet, then waits for response Receiver sends ACK/NAK, and based on that the sends another packet
Handling Duplicates For stop-and-wait protocol a 1- bit sequence number is enough Still assuming a channel that does NOT loose packets Received nak so retransmits pkt1 Received a corrupted ack or nak retransmits pkt1 Received ack OK send pkt0 rcv ack send pkt1 rcv nak send pkt1 rcv ack send pkt1 rcv ack send pkt0 pkt0 ack pkt1 nak pkt1 ack pkt1 ack pkt0 rcv pkt0 send ack rcv pkt1 send nak rcv pkt1 send ack rcv pkt1 send ack Received pkt0 OK Received pkt1 but it was corrupted Received pkt1 OK Received pkt1 OK, but it was expecting pkt0 so it detects duplicate and drops pkt1, sends an ack to get the to transmit the next pkt0 23
rdt2.1:, handles garbled ACK/NAKs rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt) L ( corrupt(rcvpkt) isnak(rcvpkt) ) rdt_send(data) sndpkt = make_pkt(0, data, checksum) call 0 from above ACK or NAK 1 rdt_send(data) sending pkt0 ACK or NAK 0 call 1 from above ( corrupt(rcvpkt) isnak(rcvpkt) ) rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt) sndpkt = make_pkt(1, data, checksum) L If ACK/NAK corrupted or if it is a NAK: Finally you know that pkt0 made it to the OK handles bit corruption but not packet loss 24
rdt2.1:, handles garbled ACK/NAKs pkt received was corrupted so send a NAK (corrupt(rcvpkt) Good Case: pkt 0 received OK notcorrupt(rcvpkt) && has_seq0(rcvpkt) extract(rcvpkt,data) deliver_data(data) sndpkt = make_pkt(ack, chksum) (corrupt(rcvpkt) sndpkt = make_pkt(nak, chksum) not corrupt(rcvpkt) && has_seq1(rcvpkt) sndpkt = make_pkt(ack, chksum) pkt received OK but the wrong sequence number, i.e., duplicate, so the did not get ACK for pkt1. Q: why do this? 0 from below 1 from below notcorrupt(rcvpkt) && has_seq1(rcvpkt) extract(rcvpkt,data) deliver_data(data) sndpkt = make_pkt(ack, chksum) sndpkt = make_pkt(nak, chksum) notcorrupt(rcvpkt) && has_seq0(rcvpkt) sndpkt = make_pkt(ack, chksum) 25
seq # added to pkt two seq. # s (0,1) will suffice. must check if received ACK/NAK corrupted twice as many states state must remember to get an ACK for pkts with seq # of 0 or 1 before transitioning must check if received packet is duplicate state indicates whether 0 or 1 is expected pkt seq # does not know if its last ACK/NAK received OK at No sequence # added to ACKs/NAKs Q: Do we need both ACKs and NAKs 26
rdt2.2: a NAK-free protocol same functionality as rdt2.1, but using ACKs only instead of NAK, sends ACK for last pkt received correctly (no errors) must explicitly include seq # of pkt being ACKed duplicate ACK at results in same action as NAK: retransmit current pkt 27
rdt2.2:, FSM fragments ACKs have checksums AND sequence numbers (corrupt(rcvpkt) has_seq1(rcvpkt)) rdt_send(data) sndpkt = make_pkt(0, data, checksum) call 0 from above 0 from below ACK 0 ( corrupt(rcvpkt) isack(rcvpkt,1) ) rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt,0) L BAD: If pkt corrupted or received ACK for pkt1 sequence in ACKs GOOD: received ACK for pkt0 BAD: pkt received was corrupted or it had wrong sequence number, so send an ACK for pkt1 again notcorrupt(rcvpkt) && has_seq1(rcvpkt) extract(rcvpkt,data) deliver_data(data) sndpkt = make_pkt(ack1, chksum) GOOD: pkt received OK and it has the correct sequence number then send ACK for pkt1 28
rdt3.0: channels with errors and loss New assumption: underlying channel can also lose packets (data, ACKs) checksum, seq. #, ACKs, retransmissions will help but NOT enough. Why? / can get stuck! Q: what would you do in the analogy of phone conversation? approach: modify only the to wait reasonable amount of time for ACK retransmits if no ACK received in this time if pkt (or ACK) just delayed (not lost): retransmission will be duplicate, but seq. # s already handles this must specify seq# of pkt being ACKed requires countdown timer picking right time is hard: timeout too short or too long 29
rdt3.0 rdt_rcv(rcvpkt) L call 0 from above rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt,1) stop_timer timeout start_timer ( corrupt(rcvpkt) isack(rcvpkt,0) ) L Wait for ACK1 rdt_send(data) sndpkt = make_pkt(0, data, checksum) start_timer rdt_send(data) Wait for ACK0 call 1 from above sndpkt = make_pkt(1, data, checksum) start_timer ( corrupt(rcvpkt) isack(rcvpkt,1) ) L timeout start_timer rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt,0) stop_timer rdt_rcv(rcvpkt) L BAD: If pkt corrupted or received ACK for pkt1 NEW! Resend based on timeout GOOD : If pkt received Ok and it is an ACK for pkt0 Sender is done with pkt0 so it goes to wait to get new data from app 30
rdt3.0 in action Timing Diagrams send pkt0 rcv ack0 send pkt1 rcv ack1 send pkt0 pkt0 ack0 pkt1 ack1 pkt0 ack0 rcv pkt0 send ack0 rcv pkt1 send ack1 rcv pkt0 send ack0 send pkt0 rcv ack0 send pkt1 timeout resend pkt1 rcv ack1 send pkt0 pkt0 ack0 pkt1 X loss pkt1 ack1 pkt0 ack0 rcv pkt0 send ack0 rcv pkt1 send ack1 rcv pkt0 send ack0 (a) no loss (b) packet loss 31
rdt3.0 in action Timing Diagrams send pkt0 rcv ack0 send pkt1 timeout resend pkt1 rcv ack1 send pkt0 pkt0 ack0 pkt1 ack1 X loss pkt1 ack1 pkt0 ack0 rcv pkt0 send ack0 rcv pkt1 send ack1 rcv pkt1 (detect duplicate) send ack1 rcv pkt0 send ack0 send pkt0 rcv ack0 send pkt1 timeout resend pkt1 rcv ack1 send pkt0 rcv ack1 rcv ack0 send pkt1 pkt0 ack0 pkt1 ack1 pkt1 pkt0 ack1 ack0 pkt1 rcv pkt0 send ack0 rcv pkt1 send ack1 rcv pkt1 (detect duplicate) send ack1 rcv pkt0 send ack0 rcv pkt1 send ack1 (c) ACK loss (d) premature timeout/ delayed ACK 32
This is the FSM for rdt3.0. Write the FSM for the. rdt_rcv(rcvpkt) L call 0 from above rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt,1) stop_timer timeout start_timer ( corrupt(rcvpkt) isack(rcvpkt,0) ) L Wait for ACK1 rdt_send(data) sndpkt = make_pkt(0, data, checksum) start_timer rdt_send(data) Wait for ACK0 call 1 from above sndpkt = make_pkt(1, data, checksum) start_timer ( corrupt(rcvpkt) isack(rcvpkt,1) ) L timeout start_timer rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isack(rcvpkt,0) stop_timer rdt_rcv(rcvpkt) L BAD: If pkt corrupted or received ACK for pkt1 NEW! Resend based on timeout GOOD : If pkt received Ok and ACK for pkt0 Sender is done with pkt0 so it goes to wait to get new data from app You can use rdt_rcv(), notcorrupt(), corrupt(), udt_send(pkt), extract(.), deliver(.), make_pkt(.), hasseq(.). start_timer 33
Solution -- rdt 3.0 from rdt2.2 will work for rdt3.0 as well! GOOD: pkt received OK and it has sequence number 0 then send ACK0 notcorrupt(rcvpkt) && has_seq0(rcvpkt) extract(rcvpkt,data) deliver_data(data) sndpkt = make_pkt(ack0, chksum) (corrupt(rcvpkt) has_seq1(rcvpkt)) sndpkt=make_pkt(ack, 1, checksum) BAD: received pkt but it was corrupt or it had sequence number -- so tell the with ACK1 that you have already gotten pkt1 0 from below notcorrupt(rcvpkt) && has_seq1(rcvpkt) extract(rcvpkt,data) deliver_data(data) sndpkt = make_pkt(ack1, chksum) 1 from below (corrupt(rcvpkt) has_seq0(rcvpkt)) sndpkt=make_pkt(ack, 0, checksum) 34
35 rdt Protocols Stop & Wait Vers. Description Mechanism for reliable data transfer rdt 1.0 underlying channel perfectly reliable rdt 2.0 bit errors possible retransmission rdt 2.1 bit errors possible retransmission ACK/NAK could also be corrupted rdt 2.2 bit errors possible retransmission only ACKs (got rid of NAKs) rdt 3.0 bit errors possible retransmission only ACKs loss possible Checksum ACK/NAK Checksum Sequence Numbers ACK/NAK have checksums Checksum Sequence Numbers ACKs have checksums AND sequence numbers Checksum Sequence Numbers ACKs with checksum & sequence numbers Timeouts at
Performance of rdt3.0 rdt3.0 is correct, but performance not so great e.g.: 1 Gbps link, 15ms one-way prop. delay, 30msec RTT, 8000 bit packet: D trans = L R 8000 bits = 10 9 = 8 microsecs bits/sec U : utilization fraction of time busy sending U = L / R RTT + L / R =.008 30.008 267Kbps throughput over 1 Gbps link = 0.00027 stop&wait network protocol limits use of physical resources!
rdt3.0: stop-and-wait operation first packet bit transmitted, t = 0 last packet bit transmitted, t = L / R RTT first packet bit arrives last packet bit arrives, send ACK ACK arrives, send next packet, t = RTT + L / R U = L / R RTT + L / R =.008 30.008 = 0.00027 40
Pipelined protocols pipelining: allows multiple, in-flight, yet-to-beacknowledged pkts range of sequence numbers must be increased buffering at and/or Two generic forms of pipelined protocols: go-back-n, selective repeat
References Some of the slides are identical or derived from 1. Slides for the 7 th edition of the book Kurose & Ross, Computer Networking: A Top-Down Approach, 2. Computer Networking, Nick McKeown and Philip Levis, 2014 Stanford University