Guidelines for implementors using connection-oriented transports in
the Session Initiation Protocol (SIP)
Ubiquity Software CorporationBuilding 3West Fawr LaneSt MellonsCardiffSouth WalesCF3 5EAcboulton@ubiquitysoftware.com Lucent Technologies2000 Lucent LaneRm 6G-440NapervilleIL60566USA+1 630 224 0216vkg@lucent.comExcel Switching Corporation75 Perseverance WayHyannisMA02601USArajnishjain@xl.comCisco Systems170 West Tasman DriveMailstop SJC-21/3San JoseCA95134USA+1 408 421 9990fluffy@cisco.com
Transport
SIPPING WGI-DInternet-DraftSIP TCP SCTP reuse connections socketThe growing SIP message size and the ensuing IP fragmentation,
scalability and performance efficiencies gained by multiplexing SIP sessions
over fewer reliable transport connections, efficient use of security
certificates etc. are engendering widespread use of connection-oriented
protocols for SIP transport. A variety of SIP transport related issues
are currently being discussed in the IETF including connection reuse,
persistent connections, outbound connection flows, SIP over SCTP, NAT
traversal, and SIP/TCP race conditions. This document attempts to unify
these techniques by describing practical guidelines for implementers
and takes a broad stroke at defining SIP Connection Management.
We hope to abstract the diverse connection techniques into a few
generic connection characteristics, which then help define a few common
connection models and use cases.
Reusing existing TCP connection between entities is not explicitly specified
in the SIP specification . The specification
recognizes that two communicating SIP entities (A and B) will have two
independent (uni-directional) connections open between them. The first
connection would be for requests going from A to B, and the second connection
for requests from B to A. The connect-reuse draft
attempts to mitigate this shortcoming
by associating an 'alias' for a connection between A and B. Thus, when
B receives a SIP request from A, it will create a mapping such that requests
going to A can re-use the same connection.Both and
recommend that connections be
kept open for some period of time after the last message was exchanged over
the connection; however, the exact time period to leave the connection open
is implementation defined. The connect-reuse draft
suggests that connections be kept
open somewhat indefinitely and only be closed to make room for new
connections. That is, the connection lifetime should be decoupled from
the SIP transaction or session lifetime. However, this behavior still does
not render connections predictable (or persistent). Overall, diverse
drafts and discussions have lead to implementations with different
assumptions on how to treat the connection once a final response has been
sent (or received). The authors' have witnessed implementations that
immediately close the connection after sending a response and others
that actually open a new TCP connection to send a provisional response.
Multiple choices lead to inefficiencies ambiguity in interoperability.An example illustrates the problems inherent in a UAS rapidly closing
connections after sending a response
Consider the following time line flow:|
2 |<-------SYN/ACK---------|
3 |----------ACK---------->|
4 |--------REGISTER------->|
5 |<---------401-----------|
6 |-REGISTER-> <-FIN/ACK-|
7 |<-FIN/ACK- -REGISTER->|
8 |----------ACK---------->|
9 |<-------FIN/ACK---------|
10|<---------ACK-----------|
Figure 1: Race condition.
]]>As shown in the figure above, sometime (a short interval) after sending
a 401, the UAS closes the TCP connection, generating a FIN which is on
its way to the UAC (step 6). At the same time, the UAC issues a new
REGISTER request with a response to the challenge and send it on the
same TCP connection. A race condition ensues. This could have been avoided
with well documented guidelines on connection management.As it turns out, the amount of time a connection is left open
will vary greatly between a UA and a proxy. A fixed (location-wise) UA
using a default outbound proxy can leave the connection open forever,
or until the proxy closes it (as an aside, the outbound draft
suggests that the UA establish multiple
connections with the outbound proxy for redundancy reasons and keep them
alive by sending a periodic burst of data). Traffic to and from the proxy
must occur on one of these connection. On the other hand, a mobile UA will
not be able to do leave a connection open. Likewise, two proxies in a
high traffic throughput peering relationship will benefit from a long lived
connection, whereas a proxy whose traffic patterns dictate that it contact many
downstream entities will need to maintain a shorter life of a TCP
connection.References and
do not address two aspects of
connections: neediness and connection duration. Neediness can best be
explained by an example: a UA behind a Network Address Traversal (NAT)
device would like to keep a NAT-negotiated connection open for a long
duration. Even when it uses the procedure outlined in , it is left up to its peer on if it will
honor the alias and send requests going in the opposite direction (i.e.
headed towards the UA behind the NAT) through the open connection.Oftentimes, it may be advantageous for both the SIP entities to agree on
a connection duration, after which it becomes stale and may be closed
by either of the entities. A duration is useful in cases where a proxy
farm is being used for a DNS-based load balancing (round robin DNS,
for example). In such a case, an upstream element wanting to send a
request to the proxy farm will use an existing connection if it is
not stale and query DNS only when the connection becomes stale. Possible
ways to mitigate neediness and connection duration are are presented in the
persistent-conn-reqs draft .And finally, existing literature on SIP connection reuse
, ,
,
does not provide any prorgammatic tricks, techniques, or heuristics on how to
consider connections stale, how to build SIP proxies that support a large
number of connections, what does the proxy or UA do when it detects
a broken connection, what does a proxy do when it runs out of
connections (clearly, it should now start closing stale connections to
reclaim resources, which brings us back to when does a connection
become stale), etc.
There, thus, exists a need for a document to serve as a guideline for
developers to reference while using connection-oriented transports. We
hope that this document serves as such a guideline. We will address the
issues we have faced while constructing SIP entities that use connection-
oriented transports. We also recognize that some of the issues may be best
served by extensions to the SIP protocol; however, it is fairly pre-mature
to quantify such extensions as yet. The analysis and discussions presented
in this draft will better guide us to a solution which may require an
extension.The authors of this document identified that while
RFC3261 comprehensively discuses the protocol
level usage of reliable, connection-oriented protocols (such as TCP,
SCTP), it in no way provides any guidance/guidelines for usage in
deployment (real world) scenarios. Experience has shown that due to this
under specification, SIP components involved in deployments have
demonstrated a wide spectrum of behavior for even the simplest scenarios.The document has been constructed based on a set of general
requirements/topics that have been listed below: Provide clarity regarding the
definition and requirements of a SIP based transport connection. Should
include detail relevant to topics such as: the re-use of
connections, the persistence of connections, connection redundancy.Introduce model representations that
define characteristics of typical SIP based connections. The detail
should focus on connections that are responsible for high throughput
(such as a proxy server connected to another proxy server) and low
throughput (such as a client a client to proxy connection).Outline generic procedures for caching
a SIP based connection and utilizing the contents of the cache for
future transactions. An important part of the discussion
should focus on defining a stale connection. This definition will
only provide guidelines as it is expected that the exact process of
identifying a stale connection and reclaiming it will be implementation
specific. The document will cover 'Stale'
connections but it should be recognized that some connections, that
may not necessarily be associated with high traffic throughput, need to
be kept open and not reclaimed as stale e.g. connections that traverse a
Network Address Translator(NAT). It must be recognized that
when talking about generic SIP based connections, many variables exist
at the operating system level. The discussion should include both
general and Operating System specific information that needs to be
taken into consideration. The culmination of information provided in the
previous topics listed in this section should be utilized to provide a
clear set of connection guideline use-cases for specific scenarios e.g.
UAC--> Proxy, Proxy-->Proxy etc. SIP, as an application layer stacked above the transport layer in the
Internet Protocol model, specifies certain mechanisms in order to utilize
transport protocols. In order to render a uniform behavior to the
application core, SIP tends to abstract the diversity of transport protocols
used underneath it. For instance, when SIP is transported over UDP it offers
its own reliability mechanism (through retransmissions, 100rel). Likewise for
connection oriented transport protocols such as TCP and SCTP, SIP utilizes a
somewhat sophisticated connection management.SIP connections not only affect application behaviors (such as NAT
traversal, application/transport race conditions, redundant connections) and
network conditions (such as congestion), but they are also critical in
engineering systems that are scalable and introduce minimum signaling
latency. Implementation experience, network intermediaries etc. have
engendered diverse requirements for SIP transport and connection management
in general. To cope with these requirements various schemes of connection
management have been devised. These schemes are detailed in the core SIP
specification , connect-reuse draft
, persistent-connections draft
, outbound draft
, and sip-sctp draft
.In order to provide guidelines to implementers, and to gradually build
towards a coherent concept of SIP connection management, we attempt to view
the diverse connection mechanisms in terms of a few common characteristics
of the connections. These characteristics essentially help define a common
vocabulary to speak about the individual requirements and solutions. Once the
connection characteristics are identified and enumerated, the intent is to
use them in defining SIP Transport Connection Models in the subsequent
sections.According to the core SIP specification ,
transport layer connections are essentially unidirectional (half-duplex)
at the SIP transaction layer, even though the transport connections are
inherently bidirectional. SIP imposes a directional bias on the transport
connections. Because a SIP transaction is composed of a request and one
or more responses, such connections carry SIP messages in both directions.
However, they carry SIP transactions (or SIP requests) in only one
direction. The reason why this directionality constraint exists is somewhat
due to the loose coupling between the SIP application layer and the
transport layer below it (i.e., the use of an ephemeral port to initiate
a connection). The constructs in the two layers (application and transport)
have a somewhat independent life cycle, so connections created by one side
can not be taken for granted by the other side. There is an underlying
assumption here that the SIP entity (UAC) that created the connection
owns the connection and can close it whenever it chooses. Of course, this
does not preclude the connection recipient (UAS) from closing the connection
any time it chooses. If the connection is closed in the middle of the
transaction, a new connection is created by the side that has an imminent
message to be sent out.A SIP transaction starts out with a temporary coupling with the transport
connection as the messages in the transaction are expected to utilize the
same connection. While this behavior is not guaranteed, the temporary
coupling helps gain efficiencies and alleviates some race conditions.
Typically, once the transaction is terminated, so is the coupling with the
transport connection. New transactions (to the same destination and in the
same direction as the connection-establishing transaction) may utilize an
existing connection. From a programming perspective, this usually implies
incrementing the transaction usage reference count for the connection, and
possibly resetting of the connection-idle timer.The connection directionality constraint in the core SIP specification
is primarily a manifestation of connection unpredictability. Fundamentally,
this is a connection persistence issue. If the two sides of the connection
somehow come to an agreement that the connection is not likely to go away,
there is no reason why the connection cannot be used for transactions in both
directions. The connect-reuse draft
provides one method to communicate
such an agreement.The connection-reuse I-D adds another data point to the directionality
characteristic of SIP transport connections. This I-D extends SIP to render
transport connections bidirectional (full-duplex) such that they can be used
to transmit SIP transactions in both directions. This extension works by
including a parameter (called "alias") in the "Via" header such that the
receiving end gets a hint to reuse the connection for transactions initiated
in the reverse direction. While the connection-reuse draft appears to specify
a use case for the connection directionality characteristic, it can also be
viewed as a connection persistence characteristic. By suggesting that the
connection-recipient reuse the connection, the fundamental intent is to
communicate that the connection is likely to be persistent.It's worth noting that the semantics of the "alias" parameter in the draft
is only a hint, not an enforcement. In some cases connection reuse simply
helps gain efficiencies (due to use of one connection as opposed to two), but
in some other cases (such as NAT traversal) connection reuse is a necessity.
Perhaps, the "alias" parameter needs to be interpreted as MUST, not as a
SHOULD. That is, the SIP entity receiving the connection with the "alias"
parameter present MUST reuse the connection for as long as it is alive.
The semantics of "alias" parameter would then be somewhat analogous to the
"rport" parameter defined in RFC 3581 . For
backward compatibility reasons, the client cannot assume that the connection
will be reused and must always be ready to accept new connections on its
advertised port.Connection persistence refers to the predictability and the duration for
which the connections are active. The core SIP specification cautions the
implementers that connections be fundamentally treated as ephemeral. The
specification does not explicitly provide a way to distinguish a persistent
connection from an ephemeral one, or to communicate the desired connection
duration between two SIP entities. The connect-reuse draft does
imply that the "alias"ed connections are indeed persistent. But, while the
draft stresses on directionality, it lacks the notion of forcing a
persistent connection. While there are guidelines (e.g. in the
connection-reuse draft) that the connections SHOULD be kept open beyond the
SIP transaction or dialog lifetime, there is no real guarantee that the
connections will indeed persist for the desired duration. Therefore, either
side must always be prepared to recover from a connection loss. The persistent-connections draft
looks into a few potential ways to communicate a hint for persistent
connection over SIP. The draft suggests that connection directionality
and connection persistence are subtly different characteristics, and one
can be specified completely independently of the other. Connection
persistence may simply suggest that a unidirectional connection (without
the "alias") be persistent. That way the notion of directionality
and persistence are not mixed together. For instance, a SIP entity such as a media server or voice mail server
that typically only receives transactions cannot particularly offer the
behavior expected by the "alias" parameter. However, if a connection to this
entity needs to be persistent, a mechanism suggested in
persistent-connections draft may prove useful. Noting the subtly different
outcomes of directionality and persistence, the two are being treated as
distinct characteristics in this document.Connection persistence is also attributable to SIP/transport race
conditions as exemplified in section 1. Such race conditions can be
alleviated through some kind of connection persistence mechanisms but not
through a connection directionality mechanism.The term "connection cardinality" is a way to refer to the n:m mapping
between the constructs in the SIP application layer and the constructs in the
transport layer. The term "cardinality" refers generally to the number of
members in a set. The term is used in object-oriented programming to describe
one-to-one (1:1), one-to-many (1:n), many-to-one (n:1) and many-to-many (n:m)
relationship model between two objects. The relationship between SIP
application layer objects (such as transactions and dialogs) and transport
layer objects (such as sockets in TCP, streams and associations in SCTP)
appears to fit this model. At a high-level, the core SIP specification,
connect-reuse draft ,
persistent-connections draft ,
outbound draft , and sip-sctp draft
all seem to specify one or another
mechanism that can be expressed as a connection cardinality characteristic.The core SIP specification specifies a
many UAC transactions to one connection cardinality. Figure 2 and 3 below
show a representation of this cardinality for transactions going in each
direction respectively. The naming convention for the figures below is the
following:UAC-PaT1 - Proxy Pa's client transaction number T1UAC-PaT2 - Proxy Pa's client transaction number T2UAS-PaT1 - Proxy Pa's server transaction number T1UAS-PaT2 - Proxy Pa's server transaction number T2UAC-PbT1 - Proxy Pb's client transaction number T1UAC-PbT2 - Proxy Pb's client transaction number T2UAS-PbT1 - Proxy Pb's server transaction number T1UAS-PbT2 - Proxy Pb's server transaction number T2C-PaC1 - Proxy Pa's TCP client connection number C1S-PbC1 - Proxy Pb's TCP server connection number C1S-PaC1 - Proxy Pa's TCP server connection number C1C-PbC1 - Proxy Pb's TCP client connection number C1The numbers at the two ends of the lines connecting a SIP construct to
a transport construct indicate the cardinality of the association.The connect-reuse draft tends
to eliminate the directional bias for use of transport connections at the
SIP transaction layer. The connections allowed by this draft can be
expressed with "many UAC/UAS transactions to one connection" cardinality.
Figure 4 below depicts this relationship. In the figure, both
proxies, Pa and Pb, have a client and server transaction with each other
over a single connection, which was originated by Pa and "alias"ed by Pb.The outbound draft suggests a
connection management mechanism that works at a somewhat higher level (as
compared to core SIP, and connection-reuse). The entities in question
here are the overall SIP UAs not ephemeral transactions or dialogs. To
achieve redundancy, the outbound draft suggests establishment of
multiple alternate connections (called as "flows"). The transport "flows,"
which are an abstraction over connections and datagrams, use some kind of
a keepalive mechanism to keep the flow active. In order to distinguish
one flow from another, each flow is treated like a sub-contact in an
AOR/Contact binding in the location service. That is, the
AOR/Contact binding contains individual contexts where each flow is
identified by a unique connection-id.The connection management specified in outbound draft can be
viewed as a connection cardinality characteristic. In the case of core SIP
specification and connection-reuse draft we noticed the cardinality
between SIP transaction constructs and transport connections. In case of
outbound draft the SIP layer constructs would be the
sub-contacts (or connection instances). The connection cardinality in this
case could possibly be described as "one UA many connections."SCTP supports the notion of streams within associations (associations
are somewhat analogous to connections in TCP). Streams are essentially
independent, service-defining flows of data that help alleviate the
head of the line blocking problem. This feature along with other features
of SCTP (such as multi-homing, unordered delivery, cookie based connection
establishment) are especially useful for transporting signaling (traditional
or IP) messages over SCTP.The notion of streams and associations in SCTP renders two constructs
in the transport layer (as opposed to one "connection" in case of TCP).
Accordingly, the connection cardinalities here depend on how SCTP constructs
(stream and associations) are mapped to SIP constructs (transactions,
dialogs, UA instances).The sip-sctp draft suggests a
simplistic many transactions to one association, one stream cardinality.
By default, the association and streams would be unidirectional at the
SIP transaction layer. However, "alias"ed SCTP associations and streams
can carry transactions in both directions. This is the arrangement
shown in figure 5 below. The naming conventions are as following:PaA1 - Proxy Pa Association number 1PbA1 - Proxy Pb Association number 1PaA1S0 - Proxy Pa Association number 1, Stream number 0PbA1S0 - Proxy Pb Association number 1, Stream number 0PaA1S1 - Proxy Pa Association number 1, Stream number 1PbA1S2 - Proxy Pb Association number 1, Stream number 2PaA1S1 - Proxy Pa Association number 1, Stream number 1PbA1S2 - Proxy Pb Association number 1, Stream number 2In order to alleviate the head of the line blocking problem across
different transactions and also to gain some performance in transaction
matching, a different SIP/SCTP connection cardinality can be established. In
this cardinality, each transaction maps to a unique stream. The stream id
serves to identify the transaction such that transaction matching mechanism
can be skipped. Figure 6 below shows this cardinality arrangement. Use of
("alias"ed) associations in the figure is just for illustration
(cardinality and directionality are two truly independent
characteristics).We define a connection model as a specific aggregation of the
characteristics discussed in the previous section. A connection model
defines the behavior exhibited by the two ends of a connection. Viewing
the relationship of the communicating peers in terms of a connection model
allows us to decouple the ensuing discussion from communicating pair-wise
behavior between a UA-UA, UA-Proxy, Proxy-Proxy, Proxy-UA and other such
permutations.We define three connection models: a high-throughput connection model,
a low-throughput connection model, and a NAT-driven connection model. The
last model could actually also exhibit behavior associated with the first
two. While the demarcation between these models are not set in stone,
categorizing a connection as falling in a category provides a hint to
the developer as to what characteristics should apply.High-throughput connections are defined by a large volume of
transactions between two SIP entities. The key feature of a high volume
SIP peer is it has a stable DNS name, DNS load balancing can be used
for reliability, and is probably not behind a NAT. Some examples of such
connections will include proxy peering relationships and gateway user
agent to application server relationship.A high-throughput connection peer may open a persistent, bi-
directional socket to its peer. It may perform SIP keepalives on it and
use one socket to multiplex many transactions if each such transaction
is going to the same destination.Low-throughput connections are defined by a low volume transaction
exchange between two SIP peers. Typically, this may include SIP user
agents registering with a registrar or querying a redirect server,
or even a SIP user agent contacting its default outbound proxy. One
distinguishing factor for a low throughput connection is the degree
of personalization a SIP user agent has with its owner. SIP user
agents resident on mobile devices or laptops will typically exhibit
low-throughput connection characteristics.A low-throughput connection may simply exhibit the connection
handling behavior specified in RFC 3261; namely, open a uni-
directional connection for a request to go out and responses to
come in; it may use the "alias" parameter to receive subsequent
requests on the same connection, or it may close the connection once
the transaction has exceeded its lifetime. There will typically
not be a keepalive mechanism used in such connections.A NAT-driven connection has specific needs. For one, the connection
may be kept open indefinitely beyond the transaction lifetime (since
requests from the outside would not be able to come in if the connection
was closed). Second, a NAT-driven connection may use an aggressive keep-
alive strategy least an overzealous firewall or NAT closes the IP
bindings. Third, in order to converse with multiple endpoints beyond the
firewall, the peer may open multiple connections and reuse each such
connection for multiple transactions; thus connection persistence is a
must for such connections.Note that either of the high-throughput or low-throughput connections
could be NAT-driven as well.In order to reuse TCP connections, UACs and proxies maintain a
cache. The cache is populated by UACs (including the UAC half of a proxy)
based on the result of DNS lookups as specified in RFC3263
. Once a downstream destination has been
identified and the IP address/port combination is obtained, the UAC MUST
check the cache to determine if an existing connection to the downstream
host is available; if so, the existing connection MUST be used. If
the check fails, the UAC establishes a connection with the downstream
UAS and caches the connection information. As an added optimization,
a UAS-half of a proxy sending a response upstream over a connection-
oriented transport and finding the connection stale, will open a new
connection to the host identified in the topmost Via. This connection
MAY be cached for future use as well.The cache may be indexed by the server's IP address and port number.
Other ancillary information that an implementation may find useful may
be saved for the connection; this includes the connection creation
timestamp, timestamp when the last activity occurred on the connection,
or a reference count of how many times the connection has been used.Clearly, the entries in the cache need to be periodically reclaimed
to preserve operating resources (file descriptors, buffers, etc.).
Strategies to expire the entries in the cache are implementation
dependent. Some strategies that may be used include expiring
least recently used (LRU) connections or expiring the connection with
the earliest timestamp (note that the LRU connection may not be the same
with the earliest timestamp). See discussion in Section 2.3 for some
more heuristics.A connection is considered stale when the metric that a particular
implementation uses to determine the validity of the connection indicates
so. Based on the discussion in the previous section, this could be the
LRU timestamp or the timestamp when a connection was created.
Implementations are free to define and save implementation-specific metrics
to aid in the determination of connection staleness. This draft does
not recommend any specific metrics (NOTE: should we?).A connection is also considered stale if the underlying TCP state
machine is not in a connected mode when an attempt is made to use
that connection (i.e. the peer closed its end of the connection). In
such a case, the remaining peer MUST close the connection to reclaim
resources and remove the connection tuple from the cache.Section 2.1 provided some heuristics for determining candidate
connections that can be closed. However, note that this determination
is implementation dependent and many factors can be considered besides
LRU and earliest-timestamp-first. For instance, if a connection has
been setup for emergency calls, it must be maintained even though
minimal traffic has utilized it and it has been open for a long
time. Likewise, the imposition of NATs and firewalls may argue that
a connection, once opened, remains so until explicitly closed. An
implementation must take into consideration such heuristics which are
appropriate for its proper functioning in order to arrive at a sufficient
metric for connection expiration.Additionally, parties that have negotiated TLS ciphers and
authentication tokens between themselves would, in all probability,
like to keep the connection open for as long as possible. Thus,
another heuristic could be the nature (i.e. TLS over TCP) of the
TCP connection.And finally, it could be that a hierarchy of heuristics is
needed instead of just one rule of thumb. The hierarchy may dictate
that LRU connections be reclaimed first, followed by those connections
which have been opened for a long time and do not require the
use of emergency called routing, followed by TLS connections, and so
on.To fill in. Point to consider: a UAC behind a firewall
may want to tell the SIP peer beyond the firewall to not
close the connection after the transaction is over, but
instead, keep it open for as long as possible.To fill in. Some points to consider: use the SO_KEEPALIVE
option on the socket or an application layer mechanism (say,
sending a CRLF every so often). Many problems with SO_KEEPALIVE
mechanism: long time out; to the order of two hours. On some
systems, the keepalive may impact all sockets, not just the
one on which it was set. And finally, the SO_KEEPALIVE mechanism
may inadvertently indicate a lost peer if there was a router or
routing-related problem in the network, irrespective of the health
of the communicating entities themselves.For an application-based solution, one or both of the communicating
entities will send CRLF over the socket after a random interval.
While it is possible for only one entity to send a CRLF, having
both entities do so allows the surviving entity to reclaim socket
resources when its peer goes down without any notification (for
example, a UAC running on a personal computer simply vanished
because the computer crashed or was abruptly powered down; in
this scenario, the normal TCP FIN will not occur. Thus the
surviving entity will think the socket is still connected. If
the surviving entity is a proxy, it may be important to reclaim
socket resources as soon as a peer vanishes).Note that some SIP phones already keep a connection warm by
sending empty packets (CRLF) to the SIP ports.A UAC wishing to send and receive SIP signaling to a proxy server
using TCP has to create and manage a connection. The connect-reuse
draft provides guidelines
specifying that, once created, not only should TCP connections be
used for SIP transactional exchanges (including both request and
response), they should also be used for subsequent SIP
request/response exchanges. This includes bi-directional SIP
transactions initiated by either SIP element involved in the TCP
connection. It is not restricted to the initiating UAC but also
covers subsequent dialogs initiated in the opposite direction.
See connect-reuse draft for
more information regarding re-use of TCP connections for SIP dialogs
using a previously created TCP socket.The primary focus of this section is to provide guidelines for
management of TCP connections from a User Agent Client (UAC) to Proxy
Server connection. The procedures outlined in this document vastly
improve the resource management of TCP connections and also help
network architectures that are required to traverse non-SIP aware Network
Address Translators (NAT) and firewalls. On constructing a SIP request that is to be sent to a proxy
server using TCP, a UAC will determine a remote destination IP
address and port from the SIP message. This information will either
be deduced explicitly or derived by performing DNS queries, as
detailed in RFC3263 . Once an IP address
and port have been identified, the UAC MUST check the cache for an
existing connection. If a connection exists and is still in
a connected state (i.e. not stale), it MUST be used for transporting the
SIP request. If a connection exists, but is in a stale state, then this
condition MUST be treated as if there wasn't any connection in the
cache at all (discussed in the following paragraph). The stale
connection MUST be closed and any resources associated with it MUST
be reclaimed.If an connection does not exist, the UAC will open
and use a new TCP connection to the proxy server for transporting
the SIP request. It MAY save the connection in the cache. Once
the SIP transaction is complete, a UAC MAY choose not to close the
connection. The connection MAY remain 'open' for the duration of
the UAC instance and be available for use by subsequent
request/response exchanges, including those received in the reverse
direction, as specified in the
connect-reuse draft.Unintentional transport errors may occur after a UAC has sent a
request, but before it has received a response. Such errors MUST
NOT be taken as an indication of the end of a transaction; rather,
the UAC MUST be prepared to receive a response on a new TCP
connection. The new TCP connection, once opened, will be subject to
the same staleness rules that connections opened by the UAC are
subject to. We do note that a UAS closing a connection before
generating a final response on that connection is exhibiting sub-
optimal behavior. Responses always use the same connection over
which the request was received.Guidelines for negotiating a persistent connection between SIP
entities can be found in the persistent-connections draft
. A UAC adhering to
the guidelines discussed in this specification MAY be required,
during it's life-cycle, to reclaim TCP connection resources if
demand exists. The method a UAC uses to 'close' and reclaim
TCP connection resources are subject to local policy, as discussed
earlier. The connection resource associated with the previously
identified connection SHOULD be reclaimed and re-used for the new
connection.A SIP proxy server listens for, and receives incoming connections
from clients, which can either be UACs or other proxies. SIP
transactional responses will use the same connection created for the
incoming request, as specified in RFC3261 .
On completion of a SIP transaction exchange, the proxy server
SHOULD NOT close the connection, and it SHOULD keep the connection
'open' for the duration of the Proxy Server instance. This
connection would then be available for use by subsequent request/response
exchanges, including those sent in the reverse direction as specified
in the connect-reuse draft .
Guidelines for negotiating a persistent connection between SIP entities
can be found in the persistent-connection draft
. A Proxy Server
adhering to the guidelines discussed in this specification MAY be
required, during it's life-cycle, to reclaim TCP connection resources
if demand exists. The method a Proxy Server uses to 'close' and
reclaim TCP connection resources is subject to local policy, as
discussed earlier. The connection resource associated with the
selected connection SHOULD be reclaimed and re-used by the new
connection.The persistent-connection draft
also includes a mechanism that allows Proxy Servers to negotiate a
heart beat mechanism with the client that can detect client failure
at the other end of a connection. Connections identified as being
failed MUST be reclaimed and returned to the pool of available
connection resources.In the interest of minimizing the delay it takes to set up and tear
down a session between two user agents, it is RECOMMENDED that
proxies keep connections open to their upstream UACs beyond the initial
transaction that establishes the session. SIP makes it possible that
a proxy may not be involved in subsequent signaling once a session is
set up, nonetheless, if the proxy is involved, subsequent messages will
experience less delay if the connection is already set up. Proxies,
as SIP intermediaries, should be more resilient and fast in comparison
to the UAC, which may only be serving one user and thus can absorb
session setup and teardown delays exhibited by establishing new
connections.On receiving a SIP request, a Proxy Server might be responsible for
routing the SIP message to a specified downstream destination which
can either be a Proxy Server or a UAS. This section will specifically
detail guidelines for the Proxy Server to UAS scenario using a reliable
transport protocol such as TCP.When a Proxy Server is connecting to a UAS it can be seen as
acting in the role of a client. The guidelines in this section are
similar to those specified in section 3.1 for a UAC.On constructing a SIP request that is to be sent to a UAS using
TCP, a Proxy Server will determine a remote destination IP address and
port from the SIP message. This information will either be deduced
explicitly or derived by performing DNS queries, as detailed in RFC3263
. Once an IP address and port
have been identified, the proxy MUST check the cache for an
existing connection. If an existing connection exists and is still
in a connected state (i.e. not stale), it MUST be used for transporting
the SIP request.If an existing connection does not exist, the Proxy Server will
open and use a new TCP connection to the UAS for transporting the
SIP request. It SHOULD save the connection in the cache for subsequent
use. Once the SIP transaction is complete, a Proxy Server
SHOULD NOT close the connection. The connection SHOULD remain 'open'
for the duration of the Proxy Server instance and be available for
use by subsequent request/response exchanges, including those received
in the reverse direction, as specified in the connect-reuse
draft.Guidelines for negotiating a persistent connection between
SIP entities can be found in the persistent-connection draft
. A Proxy Server
adhering to the guidelines discussed in this specification MAY be
required, during it's life-cycle, to reclaim TCP connection resources
if demand exists. The method a Proxy Server uses to 'close' and
reclaim TCP connection resources are subject to local policy, as
discussed earlier. The connection resource associated with the
previously identified connection MUST be reclaimed and re-used by
the new connection. The persistent-connection draft
also includes a mechanism
that allows Proxy Servers to negotiate a heart beat mechanism with
the client that can detect client failure at the other end of a
connection. Connections identified as being failed MUST be reclaimed
and returned to the pool of available connection resources.In the interest of minimizing the delay it takes to set up and tear
down a session between two user agents, it is RECOMMENDED that
proxies keep connections open to their downstream UASs beyond the
initial transaction that establishes the session. SIP makes it
possible that a proxy may not be involved in subsequent signaling
once a session is set up, nonetheless, if the proxy is involved,
subsequent messages will experience less delay if the connection is
already set up. Proxies, as SIP intermediaries, should be more
resilient and fast in comparison to the UAS, which may only be
serving one user and thus can absorb session setup and teardown delays
exhibited by establishing new connections.A SIP UAS listens for, and receives incoming connections from
clients, which can either be UACs or other proxies. SIP transactional
responses will use the same connection created for the incoming request,
as specified in RFC3261. On completion
of a SIP transaction exchange, the UAS MAY choose to not close the
connection, and it MAY keep the connection 'open' for the duration of
the UAS instance. This connection would then be available for use by
subsequent request/response exchanges, including those sent in the
reverse direction as specified in the connect-reuse draft . Guidelines for negotiating
a persistent connection between SIP entities can be found in the
persistent-connection draft .
A UAS adhering to the guidelines discussed in this specification
MAY be required, during it's life-cycle, to reclaim TCP connection
resources if demand exists. The method a UAS uses to 'close' and
reclaim TCP connection resources is subject to local policy, as discussed
earlier. The connection resource associated with the selected
connection SHOULD be reclaimed and re-used for the new connection.To fill in. Some points to consider: if this is a heavily
used connection, it should be kept open as long as possible.
Subsequent messages between these proxies must be sent over
this connection.To fill inTo fill inIt is not the intent of this draft to provide an over-arching
strategy for a particular operating system. Rather, we outline some of
our experience from building SIP servers that use connection-oriented
transports (a lot of this experience has been distilled using the
work of many others documented on the Internet, especially that of
Dan Kegel and Neil Provos).First, a SIP server using connection-oriented transports should be
designed in such a manner to be asynchronous. This can be achieved by
multi-threading or using other strategies like the use of the select()
system call, the use of the /dev/poll interface on Solaris or simply
rendering the socket to be non-blocking using the native fcntl()
system call [Aside: what is the Windows equivalent of fcntl()?).
The synchronous behavior spans I/O operations; for instance, under certain
circumstances, the connect() system call takes over 3 minutes to return
failure on a properly configured host running the Solaris operating
system (more specifically, on a working network that is not using a
private address space , a call
to connect() with a host using an IP address of, say, 10.10.1.1 will
cause the connect() to block for 3 minutes and 40 seconds).A second concern is scalability. Techniques such as the use of
select() are not scalable (select()'s performance is O(n); effectively,
as the descriptor size grows in select(), the system may have to work
more to find the right descriptor on which the I/O activity occurred).
Furthermore, select() is limited to FD_SETSIZE handles, and this limit
is compiled into the kernel and is not programmatically tunable.A better answer to select() is using traditional poll() system
call. Unlike select(), there isn't a upper limit on the number of file
descriptors that poll() can handle. However, performance is impacted
beyond a few thousand file descriptors since most file descriptors will
be idle at one time and scanning through thousands of file descriptors
will take time./dev/poll is the recommended replacement for Solaris platforms and
improves upon the performance of traditional poll(). However, /dev/poll
is not available in Windows or Linux. Linux sports /dev/epoll, which
is not available on Solaris or Windows. kqueue() is another /dev/poll
replacement for FreeBSD.Third, investigating the TCP (or SCTP) tunable parameters in an
operating system is also worth the effort. Certain operating systems
and their libraries allow the programmers to set tunable parameters
programmatically. On UNIXes, one of the most commonly allowable
tunable parameter is the number of concurrent open file descriptors.
By default, this number is usually set to 256; increasing it to the
highest value will allow more connections to be accepted simultaneously.
If an operating system provides a "zero-copy" option, it should
definitely be used to move the data efficiently from kernel space to
user space. On the sending side of TCP, disabling the Nagle algorithm
(set the TCP_NODELAY option) may be considered.Finally, in SIP, DNS plays a big part. DNS queries, by default are
blocking. While this is not strictly an operating system specific
problem, investigating in a non-blocking DNS framework may yield
performance gains. There are many asynchronous DNS resolvers available;
some of the most well known are ARES from MIT and ADNS (distributed under
a GNU license).It should be recognized that leaving TCP connections open indefinitely
could lead to session hi-jacking. While the threat of session hi-jacking
also persists in those TCP connections that are bounded by the lifetime of
a transaction, the unique nature of leaving a TCP connection open for
a long duration may exacerbate the problem. Hi-jacking an indefinitely
open TLS connection is considerably harder, although care must be taken
to ensure that the certificate is valid for the duration that the
TLS connection is left open.Aside from that recognition, this document does not raise additional
security considerations beyond those that are already well known in
the SIP community and documented
in and
.The race condition presented in Figure 1 was documented by Yosuke Itoh
<itoh.yosuke@lab.ntt.co.jp>.SIP: Session Initiation ProtocolConnection Reuse in the Session Initiation Protocol (SIP)Requirements for Persistent Connection Management in the Session
Initiation Protocol (SIP)SIP Conventions for Connection UsageThe Stream Control Transmission Protocol (SCTP) as a Transport for
the Session Initiation Protocol (SIP)Session Initiation Protocol (SIP): Locating SIP ServersAddress Allocation for Private InternetsAn Extension to the Session Initiation Protocol (SIP) for
Symmetric Response Routing