[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