Subscribe to Windows IT Pro
June 01, 2000 12:00 AM

Bind Basics

Windows IT Pro
InstantDoc ID #9196
Rating: (0)

In Windows NT, the system typically assigns network-based TCP/IP services to a well-known port, in accordance with Request for Comments (RFC) 1700. POP3 servers, the topic of this continuing series of articles, run on TCP port 110. The first step in getting your mail server to answer requests on that port is to bind the socket.

To understand how to bind a TCP socket to a port, you need to look at the arguments for the bind() function. One of these arguments (the second) is a pointer to a sockaddr structure. For IP applications, that pointer is typically a sockaddr_in structure that contains the numeric IP address and port that you want to bind to locally. If you can't easily identify what interfaces are available, you can simply bind to all available local interfaces by specifying INADDR_ANY as the address.

One security risk that you need to be aware of is that users can bind two sockets to the same port using a socket option known as SO_REUSEADDR. In other words, two different applications can answer connections on the same port. So, in the case of a POP3 server, one application might be delivering mail, while another is stealing passwords. Working with NT 4.0 and earlier requires a lot of Registry reads to determine which IP addresses are available. As a result, many programmers simply specify INADDR_ANY to get all the interfaces. Under Windows 2000, you can have new interfaces popping up and down on the fly. Unless you’re prepared to write code to detect these changes, your service might not behave properly if you don’t bind to all the interfaces.

You're probably thinking, "Why not just specify INADDR_ANY all the time and avoid these problems?" Here's the catch: If someone does bind to a specific IP address, the OS prefers the specifically bound socket to one that binds to all available interfaces. To handle this problem, Microsoft implemented the SO_EXCLUSIVEADDRUSE socket option in NT 4.0 Service Pack 4 (SP4) and Win2K.

The code in Listing 1 demonstrates how you use this option and contains a function you can use in your code to make binding sockets easier. The first function in the code, InitWinsock(), is a requirement for all Winsock applications. However, before you paste this function into your code, take heed of the comments—this version works only with Winsock 2.0 and higher.

The second function, BindSocket(), does a lot of work, so let’s look at it in detail. To begin, we want to check for errors in the inputs—note from the sample code that I’m not concerned about a null pointer for the IP address. Next, the code initializes the sockaddr_in structure (line 57). The sin_family member is always set to AF_INET. The sin_addr member is actually an inet_addr structure that contains the IP address of the interface we want to bind our socket to. If the user doesn’t specify an address by passing a null pointer, we’ll use the specially defined value of INADDR_ANY. If we look in your winsock2.h file, we see that this value is defined to be 0.

If the user passes the BindSocket() function an IP address represented as a string, we use the inet_addr() function to convert that string to an unsigned long value—inet_addr() will return INADDR_NONE (0xffffffff or ~0) if inet_addr() fails. Note that the code also checks for a 0 return by this function, which the software development kit (SDK) doesn't document as a possible error value but can occur. If an error occurs at this stage, the function can't know what interface to bind, and the function returns an error.

If we look at main(), the code initializes Winsock and creates the two sockets. The next step is to test to see whether SO_EXCLUSIVEADDRUSE is available. The testport variable, which the code defines as a const at the top of the file, specifies the port that the first socket binds to. This port is typically not in use. However, if this port is in use, change testport to a port number that is not in use. Next, the code sets SO_REUSEADDR on sock2, which is required to reuse a port, and tests whether the bind succeeds.

The sample code in Listing 1 shows you the best way to avoid security problems with reused ports, and contains some functions that can help you build your applications more easily. Next time, I’ll explain the ins and outs of service user contexts.

Related Content:

ARTICLE TOOLS

Comments
  • Karan
    8 years ago
    Jul 08, 2004

    This is a nice article and really gives an insight about how process get bind to a port.

    I am really sorry I am using this feedback form for discussing my problem.

    But I would like to ask one thing. I am facing a JVM bind error in my application occasionally.

    To give an insight of the application, I have a Java/EJB application. Many EJB services are running on different ports.

    the problem here is, sometime once the site is up. some ports remain occupied once the process cummunicating with them ends. and then this lead to a server socket connection refused error and lead subsytem to the shutdown mode.

    then i have to restart the server by killing those process and free the port to let the site working properly

    I am not sure what is causing the ports to be occupied once the site gets a clean start.

    To give an example, what i am saying, Some time say a process running on port 2145 will be occupied by the process running on port 1433 (SQL SERVER defaul port). It is just a one case of my problem.

    Please help me in this.

    I would be very thankful to you :)

You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement

advertisement

Windows is a trademark of the Microsoft group of companies. Windows IT Pro is used by Penton Media Inc. under license from owner.