Observing TCP behavior On using our classroom’s network hardware capabilities to perform experiments with TCP sockets ‘slowecho.cpp’ • This is a TCP ‘echo-server’ which sends back data it receives, one-byte-at-a-time, with a user-specified time-delay after any byte has been transmitted • The user specifies a desired time-delay (in microseconds) by typing a command-line argument when this server is launched; e.g., for a one-second time-delay, type $ ./slowecho 1000000 ‘peekdemo.cpp’ • This is a ‘client’ for the ‘slowecho’ server, but instead of using the ‘read()’ function, it uses ‘recv()’ and it supplies ‘MSG_PEEK’ as the flag-argument, thus allowing users to watch the data arriving from ‘slowecho’ while it sits in the socket’s receive-queue • It also shrinks the size of its TCP socket’s receive-buffer, for a dramatic new demo Packet ‘sniffing’ • If we turn off the socket’s ‘window scaling’ option, so the ‘window size’ field in every outgoing acknowledgement-packet’s TCP Header expresses the number of bytes of available space remaining in this client’s receive-buffer, we will create an concrete visualization for the window-size’s role Setup steps We will need to use a ‘quiet’ network (e.g, our ‘eth1’ interfaces) so we won’t be distracted by seeing hundreds of irrelevant network-packets! (So those interfaces will need to configured with private IP-addresses) Step 2: logon ‘hrn23511’ Step 1: logon ‘hrn23511’ Assign an IP-address to the ‘eth1’ interface and bring it UP (using ‘sudo /sbin/ifconfig’), then lauch ‘nicwatch eth1’ Disable TCP ‘window scaling’; and then launch ‘slowecho’ with a one-second time-delay Step 3: logon ‘hrn23512’ Assign an IP-address to ‘eth1’; Launch our ‘peekdemo’ client specifying the IP-address for ‘hrn23511’ as the target-server What to watch? to server from client ACK window size sequence number to server from client ACK window size sequence number W. Richard Stevens “This book is the result of my being asked lots of questions on TCP/IP for which I could find no quick answers. It was then that I realized that the easiest way to obtain the answers was to run small tests, forcing certain conditions to occur, and just watch what happens.” Preface, page xix “A book on networking needs a real network to work with along with access to the Internet” “TCP/IP Illustrated, Volume 1: The Protocols” Addison-Wesley (1994) The ‘silly window’ syndrome • This situation arises when data-bytes are sent one-at-a-time within TCP/IP packets • Such packets have at least 20 bytes of IP Header plus 20 bytes of TCP Header, yet only 1 byte of data, thus a 40-to-1 ratio of “protocol overhead” to “useful information” • On Ethernet, with14 more bytes of header, this yields an efficiency-rate of under 2% The Nagle algorithm • It’s a means for improving the efficiency of TCP/IP networks, by reducing the number of packets that need to be transmitted • It combines several small-sized outgoing packets and sends them out all at once • (It can interact poorly with TCP’s ‘delayed acknowledgement’ algorithm, so a way to disable it is quite commonly provided) pseudo-code // A high-level description of John Nagle’s algorithm for congestion control if there is any available data to send { if the window-size is >= MSS and available data >= MSS send a complete MSS packet now else { if there is unacknowledged data still in transit enqueue data in the send buffer until an ACK arrives else send available data immediately } } // NOTE: Here MSS denotes the TCP socket’s ‘Maximum Segment Size’ ‘usenagle.cpp’ • This program allows us to see the default behavior of Linux’s TCP implementation, by using our ‘nicwatch’ packet-sniffer • Unless it has been overridden by a TCP ‘socket option’, Linux employs the Nagle algorithm as a way to cut down on the number of TCP packets being exchanged • Use this with our ‘tcpserver.cpp’ program Three windows again Launch our ‘tcpserver’ application here Launch our ‘nicwatch’ packet sniffer here Launch our ‘usenagle’ application here ‘nodelay.cpp’ • This is a modified version of the code we used in the previous ‘usenagle’ program • It overrides use of the Nagle Algorithm by using the ‘TCP_NODELAY’ socket option • With ‘nicwatch’ you can see the effect on the total number of packets exchanged when we use this client with our original ‘tcpserver.cpp’ application ‘corkdemo.cpp’ • This is a very different modification of our ‘usenagle’ program, which makes use of the TCP_CORK socket-option rather than TCP_NODELAY • With ‘nicwatch’ you will see a dramatically different result when you count the total number of packets that are exchanged with our earlier ‘tcpserver’ application Applications • Connection-oriented applications such as ‘telnet’ need a quick response to any key a user presses (i.e., TCP_NODELAY) • But an application that transfers bulk data such as ‘ftp’ is more efficient if lots of the data is transmitted within each individual packet (i.e., the TCP_CORK option) • Nagle is compromise between these two In-class exercises • Apply the same 3-window setup that we used for observing the Nagle Algorithm • How many packets are needed when you execute our ‘nodelay.cpp’ application? • How many packets are needed when you execute our ‘corkdemo.cpp’ application? • Do you think it make sense to regard the Nagle Algorithm as a “compromise”?