<< |
Winsock Programmer's FAQ |
>> |
Debugging TCP/IPby Warren Young (This article was written with the Winsock programmer in mind, but the information in it can be used by Unix programmers, as well as administrators and technicians.) TCP is a simple protocol in a certain sense: you send data, it delivers it. Because it was engineered for reliability in networks of uncertain quality, it works around a lot of problems without bothering the end user. But partially because of this reliability, TCP exhibits behaviors that surprise those that don't truly understand the protocol. This tutorial will introduce you to the most important of these issues, but it's really the tip of the iceberg. For the submerged part, see TCP/IP Illustrated. Incidentally, the state/transition diagram below comes from volume 2 of that series. It happens to be printed in Volume 1 of the series as well, and in Stevens' Unix Network Programming, volume 1. You can also get that diagram in Postscript format off the web; see the Miscellaneous Resources section of the FAQ for a pointer. In this tutorial, we use the term "packet" to mean "frame" rather than "datagram." That is, a packet for our purposes is a collection of data wrapped in a TCP frame. The nebulous thing called "the network" is allowed to split the data in a TCP frame over multiple frames, or coalesce data from multiple frames into a single frame, etc., but the frame itself will remain functionally intact. This is as opposed to the "datagram" meaning of "packet," for an inviolable block of data that is unchanged from sender to receiver. TCP Control BitsWhen a TCP implementation decides to send a packet of data to the remote peer, it first wraps the data with 20-plus bytes of data called the "header". Headers are an essential part of network protocols, because they enable the participants in the network make decisions regarding the data flowing over it. Every protocol adds headers (and sometimes trailers) to your data. We won't discuss the TCP and IP headers in detail here, as that's better left to books like W. Richard Stevens'. Within the header is a field that I will call the "control bits," for
lack of a better term. The bits that interest us here are called SYN, ACK,
FIN and RST, for "synchronize," "acknowledge," "finish," and "reset,"
respectively. These bits are set in TCP packets for the sole benefit
of the remote peer's network stack The State/Transition DiagramBelow is the state/transition diagram for the TCP protocol. The
states are in round-ended boxes, and the transitions are the labelled
arrows. The transitions show how how your program can make TCP move
from one state to another. It also shows how the remote peer can make
your stack change TCP states, and how you can recognize these changes at
the application level. Note that transition labels come from the names
of BSD sockets functions; although there are differences in the Winsock
API, the effects are the same at this level. (I apologize for the so-so
readability of the text in this image, but it's already too big at 20K, so
I'm unwilling to make it any bigger
Understanding this diagram is really one of the keys to understanding
TCP, so let's go through a few exercises. But first, you need to know
about the The Microsoft A Micro-FAQNow for those exercises I promised:
Tools for TCPersBelow is a small batch file I find helpful in dealing with TCP state issues, which I call "showwait." Basically, it shows you the current WAIT states every second until you hit Ctrl-C. I have a similar script on my Unix machines as well. @echo off :loop netstat -na |grep WAIT delay 1 goto loop This script depends on a 4DOS feature called "delay". If you don't use this shell, get an implementation of the "sleep" command, which does the same thing. The Cygwin toolset, mentioned above, includes one. (Are you maybe getting the impression that I'm a closet Unixhead? Oh, noooo.... B-> ) There's one problem with this tool: it only catches problems with "WAIT" in their name. Less common states like LAST_ACK and SYN_RCVD won't be seen by this script. SYN_RCVD in particular signals serious problems if it stays around for a prolonged amount of time, because it indicates that a remote machine sent your machine a SYN packet, your machine ACK'd it, and the remote machine has failed to ACK your SYN/ACK. Since this exchange typically only takes from a few tens to a few hundreds of milliseconds, a persistent SYN_RCVD indicates a badly-written network stack, or a very "crashy" computer. If you see many of these states at once, it may mean you're under a "SYN attack", one of several "Denial of Service" attacks that are going around these days. At that point, it's time to break out the network sniffer and start some detective work. ConclusionThe techniques and information in this article reflect the basic mental tools that your organization needs to develop, even if it's just appointing a single "networking guru" who will master this material, and become a resource for the other developers in the company. This knowledge is very widely useful; for example, it can make reading sniffer dumps less painful and more productive. Also, these techniques can reasonably be applied by technicians working with knowledgeable users over the phone to gather information about failures in your program that otherwise would get logged as random failures. I hope you have learned something about TCP/IP debugging from this article. If you can think of anything else that would fit within the scope of this article, propose an extension and I'll seriously consider adding it. Happy hacking! Copyright © 1998 by Warren Young. All rights reserved. |
<< The Lame List | BSD Sockets Compatibility >> |
Last modified on 29 April 2000 at 15:52 UTC-7 | Please send corrections to tangent@cyberport.com. |
< Go to the main FAQ page |
|
<<< Go to my Home Page |