< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

Re: [reSIProcate-users] header(h_SessionExpires).param(p_refresher)


Hi Ruadhri,

You've covered a lot of ground here.  Let me see if I can help.  : )  The documentation in Profile.hxx attempted to explain all this, I'm not sure if you've seen it or not yet.  

      /// Only used if timer option tag is set in MasterProfile.
      /// Set to PreferLocalRefreshes if you prefer that the local UA performs the refreshes.  
      /// Set to PreferRemoteRefreshes if you prefer that the remote UA peforms the refreshes.
      /// Set to PreferUACRefreshes if you prefer that the UAC (for the session - caller) performs the refreshes.
      /// Set to PreferUASRefreshes if you prefer that the UAS (for the session - callee) performs the refreshes.
      /// Note: determining the refresher is a negotiation, so despite this setting the remote 
      /// end may end up enforcing their preference.  Also if the remote end doesn't support 
      /// SessionTimers then the refresher will always be local.
      /// This implementation follows the RECOMMENDED practices from section 7.1 of the draft 
      /// and does not specify a refresher parameter in UAC requests.

It would be possible to add a new setting to Profile.hxx to request that DUM place the refresher parameter in the original INVITE, but I didn't have a use case for this, and it goes against the RFC recommendation.

As for your comment about finding a bug, I think this is just a miss understanding of the how the refresher parameter works.  I found this part very confusing when I was implementing this stuff, and had to seek advice from the RFC authors.  The way the profile uses the terms UAS and UAC are different from the way the refresher parameter works.  The setting PreferUACRefreshes is really referring to the caller as the preferred refresher (it should really be renamed) - it is only referring to the very initial INVITE that started the session.  However the refresher parameter in the SIP messages is on a transaction by transaction basis.  So in your example, when the session refresh comes from the other end and specifies UAS as the refresher, this is really asking us to now be the refresher, since the sender is the UAC in this REINVITE or UPDATE transaction, and our end is the UAS.  So it is expected that the next refresh would be generated locally.  I think a number of implementations get this part wrong, since it's not that clear in the RFC.  I will rename the profile settings from UAC to Caller and UAS to Callee in order to try to avoid future confusion about these settings.

I hope this helps.

Scott

On Thu, Jun 18, 2009 at 6:29 AM, Ruadhri Howman <ruadhri@xxxxxxxxx> wrote:
Hi,

I want to set the refresher parameter of the Session-Expires header when I send an INVITE.

I've set the following in my MasterProfile:
    masterProfile->addSupportedOptionTag(Token(Symbols::Timer));
    masterProfile->setDefaultSessionTime(1800);
    masterProfile->setDefaultSessionTimerMode(Profile::PreferUASRefreshes);

However, when I send down an INVITE, it contains only the Session-Expires time, without the refresher parameter:
Session-Expires: 1800
Min-SE: 900

Rather than:
Session-Expires: 1800;refresher=uas
Min-SE: 900

I had a poke about the code, and it appears that the InviteSessionCreator constructor doesn't check the value of Profile::mDefaultSessionTimerMode when creating the INVITE.

I've modified the file InviteSessionCreator.cxx to take account of this value:
Index: resip/dum/InviteSessionCreator.cxx
===================================================================
--- resip/dum/InviteSessionCreator.cxx    (revision 8515)
+++ resip/dum/InviteSessionCreator.cxx    (working copy)
@@ -34,6 +34,19 @@
       if(userProfile->getDefaultSessionTime() >= 90)
       {
          getLastRequest()->header(h_SessionExpires).value() = userProfile->getDefaultSessionTime();
+
+         switch(userProfile->getDefaultSessionTimerMode())
+         {
+         case Profile::PreferLocalRefreshes:
+         case Profile::PreferUACRefreshes:
+             getLastRequest()->header(h_SessionExpires).param(p_refresher) = Data("uac");
+             break;
+         case Profile::PreferRemoteRefreshes:
+         case Profile::PreferUASRefreshes:
+             getLastRequest()->header(h_SessionExpires).param(p_refresher) = Data("uas");
+             break;
+         }
+
          getLastRequest()->header(h_MinSE).value() = 90;  // Absolute minimum specified by RFC4028
       }
    }

This seems to work fine, in that my INVITE now contains:
Session-Expires: 1800;refresher=uas
Min-SE: 900

However, it may not be correct in treating Profile::PreferLocalRefreshes as the same as Profile::PreferUACRefreshes and Profile::PreferRemoteRefreshes as the same as Profile::PreferUASRefreshes.


There also seems to be a related bug (though this could come down to the difference between on the one hand: Profile::PreferLocalRefreshes and Profile::PreferUACRefreshes; and on the other hand: Profile::PreferRemoteRefreshes and Profile::PreferUASRefreshes -- the subtleties of which I might misunderstand).

After the timer Session-Expires timer expires the first time (or rather the Min-SE timer), the UAS sends my application a re-INVITE which I acknowledge. The INVITE received contains:
Session-Expires: 1800;refresher=uas
Min-SE: 900

And my 200 OK contains:
Session-Expires: 1800;refresher=uas
Min-SE: 900

However, when the timer fires next time, my reSIProcate sends down an UPDATE, rather than waiting to receive the re-INVITE. This update contains:
Session-Expires: 1800;refresher=uac
Min-SE: 900

I haven't investigated this too much yet, but I think it might be in InviteSession::setSessionTimerHeader(), where the refresher is primarily decided on the basis of whether the message is a request or not, rather than on either the Profile preference, or the content of the refresher parameter in the received message:
      msg.header(h_SessionExpires).value() = mSessionInterval;
      if(msg.isRequest())
      {
         msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uac" : "uas");
      }
      else
      {
         msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uas" : "uac");
      }
      msg.header(h_MinSE).value() = mMinSE;


I'll look into this further.


Regards,
Ruadhri.
_______________________________________________
resiprocate-users mailing list
resiprocate-users@xxxxxxxxxxxxxxx
List Archive: http://list.resiprocate.org/archive/resiprocate-users/