The connection manager provides I/O functionality. The connection manager is not part of the library but interacts with the stack using well defined interfaces. This section describes the usage model of the connection manager, its interface with the stack, and the requirements that are imposed by the library. The connection manager must register the following mandatory interfaces with the stack as part of stack initialization:
int sip_conn_send(const sip_conn_object_t, char *, int); void sip_hold_conn_object(sip_conn_object_t); void sip_rel_conn_object(sip_conn_object_t); boolean_t sip_conn_is_reliable(sip_conn_object_t); boolean_t sip_conn_is_stream(sip_conn_object_t); int sip_conn_remote_address(sip_conn_object_t, struc sockaddr *, socklen_t *); int sip_conn_local_address(sip_conn_object_t, struct sockaddr *, socklen_t *); int sip_conn_transport(sip_conn_object_t);
If the application uses timer values that are specific to a connection object, the application must register the following interfaces to provide those values for Timer 1, Timer 2, Timer 4, and Timer D:
int sip_conn_timer1(sip_conn_object_t); int sip_conn_timer2(sip_conn_object_t); int sip_conn_timer4(sip_conn_object_t); int sip_conn_timerd(sip_conn_object_t);
A connection object represents a connection. A connection is identified by the local endpoint, the remote endpoint, and the transport.
The library requires that the first element of the connection object is a void pointer. The stack reserves this void pointer for its own use. The application must initialize each connection object by calling the sip_init_conn_object() function before using the object. The connection object is opaque to the stack.
When the stack initializes a connection object, the stack sets the first element of a connection object to point to a structure. The structure tracks transactions that cache the connection object. The stack also uses the structure to break a TCP stream at the message boundaries.
Because the library does not interact with listening endpoints, it does not impose any restriction on creating or maintaining listening endpoints.
The connection manager maintains a unique connection object for each remote address, local address, and transport tuple. This behavior is particularly important for UDP, where the underlying endpoint does not uniquely identify a local/remote endpoint pair.
The stack caches connection objects for use by the transaction layer. The stack increments the reference count on the connection object to prevent the connection object from being freed by the system when the connection object is in use by the stack. When the transport protocol is TCP, the stack adds a reference count on the connection object when the stack allocates resources to break the TCP stream at message boundaries. The connection manager registers the sip_hold_conn_object() and sip_rel_conn_object() functions for the purposes of holding and releasing connection objects.
The connection manager can close a connection at any time. The connection manager cannot free the connection object while references to the connection object exist. To free a connection object that has existing references, the connection manager calls the sip_conn_destroyed() function. The library provides this function. When the connection manager invokes the sip_conn_destroyed() function, the stack locates and terminates the transactions that are caching the connection object. The stack frees any resources that had been allocated for TCP handling after terminating the transactions.
When an application sends a message by using the sip_sendmsg() function, the stack calls the sip_conn_send() function. The connection manager registers the sip_conn_send() function with the stack. The stack calls the sip_conn_send() function after the stack processes the outbound message. In case of a network error, the application can define the response of the connection manager, including returning an error. The connection manager's behavior must be consistent for all subsequent calls that use the same connection object. The connection manager can create a new connection to update an existing connection. The connection manager must flush any stale TCP data that is left in the connection object as a result of breaking the TCP stream at message boundaries. The connection manager uses the library function sip_clear_stale_data() to flush any stale TCP data. The Connection Manager must not change the transport type of a connection object.
The Connection Manager delivers new packets to the stack by calling the sip_process_new_packet(). After processing the message, the stack calls the receive callback function to pass the message to the application. The application must register the receive callback function with the stack at initialization. The stack frees the message and releases the connection object when the application's receive function returns. To queue a message, an application must manage the reference counts on the connection object as described in the Caching Connection Objects section. The application uses the sip_hold_msg() and sip_free_msg() functions to manage a SIP message's reference counts.
The transaction layer uses a cached connection object to send messages such as retransmitting requests or responses. In the event of a network error, the transaction layer releases the connection object. If the application registered a callback function for transaction error notification, the transaction layer invokes that function. If the application did not register a callback function for transaction error notification, or if the callback function returns a nonzero value, the stack terminates the transaction. If the callback function returns a value of zero, the stack does not release the cached object.