Networking APIs

 < Day Day Up > 

Windows implements multiple networking APIs to provide support for legacy applications and compatibility with industry standards. In this section, we'll briefly look at the networking APIs and describe how applications use them. It's important to keep in mind that the decision about which API an application uses depends on characteristics of the API, such as which protocols the API can layer over, whether the API supports reliable or bidirectional communication, and the API's portability to other Windows platforms the application might run on. We'll discuss the following networking APIs:

  • Windows Sockets (Winsock)

  • Remote procedure call (RPC)

  • Web access APIs

  • Named pipes and mailslots

  • NetBIOS

  • Other networking APIs

Windows Sockets

The original Windows Sockets (Winsock) (version 1.0) was Microsoft's implementation of BSD (Berkeley Software Distribution) Sockets, a programming API that became the standard by which UNIX systems have communicated over the Internet since the 1980s. Support for sockets on Windows makes the task of porting UNIX networking applications to Windows relatively straightforward. The modern versions of Winsock include most of the functionality of BSD Sockets but also include Microsoft-specific enhancements, which continue to evolve. Winsock supports reliable-connection-oriented communication as well as unreliable-connectionless communication. Windows provides Winsock 2.2, which is also either included with or available as an add-on for all current versions of Windows. Winsock 2.2 adds numerous features beyond the BSD Sockets specification, such as adding functions that take advantage of Windows asynchronous I/O that offer far better performance and scalability over straight BSD Socket programming.

Winsock includes the following features:

  • Support for scatter-gather and asynchronous application I/O.

  • Quality of service (QoS) conventions so that applications can negotiate latency and bandwidth requirements when the underlying network supports QoS.

  • Extensibility so that Winsock can be used with protocols other than those Windows requires it to support.

  • Support for integrated namespaces other than those defined by a protocol an application is using with Winsock. A server can publish its name in Active Directory, for example, and using namespace extensions, a client can look up the server's address in Active Directory.

  • Support for multipoint messages where messages transmit from a single source to multiple receivers simultaneously.

We'll examine typical Winsock operation and then describe ways that Winsock can be extended.

Winsock Client Operation

The first step a Winsock application takes is to initialize the Winsock API with a call to an initialization function. On a Windows 2000 system, a Winsock application's next step is to create a socket that will represent a communications endpoint. The application obtains the address of the server to which it wants to connect by calling gethostbyname. Winsock is a protocol-independent API, so an address can be specified for any protocol installed on the system over which Winsock operates (TCP/IP, TCP/IP with IP version 6, IPX). After obtaining the server address, a connection-oriented client attempts to connect to the server by using connect and specifying the server address.

On Windows XP and Windows Server 2003, an application should use getaddrinfo to obtain a server's address instead of using gethostbyname. getaddrinfo returns the list of addresses assigned to the server, and the client attempts to connect to each one in turn until it is able to establish a connection with one of them. This ensures that a client that only supports IP version 4 (IPv4), for instance, connects to the appropriate IPv4 address on a server that might have both IPv4 and IP version 6 (IPv6) addresses assigned to it.

When a connection is established, the client can send and receive data over its socket using recv and send, for example. A connectionless client specifies the remote address with connectionless APIs, such as the connectionless equivalents of send and recv, and sendto and recvfrom.

Winsock Server Operation

The sequence of steps for a server application differs from that of a client. After initializing the Winsock API, the server creates a socket and then binds it to a local address by using bind. Again, the address type specified whether TCP/IP, TCP/IP with IP version 6, or some other address type is up to the server application.

If the server is connection-oriented, it performs a listen operation on the socket, indicating the number of connections that it can support for the socket. Then it performs an accept operation to allow a client to connect to the socket. If there is a pending connection request, the accept call completes immediately; otherwise, it completes when a connection request arrives. When a connection is made, the accept function returns a new socket that represents the server's end of the connection. The server can perform receive and send operations by using functions such as recv and send. Figure 13-3 shows connection-oriented communication between a Winsock client and server.

Figure 13-3. Connection-oriented Winsock operation


After binding an address, a connectionless server is no different from a connectionless client: it can send and receive data over the socket simply by specifying the remote address with each operation. Most connectionless protocols are unreliable and in general will not know whether the destination actually received the sent data packets, known as datagrams. Datagram protocols are ideal for quick message passing, where the overhead of establishing a connection is not too much and reliability is not required (although an application can build reliability on top of the protocol).

Winsock Extensions

A powerful feature from a Windows programming point of view is that the Winsock API is integrated with Windows messages. A Winsock application can take advantage of this feature to perform asynchronous socket operations and receive notification of an operation's completion via a standard Windows message or through the execution of a callback function. This capability simplifies the design of a Windows application because the application doesn't need to be multithreaded or manage synchronization objects to both perform network I/O and respond to user input or requests from the window manager to update the application windows.

In addition to supporting functions that correspond directly to those implemented in BSD Sockets, Microsoft has added a handful of functions that aren't part of the Winsock standard. Two of these functions, AcceptEx and TransmitFile, are worth describing because many Web servers on Windows use them to achieve high performance. AcceptEx is a version of the accept function that, in the process of establishing a connection with a client, returns the client's address and the client's first message. AcceptEx allows the server application to prepost multiple accept operations so that high volumes of incoming connection requests can be handled. With this function, a Web server avoids executing multiple Winsock functions that would otherwise be required.

After establishing a connection with a client, a Web server usually sends a file, such as a Web page, to the client. The TransmitFile function's implementation is integrated with the Windows cache manager so that a client can send a file directly from the file system cache. Sending data in this way is called zero-copy because the server doesn't have to touch the file data to send it; it simply specifies a handle to a file and the ranges of the file to send. In addition, TransmitFile allows a server to prepend or append data to the file's data so that the server can send header information, which might include the name of the Web server and a field that indicates to the client the size of the message the server is sending. Internet Information Services (IIS), which is bundled with Windows, uses both AcceptEx and TransmitFile.

Windows XP and Windows Server 2003 add a handful of other, multifunction APIs, including ConnectEx, DisconnectEx, and TransmitPackets. ConnectEx establishes a connection and sends the first message on the connection. DisconnectEx closes a connection and allows the socket handle representing the connection to be reused in a call to AcceptEx or ConnectEx. Finally, TransmitPackets is similar to TransmitFile, except that it allows for the sending of in-memory data in addition to or in lieu of file data.

Extending Winsock

Winsock is an extensible API on Windows because third parties can add a transport service provider that interfaces Winsock with other protocols or layers on top of existing protocols to provide functionality such as proxying. Third parties can also add a namespace service provider to augment Winsock's name-resolution facilities. Service providers plug in to Winsock using the Winsock service provider interface (SPI). When a transport service provider is registered with Winsock, Winsock uses the transport service provider to implement socket functions, such as connect and accept, for the address types that the provider indicates it implements. There are no restrictions on how the transport service provider implements the functions, but the implementation usually involves communicating with a transport driver in kernel mode.

A requirement of any Winsock client/server application is for the server to make its address available to clients so that the clients can connect to the server. Standard services that execute on the TCP/IP protocol use "well-known addresses" to make their addresses available. As long as a browser knows the name of the computer a Web server is running on, it can connect to the Web server by specifying the well-known Web server address (the IP address of the server concatenated with :80, the port number used for HTTP). Namespace service providers make it possible for servers to register their presence in other ways. For example, one namespace service provider might on the server side register the server's address in Active Directory, and on the client side look up the server's address in Active Directory. Namespace service providers supply this functionality to Winsock by implementing standard Winsock name-resolution functions such as getaddrinfo (a replacement for gethostbyname) and getnameinfo.

EXPERIMENT: Looking at Winsock Service Providers

The Windows Sockets Configuration utility (Sporder.exe) included with the Platform SDK shows the registered Winsock transport and namespace providers and allows you to change the order in which transport service providers are enumerated. For example, if there are two TCP/IP transport service providers, the first one listed is the default provider for Winsock applications using the TCP/IP protocol. Here's a screen shot from Sporder showing the registered transport service providers:




Winsock Implementation

Winsock's implementation is shown in Figure 13-4. Its application interface consists of an API DLL, Ws2_32.dll (\Windows\System32\Ws2_32.dll), which provides applications access to Winsock functions. Ws2_32.dll calls on the services of namespace and transport service providers to carry out name and message operations. The Mswsock.dll library acts as a transport service provider for the protocols Microsoft provides support for in Winsock, and uses Winsock Helper libraries that are protocol specific to communicate with kernelmode protocol drivers. For example, Wshtcpip.dll is the TCP/IP helper. Mswsock.dll (\Windows\System32\Mswsock.dll) implements the Microsoft Winsock extension functions, such as TransmitFile, AcceptEx, and WSARecvEx. Windows ships with helper DLLs for TCP/IP, TCP/IP with IPv6, AppleTalk, IPX/SPX, ATM, and IrDA (Infrared Data Association) and namespace service providers for DNS (TCP/IP), Active Directory, and IPX/SPX.

Figure 13-4. Winsock implementation


Like the named pipe and mailslot APIs (described later in this chapter), Winsock integrates with the Windows I/O model and uses file handles to represent sockets. This support requires the aid of a kernel-mode file system driver, so Msafd.dll uses the services of the Ancillary Function Driver (AFD \Windows\System32\Drivers\Afd.sys) to implement socket-based functions. AFD is a TDI client and executes network socket operations, such as sending and receiving messages, by sending TDI IRPs to protocol drivers. AFD isn't coded to use particular protocol drivers; instead, Msafd.dll informs AFD of the name of the protocol used for each socket so that AFD can open the device object representing the protocol.

Windows Sockets Direct

Windows Sockets Direct (WSD) is an interface that allows Winsock applications to take advantage of System Area Networks (SANs), which are also known as Remote Direct Memory Access (RDMA) fabric, without application modification. The high-performance characteristics of SANs make them ideal for applications ranging from distributed computation to threetier e-commerce architectures like the one shown in Figure 13-5. In the system depicted, SANs connect the front-end Web servers with business logic servers, and the business logic servers with backend database servers to provide high-speed data movement through the data-processing layers. WSD is available on Windows 2003 and Windows 2000 Data Center Server or Windows 2000 Advanced Server with Service Pack (SP) 2 or higher.

Figure 13-5. Use of a SAN in a three-tier e-commerce architecture


SAN Interconnect SANs usually achieve their high performance characteristics by relying on specialized network interconnect and switching hardware. Common SAN interconnect types include InfiniBand, Gigabit Ethernet, FiberChannel, and proprietary solutions. Physical memory shared between two computers can also serve as a SAN interconnect.

SAN switching hardware implements a nonroutable protocol that provides TCP-like guarantees such as reliable, in-order message delivery. They also support a SAN feature called Remote Direct Memory Access (RDMA) that allows messages to be transmitted directly from the physical memory of a source computer to that of a destination computer without the intermediate memory copy operation that normally takes place on the receive end of a message transmission. RDMA thus frees both CPU and memory bus bandwidth that a copy operation consumes.

SAN implementations also permit applications to bypass kernel-mode components altogether, sending and receiving data directly to or from user applications. This minimizes the number of system calls applications make and further reduces time spent in operating system networking code.

WSD Architecture Most SAN implementations require application changes for the applications to interface with SAN network protocols and take advantage of SAN hardware-implemented network protocols and SAN features such as RDMA, but WSD allows any Winsockbased application that uses the TCP protocol to take advantage of SANs without modification. WSD gets its name from the fact that it gives applications direct access to SAN hardware, bypassing the TCP/IP stack. This shortcut to the network hardware gives applications a performance improvement of 2 to 2.5.

WSD achieves its shortcut to SAN hardware by using a software switch beneath the Winsock DLL, as shown in Figure 13-6. The switch routes SAN network activity to a vendor-supplied SAN Winsock service provider (WSP). The WSP acts as the user-mode equivalent of an NDIS driver, with the capability to map SAN hardware registers into user-mode memory and then manipulate the hardware without going through kernel-mode components. Some network activity does require the aid of a kernel-mode component (for instance, to map hardware into user-mode memory), which is also provided by the SAN vendor. Finally, the SAN vendor supplies a NDIS miniport driver to interface the TCP/IP stack to SAN hardware for applications that use Winsock networking features not supported natively by the SAN.

Figure 13-6. Traditional Winsock model vs. WSD model


Remote Procedure Call

Remote procedure call (RPC) is a network programming standard originally developed in the early 1980s. The Open Software Foundation (now The Open Group) made RPC part of the distributed computing environment (DCE) distributed computing standard. Although there is a second RPC standard, SunRPC, the Microsoft RPC implementation is compatible with the OSF/DCE standard. RPC builds on other networking APIs, such as named pipes or Winsock, to provide an alternate programming model that in some sense hides the details of networking programming from an application developer.

RPC Operation

An RPC facility is one that allows a programmer to create an application consisting of any number of procedures, some that execute locally and others that execute on remote computers via a network. It provides a procedural view of networked operations rather than a transport-centered view, thus simplifying the development of distributed applications.

Networking software is traditionally structured around an I/O model of processing. In Windows, for example, a network operation is initiated when an application issues a remote I/O request. The operating system processes it accordingly by forwarding it to a redirector, which acts as a remote file system by making the client interaction with the remote file system invisible to the client. The redirector passes the operation to the remote file system, and after the remote system fills the request and returns the results, the local network card interrupts. The kernel handles the interrupt, and the original I/O operation completes, returning results to the caller.

RPC takes a different approach altogether. RPC applications are like other structured applications, with a main program that calls procedures or procedure libraries to perform specific tasks. The difference between RPC applications and regular applications, however, is that some of the procedure libraries in an RPC application execute on remote computers, as shown in Figure 13-7, whereas others execute locally.

Figure 13-7. RPC operation


To the RPC application, all the procedures appear to execute locally. In other words, instead of making a programmer actively write code to transmit computational or I/O-related requests across a network, handle network protocols, deal with network errors, wait for results, and so forth, RPC software handles these tasks automatically. And the Windows RPC facility can operate over any available transports loaded into the system.

To write an RPC application, the programmer decides which procedures will execute locally and which will execute remotely. For example, suppose an ordinary workstation has a network connection to a Cray supercomputer or to a machine designed specifically for highspeed vector operations. If the programmer were writing an application that manipulated large matrices, it would make sense from a performance point of view to offload the mathematical calculations to the remote computer by writing the program as an RPC application.

RPC applications work like this: As an application runs, it calls local procedures as well as procedures that aren't present on the local machine. To handle the latter case, the application is linked to a local static-link library or DLL that contains stub procedures, one for each remote procedure. For simple applications, the stub procedures are statically linked with the application, but for bigger components the stubs are included in separate DLLs. In DCOM, covered later in the chapter, the latter method is typically used. The stub procedures have the same name and use the same interface as the remote procedures, but instead of performing the required operations, the stub takes the parameters passed to it and marshals them for transmission across the network. Marshaling parameters means ordering and packaging them in a particular way to suit a network link, such as resolving references and picking up a copy of any data structures that a pointer refers to.

The stub then calls RPC run-time procedures that locate the computer where the remote procedure resides, determine which transport mechanisms that computer uses, and send the request to it using local transport software. When the remote server receives the RPC request, it unmarshals the parameters (the reverse of marshaling them), reconstructs the original procedure call, and calls the procedure. When the server finishes, it performs the reverse sequence to return results to the caller.

In addition to the synchronous function-call-based interface described here, Windows RPC also supports asynchronous RPC. Asynchronous RPC lets an RPC application execute a function but not wait until the function completes to continue processing. Instead, the application can execute other code and later, when a response has arrived from the server, the RPC run time notifies the client that the operation has completed. The RPC run time uses the notification mechanism requested by the client. If the client uses an event synchronization object for notification, it waits for the signaling of the event object by calling the WaitForSingleObject or WaitForMultipleObject function. If the client provides an Asynchronous Procedure Call (APC), the run time queues the execution of the APC to the thread that executed the RPC function. If the client program uses I/O completion port as its notification mechanism, it must call GetQueuedCompletionStatus to learn of the function's completion. Alternatively, a client can poll for completion by calling RcpAsyncGetCallStatus.

In addition to the RPC run time, Microsoft's RPC facility includes a compiler, called the Microsoft Interface Definition Language (MIDL) compiler. The MIDL compiler simplifies the creation of an RPC application. The programmer writes a series of ordinary function prototypes (assuming a C or C++ application) that describe the remote routines and then places the routines in a file. The programmer then adds some additional information to these prototypes, such as a network-unique identifier for the package of routines and a version number, plus attributes that specify whether the parameters are input, output, or both. The embellished prototypes form the developer's Interface Definition Language (IDL) file.

Once the IDL file is created, the programmer compiles it with the MIDL compiler, which produces both client-side and server-side stub routines, mentioned previously, as well as header files to be included in the application. When the client-side application is linked to the stub routines file, all remote procedure references are resolved. The remote procedures are then installed, using a similar process, on the server machine. A programmer who wants to call an existing RPC application need only write the client side of the software and link the application to the local RPC run-time facility.

The RPC run time uses a generic RPC transport provider interface to talk to a transport protocol. The provider interface acts as a thin layer between the RPC facility and the transport, mapping RPC operations onto the functions provided by the transport. The Windows RPC facility implements transport provider DLLs for named pipes, NetBIOS, SPX, TCP/IP, and UDP. Windows Server 2003 removes the NetBIOS transport provider and adds a provider for HTTP.. In a similar fashion, the RPC facility is designed to work with different network security facilities.

Note

In Windows 2000, you can write new provider DLLs to support additional transports, but support for add-on provider DLLs was removed as of Windows XP.


Most of the Windows networking services are RPC applications, which means that both local processes and processes on remote computers can call them. Thus, a remote client computer can call the server service to list shares, open files, write to print queues, or activate users on your server, or it can call the messenger service to direct messages to you (all subject to security constraints, of course).

Server name publishing, which is the ability of a server to register its name in a location accessible for client lookup, is in RPC and is integrated with Active Directory. If Active Directory isn't installed, the RPC name locator services fall back on NetBIOS broadcast. This behavior ensures interoperability with Windows NT 4 systems and allows RPC to function on standalone servers and workstations.

RPC Security

Windows RPC includes integration with security support providers (SSPs) so that RPC clients and servers can use authenticated or encrypted communications. When an RPC server wants secure communication, it tells the RPC run time what authentication service to add to the list of available authentication services. When a client wants to use secure communication, it binds to the server. At that time, it must tell the RPC run time the authentication service and authentication level it wants. Various authentication levels exist to ensure that only authorized clients connect to a server, verify that each message a server receives originates at an authorized client, check the integrity of RPC messages to detect manipulation, and even encrypt RPC message data. Obviously, higher authentication levels require more processing. The client can also optionally specify the server principal name. A principal is an entity that the RPC security system recognizes. The server must register its SSP-specific principal name with an SSP.

An SSP handles the details of performing network communication authentication and encryption, not only for RPC but also for Winsock. Windows includes a number of built-in SSPs, including a Kerberos SSP to implement Kerberos version 5 authentication, Secure Channel (SChannel), which implements Secure Sockets Layer (SSL) and the Transport Layer Security (TLS) protocols. In the absence of a specified SSP, RPC software uses the built-in security of the underlying transport. Some transports, such as named pipes or Local RPC, have built-in security. Others, like TCP do not, and in this case RPC makes insecure calls in the absence of a specified SSP.

Another feature of RPC security is the ability of a server to impersonate the security identity of a client with the RpcImpersonateClient function. After a server has finished performing impersonated operations on behalf of a client, it returns to its own security identity by calling RpcRevertToSelf or RpcRevertToSelfEx. (See Chapter 8 for more information on impersonation.)

RPC Implementation

RPC implementation is depicted in Figure 13-8, which shows that an RPC-based application links with the RPC run-time DLL (\Windows\System32\Rpcrt4.dll). The RPC run-time DLL provides marshaling and unmarshaling functions for use by an application's RPC function stubs as well as functions for sending and receiving marshaled data. The RPC run-time DLL includes support routines to handle RPC over a network as well as a form of RPC called local RPC. Local RPC can be used for communication between two processes located on the same system, and the RPC run-time DLL uses the local procedure call (LPC) facilities in kernel mode as the local networking API. (See Chapter 3 for more information on LPCs.) When RPC is based on nonlocal communication mechanisms, the RPC run-time DLL uses the Winsock, named pipe, or Message Queuing (described shortly) APIs.

Figure 13-8. RPC implementation


Note

Message Queuing is not supported as a transport mechanism in Windows Server 2003.


The RPC Subsystem (RPCSS \Windows\System32\Rpcss.dll) is implemented as a Windows service. RPCSS is itself an RPC application that communicates with instances of itself on other systems to perform name lookup, registration, and dynamic endpoint mapping. (For clarity, Figure 13-8 doesn't show RPCSS linked with the RPC run-time DLL.)

Web Access APIs

To ease the development of Internet applications, Windows provides both client and server Internet APIs. By using the APIs, applications can provide and use Gopher, FTP, and HTTP services without knowledge of the intricacies of the corresponding protocols. The client APIs include Windows Internet, also known as WinInet which enables applications to interact with the Gopher, FTP, and HTTP protocols and WinHTTP, which enables applications to interact with the HTTP protocol and is more suitable than WinInet in certain situations. HTTP is a server-side API that was introduced in Windows Server 2003 to enable the development of Web server applications.

WinInet

WinInet supports the Gopher, FTP, and HTTP 1.0 and 1.1 protocols. The APIs break down into sub-API sets specific to each protocol. Using the FTP-related APIs such as InternetConnect to connect to an FTP server, FtpFindFirstFile and FtpFindNextFile to enumerate the contents of an FTP directory, and FtpGetFile and FtpPutFile to receive and send files an application developer avoids the details of establishing a connection and formatting TCP/IP messages to the FTP protocol. The Gopher-related and HTTP-related APIs provide similar levels of abstraction with the HTTP APIs providing cookie persistence, automatic dialup services, client-side file caching, and automatic credential dialog handling. WinInet is used by core Windows components such as Explorer and Internet Explorer.

WinHTTP

The current version of the WinHTTP API, 5.1, is available on Windows 2000 with Service Pack 3 installed, Windows XP, and Windows Server 2003. It provides an abstraction of the HTTP/1.1 protocol for HTTP client applications similar to what the WinInet HTTP-related APIs provide. However, whereas the WinInet HTTP APIs are intended for user-interactive client-side applications, the WinHTTP API is designed for server applications that communicate with HTTP servers. Server applications are often implemented as Windows services that do not provide a user interface and so do not desire the dialog boxes that WinInet APIs display. In addition, the WinHTTP APIs are more scalable and offer security functionality, such as thread impersonation, not available from the WinInet API.

HTTP

Using the HTTP API, which Windows Server 2003 implements, server applications can register to receive HTTP requests for particular URLs, receive HTTP requests, and send HTTP responses. The HTTP API includes Secure Sockets Layer (SSL) support so that applications can exchange data over secure HTTP connections. The API includes server-side caching capabilities, synchronous and asynchronous I/O models, and both IPv4 and IPv6 addressing. Internet Information Services (IIS) version 6, the version that ships with Windows Server 2003, uses the HTTP API.

The HTTP API, which applications access through the Httpapi.dll library, relies on the kernelmode Http.sys driver. Http.sys starts on demand the first time any application on the system calls HttpInitialize. Applications use HttpCreateHttpHandle to create a private request queue and specify the URLs that it wants to handle requests for with HttpAddUrl. Using the request queues and their registered URLs, Http.sys allows more than one application to service HTTP requests on a given port (port 80 for example), with each servicing HTTP requests to different parts of the URL namespace.

HttpReceiveHttpRequest receives incoming requests directed at registered URLs, and HttpSendHttpResponse sends HTTP responses. Both functions offer asynchronous operation so that an application can use GetOverlappedResult or I/O completion ports to determine when an operation is completed.

Applications can use Http.sys to cache data in nonpaged physical memory by calling HttpAddToFragmentCache and associating a fragment name with the cached data. Http.sys invokes the Memory Manager function MmAllocatePagesForMdl to allocate unmapped physical pages. When Http.sys requires a virtual address mapping for the physical memory described by an entry in the cache, for instance when it copies data to the cache or sends data from the cache, it uses MmMapLockedPagesSpecifyCache and then MmUnmapLockedPages after it completes its access. Http.sys maintains cached data until an application invalidates it or an optional application-specified timeout associated with the data expires. Http.sys also trims cached data in a worker thread that wakes up when the low memory notification event is signaled. (See Chapter 7 for information on the low memory notification event.) When an application specifies one or more fragment names in a call to HttpSendHttpResponse, Http.sys passes a pointer to the cached data in physical memory to the TCP/IP driver and avoids a copy operation.

Named Pipes and Mailslots

Named pipes and mailslots are programming APIs that Microsoft originally developed for OS/2 LAN Manager and then ported to Windows NT. Named pipes provide for reliable bidirectional communications, whereas mailslots provide unreliable unidirectional data transmission. An advantage of mailslots is that they support broadcast capability. In Windows, both APIs take advantage of Windows security, which allows a server to control precisely which clients can connect to it.

The names servers assign to named pipes and clients conform to the Windows Universal Naming Convention (UNC), which is a protocol-independent way to identify resources on a Windows network. The implementation of UNC names is described later in the chapter.

Named Pipe Operation

Named pipe communication consists of a named pipe server and a named pipe client. A named pipe server is an application that creates a named pipe to which clients can connect. A named pipe's name has the format \\Server\Pipe\PipeName. The Server component of the name specifies the computer on which the named pipe server is executing. (A named pipe server can't create a named pipe on a remote system.) The name can be a DNS name (for example, mspress.microsoft.com), a NetBIOS name (mspress), or an IP address (131.107.0.1). The Pipe component of the name must be the string "Pipe", and PipeName is the unique name assigned to a named pipe. The unique portion of the named pipe's name can include subdirectories; an example of a named pipe name with a subdirectory is \\MyComputer\Pipe\ MyServerApp\ConnectionPipe.

A named pipe server uses the CreateNamedPipe Windows function to create a named pipe. One of the function's input parameters is a pointer to the named pipe name, in the form\\.\Pipe\PipeName. The "\\.\" is a Windows-defined alias for "this computer." Other parameters the function accepts include an optional security descriptor that protects access to the named pipe, a flag that specifies whether the pipe should be bidirectional or unidirectional, a value indicating the maximum number of simultaneous connections the pipe supports, and a flag specifying whether the pipe should operate in byte mode or message mode.

Most networking APIs operate only in byte mode, which means that a message sent with one send function might require the receiver to perform multiple receives, building up the complete message from fragments. Named pipes operating in message mode simplify the implementation of a receiver because there is a one-to-one correspondence between sends and receives. A receiver therefore obtains an entire message each time it completes a receive and doesn't have to concern itself with keeping track of message fragments.

The first call to CreateNamedPipe for a particular name creates the first instance of that name and establishes the behavior of all named pipe instances having that name. A server creates additional instances, up to the maximum specified in the first call, with additional calls to CreateNamedPipe. After creating at least one named pipe instance, a server executes the ConnectNamedPipe Windows function, which enables the named pipe the server created to establish connections with clients. ConnectNamedPipe can be executed synchronously or asynchronously, and it doesn't complete until a client establishes a connection with the instance (or an error occurs).

A named pipe client uses the Windows CreateFile or CallNamedPipe function, specifying the name of the pipe a server has created, to connect to a server. If the server has performed a ConnectNamedPipe call, the client's security profile and the access it requests to the pipe (read, write) are validated against the named pipe's security descriptor. (See Chapter 8 for more information on the security-check algorithms Windows uses.) If the client is granted access to a named pipe, it receives a handle representing the client side of a named pipe connection and the server's call to ConnectNamedPipe completes.

After a named pipe connection is established, the client and server can use the ReadFile and WriteFile Windows functions to read from and write to the pipe. Named pipes support both synchronous and asynchronous operation for message transmittal. Figure 13-9 shows a server and client communicating through a named pipe instance.

Figure 13-9. Named pipe communications


A unique characteristic of the named pipe networking API is that it allows a server to impersonate a client by using the ImpersonateNamedPipeClient function. See the "Impersonation" section in Chapter 8 for a discussion of how impersonation is used in client/server applications.

Mailslot Operation

Mailslots provide an unreliable unidirectional broadcast mechanism. One example of an application that can use this type of communication is a time-synchronization service, which might broadcast a source time across the domain every few seconds. Receiving the sourcetime message isn't crucial for every computer on the network and is therefore a good candidate for the use of mailslots.

Like named pipes, mailslots are integrated with the Windows API. A mailslot server creates a mailslot by using the CreateMailslot function. CreateMailslot accepts a name of the form "\\.\Mailslot\MailslotName" as an input parameter. Again, like named pipes, a mailslot server can create mailslots only on the machine it's executing on, and the name it assigns to a mailslot can include subdirectories. CreateMailslot also takes a security descriptor that controls client access to the mailslot. The handles returned by CreateMailslot are overlapped, which means that operations performed on the handles, such as sending and receiving messages, are asynchronous.

Because mailslots are unidirectional and unreliable, CreateMailslot doesn't take many of the parameters that CreateNamedPipe does. After it creates a mailslot, a server simply listens for incoming client messages by executing the ReadFile function on the handle representing the mailslot.

Mailslot clients use a naming format similar to that used by named pipe clients but with variations that make it possible to broadcast messages to all the mailslots of a given name within the client's domain or a specified domain. To send a message to a particular instance of a mailslot, the client calls CreateFile, specifying the computer-specific name. An example of such a name is "\\Server\Mailslot\MailslotName". (The client can specify "\\.\" to represent the local computer.) If the client wants to obtain a handle representing all the mailslots of a given name on the domain it's a member of, it specifies the name in the format "\\*\Mailslot\ MailslotName", and if the client wants to broadcast to all the mailslots of a given name within a different domain, the format it uses is "\\DomainName\Mailslot\MailslotName".

After obtaining a handle representing the client side of a mailslot, the client sends messages by calling WriteFile. Because of the way mailslots are implemented, only messages smaller than 425 bytes can be broadcast. If a message is larger than 425 bytes, the mailslot implementation uses a reliable communications mechanism that requires a one-to-one client/server connection, which precludes broadcast capability. Also, a quirk of the mailslot implementation causes any messages of 425 or 426 bytes to be truncated to 424 bytes. These limitations make mailslots generally unsuitable for messages larger than 424 bytes. Figure 13-10 shows an example of a client broadcasting to multiple mailslot servers within a domain.

Figure 13-10. Mailslot broadcast


Named Pipe and Mailslot Implementation

As evidence of their tight integration with Windows, named pipe and mailslot functions are all implemented in the Kernel32.dll Windows client-side DLL. ReadFile and WriteFile, which are the functions applications use to send and receive messages using named pipes and mailslots, are the primary Windows I/O routines. The CreateFile function, which a client uses to open either a named pipe or a mailslot, is also a standard Windows I/O routine. However, the names specified by named pipe and mailslot applications specify file system namespaces managed by the named pipe file system driver (\Windows\System32\Drivers\Npfs.sys) and the mailslot file system driver (\Windows\System32\Drivers\Msfs.sys), as shown in Figure 13-11. The named pipe file system driver creates a device object named \Device\NamedPipe and a symbolic link to that object named \Global??\Pipe (\??\Pipe on Windows 2000), and the mailslot file system driver creates a device object named \Device\Mailslot and a symbolic link named \Global??\Mailslot that points to that object. (See Chapter 3 for an explanation of the \Global?? object manager directory.) Names passed to CreateFile of the form \\.\Pipe\… and \\.\Mailslot\… have their prefix of \\.\ translated to \Global??\ so that the names resolve through a symbolic link to a device object. The special functions CreateNamedPipe and CreateMailslot use the corresponding native functions NtCreateNamedPipeFile and NtCreateMailslotFile.

Figure 13-11. Named pipe and mailslot implementation


Later in the chapter, we'll discuss how the redirector file system driver is involved when a name that specifies a remote named pipe or mailslot resolves to a remote system. However, when a named pipe or mailslot is created by a server or opened by a client, the appropriate file system driver (FSD) on the machine where the named pipe or mailslot is located is eventually invoked. There are several reasons why FSDs in kernel mode implement named pipes and mailslots, the main one being that they integrate with the object manager namespace and can use file objects to represent opened named pipes and mailslots. This integration results in several benefits:

  • The FSDs use kernel-mode security functions to implement standard Windows security for named pipes and mailslots.

  • Applications can use CreateFile to open a named pipe or mailslot because FSDs integrate with the object manager namespace.

  • Applications can use Windows functions such as ReadFile and WriteFile to interact with named pipes and mailslots.

  • The FSDs rely on the object manager to track handle and reference counts for file objects representing named pipes and mailslots.

  • The FSDs can implement their own named pipe and mailslot namespaces, complete with subdirectories.

Because named pipes and mailslot name resolution uses the redirector FSD to communicate across the network, they indirectly rely on the Common Internet File System (CIFS) protocol. CIFS works by using the TCP/IP, TCP/IP with IPv6, and IPX protocols, so applications running on systems that have at least one of these in common can use named pipes and mailslots. For more information about CIFS, see Chapter 12.

EXPERIMENT: Listing the Named Pipe Namespace and Watching Named Pipe Activity

It's not possible to use the Windows API to open the root of the named pipe FSD and perform a directory listing, but you can do this by using native API services. The PipeList tool from http://www.sysinternals.com shows you the names of the named pipes defined on a computer as well as the number of instances that have been created for a name and the maximum number of instances as defined by a server's call to CreateNamedPipe. Here's an example of PipeList output:

C:\>pipelist PipeList v1.01 by Mark Russinovich http://www.sysinternals.com Pipe Name                           Instances        Max Instances ---------                           ---------        ------------- TerminalServer\AutoReconnect             1                 1 InitShutdown                             2                -1 lsass                                    4                -1 protected_storage                        2                -1 ntsvcs                                  58                -1 scerpc                                   2                -1 net\NtControlPipe1                       1                 1 net\NtControlPipe2                       1                 1 ExtEventPipe_Service                     1                30 net\NtControlPipe3                       1                 1 Winsock2\CatalogChangeListener-37c-0     1                 1 net\NtControlPipe4                       1                 1 net\NtControlPipe0                       1                 1 DhcpClient                               1                -1 ProfMapApi                               2                -1 winlogonrpc                              2                -1 net\NtControlPipe5                       1                 1 SfcApi                                   2                -1 net\NtControlPipe6                       1                 1 Winsock2\CatalogChangeListener-4c4-0     1                 1 atsvc                                    2                -1 epmapper                                 2                -1 net\NtControlPipe7                       1                 1 spoolss                                  2                -1 wkssvc                                   3                -1 DAVRPC   SERVICE                         2                -1 net\NtControlPipe8                       1                 1 keysvc                                   2                -1 net\NtControlPipe9                       1                 1 PCHHangRepExecPipe                       1                 8 PCHFaultRepExecPipe                      1                 8 net\NtControlPipe10                      1                 1 000000ac.000                             2                -1 Winsock2\CatalogChangeListener-ac-0      1                 1 net\NtControlPipe11                      1                 1 net\NtControlPipe12                      1                 1 winreg                                   2                -1 SECLOGON                                 2                -1 srvsvc                                   3                -1 ipsec                                    2                -1 trkwks                                   2                -1 Winsock2\CatalogChangeListener-ac-1      1                 1 net\NtControlPipe13                      1                 1 vmware-authdpipe                         1                -1 W32TIME                                  2                -1 net\NtControlPipe14                      1                 1 net\NtControlPipe15                      1                 1 Winsock2\CatalogChangeListener-e8-0      1                 1 INETINFO                                 2                -1 SMTPSVC                                  2                -1 browser                                  3                -1 net\NtControlPipe16                      1                 1 Ctx_WinStation_API_service               2                -1 ExtEventPipe_s0                          1                30 ExtEventPipe_s0_poller                   1                30 net\NtControlPipe17                      1                 1 interbas\server\gds_db                   1                -1 ROUTER                                   8                -1 PIPE_EVENTROOT\CIMV2SCM  EVENTPROVIDER   2                -1 net\NtControlPipe20                      1                 1

It's clear from this output that several system components use named pipes as their communications mechanism. For example, the InitShutdown pipe is created by Winlogon to accept remote shutdown commands, and the SecLogon pipe is created by the SecLogon service to perform logon operations on behalf of the Runas utility. You can determine what process has each of these pipes open by using the object search facility in Process Explorer from http://www.sysinternals.com. Note that a Max Instances value of -1 means that there is no upper limit on the number of instances for the given name.

The Filemon file system filter driver from http://www.sysinternals.com (see Chapter 12 for more information on Filemon) is able to attach to either the Npfs.sys or Msfs.sys file system drivers and to therefore see all named pipe or mailslot activity occurring on a system. Select the Named Pipes or Mail Slots menu entries from Filemon's Drives menu to have Filemon attach to the corresponding driver. The following screen shot shows Filemon capturing the named pipe activity generated when the My Network Places icon on the desktop was opened. Notice the messages transmitted through the LSASS and workstation service named pipes.




NetBIOS

Until the 1990s, the Network Basic Input/Output System (NetBIOS) programming API had been the most widely used programming API on PCs. NetBIOS allows for both reliable-connection-oriented and unreliable-connectionless communication. Windows supports NetBIOS for its legacy applications. Microsoft discourages application developers from using NetBIOS because other APIs, such as named pipes and Winsock, are much more flexible and portable. NetBIOS is supported by the TCP/IP and IPX/SPX protocols on Windows.

NetBIOS Names

NetBIOS relies on a naming convention whereby computers and network services are assigned a 16-byte name called a NetBIOS name. The 16th byte of a NetBIOS name is treated as a modifier that can specify a name as unique or as part of a group. Only one instance of a unique NetBIOS name can be assigned to a network, but multiple applications can assign the same group name. A client can broadcast messages by sending them to a group name.

To support interoperability with Windows NT 4 systems as well as Consumer Windows, Windows automatically defines a NetBIOS name for a domain that is up to the first 15 bytes of the left-most Domain Name System (DNS) name that an administrator assigns to the domain. For example, if a domain were named mspress.microsoft.com, the NetBIOS name of the domain would be mspress. Similarly, Windows requires an administrator to assign each computer a NetBIOS name at the time of installation.

Another concept used by NetBIOS is that of LAN adapter (LANA) numbers. A LANA number is assigned to every NetBIOS-compatible protocol that layers above a network adapter. For example, if a computer has two network adapters and TCP/IP and NWLink can use either adapter, there would be four LANA numbers. LANA numbers are important because a NetBIOS application must explicitly assign its service name to each LANA through which it's willing to accept client connections. If the application listens for client connections on a particular name, clients can access the name only via protocols on the network adapters for which the name is registered.

The "Windows Internet Name Service" section later in this chapter describes the resolution of NetBIOS names to TCP/IP addresses.

NetBIOS Operation

A NetBIOS server application uses the NetBIOS API to enumerate the LANAs present on a system and assign a NetBIOS name representing the application's service to each LANA. If the server is connection oriented, it performs a NetBIOS listen command to wait for client connection attempts. After a client is connected, the server executes NetBIOS functions to send and receive data. Connectionless communication is similar, but the server simply reads messages without establishing connections.

A connection-oriented client uses NetBIOS functions to establish a connection with a NetBIOS server and then executes further NetBIOS functions to send and receive data. An established NetBIOS connection is also known as a session. If the client wants to send connectionless messages, it simply specifies the NetBIOS name of the server with the send function.

NetBIOS consists of a number of functions, but they all route through the same interface: Netbios. This routing scheme is the result of a legacy left over from the time when NetBIOS was implemented on MS-DOS as an MS-DOS interrupt service. A NetBIOS application would execute an MS-DOS interrupt and pass a data structure to the NetBIOS implementation that specified every aspect of the command being executed. As a result, the Netbios function in Windows takes a single parameter, which is a data structure that contains the parameters specific to the service the application requests.

EXPERIMENT: Using Nbtstat to See NetBIOS Names

You can use the Nbtstat command, which is included with Windows, to list the active sessions on a system, the NetBIOS-to-TCP/IP name mappings cached on a computer, and the NetBIOS names defined on a computer. Here's an example of the Nbtstat command with the n option, which lists the NetBIOS names defined on the computer:

C:\>nbtstat -n Local Area Connection: Node IpAddress: [10.1.23.147] Scope Id: []                  NetBIOS Local  Name Table   Name                Type         Status    ------------------------------------------ ---    MARKLAP         <00>  UNIQUE      Registered      WORKGROUP      <00>   GROUP      R egistered      MARKLAP       <20>  UNIQUE      Registered      WORKGROUP       <1E> GRO UP       Registered     WORKGROUP      <1D>  UNIQUE       Registered     ..__MSBROWSE__ .<01>  GROUP        Registered Wireless Network Connection: Node IpAddress: [0.0.0.0] Scope Id: []    No names in cache


NetBIOS API Implementation

The components that implement the NetBIOS API are shown in Figure 13-12. The Netbios function is exported to applications by \Windows\System32\Netapi32.dll. Netapi32.dll opens a handle to the kernel-mode driver named the NetBIOS emulator (\Windows\System32\ Drivers\Netbios.sys) and issues Windows DeviceIoControl file commands on behalf of an application. The NetBIOS emulator translates NetBIOS commands issued by an application into TDI commands that it sends to protocol drivers.

Figure 13-12. NetBIOS API implementation


If an application wants to use NetBIOS over the TCP/IP protocol, the NetBIOS emulator requires the presence of the NetBT driver (\Windows\System32\Drivers\Netbt.sys). NetBT is known as the NetBIOS over TCP/IP driver and is responsible for supporting NetBIOS semantics that are inherent to the NetBIOS Extended User Interface (NetBEUI) protocol (included in previous versions of Windows), but not the TCP/IP protocol. For example, NetBIOS relies on NetBEUI's message-mode transmission and NetBIOS name resolution facilities, so the NetBT driver implements them on top of the TCP/IP protocol. Similarly, the NwLinkNB driver implements NetBIOS semantics over the IPX/SPX protocol.

Other Networking APIs

Windows includes other networking APIs that are used less frequently or are layered on the APIs already described (and outside the scope of this book). Four of these, however, Real-Time Communications (RTC), Distributed Component Object Model (DCOM), Message Queuing, and Universal Plug and Play (UPnP), are important enough to the operation of a Windows system and many applications to merit brief descriptions.

Real-Time Communications (RTC)

The RTC Client API, available on Windows XP and Windows Server 2003, enables developers to create applications to establish integrated multimodal communications. Applications can be developed to enable the PC to become the center for home or business communications. Audio and video calls as well as Instant Messaging (IM) and collaboration are all integrated into one communications session on the PC. In addition to PC-PC sessions, the API can establish PC-phone calls, phone-phone calls, or text-only IM sessions. Application sharing and whiteboard are also available on PC-PC sessions.

RTC supports presence information to allow clients to call contacts (or buddies) through a registrar server that maintains current location information on contacts. A contact's location can be a PC or a telephone and, in the future, a cell phone, pager, or handheld device. For example, if the application attempts to connect to a contact at his work location and the presence information indicates the contact is available on a PC at home, RTC will automatically redirect the connection to that location. The RTC API also allows users to maintain privacy by blocking specific callers from their presence information.

DCOM

Microsoft's COM API lets applications consist of different components, each component being a replaceable self-contained module. A COM object exports an object-oriented interface to methods for manipulating the data within the object. Because COM objects present welldefined interfaces, developers can implement new objects to extend existing interfaces and dynamically update applications with the new support.

DCOM extends COM by letting an application's components reside on different computers, which means that applications don't need to be concerned that one COM object might be on the local computer and another might be across the LAN. DCOM thus provides location transparency, which simplifies developing distributed applications. DCOM isn't a self-contained API but relies on RPC to carry out its work.

Message Queuing

Message Queuing is a general-purpose platform for developing distributed applications that take advantage of loosely coupled messaging. Message Queuing is therefore an API and a messaging infrastructure. Its flexibility comes from the fact that its queues serve as message repositories in which senders can queue messages for receivers, and receivers can de-queue the messages at their discretion. Senders and receivers do not need to establish connections to use Message Queuing, nor do they even need to be executing at the same time, which allows for disconnected asynchronous message exchange.

A notable feature of Message Queuing is that it is integrated with Microsoft Transaction Server (MTS) and SQL Server, so it can participate in Microsoft Distributed Transaction Coordinator (MS DTC) coordinated transactions. Using MS DTC with Message Queuing allows you to develop reliable transaction functionality to three-tier applications.

UPnP

Universal Plug and Play is an architecture for peer-to-peer network connectivity of intelligent appliances, devices, and control points. It is designed to bring easy-to-use, flexible, standardsbased connectivity to ad-hoc, managed, or unmanaged networks, whether these networks are in the home, in small businesses, or attached directly to the Internet. Universal Plug and Play is a distributed, open networking architecture that uses existing TCP/IP and Web technologies to enable seamless proximity networking in addition to control and data transfer among networked devices.

Universal Plug and Play supports zero-configuration, invisible networking, and automatic discovery for a range of device categories from a wide range of vendors. This enables a device to dynamically join a network, obtain an IP address, and convey its capabilities upon request. Then other control points can use the Control Point API with UPnP technology to learn about the presence and capabilities of other devices. A device can leave a network smoothly and automatically when it is no longer in use.

     < Day Day Up > 


    Microsoft Windows Internals
    Microsoft Windows Internals (4th Edition): Microsoft Windows Server 2003, Windows XP, and Windows 2000
    ISBN: 0735619174
    EAN: 2147483647
    Year: 2004
    Pages: 158

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net