Registration and Name Resolution

éÓÔÏÞÎÉË: Anthony Jones and Jim Ohlund "Windows Network Programming" - published by Microsoft Press, 1999

Background

Name registration is the process of associating a user-friendly name with a protocol-specific address. Host names and their IP addresses are a good example. Most people find it cumbersome to remember a workstation's address as, for example, "157.54.185.186." They would rather name their machines something easier to remember, such as "ajones1." In the case of IP, a service called Domain Name System (DNS) maps IP addresses to names. Other protocols offer ways of registering their specific addresses to friendlier names. Name spaces will be discussed in more detail in the next section.

Not only do you want to be able to register and resolve host names, you would also like the ability to map the address of your Winsock server so that clients can retrieve the address in order to connect to the server. For example, you might have a server running on machine 157.64.185.186 off port 5000. If the server runs only on that machine, you can always hardcode the server address in the client application. But what if you wanted a more dynamic server-one that can run on multiple machines, perhaps a distributed application with fault tolerance? If one server crashed or was too busy, another instance could be started somewhere else to service clients. In this case, finding out where the servers are possibly running can create headaches. Ideally, you want the ability to register your server-named "Fault Tolerant Distributed Server"-with multiple addresses. In addition, you want to be able to dynamically update the registered service and its addresses. This is what name registration and resolution is all about, and this chapter will address the facilities Winsock offers to accommodate distributed server registration and name resolution.

Name Space Models

Before we begin to explore the Winsock function, we need to introduce the various name space models to which most of the protocols adhere. A name space offers the capability to associate the protocol and its addressing attributes with a user-friendly name. Some of the more common name spaces are DNS for IP and the NetWare Directory Services (NDS) from Novell for IPX. These name spaces vary widely in their organization and implementation. Some of their properties are particularly important in understanding how to register and resolve names from Winsock.

There are three different types of name spaces: dynamic, static, and persistent. A dynamic name space allows you to register a service on the fly. This also means that clients can look up the service at run time. Typically, a dynamic name space relies on periodically broadcasting service information to signal that the service is continuously available. Examples of dynamic name spaces include Service Advertising Protocol (SAP)-used in NetWare environments-and AppleTalk's Name Binding Protocol (NBP) name space.

Static name spaces are the least flexible of the three types. Registering a service in a static name space requires that it be manually registered ahead of time. This means that there is no way to register a name with a static name space from Winsock-there is only a method of resolving names. DNS is an example of a static name space. For example, with DNS you manually enter IP addresses and host names into a file that the DNS service uses to handle resolution requests.

Persistent name spaces, like dynamic name spaces, allow services to register on the fly. Unlike dynamic name spaces, however, the persistent model maintains the registration information in nonvolatile storage, such as a file on a disk. Only when the service requests that it be removed will a persistent name space delete its entry. The advantage of a persistent name space is that it is flexible yet does not continually broadcast any kind of availability information. The drawback is that if a service is not well behaved (or is poorly written), it can go away without ever notifying the name space provider to remove its service entry, leading clients to believe incorrectly that the service is still available. NDS is an example of a persistent name space.

Enumerating Name Spaces

Now that you are acquainted with the various attributes of a name space, let's examine how to find out which name spaces are available on a machine. Most of the predefined name spaces are declared in the Nspapi.h header file. Each name space has an integer value assigned to it. Table 10-1 contains some of the more commonly supported name spaces available on Win32 platforms. The name spaces returned depend on which protocols are installed on the workstation. For example, unless IPX/SPX is installed on a workstation, the NS_SAP name space will not be returned.

Table 10-1. Supported name spaces

Name Space Value Description
NS_SAP 1 SAP name space; used on IPX networks
NS_NDS 2 NDS name space; also used on IPX networks
NS_DNS 11 DNS name space; most commonly found on TCP/IP networks and on the Internet
ND_NTDS 32 Windows NT domain space; protocol-independent name space found on Windows 2000

When you install IPX/SPX on a machine, the SAP name space is supported for queries only. If you want to register your own service, you also need to install the SAP Agent service. In some cases, the Client Services for NetWare are required to display local IPX interface addresses correctly. Without this service, the local addresses show up as all zeros. Additionally, you must add an NDS client to utilize the NDS name space. All of these protocols and services can be added from the Control Panel.

Winsock 2 provides a method of programmatically obtaining a list of the name spaces available on a system. This is accomplished by calling the function WSAEnumNameSpaceProviders, which is defined as

INTšWSAEnumNameSpaceProviders(
  ššššLPDWORDšlpdwBufferLength,
š  šššLPWSANAMESPACE_INFOšlpnspBuffer  
);

The first parameter is the size of the buffer submitted as lpnspBuffer, which is a sufficiently large array of WSANAMESPACE_INFO structures. If the function is called with an insufficiently large buffer, it fails, sets lpdwBufferLength to the required minimum size, and causes WSAGetLastError to return WSAEFAULT. The function returns the number of WSANAMESPACE_INFO structures returned, or SOCKET_ERROR upon any error.

The WSANAMESPACE_INFO structure describes an individual name space installed on the machine. This structure is defined as

typedefšstructš_WSANAMESPACE_INFO{
  GUIDšNSProviderId;
  DWORDšdwNameSpace;
  BOOLšfActive;
  DWORDšdwVersion;
  LPTSTRšlpszIdentifier;
}šWSANAMESPACE_INFO,š*PWSANAMESPACE_INFO,
š  LPWSANAMESPACE_INFO;

There are actually two definitions for this structure-one is Unicode, and one is ANSI. The Winsock 2 header file type-defines the appropriate structure to WSANAMESPACE_INFO according to how you build your project. In actuality, all structures and Winsock 2 registration and name resolution functions have both ANSI and UNICODE versions. The first member of this structure, NSProviderId, is a globally unique identifier (GUID) that describes this particular name space. The dwNameSpace field is the name space's integer constant, such as NS_DNS or NS_SAP. The fActive member is a Boolean value, which if true indicates that the name space is available and ready to take queries; otherwise, the provider is inactive and unable to take queries that specifically reference this provider. The dwVersion field simply identifies the version of this provider. Finally the lpszIdentifier is a descriptive string identifier for this provider.