WSAConnectByName() and WSAConnectByList()

G’Day, my name is Brad Williamson, a Software Design Engineer with the Windows Networking Developer Platform (WNDP) group here at Microsoft. I am going to talk about two APIs that were introduced in Windows Vista Beta 2 to simplify the process of connecting to another connection-oriented socket application.

By far, one of the most common scenarios in sockets programming is to connect to a remote address after resolving the hostname. To do this, you first call getaddrinfo() to resolve a hostname. Then, for each address, you create a socket, bind to that socket, and call connect(),WSAConnect(), or ConnectEx(). This process continues until the connection succeeds or the address list has been exhausted. With IPv6 becoming more prevalent, the address list that you have to traverse will be large.

Furthermore, if you have a machine with multiple interfaces (whether that be multiple NICs and/or multiple IP addresses on the same NIC), you may want to determine which interface best suits the destination address, and then bind appropriately.

As you will agree, the process of connecting optimally to a destination connection-oriented socket requires a lot of code.

With Windows Vista, this process is simplified with the introduction of two new Winsock APIs: WSAConnectByName() and WSAConnectByList().

WSAConnectByName() establishes a connection to another application, using an optimal source and destination address pair, given a specified socket, host and port. Given a socket s, host name and port (or a well known service name); WSAConnectByName() will connect to the destination. If successful, WSAConnectByName() will return the local address which socket s is bound to, and the remote address connected to.

 BOOL PASCAL WSAConnectByName(
  SOCKET s,
  LPSTR nodename,
  LPSTR servicename,
  LPDWORD LocalAddressLength,
  LPSOCKADDR LocalAddress,
  LPDWORD RemoteAddressLength,
  LPSOCKADDR RemoteAddress,
  const struct timeval* timeout,
  LPWSAOVERLAPPED Reserved
);

In addition to WSAConnectByName(), we have introduced WSAConnectByList() which establishes a connection to one of the addresses specified in the SocketAddressList structure.

 BOOL PASCAL WSAConnectByList(
  SOCKET s,
  PSOCKET_ADDRESS_LIST SocketAddressList,
  LPDWORD LocalAddressLength,
  LPSOCKADDR LocalAddress,
  LPDWORD RemoteAddressLength,
  LPSOCKADDR RemoteAddress,
  const struct timeval* timeout,
  LPWSAOVERLAPPED Reserved
);

By using WSAConnectByName() and WSAConnectByList():

  1. For WSAConnectByName(), your application is transparent to the name resolution. The list of remote addresses that we attempt to connect to is determined by the socket type passed in. This also includes dual-mode sockets (supporting IPv4 and IPv6) where the socket option IPV6_V6ONLY has been set to FALSE.
  2. Your application does not have to optimize the address list to determine which interface you should bind to.
  3. Eliminates the need for your application to include code to minimize the time of the connecting.

Having said this, here are two caveats to using these APIs:

  1. Connection-oriented mode is only supported, and
  2. Overlapped I/O is not supported. These APIs will block even if the socket is in non-blocking mode. Update: We will support Overlapped I/O in a future release.

More information about these new APIs can be found in:

https://msdn.microsoft.com/library/en-us/winsock/winsock/wsaconnectbyname_2.asp

and

https://msdn.microsoft.com/library/en-us/winsock/winsock/wsaconnectbylist.asp

So, when writing your next Winsock based application using Windows Vista, be sure to try out WSAConnectByName() and WSAConnectByList(). Please let us know if you have any questions, comments or suggestions.

--Brad Williamson