Lecture 5:
UDP &
Principles of Network Transport
Aggelos Bletsas
Computer Networks II
Spring Semester 2021
School of ECE, Technical Univ. of Crete
1
Slides adapted from “Computer Networking: A top-down Approach – 5th
edition” by Jim Kurose and Keith Ross, Addison-Wesley, April 2009.
All material copyright 1996-2009
J.F Kurose and K.W. Ross, All Rights Reserved
2
Transport Layer
Our goals:
• understand • learn about transport
principles behind layer protocols in the
transport layer Internet:
services: – UDP: connectionless
– multiplexing/demulti- transport
plexing – TCP: connection-
– reliable data transfer oriented transport
– flow control – TCP congestion control
– congestion control
Transport services and protocols
application
transport
• provide logical communication network
data link
between app processes physical
lo
running on different hosts
gi
ca
• transport protocols run in end
le
nd
systems
-e
nd
– send side: breaks app
tr
ans
messages into segments,
po
rt
passes to network layer
– rcv side: reassembles application
transport
segments into messages, network
data link
passes to app layer physical
• more than one transport
protocol available to apps
– Internet: TCP and UDP
Transport vs. network layer
• network layer: logical Household analogy:
communication 12 kids sending letters to
12 kids
between hosts
• processes = kids
• transport layer: logical
• app messages = letters
communication in envelopes
between processes • hosts = houses
– relies on, enhances, • transport protocol = Ann
network layer services and Bill
• network-layer protocol =
postal service
Internet transport-layer protocols
• reliable, in-order application
transport
network
delivery (TCP) data link
physical
network
– congestion control data link
lo
network
physical
gi
data link
ca
– flow control physical
le
nd
– connection setup
-e
nd
network
• unreliable, unordered
tr
data link
a
physicalnetwork
ns
data link
delivery: UDP
po
physical
rt
network
– “best-effort” IP data link
physical network
application
transport
data link network
• services not physical data link
physical
available:
– delay guarantees
– bandwidth guarantees
Multiplexing/demultiplexing
Demultiplexing at rcv host: Multiplexing at send host:
gathering data from multiple
delivering received segments
sockets, enveloping data with
to correct socket
header (later used for
demultiplexing)
= socket = process
P3 P1
P1 P2 P4 application
application application
transport transport transport
network network network
link link link
physical physical physical
host 2 host 3
host 1
How demultiplexing works
32 bits
• host receives IP datagrams
– each datagram has source source port # dest port #
IP address, destination IP
address other header fields
– each datagram carries 1
transport-layer segment
– each segment has source,
application
destination port number
data
• host uses IP addresses & port (message)
numbers to direct segment to
appropriate socket
TCP/UDP segment format
Connectionless demultiplexing
• Create sockets with port • When host receives UDP
numbers: segment:
DatagramSocket mySocket1 = new – checks destination port
DatagramSocket(12534); number in segment
DatagramSocket mySocket2 = new – directs UDP segment to
DatagramSocket(12535); socket with that port number
• UDP socket identified by • IP datagrams with
different source IP
two-tuple:
addresses and/or source
(dest IP address, dest port number) port numbers directed to
same socket
Connectionless demux (cont.)
DatagramSocket serverSocket = new
DatagramSocket(6428);
P2 P1
P1
P3
SP: 6428 SP: 6428
DP: 9157 DP: 5775
SP: 9157 SP: 5775
client DP: 6428 DP: 6428 Client
server
IP: A IP: C IP:B
Why do we need SP ? SP provides “return address”
Connection-oriented demux
(cont)
P1 P4 P5 P6 P2 P1P3
SP: 5775
DP: 80
S-IP: B
D-IP:C
SP: 9157 SP: 9157
client DP: 80 DP: 80 Client
server
IP: A S-IP: A
IP: C S-IP: B IP:B
D-IP:C D-IP:C
Connection-oriented demux:
Threaded Web Server
P1 P4 P2 P1P3
SP: 5775
DP: 80
S-IP: B
D-IP:C
SP: 9157 SP: 9157
client DP: 80 DP: 80 Client
server
IP: A S-IP: A
IP: C S-IP: B IP:B
D-IP:C D-IP:C
UDP: User Datagram Protocol [RFC 768]
• “no frills,” “bare bones”
Internet transport protocol Why is there a UDP?
• “best effort” service, UDP • no connection establishment
segments may be: (which can add delay)
– lost • simple: no connection state
– delivered out of order to at sender, receiver
app • small segment header
• connectionless: • no congestion control: UDP
– no handshaking between can blast away as fast as
UDP sender, receiver desired
– each UDP segment
handled independently of
others
UDP: more
• often used for streaming
multimedia apps 32 bits
– loss tolerant Length, in source port # dest port #
– rate sensitive bytes of UDP length checksum
segment,
• other UDP uses including
– DNS header
– SNMP
• reliable transfer over UDP: Application
add reliability at application data
layer (message)
– application-specific error
recovery!
UDP segment format
UDP checksum
Goal: detect “errors” (e.g., flipped bits) in
transmitted segment
Sender: Receiver:
• treat segment contents • compute checksum of
as sequence of 16-bit received segment
integers • check if computed
• checksum: addition (1’s checksum equals
complement sum) of checksum field value:
segment contents – NO - error detected
• sender puts checksum – YES - no error
value into UDP detected.
checksum field
Internet Checksum Example
• Note
– When adding numbers, a carryout from the
most significant bit needs to be added to
the result
• Example: add two 16-bit integers
1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 0 1
1 1 0 00 1 1 1 1 0 0 0 01 1 0 0
wraparound 1 0 1 0 0 1 0 1 0 1 1 0 0 0 0 0 1
sum 1 0 1 0 0 1 0 1 0 1 1 0 0 0 0 1 0
checksum 1 1 0 1 1 0 1 0 1 0 0 1 1 1 1 0 1
[sum + checksum should give only 1’s]
Why do we need checksum in
Transport Layer?
• Data integrity is usually subject of link layer,
right?
Principles of Reliable data transfer
• important in app., transport, link layers
• top-10 list of important networking topics!
• characteristics of unreliable channel will determine
complexity of reliable data transfer protocol (rdt)
Reliable data transfer: getting started
rdt_send(): called from above, deliver_data(): called by
(e.g., by app.). Passed data to rdt to deliver data to upper
deliver to receiver upper layer
send receive
side side
udt_send(): called by rdt, rdt_rcv(): called when packet
to transfer packet over arrives on rcv-side of channel
unreliable channel to receiver
Reliable data transfer: getting started
We’ll:
• incrementally develop sender, receiver
sides of 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
sender, receiver event causing state transition
actions taken on state transition
state: when in this state
“state” next state state
1 event
uniquely 2
actions
determined by next
event
Rdt1.0: reliable transfer over a reliable channel
• underlying channel perfectly reliable
– no bit errors
– no loss of packets
• separate FSMs for sender, receiver:
– sender sends data into underlying channel
– receiver read data from underlying channel
Wait for rdt_send(data) Wait for rdt_rcv(packet)
call from call from extract (packet,data)
above packet = make_pkt(data) below deliver_data(data)
udt_send(packet)
sender receiver
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): receiver explicitly tells sender
that pkt received OK
– negative acknowledgements (NAKs): receiver explicitly tells
sender that pkt had errors
– sender retransmits pkt on receipt of NAK
• new mechanisms in rdt2.0 (beyond rdt1.0):
– error detection
– receiver feedback: control msgs (ACK,NAK) rcvr->sender
rdt2.0: FSM specification
rdt_send(data)
snkpkt = make_pkt(data, checksum) receiver
udt_send(sndpkt)
rdt_rcv(rcvpkt) &&
isNAK(rcvpkt)
Wait for Wait for rdt_rcv(rcvpkt) &&
call from ACK or udt_send(sndpkt) corrupt(rcvpkt)
above NAK
udt_send(NAK)
rdt_rcv(rcvpkt) && isACK(rcvpkt)
Wait for
L
call from
sender below
rdt_rcv(rcvpkt) &&
notcorrupt(rcvpkt)
extract(rcvpkt,data)
deliver_data(data)
udt_send(ACK)
rdt2.0: operation with no errors
rdt_send(data)
snkpkt = make_pkt(data, checksum)
udt_send(sndpkt)
rdt_rcv(rcvpkt) &&
isNAK(rcvpkt)
Wait for Wait for rdt_rcv(rcvpkt) &&
call from ACK or udt_send(sndpkt) corrupt(rcvpkt)
above NAK
udt_send(NAK)
rdt_rcv(rcvpkt) && isACK(rcvpkt)
Wait for
L call from
below
rdt_rcv(rcvpkt) &&
notcorrupt(rcvpkt)
extract(rcvpkt,data)
deliver_data(data)
udt_send(ACK)
rdt2.0: error scenario
rdt_send(data)
snkpkt = make_pkt(data, checksum)
udt_send(sndpkt)
rdt_rcv(rcvpkt) &&
isNAK(rcvpkt)
Wait for Wait for rdt_rcv(rcvpkt) &&
call from ACK or udt_send(sndpkt) corrupt(rcvpkt)
above NAK
udt_send(NAK)
rdt_rcv(rcvpkt) && isACK(rcvpkt)
Wait for
L call from
below
rdt_rcv(rcvpkt) &&
notcorrupt(rcvpkt)
extract(rcvpkt,data)
deliver_data(data)
udt_send(ACK)
rdt2.0 has a fatal flaw!
What happens if Handling duplicates:
ACK/NAK corrupted? • sender retransmits current pkt
if ACK/NAK garbled
• sender doesn’t know
• sender adds sequence number
what happened at to each pkt
receiver! • receiver discards (doesn’t
• can’t just retransmit: deliver up) duplicate pkt
possible duplicate
stop and wait
Sender sends one packet,
then waits for receiver
response
rdt2.1: sender, handles garbled
ACK/NAKs
rdt_send(data)
sndpkt = make_pkt(0, data, checksum)
udt_send(sndpkt) rdt_rcv(rcvpkt) &&
( corrupt(rcvpkt) ||
Wait for Wait for
ACK or
isNAK(rcvpkt) )
call 0 from
NAK 0 udt_send(sndpkt)
above
rdt_rcv(rcvpkt)
&& notcorrupt(rcvpkt) rdt_rcv(rcvpkt)
&& isACK(rcvpkt) && notcorrupt(rcvpkt)
&& isACK(rcvpkt)
L
L
Wait for Wait for
ACK or call 1 from
rdt_rcv(rcvpkt) && NAK 1 above
( corrupt(rcvpkt) ||
isNAK(rcvpkt) ) rdt_send(data)
udt_send(sndpkt) sndpkt = make_pkt(1, data, checksum)
udt_send(sndpkt)
rdt2.1: receiver, handles garbled
ACK/NAKs
rdt_rcv(rcvpkt) && notcorrupt(rcvpkt)
&& has_seq0(rcvpkt)
extract(rcvpkt,data)
deliver_data(data)
sndpkt = make_pkt(ACK, chksum)
udt_send(sndpkt)
rdt_rcv(rcvpkt) && (corrupt(rcvpkt) rdt_rcv(rcvpkt) && (corrupt(rcvpkt)
sndpkt = make_pkt(NAK, chksum) sndpkt = make_pkt(NAK, chksum)
udt_send(sndpkt) udt_send(sndpkt)
Wait for Wait for
rdt_rcv(rcvpkt) && 0 from 1 from rdt_rcv(rcvpkt) &&
not corrupt(rcvpkt) && below below not corrupt(rcvpkt) &&
has_seq1(rcvpkt) has_seq0(rcvpkt)
sndpkt = make_pkt(ACK, chksum) sndpkt = make_pkt(ACK, chksum)
udt_send(sndpkt) udt_send(sndpkt)
rdt_rcv(rcvpkt) && notcorrupt(rcvpkt)
&& has_seq1(rcvpkt)
extract(rcvpkt,data)
deliver_data(data)
sndpkt = make_pkt(ACK, chksum)
udt_send(sndpkt)
rdt2.1: discussion
Sender: Receiver:
• seq # added to pkt • must check if
• two seq. #’s (0,1) will received packet is
suffice. Why? duplicate
• must check if – state indicates
whether 0 or 1 is
received ACK/NAK expected pkt seq #
corrupted
• note: receiver can not
• twice as many states know if its last
– state must “remember” ACK/NAK received
whether “current” pkt
OK at sender
has 0 or 1 seq. #
rdt2.2: a NAK-free protocol
• same functionality as rdt2.1, using ACKs only
• instead of NAK, receiver sends ACK for last pkt
received OK
– receiver must explicitly include seq # of pkt being
ACKed
• duplicate ACK at sender results in same action
as NAK: retransmit current pkt
rdt2.2: sender, receiver fragments
rdt_send(data)
sndpkt = make_pkt(0, data, checksum)
udt_send(sndpkt)
rdt_rcv(rcvpkt) &&
( corrupt(rcvpkt) ||
Wait for Wait for
ACK isACK(rcvpkt,1) )
call 0 from
above 0 udt_send(sndpkt)
sender FSM
fragment rdt_rcv(rcvpkt)
&& notcorrupt(rcvpkt)
rdt_rcv(rcvpkt) && && isACK(rcvpkt,0)
(corrupt(rcvpkt) || L
has_seq1(rcvpkt)) Wait for receiver FSM
0 from
udt_send(sndpkt) below fragment
rdt_rcv(rcvpkt) && notcorrupt(rcvpkt)
&& has_seq1(rcvpkt)
extract(rcvpkt,data)
deliver_data(data)
sndpkt = make_pkt(ACK1, chksum)
udt_send(sndpkt)
rdt3.0: channels with errors and loss
New assumption: Approach: sender waits
underlying channel “reasonable” amount of
can also lose packets time for ACK
• retransmits if no ACK received
(data or ACKs) in this time
– checksum, seq. #, • if pkt (or ACK) just delayed (not
ACKs, retransmissions lost):
will be of help, but not – retransmission will be
enough duplicate, but use of seq.
#’s already handles this
– receiver must specify seq #
of pkt being ACKed
• requires countdown timer
rdt3.0 sender
rdt_send(data)
rdt_rcv(rcvpkt) &&
sndpkt = make_pkt(0, data, checksum) ( corrupt(rcvpkt) ||
udt_send(sndpkt) isACK(rcvpkt,1) )
rdt_rcv(rcvpkt) start_timer L
L Wait for Wait
for timeout
call 0 from
ACK0 udt_send(sndpkt)
above
start_timer
rdt_rcv(rcvpkt)
&& notcorrupt(rcvpkt) rdt_rcv(rcvpkt)
&& isACK(rcvpkt,1) && notcorrupt(rcvpkt)
stop_timer && isACK(rcvpkt,0)
stop_timer
Wait Wait for
timeout for call 1 from
udt_send(sndpkt) ACK1 above
start_timer rdt_rcv(rcvpkt)
rdt_send(data) L
rdt_rcv(rcvpkt) &&
( corrupt(rcvpkt) || sndpkt = make_pkt(1, data, checksum)
isACK(rcvpkt,0) ) udt_send(sndpkt)
start_timer
L
rdt3.0 in action
rdt3.0 in action
Thank you!
36