The transport layer is responsible for the actual transmission of
requests and responses over network transports. This includes
determination of the connection to use for a request or response in
the case of connection-oriented transports.
The transport layer is responsible for managing persistent
connections for transport protocols like TCP and SCTP, or TLS over
those, including ones opened to the transport layer. This includes
connections opened by the client or server transports, so that
connections are shared between client and server transport functions.
These connections are indexed by the tuple formed from the address,
port, and transport protocol at the far end of the connection. When
a connection is opened by the transport layer, this index is set to
the destination IP, port and transport. When the connection is
accepted by the transport layer, this index is set to the source IP
address, port number, and transport. Note that, because the source
port is often ephemeral, but it cannot be known whether it is
ephemeral or selected through procedures in [4], connections accepted
by the transport layer will frequently not be reused. The result is
that two proxies in a "peering" relationship using a connection-
oriented transport frequently will have two connections in use, one
for transactions initiated in each direction.
It is RECOMMENDED that connections be kept open for some
implementation-defined duration after the last message was sent or
received over that connection. This duration SHOULD at least equal
the longest amount of time the element would need in order to bring a
transaction from instantiation to the terminated state. This is to
make it likely that transactions are completed over the same
connection on which they are initiated (for example, request,
response, and in the case of INVITE, ACK for non-2xx responses).
This usually means at least 64*T1 (see Section 17.1.1.1 for a
definition of T1). However, it could be larger in an element that
has a TU using a large value for timer C (bullet 11 of Section 16.6),
for example.
All SIP elements MUST implement UDP and TCP. SIP elements MAY
implement other protocols.
Making TCP mandatory for the UA is a substantial change from RFC
2543(-> 3265prop | 3264prop | 3263prop | 3262prop | 3261prop). It has arisen out of the need to handle larger messages,
which MUST use TCP, as discussed below. Thus, even if an element
never sends large messages, it may receive one and needs to be
able to handle them.
18.1.1. Sending Requests
The client side of the transport layer is responsible for sending the
request and receiving responses. The user of the transport layer
passes the client transport the request, an IP address, port,
transport, and possibly TTL for multicast destinations.
If a request is within 200 bytes of the path MTU, or if it is larger
than 1300 bytes and the path MTU is unknown, the request MUST be sent
using an RFC 2914 [43] congestion controlled transport protocol, such
as TCP. If this causes a change in the transport protocol from the
one indicated in the top Via, the value in the top Via MUST be
changed. This prevents fragmentation of messages over UDP and
provides congestion control for larger messages. However,
implementations MUST be able to handle messages up to the maximum
datagram packet size. For UDP, this size is 65,535 bytes, including
IP and UDP headers.
The 200 byte "buffer" between the message size and the MTU
accommodates the fact that the response in SIP can be larger than
the request. This happens due to the addition of Record-Route
header field values to the responses to INVITE, for example. With
the extra buffer, the response can be about 170 bytes larger than
the request, and still not be fragmented on IPv4 (about 30 bytes
is consumed by IP/UDP, assuming no IPSec). 1300 is chosen when
path MTU is not known, based on the assumption of a 1500 byte
Ethernet MTU.
If an element sends a request over TCP because of these message size
constraints, and that request would have otherwise been sent over
UDP, if the attempt to establish the connection generates either an
ICMP Protocol Not Supported, or results in a TCP reset, the element
SHOULD retry the request, using UDP. This is only to provide
backwards compatibility with RFC 2543(-> 3265prop | 3264prop | 3263prop | 3262prop | 3261prop) compliant implementations that
do not support TCP. It is anticipated that this behavior will be
deprecated in a future revision of this specification.
A client that sends a request to a multicast address MUST add the
"maddr" parameter to its Via header field value containing the
destination multicast address, and for IPv4, SHOULD add the "ttl"
parameter with a value of 1. Usage of IPv6 multicast is not defined
in this specification, and will be a subject of future
standardization when the need arises.
These rules result in a purposeful limitation of multicast in SIP.
Its primary function is to provide a "single-hop-discovery-like"
service, delivering a request to a group of homogeneous servers,
where it is only required to process the response from any one of
them. This functionality is most useful for registrations. In fact,
based on the transaction processing rules in Section 17.1.3, the
client transaction will accept the first response, and view any
others as retransmissions because they all contain the same Via
branch identifier.
Before a request is sent, the client transport MUST insert a value of
the "sent-by" field into the Via header field. This field contains
an IP address or host name, and port. The usage of an FQDN is
RECOMMENDED. This field is used for sending responses under certain
conditions, described below. If the port is absent, the default
value depends on the transport. It is 5060 for UDP, TCP and SCTP,
5061 for TLS.
For reliable transports, the response is normally sent on the
connection on which the request was received. Therefore, the client
transport MUST be prepared to receive the response on the same
connection used to send the request. Under error conditions, the
server may attempt to open a new connection to send the response. To
handle this case, the transport layer MUST also be prepared to
receive an incoming connection on the source IP address from which
the request was sent and port number in the "sent-by" field. It also
MUST be prepared to receive incoming connections on any address and
port that would be selected by a server based on the procedures
described in Section 5 of [4].
For unreliable unicast transports, the client transport MUST be
prepared to receive responses on the source IP address from which the
request is sent (as responses are sent back to the source address)
and the port number in the "sent-by" field. Furthermore, as with
reliable transports, in certain cases the response will be sent
elsewhere. The client MUST be prepared to receive responses on any
address and port that would be selected by a server based on the
procedures described in Section 5 of [4].
For multicast, the client transport MUST be prepared to receive
responses on the same multicast group and port to which the request
is sent (that is, it needs to be a member of the multicast group it
sent the request to.)
If a request is destined to an IP address, port, and transport to
which an existing connection is open, it is RECOMMENDED that this
connection be used to send the request, but another connection MAY be
opened and used.
If a request is sent using multicast, it is sent to the group
address, port, and TTL provided by the transport user. If a request
is sent using unicast unreliable transports, it is sent to the IP
address and port provided by the transport user.
When a response is received, the client transport examines the top
Via header field value. If the value of the "sent-by" parameter in
that header field value does not correspond to a value that the
client transport is configured to insert into requests, the response
MUST be silently discarded.
If there are any client transactions in existence, the client
transport uses the matching procedures of Section 17.1.3 to attempt
to match the response to an existing transaction. If there is a
match, the response MUST be passed to that transaction. Otherwise,
the response MUST be passed to the core (whether it be stateless
proxy, stateful proxy, or UA) for further processing. Handling of
these "stray" responses is dependent on the core (a proxy will
forward them, while a UA will discard, for example).
18.2. Servers
A server SHOULD be prepared to receive requests on any IP address,
port and transport combination that can be the result of a DNS lookup
on a SIP or SIPS URI [4] that is handed out for the purposes of
communicating with that server. In this context, "handing out"
includes placing a URI in a Contact header field in a REGISTER
request or a redirect response, or in a Record-Route header field in
a request or response. A URI can also be "handed out" by placing it
on a web page or business card. It is also RECOMMENDED that a server
listen for requests on the default SIP ports (5060 for TCP and UDP,
5061 for TLS over TCP) on all public interfaces. The typical
exception would be private networks, or when multiple server
instances are running on the same host. For any port and interface
that a server listens on for UDP, it MUST listen on that same port
and interface for TCP. This is because a message may need to be sent
using TCP, rather than UDP, if it is too large. As a result, the
converse is not true. A server need not listen for UDP on a
particular address and port just because it is listening on that same
address and port for TCP. There may, of course, be other reasons why
a server needs to listen for UDP on a particular address and port.
When the server transport receives a request over any transport, it
MUST examine the value of the "sent-by" parameter in the top Via
header field value. If the host portion of the "sent-by" parameter
contains a domain name, or if it contains an IP address that differs
from the packet source address, the server MUST add a "received"
parameter to that Via header field value. This parameter MUST
contain the source address from which the packet was received. This
is to assist the server transport layer in sending the response,
since it must be sent to the source IP address from which the request
came.
Consider a request received by the server transport which looks like,
in part:
INVITE sip:bob@Biloxi.com SIP/2.0
Via: SIP/2.0/UDP bobspc.biloxi.com:5060
The request is received with a source IP address of 192.0.2.4.
Before passing the request up, the transport adds a "received"
parameter, so that the request would look like, in part:
INVITE sip:bob@Biloxi.com SIP/2.0
Via: SIP/2.0/UDP bobspc.biloxi.com:5060;received=192.0.2.4
Next, the server transport attempts to match the request to a server
transaction. It does so using the matching rules described in
Section 17.2.3. If a matching server transaction is found, the
request is passed to that transaction for processing. If no match is
found, the request is passed to the core, which may decide to
construct a new server transaction for that request. Note that when
a UAS core sends a 2xx response to INVITE, the server transaction is
destroyed. This means that when the ACK arrives, there will be no
matching server transaction, and based on this rule, the ACK is
passed to the UAS core, where it is processed.
18.2.2. Sending Responses
The server transport uses the value of the top Via header field in
order to determine where to send a response. It MUST follow the
following process:
o If the "sent-protocol" is a reliable transport protocol such as
TCP or SCTP, or TLS over those, the response MUST be sent using
the existing connection to the source of the original request
that created the transaction, if that connection is still open.
This requires the server transport to maintain an association
between server transactions and transport connections. If that
connection is no longer open, the server SHOULD open a
connection to the IP address in the "received" parameter, if
present, using the port in the "sent-by" value, or the default
port for that transport, if no port is specified. If that
connection attempt fails, the server SHOULD use the procedures
in [4] for servers in order to determine the IP address and
port to open the connection and send the response to.
o Otherwise, if the Via header field value contains a "maddr"
parameter, the response MUST be forwarded to the address listed
there, using the port indicated in "sent-by", or port 5060 if
none is present. If the address is a multicast address, the
response SHOULD be sent using the TTL indicated in the "ttl"
parameter, or with a TTL of 1 if that parameter is not present.
o Otherwise (for unreliable unicast transports), if the top Via
has a "received" parameter, the response MUST be sent to the
address in the "received" parameter, using the port indicated
in the "sent-by" value, or using port 5060 if none is specified
explicitly. If this fails, for example, elicits an ICMP "port
unreachable" response, the procedures of Section 5 of [4]
SHOULD be used to determine where to send the response.
o Otherwise, if it is not receiver-tagged, the response MUST be
sent to the address indicated by the "sent-by" value, using the
procedures in Section 5 of [4].
18.3. Framing
In the case of message-oriented transports (such as UDP), if the
message has a Content-Length header field, the message body is
assumed to contain that many bytes. If there are additional bytes in
the transport packet beyond the end of the body, they MUST be
discarded. If the transport packet ends before the end of the
message body, this is considered an error. If the message is a
response, it MUST be discarded. If the message is a request, the
element SHOULD generate a 400 (Bad Request) response. If the message
has no Content-Length header field, the message body is assumed to
end at the end of the transport packet.
In the case of stream-oriented transports such as TCP, the Content-
Length header field indicates the size of the body. The Content-
Length header field MUST be used with stream oriented transports.
Error handling is independent of whether the message was a request or
response.
If the transport user asks for a message to be sent over an
unreliable transport, and the result is an ICMP error, the behavior
depends on the type of ICMP error. Host, network, port or protocol
unreachable errors, or parameter problem errors SHOULD cause the
transport layer to inform the transport user of a failure in sending.
Source quench and TTL exceeded ICMP errors SHOULD be ignored.
If the transport user asks for a request to be sent over a reliable
transport, and the result is a connection failure, the transport
layer SHOULD inform the transport user of a failure in sending.