1086 lines
No EOL
80 KiB
HTML
1086 lines
No EOL
80 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
<html lang="en">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
||
<title>5.3. Transport Layer — Computer Systems Fundamentals</title>
|
||
|
||
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
|
||
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
|
||
|
||
<style>
|
||
.underline { text-decoration: underline; }
|
||
</style>
|
||
|
||
<script type="text/javascript">
|
||
var DOCUMENTATION_OPTIONS = {
|
||
URL_ROOT: './',
|
||
VERSION: '0.4.1',
|
||
COLLAPSE_INDEX: false,
|
||
FILE_SUFFIX: '.html',
|
||
HAS_SOURCE: true
|
||
};
|
||
</script>
|
||
|
||
<script type="text/x-mathjax-config">
|
||
MathJax.Hub.Config({
|
||
tex2jax: {
|
||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||
processEscapes: true
|
||
},
|
||
"HTML-CSS": {
|
||
scale: "80"
|
||
}
|
||
});
|
||
</script>
|
||
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
|
||
<link rel="next" title="4. Network Security Fundamentals" href="NetSec.html" />
|
||
<link rel="prev" title="2. Application Layer: Overlay Networks" href="AppLayer.html" />
|
||
|
||
</head><body>
|
||
|
||
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
|
||
|
||
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
|
||
<!-- Show a navbar toggler on mobile -->
|
||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
|
||
<span class="navbar-toggler-icon"></span>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="defaultNavbars">
|
||
<ul class="navbar-nav mr-auto">
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle jmu-gold rounded" href="TransLayer.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
|
||
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
|
||
<a class="dropdown-item" tabindex="-1" href="TransLayer.html#"><b>Chapter 1</b></a>
|
||
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
||
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
||
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
||
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
||
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
||
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
||
<a class="dropdown-item" href="StateModelImplementation.html"> 1.7. Extended Example: State Model Implementation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
|
||
<a class="dropdown-item" href="ProcessesOverview.html"> 2.1. Processes and OS Basics</a>
|
||
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
||
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
||
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
||
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
||
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
||
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
||
<a class="dropdown-item" href="Extended2Processes.html"> 2.8. Extended Example: Listing Files with Processes</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
|
||
<a class="dropdown-item" href="IPCOverview.html"> 3.1. Concurrency with IPC</a>
|
||
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
||
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
||
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
||
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
||
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
||
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
||
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
||
<a class="dropdown-item" href="Extended3Bash.html"> 3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
|
||
<a class="dropdown-item" href="SocketsOverview.html"> 4.1. Networked Concurrency</a>
|
||
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
||
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
||
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
||
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
||
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
||
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
||
<a class="dropdown-item" href="Extended4CGI.html"> 4.8. Extended Example: CGI Web Server</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
|
||
<a class="dropdown-item" href="InternetOverview.html"> 5.1. The Internet and Connectivity</a>
|
||
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
||
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
||
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
||
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
||
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
||
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
||
<a class="dropdown-item" href="Extended5DNS.html"> 5.8. Extended Example: DNS client</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
|
||
<a class="dropdown-item" href="ThreadsOverview.html"> 6.1. Concurrency with Multithreading</a>
|
||
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
||
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
||
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
||
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
||
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
||
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
||
<a class="dropdown-item" href="Extended6Primes.html"> 6.8. Extended Example: Concurrent Prime Number Search</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
|
||
<a class="dropdown-item" href="SynchOverview.html"> 7.1. Synchronization Primitives</a>
|
||
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
||
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
||
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
||
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
||
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
||
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
||
<a class="dropdown-item" href="Extended7Events.html"> 7.8. Extended Example: Event Log File</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
|
||
<a class="dropdown-item" href="SynchProblemsOverview.html"> 8.1. Synchronization Patterns and Problems</a>
|
||
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
||
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
||
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
||
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
||
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
||
<a class="dropdown-item" href="Extended8ModExp.html"> 8.7. Extended Example: Parallel Modular Exponentiation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
|
||
<a class="dropdown-item" href="ParallelDistributedOverview.html"> 9.1. Parallel and Distributed Systems</a>
|
||
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
||
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
||
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
||
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
||
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
||
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
||
<a class="dropdown-item" href="Extended9Blockchain.html"> 9.8. Extended Example: Blockchain Proof-of-Work</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Appendix A</b></a>
|
||
<a class="dropdown-item" href="CLangOverview.html"> A.1. C Language Reintroduction</a>
|
||
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
||
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
||
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
||
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
||
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
||
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
||
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
||
<a class="dropdown-item" href="Files.html"> A.9. Files</a>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/TransLayer.rst"
|
||
target="_blank" rel="nofollow">Show Source</a></li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
|
||
<div class="container center">
|
||
«  <a id="prevmod" href="AppLayer.html">5.2. Application Layer: Overlay Networks</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod" href="NetSec.html">5.4. Network Security Fundamentals</a>  »
|
||
|
||
</div>
|
||
<br />
|
||
|
||
|
||
|
||
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
|
||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/config.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "TransLayer";ODSA.SETTINGS.MODULE_LONG_NAME = "Transport Layer";ODSA.SETTINGS.MODULE_CHAPTER = "The Internet and Connectivity"; ODSA.SETTINGS.BUILD_DATE = "2021-06-11 17:38:24"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="transport-layer">
|
||
<h1>5.3. Transport Layer<a class="headerlink" href="TransLayer.html#transport-layer" title="Permalink to this headline">¶</a></h1>
|
||
<p>Up to this point, we have used application-layer socket programming essentially as another form of
|
||
IPC for exchanging data between processes on different hosts. Communication at that level can follow
|
||
a protocol that defines human-readable message formats, such as HTTP. Other applications, such as
|
||
DNS or DHCP, exchange highly structured binary messages that are intended to be interpreted by peer
|
||
processes. In either regard, the communication is specific to that application, and there is an
|
||
assumption that “the network”—a mysterious, almost magical entity—transmits the data. That is,
|
||
application-layer network programming can be easily conflated with other forms of IPC, replacing the
|
||
OS with the network as the service provider. There is truth to this conflation, as some layers and
|
||
protocols (including TCP and IP) are typically implemented within the OS. However, other layers are
|
||
implemented in hardware, including network interface cards, cables between devices, and radios.</p>
|
||
<p>The <a class="reference internal" href="Glossary.html#term-transport-layer"><span class="xref std std-term">transport layer</span></a> provides the first level of abstraction that application-layer
|
||
programmers rely on. Specifically, the transport layer establishes the logical structure of a
|
||
virtual <a class="reference internal" href="Glossary.html#term-end-to-end-communication"><span class="xref std std-term">end-to-end communication</span></a> channel between processes. When you use a web browser to
|
||
access <code class="docutils literal notranslate"><span class="pre">www.example.com</span></code>, you are intending to communicate with a particular process running on
|
||
that other host, not just the machine in general; you would probably be surprised if your web
|
||
browser suddenly began showing you binary DHCP or DNS responses instead of HTML-formatted
|
||
information. The transport layer ensures that your request gets delivered to the process running the
|
||
web server on the remote host, while returning the web page to your web browser process.</p>
|
||
<p>In contrast to a monolithic entity like an OS, the network is a layered architecture of distributed
|
||
components that cooperate to exchange data. For a variety of reasons, the distributed nature of
|
||
these components causes failed attempts at a significantly higher rate than an OS would ever
|
||
encounter. As an example, consider the effect of someone tripping over the cord of a server and
|
||
unplugging it; there is no possible way for your laptop to communicate with another machine that is
|
||
turned off. As a less extreme example, the message might not actually be lost, but it may encounter
|
||
a delay in the network that causes it to arrive too late. Failures and disruptions like this can
|
||
happen at any time. One key feature for choosing a transport layer protocol is whether or not the
|
||
application is requesting a <a class="reference internal" href="Glossary.html#term-reliable-transport"><span class="xref std std-term">reliable transport</span></a> service that attempts to correct failures
|
||
that occur. UDP provides fast but <a class="reference internal" href="Glossary.html#term-unreliable-transport"><span class="xref std std-term">unreliable transport</span></a>, while TCP features reliable
|
||
transport.</p>
|
||
<div class="section" id="unreliable-transport-udp">
|
||
<h2>5.3.1. Unreliable Transport: UDP<a class="headerlink" href="TransLayer.html#unreliable-transport-udp" title="Permalink to this headline">¶</a></h2>
|
||
<p>The simpler approach to transport-layer service is to provide an unreliable transport, which is the
|
||
purpose of the <a class="reference internal" href="Glossary.html#term-user-datagram-protocol"><span class="xref std std-term">User Datagram Protocol</span></a> (UDP), defined in RFC 768. UDP provides a fast
|
||
<em>best effort</em> delivery service, which is a polite way to say that it will try but it makes
|
||
no guarantees. UDP provides a minimal amount of end-to-end error checking to determine if the full
|
||
payload has been received and the contents have not been corrupted during transmission.</p>
|
||
<center>
|
||
<div class="col-md-6">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="p-0 center" style="width: 50%">0-15</th>
|
||
<th class="p-0 center" style="width: 50%">16-31</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center"><code>source port</code></td>
|
||
<td class="py-0 center"><code>destination port</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center"><code>length</code></td>
|
||
<td class="py-0 center"><code>checksum</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center" colspan="2"><code>payload</code><br />(application-layer data)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 5.2: Structure of a UDP segment
|
||
</p>
|
||
</div>
|
||
</center><p><a class="reference external" href="TransLayer.html#tbl5-2">Table 5.2</a> shows the structure of a UDP segment. The datagram contains a header with
|
||
four fields: the port numbers of the source and destination processes, the length of the segment
|
||
(including both the header and the payload), and a 16-bit checksum calculation. The following
|
||
examples show the UDP segment for a DNS request from the previous chapter.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 5.3.1 </p><hr class="mt-1" />
|
||
<p>In this example, the client had opened ephemeral port 5000 (<code class="docutils literal notranslate"><span class="pre">0x1388</span></code>) and sent the request to the
|
||
OpenDNS server, which was listening on port 53 (<code class="docutils literal notranslate"><span class="pre">0x0035</span></code>). The header requires eight bytes and the
|
||
request payload was 29 bytes, so the total length of the UDP segment was 37 bytes; the response was
|
||
53 bytes, due to the longer response in the payload.</p>
|
||
<center>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0">Header</td>
|
||
<td class="py-0" width="40%"><code>1388<br />0035<br />0025<br />f693</code></td>
|
||
<td class="py-0" width="50%"><code>source port = 5000 (0x1388)<br />destination port = 53 (0x0035)<br />length = 37 (0x0025)<br />checksum</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0">Payload</td>
|
||
<td class="py-0"><code>1234 0100 0001 0000 0000 0000<br />0765 7861 6d70 6d64 0363 6f6d<br />0000 0100 01</code></td>
|
||
<td class="py-0">DNS request for <code>example.com</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0">Header</td>
|
||
<td class="py-0" width="40%"><code>0035<br />1388<br />0035<br />af04</code></td>
|
||
<td class="py-0" width="50%"><code>source port = 53 (0x0035)<br />destination port = 5000 (0x1388)<br />length = 53 (0x0035)<br />checksum</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0">Payload</td>
|
||
<td class="py-0"><code>1234 8180 0001 0001 0000 0000<br />0765 7861 6d70 6d64 0363 6f6d<br />0000 0100 01c0 0c00 0100 0100<br />00e9 4900 045d b8d8 22</code></td>
|
||
<td class="py-0">DNS response for <code>example.com</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</center></div>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">checksum</span></code> value is the result of repeated one’s complement addition of 16-bit values in the
|
||
UDP segment, as shown in <a class="reference external" href="TransLayer.html#cl5-1">Code Listing 5.1</a>. In UDP, the checksum is evaluated over the
|
||
payload, parts of the IP header (which we are ignoring here, as we have not examined IP yet), and a
|
||
UDP <a class="reference internal" href="Glossary.html#term-pseudo-header"><span class="xref std std-term">pseudo-header</span></a>. The UDP pseudo-header contains the <code class="docutils literal notranslate"><span class="pre">source</span> <span class="pre">port</span></code>, <code class="docutils literal notranslate"><span class="pre">destination</span> <span class="pre">port</span></code>,
|
||
and the <code class="docutils literal notranslate"><span class="pre">length</span></code> fields of the regular UDP header. The <code class="docutils literal notranslate"><span class="pre">checksum</span></code> field is replaced with a
|
||
16-bit value containing information about the protocol, which is defined in RFC 762; for UDP, this
|
||
16-bit value is 0x0011. Regarding the payload, if there are an odd number of bytes (as shown in the
|
||
previous messages), that last byte is concatenated with zeroes to create a 16-bit value.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl5-1"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 5.1:</span>
|
||
<span class="cm"> Calculate a 16-bit checksum for use in UDP</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Calculates a 16-bit checksum */</span>
|
||
<span class="kt">uint16_t</span>
|
||
<span class="nf">cksum</span> <span class="p">(</span><span class="kt">uint16_t</span> <span class="o">*</span><span class="n">bytes</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">length</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="kt">uint32_t</span> <span class="n">sum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
|
||
<span class="cm">/* Loop through, adding 16 bits at a time */</span>
|
||
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">length</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="n">sum</span> <span class="o">+=</span> <span class="n">bytes</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
|
||
<span class="cm">/* If there is a leading 1, combine the two halves */</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">sum</span> <span class="o">&</span> <span class="mh">0x80000000</span><span class="p">)</span>
|
||
<span class="n">sum</span> <span class="o">=</span> <span class="p">(</span><span class="n">sum</span> <span class="o">&</span> <span class="mh">0xffff</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">sum</span> <span class="o">>></span> <span class="mi">16</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
<span class="cm">/* If there are an odd number of bytes, pad the last with leading</span>
|
||
<span class="cm"> zeroes */</span>
|
||
<span class="k">if</span> <span class="p">(</span> <span class="p">(</span><span class="n">length</span> <span class="o">%</span> <span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="n">sum</span> <span class="o">+=</span> <span class="p">((</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">bytes</span><span class="p">)[</span><span class="n">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>
|
||
|
||
<span class="cm">/* Finalize the result by combining the two halves and flipping</span>
|
||
<span class="cm"> the bits */</span>
|
||
<span class="n">sum</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint16_t</span><span class="p">)</span> <span class="n">sum</span> <span class="o">+</span> <span class="p">(</span><span class="kt">uint16_t</span><span class="p">)</span> <span class="p">(</span><span class="n">sum</span> <span class="o">>></span> <span class="mi">16</span><span class="p">);</span>
|
||
<span class="k">return</span> <span class="o">~</span><span class="n">sum</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p><a class="reference external" href="TransLayer.html#tbl5-3">Table 5.3</a> illustrates the mechanics of how one’s complement addition works by adding the
|
||
values <code class="docutils literal notranslate"><span class="pre">0x7d09</span></code> and <code class="docutils literal notranslate"><span class="pre">0xb5fc.</span></code> The result of this calculation would be <code class="docutils literal notranslate"><span class="pre">0x13305</span></code> based on
|
||
binary arithmetic that does not require a fixed size. However, UDP checksums are fixed at a length
|
||
of 16 bits. Whenever the addition would produce a carry out of 1 (requiring a 17<sup>th</sup> bit),
|
||
that bit is folded around to the least-significant bit location. Consequently, the leading bit of
|
||
<code class="docutils literal notranslate"><span class="pre">0x13305</span></code> would be removed (creating <code class="docutils literal notranslate"><span class="pre">0x3305</span></code>) and added to the least-significant bit, yielding
|
||
the result <code class="docutils literal notranslate"><span class="pre">0x3306</span></code>.</p>
|
||
<center>
|
||
<div class="col-md-8">
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center"><code>7d09</code></td>
|
||
<td class="py-0 center"> </td>
|
||
<td class="py-0 center"><code>0 1 1 1</code></td>
|
||
<td class="py-0 center"><code>1 1 0 1</code></td>
|
||
<td class="py-0 center"><code>0 0 0 0</code></td>
|
||
<td class="py-0 center"><code>1 0 0 1</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center"><code>b5fc</code></td>
|
||
<td class="py-0 center"> </td>
|
||
<td class="py-0 center"><code>1 0 1 1</code></td>
|
||
<td class="py-0 center"><code>0 1 0 1</code></td>
|
||
<td class="py-0 center"><code>1 1 1 1</code></td>
|
||
<td class="py-0 center"><code>1 1 0 0</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center"><code>13305</code></td>
|
||
<td class="py-0 center"><code>1</code></td>
|
||
<td class="py-0 center"><code>0 0 1 1</code></td>
|
||
<td class="py-0 center"><code>0 0 1 1</code></td>
|
||
<td class="py-0 center"><code>0 0 0 0</code></td>
|
||
<td class="py-0 center"><code>0 1 0 1</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center"><code>3306</code></td>
|
||
<td class="py-0 center"> </td>
|
||
<td class="py-0 center"><code>0 0 1 1</code></td>
|
||
<td class="py-0 center"><code>0 0 1 1</code></td>
|
||
<td class="py-0 center"><code>0 0 0 0</code></td>
|
||
<td class="py-0 center"><code>0 1 1 0</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
UDP checksum for two 16-bit values
|
||
</p>
|
||
</div>
|
||
</center><p>The UDP checksum provides a minimal form of error-checking for end-to-end communication. As we will
|
||
note later in this chapter, both IP and Ethernet also provide error detection. As such, if the
|
||
segment is sent with these network and link layer protocols, UDP is performing a redundant service.
|
||
Furthermore, as UDP will make no attempt to correct the errors it detects, the UDP checksum may seem
|
||
to be pointless redundancy. This criticism is fair, although UDP can also be used with other network
|
||
or link-layer protocols that do not perform error correction. One disadvantage of a layered
|
||
architecture, such as the Internet protocol stack, is that the individual layers must be designed
|
||
without underlying assumptions of the other layers.</p>
|
||
<p>At first glance, UDP’s unreliable transport service may appear to be a poor choice, and for certain
|
||
applications it is. But UDP provides service that is good enough for other applications, while
|
||
avoiding the overhead penalties associated with a reliable transport. For instance, UDP is commonly
|
||
used in streaming multimedia applications that only require <em>most</em> of the data to be successfully
|
||
transmitted; the application can compensate for lost data by providing slightly worse quality, such
|
||
as pixelated images or temporarily pausing the media until more data can be received and buffered.
|
||
The application can detect the lost or corrupted data by checking the return value from
|
||
<code class="docutils literal notranslate"><span class="pre">recvfrom()</span></code>, sending new requests only as needed. UDP is also commonly used in application-layer
|
||
services that users do not typically interact with directly, such as DNS or DHCP.</p>
|
||
</div>
|
||
<div class="section" id="reliable-transport-tcp">
|
||
<h2>5.3.2. Reliable Transport: TCP<a class="headerlink" href="TransLayer.html#reliable-transport-tcp" title="Permalink to this headline">¶</a></h2>
|
||
<p>Although UDP provides a lightweight, fast transport service, the unreliability is simply not
|
||
appropriate for some applications. Consider how frustrating it would be to visit a web page that was
|
||
missing a portion of text; if the missing data occurred in the middle of HTML formatting or link
|
||
tags, then the appearance would be wrong or links to other web pages would be broken. As such, many
|
||
applications require the reliable transport service provided by the <a class="reference internal" href="Glossary.html#term-transmission-control-protocol"><span class="xref std std-term">Transmission Control
|
||
Protocol</span></a> (TCP), which is defined primarily in RFC 793. TCP is a <a class="reference internal" href="Glossary.html#term-connection-oriented-protocol"><span class="xref std std-term">connection-oriented</span></a>
|
||
protocol, indicating that the hosts maintain some form of state between messages. That is, the hosts
|
||
create a connection to establish a <a class="reference internal" href="Glossary.html#term-session"><span class="xref std std-term">session</span></a> that is likely to contain multiple messages sent
|
||
back and forth between the hosts; during this session, hosts may resend messages that are lost or
|
||
corrupted, while also taking steps to avoid overwhelming each other with too much data at any time.
|
||
The full operation of TCP is rather complex, but we will restrict our focus to the key concepts of
|
||
<em>reliable data delivery</em> and <a class="reference internal" href="Glossary.html#term-flow-control"><span class="xref std std-term">flow control</span></a>.</p>
|
||
<p>As with UDP, TCP segments include the 16-bit <code class="docutils literal notranslate"><span class="pre">source</span></code> and <code class="docutils literal notranslate"><span class="pre">destination</span> <span class="pre">port</span></code> numbers to designate the
|
||
processes at either end of the connection, as shown in <a class="reference external" href="TransLayer.html#tbl5-4">Table 5.4</a>. Similarly, the TCP
|
||
header contains a <code class="docutils literal notranslate"><span class="pre">checksum</span></code> that is used to detect errors that may have occurred in transmission; in
|
||
contrast to UDP, the TCP pseudo-header is based on information from the IP header. The <code class="docutils literal notranslate"><span class="pre">urgent</span> <span class="pre">data</span>
|
||
<span class="pre">pointer</span></code> is not used in modern practice, and the <code class="docutils literal notranslate"><span class="pre">optional</span> <span class="pre">fields</span></code> are beyond the scope of this book.
|
||
The other fields are explained below to illustrate the functioning of TCP reliable transport and flow control.</p>
|
||
<center>
|
||
<div class="col-md-6">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="p-0 center" style="width: 25%">0-7</th>
|
||
<th class="p-0 center" style="width: 25%">8-15</th>
|
||
<th class="p-0 center" style="width: 25%">16-23</th>
|
||
<th class="p-0 center" style="width: 25%">24-31</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center" colspan="2"><code>source port</code></td>
|
||
<td class="py-0 center" colspan="2"><code>destination port</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center" colspan="4"><code>sequence number (SEQ)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center" colspan="4"><code>acknowledgement number (ACK)</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center" colspan="2"><code>flags</code></td>
|
||
<td class="py-0 center" colspan="2"><code>receive window</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center" colspan="2"><code>checksum</code></td>
|
||
<td class="py-0 center" colspan="2"><code>urgent data ptr</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="p-0 center" colspan="4"><div class="xborder-highlight"><code>optional fields</code></div></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center" colspan="4"><code>payload</code><br />(application-layer data)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 5.4: Structure of a TCP segment
|
||
</p>
|
||
</div>
|
||
</center><p>In TCP segments, the <a class="reference internal" href="Glossary.html#term-sequence-number"><span class="xref std std-term">sequence number</span></a> (<code class="docutils literal notranslate"><span class="pre">SEQ</span></code>) is an identifier associated with the current
|
||
segment. Each host randomly chooses an initial value for the sequence number. Each time a host sends
|
||
a segment, it increments its internal counter for the sequence number by the size of the payload.
|
||
For example, consider a client application that uses <code class="docutils literal notranslate"><span class="pre">SEQ=25</span></code> for a segment containing the five
|
||
bytes <code class="docutils literal notranslate"><span class="pre">"Hello"</span></code>. If the client’s next segment is to sends the seven bytes <code class="docutils literal notranslate"><span class="pre">"Goodbye"</span></code>, it would
|
||
use <code class="docutils literal notranslate"><span class="pre">SEQ=30</span></code>. As this segment contains seven bytes, the client’s next segment would use
|
||
<code class="docutils literal notranslate"><span class="pre">SEQ=37</span></code>. In short, the sequence number denotes the order and the size of the application-layer
|
||
payload data.</p>
|
||
<div class="figure mb-2 align-right" id="id3" style="width: 35%">
|
||
<span id="internettcp"></span><a class="reference internal image-reference" href="_images/CSF-Images.5.2.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="A TCP data exchange of four messages" src="_images/CSF-Images.5.2.png" style="width: 90%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 5.3.2: A TCP data exchange of four messages</span></p>
|
||
</div>
|
||
<p>At the other end, the <a class="reference internal" href="Glossary.html#term-acknowledgement-number"><span class="xref std std-term">acknowledgement number</span></a> (<code class="docutils literal notranslate"><span class="pre">ACK</span></code>) allows a receiving host to inform the
|
||
sender that the segment was received. In the previous scenario, when the server receives the
|
||
client’s <code class="docutils literal notranslate"><span class="pre">"Hello"</span></code> segment (five bytes sent with <code class="docutils literal notranslate"><span class="pre">SEQ=25</span></code>), the server’s next segment would
|
||
contain the <code class="docutils literal notranslate"><span class="pre">ACK=30</span></code> (<code class="docutils literal notranslate"><span class="pre">SEQ</span> <span class="pre">+</span> <span class="pre">5</span></code>). <a href="TransLayer.html#internettcp">Figure 5.3.2</a> shows the sample exchange that we
|
||
have been describing. The client’s first segment used <code class="docutils literal notranslate"><span class="pre">SEQ=25</span></code>; the client sent the <code class="docutils literal notranslate"><span class="pre">ACK=42</span></code>,
|
||
indicating that was the value it expected for the server’s next segment. (This <code class="docutils literal notranslate"><span class="pre">ACK</span></code> is based on
|
||
segments shown before this sequence.) The server then responds with a segment that does, in fact,
|
||
use <code class="docutils literal notranslate"><span class="pre">SEQ=42</span></code>. Since this segment (<code class="docutils literal notranslate"><span class="pre">"Hello</span> <span class="pre">back"</span></code>) contains 10 bytes, the client indicates it
|
||
received the segment by using <code class="docutils literal notranslate"><span class="pre">ACK=52</span></code> in its next segment.</p>
|
||
<p>During the session, the OS on each host maintains a buffer for storing data until the application
|
||
reads it from the socket. As this buffer is finite in size, the hosts need to cooperate to prevent a
|
||
buffer overflow. The <a class="reference internal" href="Glossary.html#term-receive-window"><span class="xref std std-term">receive window</span></a> achieves this by declaring the maximum number of bytes
|
||
that the sender is capable of receiving in the next segment. To observe how this value is used,
|
||
consider the following analogous line of code when working with strings:</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="n">strncpy</span> <span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="n">input</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The third parameter indicates the maximum number of bytes that will be copied into the <code class="docutils literal notranslate"><span class="pre">buffer</span></code>.
|
||
For instance, if the <code class="docutils literal notranslate"><span class="pre">buffer</span></code> has space for 20 bytes, but the <code class="docutils literal notranslate"><span class="pre">input</span></code> is a string that is 50
|
||
bytes in length, the third parameter prevents the additional 30 bytes from being written beyond the
|
||
end of the <code class="docutils literal notranslate"><span class="pre">buffer</span></code>. The receive window serves the same purpose within the context of TCP
|
||
segments. If the receiver’s next segment exceeds this size, then that host would need to break up
|
||
its response and send it across multiple segments. This cooperation is the TCP <a class="reference internal" href="Glossary.html#term-flow-control"><span class="xref std std-term">flow control</span></a>
|
||
service, as each host takes steps to avoid sending too much data at a time.</p>
|
||
<p>There is subtle point regarding flow control that is easily misunderstood. Consider the sequence of
|
||
segments in <a href="TransLayer.html#internettcp">Figure 5.3.2</a>. In that scenario, the server sent two segments to the
|
||
client: one containing the string <code class="docutils literal notranslate"><span class="pre">"Hello</span> <span class="pre">back"</span></code> and one containing <code class="docutils literal notranslate"><span class="pre">"Farewell"</span></code>. One possible
|
||
explanation is that the application issued two system calls to write to the socket. Flow control
|
||
provides another explanation. Although this string in particular is unlikely, the server application
|
||
may have written the string <code class="docutils literal notranslate"><span class="pre">"Hello</span> <span class="pre">backFarewell"</span></code> to the socket. The client’s first segment
|
||
(sequence number 25) may have included a receive window indicating it only had space for 10 bytes,
|
||
so the server’s TCP implementation split the segment. The key point is that TCP itself provides
|
||
flow, and the application is typically not made aware it is happening. The sender splits the segment
|
||
without informing the application, and the receiving host’s TCP implementation concatenates all
|
||
segments in its internal buffers as needed.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3" id="transtcpexample">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 5.3.2 </p><hr class="mt-1" />
|
||
<p>The example shown here illustrates the full TCP header and payload for an HTTP <code class="docutils literal notranslate"><span class="pre">GET</span></code> request sent to <code class="docutils literal notranslate"><span class="pre">example.com</span></code>. The destination port number is 80, which is the well-known port number for HTTP, whereas the source port is an ephemeral port number, generated by the client’s OS. The receive window indicates that the client is requesting a maximum of 4096 bytes in response. The <code class="docutils literal notranslate"><span class="pre">flags</span></code> field will be explained in the next discussion on the TCP handshake, and the <code class="docutils literal notranslate"><span class="pre">urgent</span> <span class="pre">data</span> <span class="pre">pointer</span></code> field is not used. The <code class="docutils literal notranslate"><span class="pre">payload</span></code> here contains the HTTP application-layer request.</p>
|
||
<center>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0">Header</td>
|
||
<td class="py-0" width="40%"><code>1388<br />0050<br />0000 0017<br />0000 002a<br />5010<br />1000<br />cf33<br />0000</code> </td>
|
||
<td class="py-0" width="50%"><code>source port = 5000 (0x1388)<br />destination port = 80 (0x0050)<br />sequence number = 23 (0x17)<br />acknowledgement number = 42 (0x2a)<br />flags<br />receive window = 4096 (0x1000)<br />checksum<br />urgent data ptr</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0">Payload</td>
|
||
<td class="py-0"><code>4745 5420 2f20 4854 5450 2f31<br />2e31 0d0a 486f 7374 3a20 6578<br />616d 706c 652e 636f 6d0d 0a43<br />6f6e 6e65 6374 696f 6e3a 2063<br />6c6f 7365 0d0a 0d0a</code></td>
|
||
<td class="py-0"><code>GET / HTTP/1<br />.1\r\nHost: ex<br />ample.com\r\nC<br />onnection: c<br />lose\r\n\r\n</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</center></div>
|
||
</div>
|
||
<div class="section" id="tcp-handshake-and-connections">
|
||
<h2>5.3.3. TCP Handshake and Connections<a class="headerlink" href="TransLayer.html#tcp-handshake-and-connections" title="Permalink to this headline">¶</a></h2>
|
||
<p>Unlike the connectionless UDP that allows applications to send and receive data at any time, TCP
|
||
requires that the two hosts must first establish a connection to begin a communication session. That
|
||
is, prior to exchanging application-layer data, the hosts must send and receive some initial
|
||
segments to ensure both hosts know to expect the data exchange. At each end, this procedure involves
|
||
allocating internal buffers and variables, such as those needed for flow control. Just as
|
||
importantly, the hosts must also execute the <a class="reference internal" href="Glossary.html#term-tcp-handshake"><span class="xref std std-term">TCP handshake</span></a>, a lightweight initial protocol
|
||
that allows the hosts to declare their initial sequence numbers, receive windows, and other values.</p>
|
||
<p>The TCP handshake is implemented by exchanging empty segments with particular bits set in the TCP
|
||
header. Specifically, recall from <a class="reference external" href="TransLayer.html#tbl5-4">Table 5.4</a> that the TCP header contains a 16-bit
|
||
<code class="docutils literal notranslate"><span class="pre">flags</span></code> field. <a class="reference external" href="TransLayer.html#tbl5-5">Table 5.5</a> shows the internal structure of this field for a normal TCP
|
||
segment. The <code class="docutils literal notranslate"><span class="pre">data</span> <span class="pre">offset</span></code> field denotes the length of the TCP header in terms of 32-bit words.
|
||
The standard header, which contains no optional fields, has a length of five words; that constitutes
|
||
the minimum value of this field. If optional fields are used, this value can increase to 15, which
|
||
declares that TCP headers can be no longer than 60 bytes. The remainder of this section describes
|
||
the use of the <code class="docutils literal notranslate"><span class="pre">ACK</span></code>, <code class="docutils literal notranslate"><span class="pre">SYN</span></code>, and <code class="docutils literal notranslate"><span class="pre">FIN</span></code> bits.</p>
|
||
<center>
|
||
<div class="col-md-10">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="p-0 center bg-light text-dark">Index</th>
|
||
<th class="p-0 center" colspan="4">0-3</th>
|
||
<th class="p-0 center" colspan="6">4-9</th>
|
||
<th class="p-0 center" colspan="6">10-15</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<th class="py-0 px-2 center bg-light">Meaning</th>
|
||
<td class="py-0 center" colspan="4">data<br />offset</td>
|
||
<td class="py-0 center" colspan="6">unused</td>
|
||
<td class="py-0 center"><code>U<br />R<br />G</code></td>
|
||
<td class="py-0 center"><code>A<br />C<br />K</code></td>
|
||
<td class="py-0 center"><code>P<br />S<br />H</code></td>
|
||
<td class="py-0 center"><code>R<br />S<br />T</code></td>
|
||
<td class="py-0 center"><code>S<br />Y<br />N</code></td>
|
||
<td class="py-0 center"><code>F<br />I<br />N</code></td>
|
||
</tr>
|
||
<tr>
|
||
<th class="py-0 px-2 center bg-light">Value</th>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>1</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>1</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
<td class="py-0 center"><code>0</code></td>
|
||
</tr>
|
||
<tr>
|
||
<th class="py-0 px-2 center bg-light">Hex</th>
|
||
<td class="py-0 center" colspan="4"><code>5</code></td>
|
||
<td class="py-0 center" colspan="4"><code>0</code></td>
|
||
<td class="py-0 center" colspan="4"><code>0</code></td>
|
||
<td class="py-0 center" colspan="4"><code>0</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 5.5: Structure of the 16-bit TCP flags field
|
||
</p>
|
||
</div>
|
||
</center><div class="figure mb-2 align-right" id="id4" style="width: 40%">
|
||
<span id="internethandshake"></span><a class="reference internal image-reference" href="_images/CSF-Images.5.3.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="The TCP handshake" src="_images/CSF-Images.5.3.png" style="width: 90%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 5.3.4: The TCP handshake</span></p>
|
||
</div>
|
||
<p>The TCP handshake is initiated by a client application that calls the <code class="docutils literal notranslate"><span class="pre">connect()</span></code> socket function
|
||
described in the previous chapter. The steps of the TCP handshake are shown in <a href="TransLayer.html#internethandshake">Figure 5.3.4</a> and consists of three segments, commonly referred to as <code class="docutils literal notranslate"><span class="pre">"SYN"</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">"SYN-ACK"</span></code>, and <code class="docutils literal notranslate"><span class="pre">"ACK"</span></code> because of the bits they set. Note that this figure uses <code class="docutils literal notranslate"><span class="pre">"ACKnum"</span></code>
|
||
to refer to the 32-bit acknowledgement number and <code class="docutils literal notranslate"><span class="pre">"ACK"</span></code> to denote the bit in the 16-bit flags
|
||
field. A client initiates a TCP connection by sending a SYN segment (<code class="docutils literal notranslate"><span class="pre">"synchronize"</span></code>) that
|
||
contains its randomly chosen <code class="docutils literal notranslate"><span class="pre">SEQ</span></code> value, setting <code class="docutils literal notranslate"><span class="pre">SYN=1</span></code> and putting <code class="docutils literal notranslate"><span class="pre">0x5002</span></code> into the 16-bit
|
||
flags field. The server acknowledges receiving the synchronization request (setting <code class="docutils literal notranslate"><span class="pre">SYN=1</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">ACK=1</span></code> to get <code class="docutils literal notranslate"><span class="pre">0x5012</span></code>) and indicates its own initial sequence number. The client then responds
|
||
again with the <code class="docutils literal notranslate"><span class="pre">ACK=1</span></code> (<code class="docutils literal notranslate"><span class="pre">0x5010</span></code>). Note that all of these segments use an empty payload, but the
|
||
sequence numbers are incremented as if they contained a single byte.</p>
|
||
<p>After completing the TCP handshake, the client and server share a logical connection. Both hosts
|
||
know each other’s sequence numbers and initial receive window sizes. The OS on both hosts has
|
||
established internal buffers, variables, and other data structures as needed. This internal state is
|
||
maintained until the two parties close the connection. To close the connection, one host sends a
|
||
segment with an empty payload and the <em>finish</em> bit <code class="docutils literal notranslate"><span class="pre">FIN=1</span></code>; the other host responds with an
|
||
<code class="docutils literal notranslate"><span class="pre">ACK=1</span></code> segment. These two segments are then repeated, but with the other party sending the
|
||
<code class="docutils literal notranslate"><span class="pre">FIN=1</span></code> segment. As such, either side can sever the connection at any time.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Note.png"><img alt="Decorative note icon" src="_images/CSF-Images-Note.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Note</p><hr class="mt-1" />
|
||
<p>A common misunderstanding is that the <code class="docutils literal notranslate"><span class="pre">ACK</span></code> bit is used only in the TCP handshake or the
|
||
<code class="docutils literal notranslate"><span class="pre">FIN-ACK</span></code> closing exchange. That is not correct. The <code class="docutils literal notranslate"><span class="pre">ACK</span></code> bit is set any time that the
|
||
acknowledgement number is significant. That is, any time that the sender intends for the receiver
|
||
to interpret this number as an acknowledgement of a previous message, the sender sets the <code class="docutils literal notranslate"><span class="pre">ACK</span></code>
|
||
bit.</p>
|
||
</div>
|
||
<p>Recall the distinction between HTTP/1.0 and HTTP/1.1 discussed in the previous chapter. HTTP
|
||
applications use TCP for their reliable transport layer. As such, any HTTP data exchange (such as
|
||
accessing a web page, as well as retrieving the needed images and script files, require an initial
|
||
TCP handshake to establish the connection. In HTTP/1.0, every object retrieved requires its own TCP
|
||
connection session; even if all of the objects are stored on the same server, the seven segments
|
||
(three for the handshake and four to close the connection) all must be performed, and both hosts’ OS
|
||
must repeated set up and destroy internal buffers and data structures. With HTTP/1.1, the TCP
|
||
handshake is only done once per server. The connection is maintained until the client application
|
||
sends a segment containing the HTTP header <code class="docutils literal notranslate"><span class="pre">"Connection:</span> <span class="pre">close"</span></code>. The server and client then
|
||
exchange segments to close the connection.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 5.3.3 </p><hr class="mt-1" />
|
||
<p>This example illustrates the flow of a TCP handshake to set up an HTTP request. As in <a href="TransLayer.html#transtcpexample">Example 5.3.2</a>, the source and destination port numbers consist of the well-know port 80 and
|
||
an ephemeral port. When the client (typically a web browser) establishes the connection, it starts
|
||
by picking a random sequence number (4973 in this case) and using 0 as the acknowledgement number.
|
||
The client sends an empty request (i.e., there is no payload and the message is just the TCP
|
||
header) to the server as a <code class="docutils literal notranslate"><span class="pre">SYN</span></code> request.</p>
|
||
<p>The server responds with a <code class="docutils literal notranslate"><span class="pre">SYN-ACK</span></code> that sets both of these bits in the <code class="docutils literal notranslate"><span class="pre">flags</span></code> field. (Observe
|
||
that the port numbers reverse in this middle message to indicate the direction switched to be
|
||
“server to client.”) As with the <code class="docutils literal notranslate"><span class="pre">SYN</span></code> request, the server selects a random initial sequence
|
||
number (627). The acknowledgement number here is the client’s sequence number incremented by 1
|
||
(4973 + 1). Finally, the client completes the handshake with an <code class="docutils literal notranslate"><span class="pre">ACK</span></code> message back to the server.
|
||
This ACK message uses the incremented sequence number (4974) and the incremented acknowledgement of
|
||
the server’s sequence number (628). At this point, the connection is established and both hosts
|
||
have established the sequence and acknowledgement numbers for future messages.</p>
|
||
<center>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0"><code>SYN</code> request (client to server)</td>
|
||
<td class="py-0" width="40%"><code>1388<br />0050<br />0000 136d<br />0000 0000<br />5002<br />1000<br />2e67<br />0000</code></td>
|
||
<td class="py-0" width="50%"><code>source port = 5000 (0x1388)<br />destination port = 80 (0x0050)<br />sequence number = 4973 (0x136d)<br />acknowledgement number = 0<br />flags = SYN<br />receive window = 4096 (0x1000)<br />checksum<br />urgent data ptr<br /></code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0"><code>SYN-ACK</code> response (server to client)</td>
|
||
<td class="py-0" width="40%"><code>0050<br />1388<br />0000 0273<br />0000 136e<br />5012<br />1000<br />2be3<br />0000</code></td>
|
||
<td class="py-0" width="50%"><code>source port = 80 (0x0050)<br />destination port = 5000 (0x1388)<br />sequence number = 627 (0x273)<br />acknowledgement number = 4973 (0x136d)<br />flags = SYN and ACK<br />receive window = 4096 (0x1000)<br />checksum<br />urgent data ptr</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0"><code>ACK</code> response (client to server)</td>
|
||
<td class="py-0" width="40%"><code>1388<br />0050<br />0000 136e<br />0000 0274<br />5010<br />1000<br />2bf6<br />0000</code></td>
|
||
<td class="py-0" width="50%"><code>source port = 5000 (0x1388)<br />destination port = 80 (0x0050)<br />sequence number = 4974 (0x136d)<br />acknowledgement number = 628 (0x274)<br />flags = ACK<br />receive window = 4096 (0x1000)<br />checksum<br />urgent data ptr</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</center></div>
|
||
</div>
|
||
<div class="section" id="tcp-timeout-and-packet-loss">
|
||
<h2>5.3.4. TCP Timeout and Packet Loss<a class="headerlink" href="TransLayer.html#tcp-timeout-and-packet-loss" title="Permalink to this headline">¶</a></h2>
|
||
<p>The combination of the sequence number (<code class="docutils literal notranslate"><span class="pre">SEQ</span></code>) acknowledgement number (<code class="docutils literal notranslate"><span class="pre">ACK</span></code>) and the
|
||
<code class="docutils literal notranslate"><span class="pre">checksum</span></code> forms a rudimentary error detection scheme to support reliable transport. If a host
|
||
receives a segment with unexpected values in any of these fields, it can determine that <em>something</em>
|
||
has gone wrong in the data exchange. While the receiver may not be able to determine the exact cause
|
||
of the problem, the incorrect information can provide some guidance:</p>
|
||
<blockquote>
|
||
<div><ul class="simple">
|
||
<li><strong>Incorrect ACK</strong>: The sender may be indicating that the previous segment was corrupted or not
|
||
received. For example, assume a client sends <code class="docutils literal notranslate"><span class="pre">"Hello"</span></code> with <code class="docutils literal notranslate"><span class="pre">SEQ=10</span></code>; if the response contains
|
||
<code class="docutils literal notranslate"><span class="pre">ACK=10</span></code>, the <code class="docutils literal notranslate"><span class="pre">"Hello"</span></code> segment has not been acknowledged and should be re-sent.</li>
|
||
<li><strong>Incorrect SEQ</strong>: A previous segment from the server may be delayed or lost, and the server is
|
||
not aware of this fact. As an example, assume a client is expecting <code class="docutils literal notranslate"><span class="pre">SEQ=42</span></code> based on a previous
|
||
segment from the server. If the next segment it receives has <code class="docutils literal notranslate"><span class="pre">SEQ=52</span></code>, then there is some data
|
||
the client has not received. The missing data could be 10 one-byte segments or a single 10-byte
|
||
segment; the client cannot know which is true and does not actually need to. Again, the client
|
||
could re-send its last segment that contained <code class="docutils literal notranslate"><span class="pre">ACK=42</span></code>, effectively refusing to acknowledge the
|
||
newer data until the lost data is recovered.</li>
|
||
<li><strong>Incorrect checksum</strong>: Some part of the TCP segment or the payload has been corrupted or removed
|
||
in some way. As with the previous two cases, re-sending the last segment based on acknowledged data
|
||
serves as a request for the server to repeat its own segment.</li>
|
||
</ul>
|
||
</div></blockquote>
|
||
<div class="figure mb-2 align-right" id="id5" style="width: 40%">
|
||
<span id="internetresend"></span><a class="reference internal image-reference" href="_images/CSF-Images.5.4.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="The client resends the message if the acknowledgement is lost" src="_images/CSF-Images.5.4.png" style="width: 90%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 5.3.7: The client resends the message if the acknowledgement is lost</span></p>
|
||
</div>
|
||
<p><a href="TransLayer.html#internetresend">Figure 5.3.7</a> illustrates the notion of <a class="reference internal" href="Glossary.html#term-packet-loss"><span class="xref std std-term">packet loss</span></a>, another common
|
||
scenario involving TCP reliability. In this case, the server received and acknowledge the client’s
|
||
segment, but the client did not receive the server’s response. As a result, the client re-sent the
|
||
segment as a second attempt. From an omniscient perspective of all network traffic, this segment
|
||
seems unnecessary: We can observe that the server did, in fact, receive the segment the first time.
|
||
However, such a perspective is impossible; hosts can only observe the segments they send and
|
||
receive. From the client’s perspective, it is possible that the first segment—not the reply—was lost.</p>
|
||
<p>This simple scenario illustrates a critical design question for reliable transport: how long must
|
||
the client want before declaring a packet lost? Hosts need to wait long enough for packets to
|
||
traverse the network physically but waiting too long for a lost packet delays the recovery process.
|
||
To complicate matters further, network conditions can change, so determining the optimal amount of
|
||
time to wait is a moving target.</p>
|
||
<p>The original TCP specification in RFC 793 proposed measuring the <a class="reference internal" href="Glossary.html#term-round-trip-time"><span class="xref std std-term">round-trip time</span></a> (RTT),
|
||
which is the amount of time that elapses between sending a segment and receiving the response. As
|
||
the host sends and receives additional segments, it computes a <a class="reference internal" href="Glossary.html#term-smoothed-round-trip-time"><span class="xref std std-term">smoothed round-trip time</span></a>
|
||
(SRTT) as a rolling average of these delays. Based on an update in RFC 6298, in modern systems, the
|
||
SRTT is initialized to the first RTT measurement. Once a new measurement (denoted as $R’$) is made,
|
||
the SRTT is updated according to the following formula, with $\alpha$ typically set to 1/8.</p>
|
||
<center>
|
||
<span class="math inline">$\large SRTT := (1 - \alpha) SRTT + \alpha R'$</span>
|
||
</center>
|
||
<br /><div class="topic border border-dark rounded-lg bg-light px-2 mb-3" id="rttexample">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 5.3.4 </p><hr class="mt-1" />
|
||
<p>To illustrate this calculation, assume that the first measurement is $R =
|
||
4ms$. This value becomes the initial SRTT. The table below shows the changes that would occur if
|
||
the next three segments arrive with updated $R’$ values of 10 ms,
|
||
20 ms, and 2 ms, in that order.Note that all time units get rounded based on the granularity of the
|
||
clock, which is assumed to be 1 ms in this case.</p>
|
||
<center>
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="p-0 center">Old SRTT</th>
|
||
<th class="p-0 center"><span class="math inline">$R'$</span></th>
|
||
<th class="p-0 center">Updated SRTT</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center">4</td>
|
||
<td class="py-0 center">10</td>
|
||
<td class="py-0">(7/8) * 4 + (1/8) * 10 = 4.75 <i>[rounded to 5]</i></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">5</td>
|
||
<td class="py-0 center">20</td>
|
||
<td class="py-0">(7/8) * 5 + (1/8) * 20 = 6.875 <i>[rounded to 7]</i></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">7</td>
|
||
<td class="py-0 center">2</td>
|
||
<td class="py-0">(7/8) * 7 + (1/8) * 2 = 6.375 <i>[rounded to 6]</i></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 5.6: SRTT calculations for a sequence of three received segments
|
||
</p>
|
||
</center></div>
|
||
<p>The SRTT serves as an estimate for predicting the next RTT. The coefficients $\alpha$ and $(1 -
|
||
\alpha)$ act as a relative weighting factor that influences how much the new observed value changes
|
||
the estimate. Increasing the value of $\alpha$ places more weight on the most recent measurement,
|
||
thus decreasing then influence of historical values. On the other hand, decreasing $\alpha$ has the
|
||
opposite effect, relying more on the new RTT and less on the historical values.</p>
|
||
<p>The new SRTT value is used to update the retransmission timeout (RTO), which is the amount of time
|
||
that the host will wait before declaring a lost packet. While RFC 793 proposed a formula for
|
||
calculating RTO based just on SRTT, RFC 6298 updated this calculation. One problem with the original
|
||
formulation is that it does not consider the impact of variance in RTT. For example, a system that
|
||
repeatedly experiences an RTT of 20 ms every time should not be treated the same as one that
|
||
alternates between 1 ms and 39 ms, despite both systems having the same average RTT. To compensate
|
||
for this difference, RFC 6298 defines another rolling average, the RTT variation (RTTVAR), using
|
||
$\beta = 1/4$:</p>
|
||
<center>
|
||
<span class="math inline">$\large RTTVAR := (1 - \beta) RTTVAR + \beta | SRTT - R' |$</span>
|
||
</center>
|
||
<br /><p>To make sense of this factor, consider the role of the absolute value $| SRTT – R’ |$. This value
|
||
denotes the difference between the predicted RTT (SRTT) and the RTT that was actually observed
|
||
($R’$). If the prediction was perfect every time, then this absolute value would be 0. Then, each
|
||
new segment would shrink the RTTVAR to become 3/4 of its previous value. However, if there is great
|
||
variance from segment to segment, then this absolute value will be positive, potentially increasing
|
||
RTTVAR. As before, $\beta$ acts as a weighting factor to determine how much influence the new
|
||
variation should have compared with the historical values.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 5.3.5 </p><hr class="mt-1" />
|
||
<p>When calculating the new RTTVAR, the SRTT value used should be the old SRTT, not the updated value
|
||
from <a href="TransLayer.html#rttexample">Example 5.3.4</a>. The initial RTTVAR is set to $R/2$ when there are no previous
|
||
measurements to use. Since the example above used $R = 4$ as the initially observed RTT, RTTVAR is
|
||
initialized to 2. The table below illustrates the calculations for RTTVAR for the sequence of
|
||
observations $R’$ from before, using the standard value of $\beta = 1/4$.</p>
|
||
<center>
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="p-0 center">SRTT</th>
|
||
<th class="p-0 center"><span class="math inline">$R'$</span></th>
|
||
<th class="p-0 center">Old RTTVAR</th>
|
||
<th class="p-0 center">Updated RTTVAR</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center">4</td>
|
||
<td class="py-0 center">10</td>
|
||
<td class="py-0 center">2</td>
|
||
<td class="py-0">(3/4) * 2 + (1/4) * | 4 – 10 | = 3</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">5</td>
|
||
<td class="py-0 center">20</td>
|
||
<td class="py-0 center">3</td>
|
||
<td class="py-0">(3/4) * 3 + (1/4) * | 5 – 20 | = 6</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">7</td>
|
||
<td class="py-0 center">2</td>
|
||
<td class="py-0 center">6</td>
|
||
<td class="py-0">(3/4) * 6 + (1/4) * | 7 – 2 | = 5.75 <i>[rounded to 6]</i></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 5.7: SRTT calculations for a sequence of three received segments
|
||
</p>
|
||
</center></div>
|
||
<p>Based on these pieces, we can now define the RTO calculation. This formula uses a constant value $K
|
||
= 4$, while G denotes the clock’s minimum granularity. That is, if the clock can only measure time
|
||
to the accuracy of ms, it would not make sense to adjust the RTO by an unmeasurable fraction of a
|
||
ms. The new RTO is calculated by adding the SRTT and the maximum of $G$ and $K * RTTVAR$.</p>
|
||
<center>
|
||
<span class="math inline">$\large RTO := SRTT + max (G, K * RTTVAR)$</span>
|
||
</center>
|
||
<br /><p>The RTO will always be the rolling average of the RTT plus a small amount of extra time for leeway.
|
||
As the variance of RTT increases, the quantity added to RTT would increase. However, if the system
|
||
experiences perfectly consistent RTT values, the $max(G, K * RTTVAR)$ would eventually shrink to the
|
||
minimum clock granularity, providing the bare minimum of flexibility in deviation from the SRTT.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 5.3.6 </p><hr class="mt-1" />
|
||
<p>The table below shows the RTO calculations, assuming all values are in terms of ms and the clock
|
||
granularity has a minimum value of 1 ms. To summarize the results in this table, the first
|
||
measurement of $R = 4$ created the initial SRTT of 4 and RTTVAR of 2. By combining these values in
|
||
the RTO calculation, the system would wait for up to 12 ms before declaring a packet loss. The next
|
||
message arrived with an observed RTT of 10 ms, so this segment arrived before the timeout clock
|
||
expires. This segment increased the RTO value to 17 ms, but the next segment missed the timeout by
|
||
arriving with an RTT of 20 ms. After the 17 ms had elapsed, the host would have considered this a
|
||
packet loss and re-sent the previous segment. After the retransmission, the observed RTT dropped to
|
||
2; this drop increased the variation RTTVAR to 6, which has the effect of raising the RTO to 31.</p>
|
||
<center>
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="p-0 center">SRTT</th>
|
||
<th class="p-0 center">RTTVAR</th>
|
||
<th class="p-0 center">Updated RTO</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="py-0 center">4</td>
|
||
<td class="py-0 center">2</td>
|
||
<td class="py-0">4 + max(1, 4 * 2) = 4 + 8 = 12 <i>[initial value]</i></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">5</td>
|
||
<td class="py-0 center">3</td>
|
||
<td class="py-0">5 + max(1, 4 * 3) = 5 + 12 = 17</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">7</td>
|
||
<td class="py-0 center">6</td>
|
||
<td class="py-0">7 + max(1, 4 * 6) = 7 + 24 = 31</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="py-0 center">6</td>
|
||
<td class="py-0 center">6</td>
|
||
<td class="py-0">6 + max(1, 4 * 6) = 6 + 24 = 30</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 5.8: Combining the SRTT and RTTVAR values for the new RTO
|
||
</p>
|
||
</center></div>
|
||
<p>It may seem odd to increase the RTO when the observed RTT actually dropped, but the drop creates a
|
||
higher level of variance. Consequently, TCP interprets these measurements as an indication that the
|
||
network is behaving unpredictably and grants the system more time before giving up on an expected
|
||
segment. That is, since the expected and actual RTT values differ significantly, TCP has less
|
||
confidence that replies will be received within a short amount of time. If the variance later
|
||
decreases, TCP would shrink the RTO value, under the premise that the predictable behavior is likely
|
||
to continue.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Note.png"><img alt="Decorative note icon" src="_images/CSF-Images-Note.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Note</p><hr class="mt-1" />
|
||
<p>Our description of TCP here has focused on the basic principle of reliable data transport,
|
||
specifically focusing on the role of the TCP handshake and detecting packet loss. TCP is a
|
||
significantly more complex protocol than we have presented, as it uses additional techniques to
|
||
further increase the reliability of communication over the Internet. For instance, rather than
|
||
acknowledging every message, TCP hosts can use <em>cumulative acknowledgement</em>, in which
|
||
multiple messages can be acknowledged all at once. In addition, TCP <em>congestion control</em>
|
||
allows a host to detect delays in the network, throttling their sending rate to reduce traffic and
|
||
prevent future delays. For a more complete discussion of these topics, we refer interested readers
|
||
to textbooks that focus exclusively on the topic of networking, such as <em>Computer Networking: A
|
||
Top-Down Approach (7th Edition)</em> <a class="reference internal" href="Bibliography.html#kurose2016" id="id2">[Kurose2016]</a> by Kurose and Ross.</p>
|
||
</div>
|
||
<p>In summary, TCP provides two key transport services that UDP does not: reliable data transport and
|
||
flow control. These services are implemented by combining multiple pieces of information in the TCP
|
||
segment header with observations of the network behavior. Hosts implement TCP reliability by
|
||
tracking the sequence and acknowledgement numbers of each message, along with maintaining a rolling
|
||
average of the expected wait times for segments. If a segment is not acknowledged within an expected
|
||
time frame, hosts can implicitly request re-transmission by re-sending previous messages. Throughout
|
||
this process, TCP hosts use the receive window as a means of flow control; by informing each other
|
||
of the current capacity of their internal data buffers, the hosts are taking proactive steps to
|
||
support reliability by preventing buffer overflows at the other end. These features make TCP the
|
||
preferred choice for applications that depend on the successful transmission of all data, rather
|
||
than compensating for lost data with reduced quality of service.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Note.png"><img alt="Decorative note icon" src="_images/CSF-Images-Note.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Note</p><hr class="mt-1" />
|
||
<p>Unlike the application layer, there is no universal, straightforward mechanism to access the
|
||
transport, network, or link layer protocol headers. Accessing these layers requires the use of a
|
||
raw socket, created by passing <code class="docutils literal notranslate"><span class="pre">SOCK_RAW</span></code> as the type parameter when calling <code class="docutils literal notranslate"><span class="pre">socket()</span></code>. The
|
||
difficulty here is that many systems require root privileges to create raw sockets. Consequently,
|
||
normal user-mode programs cannot easily gain access to these headers.</p>
|
||
<p>From a learning standpoint, there is also little value to demonstrating code for accessing these
|
||
headers. The technique would be the same as we used in the section describing DNS. Specifically,
|
||
the primary difference between that example and one that illustrates what UDP adds would involve
|
||
increasing the size of the message buffer to contain the eight bytes of the UDP header at the
|
||
beginning.</p>
|
||
<p>Readers interested in the intricacies of these lower layers should consider using a packet
|
||
analyzer, such as <code class="docutils literal notranslate"><span class="pre">tcpdump</span></code> (<code class="docutils literal notranslate"><span class="pre">http://www.tcpdump.org/</span></code>) or Wireshark
|
||
(<code class="docutils literal notranslate"><span class="pre">https://www.wireshark.org/</span></code>). These programs are freely available as open-source software. In
|
||
addition, the <code class="docutils literal notranslate"><span class="pre">tcpdump</span></code> site provides a reusable library, <code class="docutils literal notranslate"><span class="pre">libpcap</span></code>, for building additional
|
||
tools. Readers should exercise caution, however, as using these tools—particularly in a way that
|
||
capture’s other people’s data—may violate the terms of use for access to the local network or may
|
||
even be illegal based on one’s locality.</p>
|
||
</div>
|
||
<div
|
||
id="InterTransSumm"
|
||
class="embedContainer"
|
||
data-exer-name="InterTransSumm"
|
||
data-long-name="Transport layer questions"
|
||
data-short-name="InterTransSumm"
|
||
data-frame-src="../../../Exercises/Internet/InterTransSumm.html?selfLoggingEnabled=false&localMode=true&module=TransLayer&JXOP-debug=true&JOP-lang=en&JXOP-code=java"
|
||
data-frame-width="950"
|
||
data-frame-height="775"
|
||
data-external="false"
|
||
data-points="1.0"
|
||
data-required="True"
|
||
data-showhide="show"
|
||
data-threshold="5"
|
||
data-type="ka"
|
||
data-exer-id="">
|
||
|
||
<div class="center">
|
||
<div id="InterTransSumm_iframe"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<div class="mt-4 container center">
|
||
«  <a id="prevmod1" href="AppLayer.html">5.2. Application Layer: Overlay Networks</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod1" href="NetSec.html">5.4. Network Security Fundamentals</a>  »
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div class="row jmu-dark-purple-bg">
|
||
<div class="col-md-12">
|
||
<center>
|
||
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
|
||
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
|
||
</center>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||
</body>
|
||
</html> |