[asterisk-dev] SIP session-timers: concept, discussion
John Todd
jtodd at loligo.com
Tue Jul 17 18:20:27 CDT 2007
The issue of SIP session-timers has been raised before, and I'd like
to start a discussion here if there is any interest in implementing
this in Asterisk, and to solicit anyone who might think that they
would be up to the task of coding such a useful extension to the code.
In short: session-timers are described in RFC4028
(http://www.ietf.org/rfc/rfc4028.txt) and provide a method by which
two SIP entities can periodically verify with each other that
sessions are still valid. This avoids "zombie" calls that are costly
from both a real sense (price paid to carriers or by customers) and
from a customer service sense ("My bill shows a three hour call that
I know was only 10 minutes long!")
In my experiences, Asterisk has a nasty (and frequent) habit of
hanging SIP sessions due to internal inconsistencies which are
difficult to track down. A worse condition arises when a network
becomes disconnected, and particularly stupid equipment doesn't
notice that RTP stops in one direction(1). (This brings up an
interesting side note: I haven't tested it, but does Asterisk
interpret a certain volume of ICMP unreachables on a particular RTP
destination as evidence of a failed call?) When a software or
network failure causes one end of a SIP session to terminate without
a BYE, it often is the case that a call will be "stuck" and never
will be hung up. In every large-scale instance of Asterisk that I've
run, this has been a constant problem. I've tried solving it with a
large number of external "reapers" that use the manager interface,
I've used RTP timeouts to try to detect failed calls (this doesn't
work where there is no media), and I've used absolute timers to limit
risk exposure. None of these are particularly good solutions.
The best solution I've seen suggested (but not implemented in
Asterisk) is the use of the Session-Expires: header and related
configuration options. This allows SIP devices to agree on an
interval in which they will re-confirm the existence of a session.
This can be done with a RE-INVITE to the same parameters, or it can
be done with an UPDATE. Either way, it sends a "I'm here - I'm
alive!" message that is expected between the two end "devices" in the
communication. If, after the timer expires, there has been no update
or re-INVITE, then each side knows that the other has somehow
died/gone away, and the call is hopefully terminated. Even in the
cases where this is only supported by one side (the Asterisk side) it
will still make it possible to determine that a particular session
has failed, which would hopefully start to cut down on the number of
calls that get zombied due to network or other problems.
I would be thrilled to see that for each SIP peer (or better yet,
specifiable from within the Dialplan, but I won't get too greedy) the
ability to specify how Asterisk can originate calls with Session
Timers, or could accept calls with Session Timer requests. I've
outlined what my ideal configuration options would be in the sip.conf
snippet below. My company would be willing to pay some reasonable
amount of dollars towards getting this implemented as an "assist" to
a developer (but probably not a full funding.)
Note that this would also introduce a new error handling routine (to
manage "422 Session Interval Too Small") in response to remote
systems that didn't like the timer indicated in the INVITE when calls
were originated from Asterisk.
(1) So why not just use the RTP detection routines in Asterisk? Two
reasons come to mind immediately, but there may be more. Firstly:
often, RTP is not travelling through the Asterisk server that is
responsible for the call setup, and forcing RTP through that server
may be impractical or impossible. Secondly, Session-Timers (can)
work on the equipment at both ends of a call so any disconnection
[can|will] cause both ends to hang up. The RTP timers in Asterisk
are great for closing out the call on the Asterisk system, but in the
case of a network failure (without Session-Timers) it may be the case
that the non-Asterisk side may continue the call "forever", which is
typically a big problem when there are charges for call minutes.
JT
imaginary sip.conf snippet for session-Timers:
;
; Session-Expires (aka: Session Timers)
;
; Session-Expires headers may be used to create RE-INVITE or UPDATE sessions
; periodically so that SIP calls do not get 'hung' infinitely in the case
; of a network outage, device crash, NAT timeout, or other problem which
; would prevent a correct BYE from being sent. Care should be taken not to
; set these values too low, as the additional SIP traffic may utilize
; additional system and/or network resources. This method may work even if
; only one side of the call implements Session Timers, though of course any
; side which does not support the Session-Expires headers may become 'hung'
; in an open call state. To activate Session Timers, set the
; 'session-expires' value to "originate" and you can probably leave the rest
; of the values alone.
;
; session-expires=["accept", "originate", "refuse"] - The default is "accept".
;
; This describes what this Asterisk server will do in relation to
; Session-Expires headers.
; accept = accept Session-Expires requests from remote UAs, and apply
; the values described below in accepting the timer request.
; originate = originate Session-Expires on any INVITEs to this peer,
; using the values below. If "originate" is selected, it is
; implied that this Asterisk instance will also accept
; Session-Expires headers.
; refuse = Do not respond to Session-Expires headers, but continue the
; INVITE processing. In other words: act dumb.
;
;
; session-time=[integer] - This is the time that will be presented in the
; Session-Expires: header on a call that is originated by this
Asterisk system.
; The default if unspecified is 1800, and cannot be lower than 90.
;
; session-minse=[integer] - This is the lower bound for a received
; Session-Expires header. The default if unspecified is 1800, and cannot be
; lower than 90. If a Session-Expires header is received that is below this
; time, it will be refused with a 422 error ("Session Interval Too Small") and
; this value will be handed back as the "Min-SE:" header.
;
; session-type=["uas", "uac", "auto"] - Forces sending the
refresher parameter to
; "uac" or "uas". Expert use only; forcing this setting may cause
all calls to
; time out incorrectly. Default is "auto".
;
; session-method=["update","reinvite", "auto"] - Use either a re-INVITE or an
; UPDATE at the end of the timer cycle. Default is "auto". Some
equipment may
; not understand "UPDATE" methods, and may only respond correctly
to re-INVITEs
; with the same Call-ID value. If set to "auto", then the system
will function
; as follows: during the initial INVITE, the presence of "UPDATE"
in the Allow:
; field should dictate the use of "update" for that session, otherwise
; "reinvite" is used.
;
More information about the asterisk-dev
mailing list