Transport Interfaces Programming Guide

Address Binding

In the Internet Protocol family, bindings are composed of local and foreign IP addresses, and of local and foreign port numbers. Port numbers are allocated in separate spaces, one for each system and one for each transport protocol (TCP or UDP). Through bind(), a process specifies the local IP address, local port number half of an association, while connect() and accept() complete a socket's association by specifying the foreign IP address, foreign port number part. Because the association is created in two steps, the association-uniqueness requirement might be violated, without specific care. It is unrealistic to expect user programs to always know proper values to use for the local address and local port, since a host can reside on multiple networks and the set of allocated port numbers is not directly accessible to a user.

The wildcard address simplifies local address binding in the Internet domain. When an address is specified as INADDR_ANY (a constant defined in netinet/in.h), the system interprets the address as any valid address. The sample code in Example 2-18 binds a specific port number to a socket, and leaves the local address unspecified.


Example 2-18 Bind Port Number to Socket


#include <sys/types.h>
#include <netinet/in.h>
...
struct sockaddr_in sin;
...
		s = socket(AF_INET, SOCK_STREAM, 0);
		sin.sin_family = AF_INET;
		sin.sin_addr.s_addr = htonl(INADDR_ANY);
		sin.sin_port = htons(MYPORT);
		bind(s, (struct sockaddr *) &sin, sizeof sin);

Each network interface on a host typically has a unique IP address. Sockets with wildcard local addresses can receive messages directed to the specified port number and sent to any of the possible addresses assigned to a host. For example, if a host has two interfaces with addresses 128.32.0.4 and 10.0.0.78, and a socket is bound as in Example 2-18, the process can accept connection requests addressed to 128.32.0.4 or 10.0.0.78. To allow only hosts on a specific network to connect to it, a server binds the address of the interface on the appropriate network.

Similarly, a local port number can be left unspecified (specified as 0), in which case the system selects a port number. For example, to bind a specific local address to a socket, but to leave the local port number unspecified:


sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = htons(0);
bind(s, (struct sockaddr *) &sin, sizeof sin);

The system uses two criteria to select the local port number:

The port number and IP address of the client is found through either accept() (the from result) or getpeername().

In certain cases, the algorithm used by the system to select port numbers is unsuitable for an application. This is because associations are created in a two-step process. For example, the Internet file transfer protocol specifies that data connections must always originate from the same local port. However, duplicate associations are avoided by connecting to different foreign ports. In this situation, the system would disallow binding the same local address and port number to a socket if a previous data connection's socket still existed. To override the default port selection algorithm, an option call must be performed before address binding:


 ...
int on = 1;
...
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);
bind(s, (struct sockaddr *) &sin, sizeof sin);

With this call, local addresses already in use can be bound. This does not violate the uniqueness requirement, because the system still verifies at connect time that any other sockets with the same local address and port do not have the same foreign address and port. If the association already exists, the error EADDRINUSE is returned.