Patch proposal: using the same CallerID in REGISTER method (RFC 3261 par. 10.2)

I’m using red5plugin 0.1.10 with Openser and I’ve noticed that when a user logs out his contact is not properly cleaned in Openser (I can see current AOR using openserctl ul show).
With Xlite and SJphone the log out correctly cleans the contact entry.

After a short SIP packets inspection, I’ve noticed that both Xlite and SJphone use the **same **CallerID in all REGISTER method (Cseq is incremented in each call) for a given user session, while the mjsip library uses a **different **CallerID for each call (Cseq always starts from 1).
Both behaviors seems consistent with RFC 3261 par. 10.2 (Constructing the REGISTER Request), but with Sparkweb Openser does not properly clean AOR.

I’ve modified SIPRegisterAgent in order to mimic Xlite and SJphone: when the first REGISTER method is called (and mjsip generates a random CallerID), I simply put it in a local variable and reuse it for all subsequent REGISTER invocation (both for session refresh and log out). Cseq is incremented for each call, so it is always unique for a given CallerID.

I attach the modified SIPRegisterAgent class and a message log that explains the new CallerID/Cseq behaviour in a simple login-logout scenario.
SIPRegisterAgent.java (14909 Bytes)
10.102.65.7.5071_messages.log (6861 Bytes)

Forgot to mention another change: in the loopRegister method of SIPRegisterAgent, I think that the *new KeepAliveSip *object should be assigned to local *keep_alive *variable in order for halt() method to properly stop the keepalive thread…

Thank you very much for the bug fix and code contribution

I will try out the changes as soon as I can and confirm it works fine with my Asterisk PBX.

Your good deed of the day award is in the post

hi

lets not celebrate too fast.

first- test on Asterisk probably will work as Asterisk is not fully RFC complainet and will handle also wrong signaling.

second- RFC just recomend to keep Call-ID same when its come from same UAC and not MUST:

“Call-ID: All registrations from a UAC SHOULD use the same Call-ID”.

REGISTRATION message is not established Dialog so Call-ID can be changed:“A REGISTER request does not establish a dialog”

when removing contact with Expire=0 it can be done using new REG message with new Cseq and Call-ID what count in this case is the contact header in the registartion (if exist as its not must in REG message), but for make binding it must have a contact header.

the Registrar check AOR (the TO: header) against contact when its bind or remove binding regardless of the Call-ID and Cseq.

you can send a new Registartion with same or new contact value as long as the last registartion got its final response (200 OK).

“UAs MUST NOT send a new registration (that is, containing new Contact
header field values, as opposed to a retransmission) until they have
received a final response from the registrar for the previous one or
the previous REGISTER request has timed out.”

the condition when you need to keep the CALL-ID and Cseq in order is when the PROXY chalalnge the REG with 401 (its same transaction not dialog).

than yuo must keep the CALL-ID and increnet Cseq, but change the BRANCH and add the Authentication digest…

in my proxy which is not Asterisk or openser the remove bindings is working also when the Call-ID is changed.

I agree that keeping the same Call-ID is better parctice.

I will test your changes soon.

Thank you.

Lior

Hello Janny

Just checked your patch and its work great. It is keep the Call-ID header and increnet Cseq for every new REG.

unlike your example I use the REG via SBC to keep NAT port opens and Mjsip send new REG about every 15 sec (1/2 exipere that come from SBC).

it is much better now using your patch for look the traces just filtered by the Call-ID.

thank you for sharing your work.

Lior

I have every reason to celebrate

There are many Red5 plugin and Red5phone users out there refusing to share their changes and even faults they have found. We all have freedom of choice

Personally, a post ike this makes a refreshing change from the usual “Its not working, Fix it. Ok, I fixed myself and I won’t share the experience” and keeps the whole open source, evolutionary community driven development alive

my “lets not celebrate” was refering to the RFC understanding of the problem

any help for the project is welcome and important.

Lior

Sorry,

I think I am in a strange mood today

I’m doing some more testing with Openfire 3.6.3 and Openser 1.2.1 using following clients

  • Spark 3.6.0beta with Sip Softphone 1.0
  • SparkWeb with red5plugin (my patched 0.1.10 version of course!)

SJphone 1.65.377 has been used to test both clients, and openserctl ul show command to show current contacts in Openser.

Well, with SparkWeb it seems ok. User login/logout update Openser status consistently…

I’ve changed default session expire period from 3600 to 60 in order to also test session “refresh”, and it works correctly (as SJphone/Xlite): every 30 seconds, a new REGISTER is issued with the same CallerID (equal to the first randomly generated by mjsip library) and with Cseq incremented each time.

With this condition, Openser always reported a single active contact.

With Spark, I’ve encountered some more problems. Firstly: the unregister is not done by calling REGISTER with expire set to 0 (as it should be!), but a SUBSCRIBE method is invoked instead! The source code of Sip Softphone plugin seems very buggy, I’ve fixed some points and now I can do unregister as expected.

But there is one more problem: when session is refreshed, a new CallerID is generated and Cseq restarts from 1. This is the same behavior as for red5plugin without my patch: Openser creates a new contact for each refresh!

The worst thing is that, in this condition, when SJphone tries to call Spark and more than one contact is active in Openser (for the same user, of course), Spark will receive more than one RING!

I know that “Call-ID: All registrations from a UAC SHOULD use the same Call-ID”, but with Openser (at least, my version!) this condition MUST be verified in order to properly establish SIP sessions.

I attach some more logs
10.102.250.200.5076_events.log (42531 Bytes)
10.102.250.200.5076_messages.log (36052 Bytes)

Hi

I gave up on the spark sip phone.

last time I tested it was few month ago. if I remmber correctlly it use Jain sip stack.

i had probelm with it of one way voice on incomming calls …

I just published your patch in my version with other small fix on

http://www.igniterealtime.org/community/message/187669

my goals in this project is to make a Flash phone that can work from mobile gsm phones (Flash player lite)…

for PC it not a problem just to upgrade the Flash player to a new version and work with the Flex flash object, but I belive the real use of this technology should work in the mobile devices.

In my vision people will be intersting use sip phone with no any installation from the mobile phones when WiFi or 3G internet is avalible.

for pc you have many solution in this form or another but the mobile device is still the main device to make calls and IM.

Lior

I just downloaded your 0.1.10v2 version, but there is a small oversight in the SIPRegisterAgent class .

The *onTransFailureResponse *method must increment the *registerCSeq *variable when a status code 401 or 407 is reported by sip proxy.

This is consistent with the req.setCSeqHeader(req.getCSeqHeader().incSequenceNumber()); instruction, both variables must be updated for each REGISTER call!

I attach the full patch compared to “original” 0.1.10 version
SIPRegisterAgent.java.patch (2652 Bytes)

when you are right you are RIGHT

I will make new version and update the link.

I have not noticed that because as I expalined before I work against SBC and the way it handle the siganling is as followed:

first Registartion is pass to the proxy with expire configured in the mjsip (lets say 3600)> proxy return 401 and mjsip send next REG correctlly.

on the 200ok from the proxy to the SBC proxy will use same expire as the Mjsip asked, but the 200ok that SBC send to Mjsip will have expire= like 30 sec.

in the next REG mjsip send it go just to the SBC and not forward to Proxy no more = no more 401, sbc will return by itself 200Ok.

Sbc know from the last Proxy 200ok what is the expire of the contact (in our example 3600) and when this time is almost end the SBC will forward next REG to Proxy.

Like that we do not overhead proxy with to much REG message that is require to keep NAT ports open on the customer side.

I never waited one hour with debuging for the next 401 message go to our Proxy and this is why I missed this small correction

thanks for sharing

Lior

Just tested this verion 0.1.10rev3 and its working fine to me!

Thanks Lior