Factors to Consider When Developing Applications Using the Live Communications Server API
Microsoft® Office Live Communications Server 2003
Summary: Discover how Microsoft Office Live Communications Server handles Session Initiation Protocol (SIP) messages, real-time communication traffic, and error conditions. Using this information helps you to create fast, security-enhanced, robust applications using the Live Communications Server application programming interface (API). (13 printed pages)
Choosing Between Microsoft SIP Processing Language or Managed Code
Working Around Limitations
Managing Performance Guidelines
Detecting Error Conditions
You can use the Microsoft® Office Live Communications Server 2003 application programming interface (API) to intercept and modify the Session Initiation Protocol (SIP) traffic flowing through Live Communications Server 2003. Using this powerful capability, you can modify and extend Live Communications Server to address specific business requirements. Server applications can implement additional features by using the following:
- Real-Time Communications Client API for implementing SIP user-agent functionality
- Live Communications Server Management API for configuring or administering Live Communications Server deployments programmatically
The Live Communications Server API provides managed classes for building server applications that intercept and modify SIP traffic. Server applications can implement such features as custom message filters, message routing based on predefined rules, and message logging. Because server applications interact with Live Communications Server at the protocol level, you must understand a variety of issues specific to Live Communications Server, including:
- Server topology
- Routing logic
- Server behavior
- Restrictions imposed on applications
This article is an introduction to these issues. For more information, see Additional Resources at the end of this article.
Choosing Between Microsoft SIP Processing Language or Managed Code
You can build server applications for Live Communications Server using the Microsoft SIP Processing Language (MSPL) or managed code.
MSPL is a scripting language that supports simple SIP message filtering and routing. MSPL scripts are easier to write than managed code. MSPL scripts are also significantly faster because they operate within the Live Communications Server process, while requests to managed code must be marshaled across processes (as shown in Figure 1). The default handler in Live Communications Server is an application called Routing.am, which is written in MSPL.
MSPL is not appropriate for applications that require more than simple routing and message filtering. For example, if your application needs to call external routines, perform calculations, implement complicated forking scenarios, or access databases or Web services, you must use a language compatible with the Microsoft .NET Framework and the set of managed classes provided in the Microsoft.Rtc.Sip namespace.
When planning a Live Communications Server application, the recommended strategy is to use MSPL if the language supports the required functionality. Otherwise, use managed code when complex logic or external access is required.
For applications built using the Live Communications Server API to work, you must position them along the appropriate message path with respect to other applications, including Routing.am. To make the appropriate choice requires understanding both the default routing behavior and the functionality of other applications on the server.
The first step in understanding how Live Communications Server routes messages is to become acquainted with the basic server components that handle the messages.
Live Communications Server uses a layered server architecture (see Figure 1). The base layer is the proxy, which receives and forwards messages.
The layer on top of the proxy contains three components:
- User Services
- Application Module
- Optional Archiving Module
Figure 1. Layered Live Communications Server architecture showing the path of INVITE requests
Upon receiving a request, the proxy passes it to User Services. User Services is integral to Live Communications Server and is a required component on both home servers and front-end servers. User Services functions as a SIP registrar and SIP presence-agent server. It maintains a Microsoft SQL Server Desktop Engine (MSDE) database that stores the following information about each user:
- A contact list
- Groups defined within the contact list
- An "allow and block" list that controls which users can communicate with this user
- Registration information
- A list of subscriptions to each user's presence information
User Services uses Microsoft Active Directory® directory service to authenticate users and to provide information such as whether a user is enabled for SIP messaging. It also identifies each user's SIP Uniform Resource Identifier (URI) and home server.
REGISTER requests stop with User Services, which responds directly to each user. User Services passes INVITE requests to the proxy layer, which forwards them to the application module. This is the first opportunity for third-party server applications to identify requests. If multiple server applications exist, the order in which they process the message is determined at installation time by the network administrator. For more information about application execution order, see Application Order and Routing.am later in this article.
If a third-party routing application exists on the server, it takes over routing at this point. Otherwise, the default message handler for Live Communications Server, Routing.am, routes the message.
Applications built using the Live Communications Server API reside in the application module. Such applications typically perform one or more of the following functions:
- Custom routing. Applications can route requests using criteria that may or may not overlap those used by Routing.am. Custom routing applications have the option of circumventing Routing.am entirely.
- Message logging. When writing custom logging applications, be aware that messages from enterprise users connecting from outside the corporate network are routed differently than those coming from users inside the network. You should take steps to ensure that all appropriate messages are trapped. For more information about the differences in routing internal and external messages, see Non-Registration Requests later in this article.
- Content filtering. Businesses may find it useful or necessary to filter messages for unacceptable content or unauthorized use. An application positioned to intercept messages during a SIP dialog can examine them and, for example, remove objectionable content. Or, the application can block unauthorized messages entirely. When developing such applications you also need to consider the differences in message routing for users outside the corporate network.
- Virus scanning. A message filter implemented on the server can refer all incoming requests for file transfers to a server application that scans the files for viruses. If a virus is not detected, the files are then forwarded to their designated recipients. Otherwise, the transfer is denied.
The last server application to process a request passes it back to the proxy for forwarding.
Optional Archiving Module
If the Live Communications Server optional archiving module is installed, the proxy passes the request for logging. Otherwise, the proxy forwards the message according to instructions provided by Routing.am or a custom server application that may be in charge of routing.
Connection Level Authorization
Live Communications Server allocates system resources based on the origin of new connections. Upon receiving a new connection, the server's proxy layer determines whether a new connection comes from a server, an Internet Protocol public switched telephone network (IP-PSTN) gateway, or a client. The following offers a scenario for each connection type:
Server. The connection comes from a server if it has a Mutual Transport Layer Security (MTLS) certificate with a server enhanced key usage (EKU) property. If the server is an internal server, the subject name on its MTLS certificate matches that of an internal server.
IP-PSTN Gateway. A connection (usually an IP-PSTN gateway) is marked with the Microsoft Windows® Management Instrumentation (WMI) property TreatAllConnectionsAsServer by a network administrator.
Client. The connection is treated as a client if it does not have an MTLS certificate or is not marked with TreatAllConnectionsAsServer. In this case, the server "throttles" the connection; that is, it limits the number of open transactions allowed on the connection.
A server application cannot alter throttling behavior, but it can work around it by marking a connection as TreatAllConnectionsAsServer in a static routing table on the forwarding proxy. For more information about static routing tables, see Static Routes later in this article.
Having established the nature of the connection (server, IP-PSTN gateway, or client), the proxy layer passes the message to User Services for authentication. Any client that connects as if the connection is from a server, the connection is not throttled and treated as if it is already authenticated. Therefore, the administrator should take steps to ensure that clients cannot misuse this setting.
Live Communications Server uses a network of known internal servers, all synchronized with Active Directory, and running User Services for authenticating users. Within this network, all routing occurs based on User Services:
- Finding the destination user's home server
- Routing to the destination user by means of stored routing data
- Using static routing tables in which URIs are mapped to known server addresses
Messages received from internal servers and the applications running on them are assumed to have already achieved user authentication. This list of internal servers is maintained and stored in a domain's Active Directory. It is also kept in synchronization with and cached into the SQL database maintained by User Services. In addition, connections established on certain listening addresses or static route table entries may be explicitly marked as from or to a server, which already guarantees user authentication by network administrators. An example is an administrator configuring an IP-PSTN gateway to use a static route and manually specifying that the next-hop server already has authenticated user requests.
If an incoming message comes from a connection where user authentication is assumed (by means of administrator settings or the internal servers table), the message is passed to User Services unmodified. If the message comes from a connection that can't be trusted to have already provided user authentication, Live Communications Server removes any Route headers and Record-Route headers it may contain. In this case, User Services challenges the connection. As a result, server applications can assume that all messages they receive are authenticated either locally by User Services or by a previous server.
A strict-routed message is one with a fixed, rather than indeterminate, endpoint. The following are considered to be strict routed:
- A SIP request having a Route header.
- A SIP request that has a maddr parameter in the RequestURI that does not point to the local server. For more information about the maddr parameter, see RFC 3261.
- A phone URI.
The strictRoute application attribute determines whether an application sees strict-routed messages. User Services and Routing.am process only messages that are not strict routed. Therefore, server applications (such as Routing.am) that process only messages that are not already routed by some other entity should be set to strictRoute=false. Applications that are meant to see all messages should be set to strictRoute=true. In setting the strictRoute attribute, the following applies:
- A general-purpose application, such as a logging or filtering application, may be programmed to process every message. In this case, the strictRoute attribute is true.
- Routes targeting a non-enterprise user need to be routed by a custom application (using strictRoute=true) because User Services and Routing.am ignore strict-routed messages. Similarly, applications that route IP-PSTN requests conceivably can set strictRoute=true (since User Services and Routing.am both ignore such requests) but the recommended method for routing such requests is to create new entries in the static routing table. For more information about static routing tables, see Static Routes later in this article.
SIP Routing Headers
SIP servers and server applications can affect routing behavior by inserting certain SIP headers into intercepted messages. These headers include Route headers, Via headers and Record-Route headers.
- SIP Route headers may be present in any request that is part of an established dialog. They indicate the route a request will take to get to its destination. Live Communications Server acts on Route headers only from other servers or from applications built using the Live Communications Server API. Removing Route headers from messages originating from network entities that cannot be trusted to provide proper routing data (clients, for example) is a security precaution.
- SIP Via headers provide a way for proxy servers in the path of a request to ensure that they are also included in the path of the response. Each server along the request's path can add its own Via header. Each sender along the response path removes its own Via header and forwards the response to the server specified in the next Via header on the stack.
- SIP Record-Route headers provide a way for servers and server applications to see all messages between endpoints for the duration of a dialog. As with the Via header, each proxy along a request's path can add a Record-Route header. Record-Route headers on requests originating from the Internet or from clients pose a potential problem because they could conceivably specify unauthorized entities. In order to prevent this possibility, Live Communications Server removes Record-Route headers from all requests except those originating from servers that prove their identity with a server certificate. In responses, Live Communications Server ignores Record-Route headers and uses Via headers instead.
Depending on the topology of a Live Communications Server deployment, registration requests may be handled by home servers, front-end servers, or both. If the user is connected directly to a home server, as might be the case in a small company, User Services searches the user account in Active Directory, enters the appropriate registration information in its own MSDE database, and notifies the client that registration is complete.
If the user is within the corporate network and connected to a front-end server, the server searches for the account in Active Directory, and redirects the request by returning the address of the user's home server to the client application in the form of a maddr parameter in the Request-URI. All subsequent requests go through the home server.
Routing of non-registration requests varies according to whether the user sending the request is located inside or outside the corporate network.
If the user sending the request is located inside the corporate network, the request passes through that user's home server. If this server is also the home server of the recipient, then it forwards the request directly to the recipient. If the recipient's home server is another server, then the caller's home server forwards the request to the recipient's home server.
Figure 2. Message route between two users within the corporate network
If the user is outside the corporate network, the request is routed through a server established in a perimeter network separating the corporate network from the Internet. This server forwards the request to a front-end server. Upon receiving the request, the front-end server, rather than redirecting it to the user, forwards it directly to the recipient's home server, thereby skipping the outside user's home server entirely.
Figure 3. Invite request from outside User 1 is forwarded directly to the home server of User 2
Server applications in topologies enabling outside users need to be aware that not all messages from a user are necessarily routed through that user's home server. For example, a logging application installed on a home server with the purpose of logging all traffic for its own users misses those requests originating outside the corporate network. When developing a server application, you should consider this additional routing scenario.
For more information about enabling remote users into your corporate network, see the following article, Enabling Outside User Scenarios.
If a request contains an endpoint identifier, User Services looks up the endpoint identifier in its database and adds to the request a Route header containing the registration path routing information that corresponds to that endpoint identifier.
If a request does not contain an endpoint identifier and the server is not the recipient's home server, User Services passes the message to the protocol stack for additional processing. Otherwise, the message goes to Routing.am.
Routing.am is an MSPL script application that acts as the default message handler for users on each home server. For each endpoint passed to it by User Services, Routing.am examines the length of time a user has been present, the user's current availability, and the activity level to determine the most active and available user endpoint.
Upon determining this endpoint, Routing.am adds registration-path routing information to the request as Route headers and sets the endpoint identifier in the To header to match that of the selected endpoint.
Routing.am does not process messages that are responses or that contain fixed routing information. Such information includes:
- Already existing route headers
- An endpoint identifier in the To header
- Either a maddr parameter specifying a non-local host, or a user=phone parameter in the Request-URI
Applications can override normal default routing by intercepting requests and attaching fixed routing information.
Routing.am also does not process requests to users who are unregistered in the Live Communications Server installation. Unprocessed requests are passed to the SIP protocol stack.
Application Order and Routing.am
Network administrators determine the execution order of server applications, but when developing applications you must decide whether their application should execute before or after Routing.am.
For example, an application that scans content and passes only valid text to Routing.am would have to run first. Any application that is to override default routing should also run ahead of Routing.am. One example is an application that routes incoming calls to voice mail after certain hours. Another is any application that implements complex rule-based routing behavior.
Some applications, however, might need to process messages after Routing.am. One example is an application that logs messages as they are about to leave the server.
SIP Protocol Stack
All requests, whether routed by a server application or Routing.am, continue to the SIP protocol stack for further processing. If the request includes fixed routing information, the protocol stack processes the request as follows:
- If the request contains at least one Route header, the topmost header is removed and its contents are used to replace the current Request-URI. This would happen, for example, if an application added a Route header as a way of overriding Routing.am.
- If the Request-URI contains a maddr parameter, then that parameter is the destination. Otherwise, the host portion of the Request-URI is the destination.
- If the resulting destination is an IP address, the next step depends on whether the message is authorized for direct routing.
- If the message was generated by User Services, it is authorized for direct routing and, therefore, forwarded to the appropriate destination.
- If the message was received from a server (as verified by a server certificate), it is trusted to provide valid routing data. The message is then authorized for direct routing and forwarded to the appropriate destination.
- If the message is not authorized for direct access, then the IP address is compared to entries in a static routing table maintained on the server.
- If there is no match, the message is dropped.
The static routing table is a list of IP addresses to computers serving as, for example, IP-PSTN gateways, hosts, or voice mail servers. Network administrators can use WBEMTest, a Windows Management Instrumentation (WMI) testing tool, or Microsoft Management Console (MMC) to add static routes to the static routing table.
If an entry is found in the static routing table that matches the Request-URI in the message, then the request is marked as authorized for routing, and routing is complete. If the IP address does not match an entry in the static routing table, then the request fails at this point.
Most IP-PSTN gateways and voice mail servers cannot authenticate themselves to the Live Communications Server. In order to support such connections, Live Communications Server enables network administrators to create what are known as static routes to the gateway and to mark such routes as trusted to have already provided user authentication.
A simple working topology for an IP-PSTN gateway uses a dedicated front-end server to act as the gateway host. All home servers work properly with the host server because it runs User Services to provide user authentication and is listed in the internal servers table and a static route exists for routing gateway-specific messages to it. Internal users do not connect directly to the gateway host. Instead, they connect to it indirectly through their home servers.
The administrator creates a static route and a listening address on the gateway host server and marks both as trusted to have already provided user authentication. This static route then enables the gateway host server to route outbound calls to the IP-PSTN gateway. In addition, the listening address also enables the gateway to initiate inbound connections to the host. These settings tell the server to accept messages without requesting user authentication in order to facilitate operation between the gateway and the Live Communications Server gateway host server. A potential problem is that anonymous users can use the gateway and these connection settings to send SIP requests to Live Communications Server through the gateway or by impersonating the gateway's IP address. To prevent this, the listening address should be protected so that only the gateway can reach it. An administrator can help secure the listening address either by using Internet Protocol security (IPSec), if the gateway supports it, or a firewall. Gateway security should also go through a testing cycle.
The reason these configuration settings are necessary is that most gateways do not support MTLS. When support becomes available, simpler and more effective methods to help secure them will be available because the identity of the gateway will be easily authenticated.
A front-end server working with IP gateways may itself host an application that routes outgoing calls according to rules specified on the server. For example, it might route calls to one location through one gateway, and calls to a different location through another. The application obtains the name of the appropriate gateways from a database, but still needs static routes to connect to the corresponding gateway hosts. In some cases, a network administrator can manually configure the static routes, but if the gateway pool is large or dynamic, this alternative is impractical. In such cases, the better solution is for the routing application to update the static routing table by instantiating the WMI class MSFT_SipRoutingTableData. For information about the WMI class, see MSFT_SipRoutingTableData.
Working Around Limitations
Server applications should be written to accommodate certain limitations based on server architecture, security, and unimplemented functionality. For example, an application built using the Live Communications Server API cannot:
Generate requests. SIP supports the notion of a "user-agent client," a process that runs on the server and is able to generate requests in response to external events such as a mouse click or a signal on a PSTN line. Although the Live Communications Server API provides Request and Response classes that would support such functionality, Live Communications Server does not allow user-agent clients.
For example, you may want a server application performing a virus check on file transfers to notify a sender if a file is infected. The application cannot use the Live Communications Server API to send a notification because it is unable to generate requests. Instead, it must use the RTC Client API to notify the sender. Such notification is not required, but it would provide a more satisfactory user experience.
See certain requests. A server application cannot see certain types of requests or challenge for authentication when running alongside User Services on a home server. Server applications can intercept only messages that User Services passes along for additional processing. As both a registrar and presence-agent server, the User Services component intercepts and does not forward REGISTER, SUBSCRIBE, and SERVICE requests. Since server applications can detect users only after registration or subscription, they cannot track when users come online, nor can they challenge registrations or any other type of requests.
Change the content of the To header. It might be useful for a server application to reroute a call by modifying the To header. For example, an application could reroute calls destined for a manager to the manager's assistant instead. To do so requires the application to modify the To header by replacing the manager's URI with the assistant's URI.
The Live Communications Server API supports modifying the To header as well as forwarding the modified request to the newly specified recipient. If the client application, however, is using the RTC Client API, certain checks in the code cause it to drop the modified request, even though the request is routed correctly.
To make sure a rerouted message gets to a new user, server applications should not modify the To header, but instead return a Redirect (302) response to the original request. Continuing with the previous example, the calling client, upon receiving the redirect, creates a new call routed directly to the manager's assistant.
Managing Performance Guidelines
Live Communications Server manages session traffic by imposing the following two rules:
- Each connection to the server is limited to 10 outstanding requests.
- Each transaction has a lifetime of 32 seconds. It is possible to extend a transaction lifetime by sending a Trying (100) response.
These rules have the following implications for Server API applications:
- An application should process requests as quickly as possible and call either the ProxyRequest and ProxyResponse methods, or the ServerTransaction.SendResponse and ClientTransaction.SendRequest managed API methods. It should not just receive a message and do nothing with it. Inaction causes transaction timeouts and influences throttling adversely.
- Because calls to managed code are relatively costly, applications requiring processing should dispatch only those messages where requirements exceed the functionality provided by MSPL.
- If an application needs to hold a request for a longer duration than the transaction limit in Live Communications Server, the application should generate a 100 response before the 32-second transaction time limit has expired. It should continue generating the 100 response as long as additional time is needed. Otherwise, an application receives an ObjectDisposed exception when the transaction times out.
- The most efficient way to handle responses is to use OnResponse event handlers instead of sending responses from MSPL. Because an OnResponse handler is installed on a per-request basis, if only a few requests are trapped, only a few responses are sent to managed code. In contrast, because MSPL is stateless either all of the responses or none are dispatched to managed code. The number dispatched cannot be optimized.
Applications can also improve performance by processing queued messages as quickly as possible. If an application calls the Dispatch function, and the Dispatch function finds that the message queue is full, it returns FALSE to the calling MSPL script. Applications should be written to handle this condition at the MSPL layer. One possibility is sending a Service Unavailable (503) response.
At the managed code layer, applications should be written to handle COMExceptions from the SendRequest and SendResponse methods, which indicate that the queue is overloaded. These events happen rarely and even then only when CPU utilization is very high. Applications should act on all events posted in the queue in a timely manner. If an application fails to act on these events, and if the queue continues to remain full for more than five minutes, Live Communications Server disconnects the application and posts an entry in the event log. If the application is marked critical, Live Communications Server shuts down as well.
Detecting Error Conditions
If an application forwards a request to a destination that is offline, Live Communications Server generates a Server Timeout (504) response. Additionally, if an application has registered for a transaction time-out event, that is also generated.
In order to handle time-outs, all server applications should register the OnConnectionDropped event handler. Live Communications Server generates a ServerShutdown event to notify applications that it is shutting down and give those applications a chance to properly shutdown as well. Upon receiving an OnConnectionDropped event, applications must dispose of their active ServerAgent object. They then have the option of waiting until the server comes back to register a new ServerAgent object.
The Live Communications Server API enables you to build applications that intercept and modify SIP traffic flowing through Live Communications Server. Because the API provides such low-level access, building fast, secure, robust server applications requires an understanding of how Live Communications Server authenticates and registers users, tracks presence, routes messages, and manages message traffic.
For additional information about building Live Communications Server applications, consult the following resources:
- The Live Communications Server API
- Using the Microsoft Office Communications Server API
- RTC Client API
- Live Communications Server 2003 Architecture and Deployment
- Deployment and operating Live Communications Server documentation
- Live Communications Server Management API
- Microsoft SIP Processing Language (MSPL)
- Microsoft.Rtc.Sip namespace
- RFC 3261, SIP: Session Initiation Protocol