Process session timers, even if Session-Expires header is missing
authorDavid M. Lee <dlee@digium.com>
Thu, 31 Jan 2013 20:17:15 +0000 (20:17 +0000)
committerDavid M. Lee <dlee@digium.com>
Thu, 31 Jan 2013 20:17:15 +0000 (20:17 +0000)
Previously, Asterisk only processed session timer information if both the
'Supported: timer' and 'Session-Expires' headers were present. However, the
Session-Expires header is optional. If we were to receive a request with a
Min-SE greater than our configured session-expires, we would respond with a
'Session-Expires' header that was too small.

This patch cleans the situation up a bit, always processing timer information
if the 'Supported: timer' header is present.

(closes issue ASTERISK-20787)
Reported by: Mark Michelson
Review: https://reviewboard.asterisk.org/r/2299/
........

Merged revisions 380696 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 380698 from http://svn.asterisk.org/svn/asterisk/branches/11

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@380699 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index 1d9c2d9..216b36d 100644 (file)
@@ -25492,12 +25492,12 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
        parse_oli(req, p->owner);
 
        /* Session-Timers */
-       if ((p->sipoptions & SIP_OPT_TIMER) && !ast_strlen_zero(sip_get_header(req, "Session-Expires"))) {
+       if ((p->sipoptions & SIP_OPT_TIMER)) {
                enum st_refresher_param st_ref_param;
 
                /* The UAC has requested session-timers for this session. Negotiate
                the session refresh interval and who will be the refresher */
-               ast_debug(2, "Incoming INVITE with 'timer' option supported and \"Session-Expires\" header.\n");
+               ast_debug(2, "Incoming INVITE with 'timer' option supported\n");
 
                /* Allocate Session-Timers struct w/in the dialog */
                if (!p->stimer)
@@ -25505,21 +25505,25 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
 
                /* Parse the Session-Expires header */
                p_uac_se_hdr = sip_get_header(req, "Session-Expires");
-               rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param);
-               tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
-               if (rtn != 0) {
-                       transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
-                       p->invitestate = INV_COMPLETED;
-                       if (!p->lastinvite) {
-                               sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+               if (!ast_strlen_zero(p_uac_se_hdr)) {
+                       ast_debug(2, "INVITE also has \"Session-Expires\" header.\n");
+                       rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref_param);
+                       tmp_st_ref = (st_ref_param == SESSION_TIMER_REFRESHER_PARAM_UAC) ? SESSION_TIMER_REFRESHER_THEM : SESSION_TIMER_REFRESHER_US;
+                       if (rtn != 0) {
+                               transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
+                               p->invitestate = INV_COMPLETED;
+                               if (!p->lastinvite) {
+                                       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+                               }
+                               res = INV_REQ_ERROR;
+                               goto request_invite_cleanup;
                        }
-                       res = INV_REQ_ERROR;
-                       goto request_invite_cleanup;
                }
 
                /* Parse the Min-SE header */
                p_uac_min_se = sip_get_header(req, "Min-SE");
                if (!ast_strlen_zero(p_uac_min_se)) {
+                       ast_debug(2, "INVITE also has \"Min-SE\" header.\n");
                        rtn = parse_minse(p_uac_min_se, &uac_min_se);
                        if (rtn != 0) {
                                transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
@@ -25559,6 +25563,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
                                } else {
                                        st_interval = uac_max_se;
                                }
+                       } else if (uac_min_se > 0) {
+                               int dlg_max_se = st_get_se(p, TRUE);
+                               st_interval = MAX(dlg_max_se, uac_min_se);
                        } else {
                                /* Set to default max value */
                                st_interval = global_max_se;