Technote 1145Living in a Dynamic TCP/IP EnvironmentBy Quinn "The Eskimo!" |
CONTENTSDynamic TCP/IP
Fundamentals
|
This Technote describes some of the intricacies of dealing with TCP/IP in a dynamic environment, such as that provided by Open Transport. Specifically, it describes how to write Open Transport code which correctly handles multiple IP addresses, dial-up links, sleep and wakeup on PowerBooks, modem disconnection, and user reconfiguration. This Note is directed at all developers using Open Transport TCP/IP services. |
Dynamic TCP/IP FundamentalsMany TCP/IP programs make false assumptions about the TCP/IP environment. While assumptions like "this machine has TCP/IP, therefore it must have an IP address" and "the IP address won't change" were valid for workstations on a university Ethernet, they do not hold for a PowerBook running Mac OS connected via PPP. Specifically, the following are non-obvious consequences of Mac OS's dynamic TCP/IP environment:
This Technote discusses some high-level approaches you can use to cope with these consequences. Before you start, however, you need to know some important rules about Open Transport's current TCP/IP implementation:
|
IP Address NotesWith Open Transport's support for reconfiguration without reboot and "on demand" address acquisition (for example, DHCP), you must be careful not to assume that the machine has a single static IP address. Specifically:
Getting a List of All IP AddressesThe following code snippet shows how to determine the
list of IP addresses for the machine using the calls
Multi-homing and IP AddressesOn a multi-link multi-homed computer, it's possible for the "correct" IP address of the machine to depend on the IP address of the machine you're communicating with. For example, consider a machine with two Ethernet cards, one connected to the public Internet and one connected to a private network. Each card has an IP address but the machine does not forward IP packets between the cards. This situation is illustrated below: Now consider an FTP client running on this computer. One of the (mis)features of the FTP protocol is that, when it opens a data connection, the FTP client must open a port on the local machine and send (through the control connection) the port number and the local IP address to the server in a PORT command. However, machines on the public Internet can only communicate with 17.100.55.7, and machines on the private network can only communicate with 17.200.37.41. So how does the FTP client work out which IP address to send? The answer is that the The following code snippet uses
|
No Nuisance Calls, PleaseYour software must be careful to create a TCP/IP provider only when it actually needs to use the network. This is because many users have a dial-up network connection configured to "dial on demand". The act of you opening a TCP/IP provider will cause the TCP/IP stack to load, and hence the modem to dial, even if you don't send any network traffic.
Dial on demand works best if applications open TCP/IP providers only in direct response to a user operation. For example, if the user requests information from the net, your application is free to trigger a dial because the user is expecting it. In this Technote, these requests are referred to as solicited operations. Dial on demand works badly for applications that access the Internet "in the background." For example, your application may want to periodically update a local database with information from the network. Triggering a dial for such an unsolicited operations is going to annoy the user. Your application can avoid dialing the modem for
unsolicited operations by simply calling
On the other hand, if the TCP/IP stack is not loaded, your application is faced with a dilemma: the computer may be on a non-dial-up link (such as Ethernet) where loading the TCP/IP stack is not a serious inconvenience, or the computer may be on a dial-up link where loading the TCP/IP stack will cause a "nuisance call." In many cases, you can ignore this dilemma entirely and unilaterally decide to avoid unsolicited operations while TCP/IP is unloaded. A majority of desktop users are regularly using the Internet for solicited operations, which keeps the TCP/IP stack loaded, ready to handle unsolicited operations, so this isn't really a problem. However, some developers have found this heuristic to be insufficiently rigorous for their taste. If you fall into this category, you can take further steps to ensure that your unsolicited operations get to the network. Specifically:
|
Be Prepared for a CloseAs part of its normal operation, the TCP/IP stack may decide to close your provider. When it closes a provider in this way, Open Transport calls the provider's notifier with one of two events:
Regardless of the action of your notifier, the provider
will always be closed when you return from your notifier.
Any operations on the provider after your notifier returns
will return For TCP/IP providers on which you're actively working
(for example, worker endpoints which are actively
transferring data), you can ignore these events. The next
time you use the provider, you will get a
The sample illustrates two important points:
|
Server EtiquetteHandling the events described in the previous section is
especially important for servers. A server will typically
have one or more listening endpoints
(listeners), which are waiting for
connections from clients. If the TCP/IP stack unloads, those
listeners will close, and your notifier will receive an
event to this effect. If you don't handle these events
properly, chances are that your server will keep running
just fine, except it will receive no more
The standard response to the closing of a listener is to
simply reopen the listener. You must not attempt to do this
directly in your notifier. Instead you should set a flag
that causes your main event loop to re-open the listener as
soon as the TCP/IP has loaded. You can determine this by
checking the result of Typically, opening a listener is an unsolicited operation and should be deferred if it would cause the modem to dial. If your application is likely to be used in an environment where it should dial the modem to open a listener, you may want to provide a user preference for this. An example is shown below. Typically the first option would be the default.
|
Talking to YourselfTalking to yourself may be the first sign of madness, but TCP/IP software often wants to talk to other software running on the same machine. For example, you might have a server administration tool that configures your server over the network. It's reasonable for a user to run both the server and the administration tool on the same machine. OT supports this sort of loopback, including the standard 127.0.0.1 loopback address. However, problems arise when you use this technique on a machine configured for a dial-up connection. Remember that opening a TCP/IP provider causes the TCP/IP stack to load, and loading the TCP/IP stack may cause the modem to dial. This is true even if you're just using the endpoint to talk to yourself. A future version of Open Transport may alleviate this problem as part of the multi-link multi-homing solution but, for the moment, there is no good workaround. One less-than-ideal workaround is to reconfigure TCP/IP to not connect via the modem. If no other suitable link is available, you can always configure TCP/IP to "MacIP" (with manual addressing) and configure AppleTalk to "Remote Only". The following screen shots show what this might look like. It is possible to use the Network Setup library to programatically create and switch to these settings. |
SummaryTCP/IP is no longer limited to desktop machines on Ethernet. Your code must avoid making false assumptions about the TCP/IP environment, and must adapt to radical changes in the TCP/IP environment as the user reconfigures and relocates their computer. Your code must also strive to avoid annoying users with dial-up connections by dialing their modem unexpectedly. The information in this Technote will help you write software that is a pleasure to use in a dynamic TCP/IP environment. |
Acknowledgments |
Thanks to Richard Buckle, Stuart Cheshire, Mark Cookson, Rich Kubota, Peter N Lewis, Pete Resnick, and Brad Suinn. |
|
To contact us, please use the Contact Us page. |
Updated: 2-November-98 |