YXA RFC compliance
There are many RFC's specifying how a SIP-server should work.
Here are the ones we try to implement (in whole, or partially) :
And of course, there are others for things such as DNS (NAPTR, SRV etc.) and DIGEST-MD5.
|RFC3261||SIP: Session Initiation Protocol|
|RFC3263||Locating SIP Servers|
|RFC3265||SIP-Specific Event Notification|
|RFC2916||E.164 number and DNS|
|RFC3581||Symmetric Response Routing|
|RFC3326||The Reason Header Field|
|RFC4320||SIP Non-INVITE Actions (updates RFC3261)|
|RFC3327||Registering Non-Adjacent Contacts (Path: header)|
|RFC3856||A Presence Event Package for SIP|
|RFC3903||SIP Extension for Event State Publication|
|RFC3863||Presence Information Data Format (PIDF)|
|RFC4235||An INVITE-Initiated Dialog Event Package for SIP|
Internet drafts we are implementing in whole or partially
Obtaining and Using Globally Routable User Agent (UA) URIs (GRUU) in the
Session Initiation Protocol (SIP)
Managing Client Initiated Connections in the Session Initiation Protocol (SIP)
RFC3261 (SIP: Session Initiation Protocol) notes
With a specification consisting of 269 pages, it is kind of hard to claim complete
implementation compliance. YXA implements all the important parts (in my mind) of RFC3261,
and does so almost entirely according to the RFC.
With exception to some parts where there are bugs in the RFC, we are committed to continously
trying to increase YXA's compliance but there has simply not been enough time to make everything
completely RFC compliant yet.
Known RFC3261 compliance issues (not fixed a long time ago) :
||#10.3 says we must process REGISTER synchronously. Probably we should
have a persistent registrar erlang process to achieve this.
UPDATE 04-11-18: We have concluded that this would have
too much system performance cost to be worth trying to comply with.
Making synchronous processing isn't very much in line with using a highly
concurrent programming language, like Erlang.
||#10.3 ends with saying that we SHOULD include a Date header field in
our 200 Ok response. I guess we should, even if UAC's would be better
of using NTP.
||#19.1.1 Headers can be passed in request URI, we currently do not handle that.
(#22.214.171.124 then says that some (but not all) URI headers override their traditional
header value, if present. Sigh. I beleive it is correct to only regard that for
interpreting 3xx responses - something that YXA does not do)
||#19.1.4 We must implement general URI comparision functions. This is
mostly done byte by byte today (we usually remove parameters first though).
UPDATE 04-11-18 : sipurl:uri_is_equal() is now available,
albeit not used in every place where it possibly should.
||#16.5 says we should route requests with maddr in Request-URI to that address.
This is a multicast thing and of low priority since we don't do multicast.
||#18.2.2 says we should route responses with maddr in Via to that address IF
the transport layer protocol is not reliable. This is a multicast thing and
of low priority since we don't do multicast.
||#16.6 does NOT say that we have to support q-values to sort user locations,
but it says it is a common way to do it. We should support it.
||#9.2 and #17.2.3 specifies how we should match CANCEL from RFC2543 compliant clients
to the right server transaction. We currently only succeed in doing this if the
original request was INVITE (which it almost certainly was). This is a low priority
thing to fix - go fix the RFC2543 clients instead.
||Tokens are to be compared case-insensitive. This applies also to the branch
tag in Via headers. We should only produce lowercase tokens ourselves (fixed
as of 2006-04), and lowercase if needed when doing comparision in the transaction
layer transaction matching code. This isn't high priority because I've never seen
another implementation that mucks with other proxys Via header branch casings. Not
even at SIPIT where some people had boxes intentionally trying to break SIP.
RFC3261 things implemented (non-exclusive list) :
YXA is able to parse all requests/responses we have seen in the wild, except the
terrible broken implementation (not mentioning names) that uses a constant
branch starting with the RFC3261 magic cookie "z9hG4bK" for all it's request.
We will not try to be able to talk to things that badly broken.
Incomingproxy is a registrar which stores user locations in Mnesia,
the Erlang built in distributed, multi-mastered database, so that locations
can be accessed redundantly by all nodes in your SIP system.
|Outgoing proxy/SIP router
Some clients seem to expect their registrar to handle SIP routing for them,
so incomingproxy does that.
The base sipserver handles strict routing, and is a loose router itself.
Capable of traversing strict routers.
|RFC2543 backwards compliance
YXA works with RFC2543 UA clients and remote proxys too.
YXA does stateless loop detection, unless you tell it not to. Will
probably be changed to only stateful loop detection. You should stay
away from stateless SIP elements. UPDATE 2006-06-13 :
Stateless operations was removed sometime during 2005.
All YXA applications (incomingproxy, pstnproxy, appserver) are transaction stateful.
Appserver is a full forking implementation, which understands a simple set of
The transport layer does both TCP and UDP. IPv6 is implemented, but disabled by default
because of the problem with a v4-only and a v6-only endpoint not being able to use the
The transport layer does TLS for IPv4. Erlang/OTP's ssl modules does not work with IPv6
Non-RFC compliance todo's :
||We don't detect when outbound requests/responses sent over UDP generate
a ICMP port unreachable. I don't know if this is possible in Erlang.
The RFC does not require us to detect ICMP port unreachables, but it
would be nice.
Some things are needed to make YXA more effective in failing over to
the next server in a SRV list when the current one is not reachable.
- Shorter failover timeout. Currently, the timeout for UDP no response is
the same as the one of a client transaction, so the failover will occur
at the same time as the UAC gives up (except on INVITE, where we send
a 100 Trying).
- Cache unreachable destinations for a short period of time.
We should really implement a SIP-system wide policy controller to
stop people from DoS'ing us by sending excessive ammounts of requests,
making all our phones ring at the same time, keeping lots of connections
open at the same time etc. Should work per authenticated user,
per source IP, per source approximated subnet ...
We should perhaps make use of our (new) ability to keep state in making challenges
only valid for the very same request, instead of for a fixed ammount of time.
UPDATE 04-03-10: UAC's are recommended to cache credentails for reuse in a dialog,
and may reuse it outside of a dialogue if they use an outbound proxy. Either, we
should just make sure Call-Id matches, or we should just leave it as it is.
We should implement 'fallback to PSTN' if what we find in ENUM does not work.
'Work' meaning we receive a 1xx or 2xx in a configurable ammount of time, or
we receive a 503 Service Unavailable or similar.
It should be possible to signal an YXA application to stop accepting new requests (close
all listening sockets or send some temporary failure in response to all new requests received)
and exit as soon as all existing transactions have terminated.
As of yet, performance has been of secondary importance when writing YXA. We have been
more focused on making things work than making them run fast. This is NOT to say
that performance is lousy, or that we do not care about performance.
Things needed :
- Caching of DNS lookup results
- Erlang code profiling
- SIP transactions per second benchmarking
If you have experience with profiling or want to contribute by performing benchmarks
then please contact the developers (see info at the bottom of the project home page).
If you want to optimize something, please do but talk to the developers first so that
it can be done in a way that makes it possible to import the changes to the official
YXA source repository.
UPDATE 06-01-02: The YXA application 'incomingproxy' has been
benchmarked to 70 CPS (calls per second) on a laptop computer,
with debug output turned off.
70 CPS means 70 INVITE + 70 BYE transactions per second.
This translates to quite a few users - Stockholm university with 6000 employees
generate about two calls per second during peak hours of the day.
Short bursts of 255 CPS was also handled with only slightly longer response times
as a consequence.
Things we WON'T do
And also, there are some things we will NOT do, like in section 126.96.36.199 (DoS Protection)
it says :
"When the host on which a SIP proxy server is operating is routable
from the public Internet, it SHOULD be deployed in an administrative
domain with defensive operational policies (blocking source-routed
traffic, preferably filtering ping traffic). "
RFC2916 (E.164 number and DNS) notes
We currently only support '!' as a NAPTR regexp token.
RFC3581 (Symmetric response routing) notes
I think it is all implemented, except that we do not register on which IP address
we receive UDP datagrams (if the SIP proxy has multiple IP addresses) so we can't
really guarantee UDP responses will be sent with the right IP address. Needs to
RFC3263 (Locating SIP Servers) notes
No known issues exist. If you are interested in the implementation, look at the
files dnsutil.erl and sipdst.erl.
RFC3326 (The Reason Header Field) notes
No known issues exist. Must be because for once, it wasn't a several miles long RFC
even though it was about SIP.
RFC4320 (SIP Non-INVITE Actions) notes
No known issues exist. This is the second SIP RFC I've seen that is actually quite short.
RFC3327 (Registering Non-Adjacent Contacts (Path: header)) notes
We don't do S/MIME so the UAC won't know for sure that the Path it sees in 200 OK responses
to REGISTER is what we (the Registrar) actually put in the 200 OK.
RFC3856 (A Presence Event Package for SIP) notes
- The presence state agent is currently experimental.
- Until someone contributes XCAP support, only users in your YXA domain will be allowed
to subscribe to other users in your YXA domains presence.
RFC4235 (An INVITE-Initiated Dialog Event Package for SIP) notes
- The presence state agent is currently experimental.
- I've only tried to make 'shared line appearance' work with my Snom phones, but have
not achieved interoperability yet.
We don't do Record-Route like the draft says a "home proxy" must. No explanation has
been provided on the IETF SIP mailing list as to why this is necessary. My guess is that
it will be re-worded in a later version of the draft.
- Registrar must reuse same flow, or?
- Not very well tested since there aren't many clients doing real Outbound yet.
$Id: rfc-compliance.html,v 1.18 2006/06/13 12:49:35 ft Exp $