Summary:ASTERISK-11674: All SIP users InUse counters reset to zero(even if they are on call) during sip reload
Reporter:Rizwan Hisham Qureshi (rizwanhasham)Labels:
Date Opened:2008-03-18 07:51:07Date Closed:2011-06-07 14:03:17
Versions:Frequency of
Description:Suppose a user is on a call whose call-limit=2. "sip show inuse"  shows the inuse counter of the user is set to 1. But after reloading sip (the user is still in conversation and call is up) the "sip show inuse" command shows that its inuse counter is set to zero. It shouldnt do that. i have seen inside the code in chan_sip.c that while doing sip reload, asterisk destroys all the users (not peers) by freeing the memory allocated for all users and destroying their channel variables. As it destroys all the users, their inuse counter is also lost. So if a user whose call-limit was reached before the sip reload, after doing sip reload, he can make more than allowed simultaneous calls.

I have tested and can repeat this behaviour on any version of asterisk (1.4.2, 1.4.18, 1.4.19, 1.6.0beta5)

I am using a Dell Pentium PC with CentOS4 Installed on it.

This bug has great importance for us as we have users with call-limit=30. So if a user has inuse counter reached to 28, and then a one of my script automatically issues a sip reload, the inuse counter is reset to zero and the user is able to make 30 more simultaneous calls instead of 2. So i am setting the severity of this bug to major.


My scenario is simple:
I have 2 sip users named line1 and slave each with call-limit=2. after dialing from slave to line1 the sip show inuse command shows the following output.

-- Executing [12@axvoice:1] Dial("SIP/slave-0a16ed40", "SIP/line1") in new stack
   -- Called line1
   -- SIP/line1-0a178fe0 is ringing
   -- Call on SIP/line1-0a178fe0 left from hold
   -- SIP/line1-0a178fe0 answered SIP/slave-0a16ed40
   -- Native bridging SIP/slave-0a16ed40 and SIP/line1-0a178fe0
   -- Started music on hold, class 'default', on SIP/line1-0a178fe0
sip show inuse
* User name               In use          Limit
slave                     1               2
line1                     0               2
* Peer name               In use          Limit
slave                     0/0             2
line1                     1/0             2

after doing sip reload, sip show inuse command show the following output:

Reloading SIP
 == Parsing '/etc/asterisk/sip.conf': Found
 == Parsing '/etc/asterisk/users.conf': Found
 == Parsing '/etc/asterisk/sip_notify.conf': Found
*CLI> sip show inuse
* User name               In use          Limit
slave                     0               2
line1                     0               2
* Peer name               In use          Limit
slave                     0/0             2
line1                     1/0             2

You can see here clearly that the inuse counter is reset to zero for user slave

The core show channels command can show you that the call is still up

Channel              Location             State   Application(Data)              Duration
SIP/line1-0a16ed40   (None)               Up      Bridged Call(SIP/slave-0a178fe
SIP/slave-0a178fe0   12@axvoice:1         Up      Dial(SIP/line1)                00:00:10
2 active channels
1 active call

after hangup the inuse counter remains equal to zero (incase of 1.6 the counter is decremented to -1)

All of this is because during sip reload all the sip users are destroyed first and then built again after reading the configs. As they are destroyed user->inUse is also lost. Here is the debug output for sip reload:

[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:17158 sip_do_reload: --------------- SIP reload started
[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:2506 sip_destroy_user: Destroying user object from memory: slave
[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:2506 sip_destroy_user: Destroying user object from memory: line1
[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:17182 sip_do_reload: --------------- Done destroying user list
[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:17185 sip_do_reload: --------------- Done destroying registry list
 == Parsing '/etc/asterisk/sip.conf': [Mar 18 17:54:26] DEBUG[5709]: config.c:851 config_text_file_load: Parsing /etc/asterisk/sip.conf
 == Parsing '/etc/asterisk/users.conf': [Mar 18 17:54:26] DEBUG[5709]: config.c:851 config_text_file_load: Parsing /etc/asterisk/users.conf
 == Parsing '/etc/asterisk/sip_notify.conf': [Mar 18 17:54:26] DEBUG[5709]: config.c:851 config_text_file_load: Parsing /etc/asterisk/sip_notify.conf
[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:17192 sip_do_reload: --------------- Done destroying pruned peers
[Mar 18 17:54:26] DEBUG[5709]: chan_sip.c:17201 sip_do_reload: --------------- SIP reload done

Comments:By: Olle Johansson (oej) 2008-03-25 05:55:48

Just curious: Why do you have to issue a SIP reload?

I'm thinking of different ways to fix this...

By: Rizwan Hisham Qureshi (rizwanhasham) 2008-03-25 06:10:14

Well, if i created a new sip user or modified an existing user then sip reload has to be issued.

So have you come up with an idea. I think there is only one way of fixing this. We have to save the users inuse counter in some place in the code before reloading sip and after reloading the inuse counter should be set back to its original value for every user in a call.

By: Olle Johansson (oej) 2008-03-25 06:49:48

Longterm, the "user" object will disappear and be replaced by peers.

Short term, I'm not sure what to do. Depending on your configuration, you might want to use peers instead of users.

By: Rizwan Hisham Qureshi (rizwanhasham) 2008-03-25 07:03:58

Well, i think both of your ideas will eliminate the bug but they might also eliminate the call-limit feature for users also. i ahve not checked but, if we use peers instead of users then will the call-limit variable work for outgoing calls (callers)?

By: Olle Johansson (oej) 2008-03-25 07:11:21

For peers, there's one limit for both outbound and incoming calls.

By: Rizwan Hisham Qureshi (rizwanhasham) 2008-03-25 07:15:15

ic. well i should have thought of this earlier coz i have managed to save the user limit before reload and setting the limit back after reload in the code. Can i post the code here? I dont know how to make a patch.

By: Rizwan Hisham Qureshi (rizwanhasham) 2008-03-26 06:09:10

but what if i want to use 12 as outgoing limit and 10 as incoming limit?

By: Olle Johansson (oej) 2008-03-26 07:30:15

Well, you don't need the "user" object for that, you can still define two peers with the same account code and different limits. Another way is to use groupcount in the dialplan, so there are many ways you can enforce a limit that will stay during a reload.

Anyway, I don't see any easy solution here. Use peers instead of users to keep the call counter. The user object doesn't work like you want by design and I am not sure that we want to make such a big change to released code to implement new functionality. That's something you might want to discuss on the asterisk-dev list to see what the rest of the development team think.

By: Olle Johansson (oej) 2008-07-01 10:18:50

Suspending this issue.