Author: file
Date: Sat Sep 27 07:42:30 2014
New Revision: 424056

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=424056
Log:
res_pjsip_session: Add additional checks for delaying session refreshes.

There are certain situations which no checks existed for which need to prevent
session refreshes. This includes sending a session refresh with SDP before SDP
negotiation has completed and sending a session refresh before the dialog itself
has been established. Checks for these have been added.

Additionally COLP related UPDATEs were including SDP when it is not needed.

Review: https://reviewboard.asterisk.org/r/4008/

Modified:
    branches/12/channels/chan_pjsip.c
    branches/12/res/res_pjsip_session.c

Modified: branches/12/channels/chan_pjsip.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/12/channels/chan_pjsip.c?view=diff&rev=424056&r1=424055&r2=424056
==============================================================================
--- branches/12/channels/chan_pjsip.c (original)
+++ branches/12/channels/chan_pjsip.c Sat Sep 27 07:42:30 2014
@@ -1049,11 +1049,15 @@
                }
        } else {
                enum ast_sip_session_refresh_method method = 
session->endpoint->id.refresh_method;
+               int generate_new_sdp;
                struct ast_party_id connected_id;
 
                if (session->inv_session->invite_tsx && 
(session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE)) {
                        method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE;
                }
+
+               /* Only the INVITE method actually needs SDP, UPDATE can do 
without */
+               generate_new_sdp = (method == 
AST_SIP_SESSION_REFRESH_METHOD_INVITE);
 
                /*
                 * We can get away with a shallow copy here because we are
@@ -1067,7 +1071,7 @@
                    (session->endpoint->id.trust_outbound ||
                     ((connected_id.name.presentation & AST_PRES_RESTRICTION) 
== AST_PRES_ALLOWED &&
                      (connected_id.number.presentation & AST_PRES_RESTRICTION) 
== AST_PRES_ALLOWED))) {
-                       ast_sip_session_refresh(session, NULL, NULL, NULL, 
method, 1);
+                       ast_sip_session_refresh(session, NULL, NULL, NULL, 
method, generate_new_sdp);
                }
        }
 

Modified: branches/12/res/res_pjsip_session.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/12/res/res_pjsip_session.c?view=diff&rev=424056&r1=424055&r2=424056
==============================================================================
--- branches/12/res/res_pjsip_session.c (original)
+++ branches/12/res/res_pjsip_session.c Sat Sep 27 07:42:30 2014
@@ -620,6 +620,8 @@
        ast_sip_session_sdp_creation_cb on_sdp_creation;
        /*! Callback to call when the delayed request receives a response */
        ast_sip_session_response_cb on_response;
+       /*! Whether to generate new SDP */
+       int generate_new_sdp;
        /*! Request to send */
        pjsip_tx_data *tdata;
        AST_LIST_ENTRY(ast_sip_session_delayed_request) next;
@@ -629,6 +631,7 @@
                ast_sip_session_request_creation_cb on_request_creation,
                ast_sip_session_sdp_creation_cb on_sdp_creation,
                ast_sip_session_response_cb on_response,
+               int generate_new_sdp,
                pjsip_tx_data *tdata)
 {
        struct ast_sip_session_delayed_request *delay = ast_calloc(1, 
sizeof(*delay));
@@ -639,6 +642,7 @@
        delay->on_request_creation = on_request_creation;
        delay->on_sdp_creation = on_sdp_creation;
        delay->on_response = on_response;
+       delay->generate_new_sdp = generate_new_sdp;
        delay->tdata = tdata;
        return delay;
 }
@@ -654,10 +658,10 @@
 
        if (!strcmp(delay->method, "INVITE")) {
                ast_sip_session_refresh(session, delay->on_request_creation,
-                               delay->on_sdp_creation, delay->on_response, 
AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1);
+                               delay->on_sdp_creation, delay->on_response, 
AST_SIP_SESSION_REFRESH_METHOD_INVITE, delay->generate_new_sdp);
        } else if (!strcmp(delay->method, "UPDATE")) {
                ast_sip_session_refresh(session, delay->on_request_creation,
-                               delay->on_sdp_creation, delay->on_response, 
AST_SIP_SESSION_REFRESH_METHOD_UPDATE, 1);
+                               delay->on_sdp_creation, delay->on_response, 
AST_SIP_SESSION_REFRESH_METHOD_UPDATE, delay->generate_new_sdp);
        } else {
                ast_log(LOG_WARNING, "Unexpected delayed %s request with no 
existing request structure\n", delay->method);
                return -1;
@@ -694,10 +698,10 @@
 
 static int delay_request(struct ast_sip_session *session, 
ast_sip_session_request_creation_cb on_request,
                ast_sip_session_sdp_creation_cb on_sdp_creation, 
ast_sip_session_response_cb on_response,
-               const char *method, pjsip_tx_data *tdata)
+               int generate_new_sdp, const char *method, pjsip_tx_data *tdata)
 {
        struct ast_sip_session_delayed_request *delay = 
delayed_request_alloc(method,
-                       on_request, on_sdp_creation, on_response, tdata);
+                       on_request, on_sdp_creation, on_response, 
generate_new_sdp, tdata);
 
        if (!delay) {
                return -1;
@@ -737,12 +741,21 @@
                return 0;
        }
 
+       /* If the dialog has not yet been established we have to defer until it 
has */
+       if (inv_session->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
+               ast_debug(3, "Delaying sending request to %s because dialog has 
not been established...\n",
+                       ast_sorcery_object_get_id(session->endpoint));
+               return delay_request(session, on_request_creation, 
on_sdp_creation, on_response, generate_new_sdp,
+                       method == AST_SIP_SESSION_REFRESH_METHOD_INVITE ? 
"INVITE" : "UPDATE", NULL);
+       }
+
        if (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE) {
                if (inv_session->invite_tsx) {
                        /* We can't send a reinvite yet, so delay it */
                        ast_debug(3, "Delaying sending reinvite to %s because 
of outstanding transaction...\n",
                                        
ast_sorcery_object_get_id(session->endpoint));
-                       return delay_request(session, on_request_creation, 
on_sdp_creation, on_response, "INVITE", NULL);
+                       return delay_request(session, on_request_creation, 
on_sdp_creation, on_response,
+                               generate_new_sdp, "INVITE", NULL);
                } else if (inv_session->state != PJSIP_INV_STATE_CONFIRMED) {
                        /* Initial INVITE transaction failed to progress us to 
a confirmed state
                         * which means re-invites are not possible
@@ -754,6 +767,14 @@
        }
 
        if (generate_new_sdp) {
+               /* SDP can only be generated if current negotiation has already 
completed */
+               if (pjmedia_sdp_neg_get_state(inv_session->neg) != 
PJMEDIA_SDP_NEG_STATE_DONE) {
+                       ast_debug(3, "Delaying session refresh with new SDP to 
%s because SDP negotiation is not yet done...\n",
+                               ast_sorcery_object_get_id(session->endpoint));
+                       return delay_request(session, on_request_creation, 
on_sdp_creation, on_response, generate_new_sdp,
+                               method == AST_SIP_SESSION_REFRESH_METHOD_INVITE 
? "INVITE" : "UPDATE", NULL);
+               }
+
                new_sdp = generate_session_refresh_sdp(session);
                if (!new_sdp) {
                        ast_log(LOG_ERROR, "Failed to generate session refresh 
SDP. Not sending session refresh\n");
@@ -1722,7 +1743,7 @@
 static void reschedule_reinvite(struct ast_sip_session *session, 
ast_sip_session_response_cb on_response, pjsip_tx_data *tdata)
 {
        struct ast_sip_session_delayed_request *delay = 
delayed_request_alloc("INVITE",
-                       NULL, NULL, on_response, tdata);
+                       NULL, NULL, on_response, 1, tdata);
        pjsip_inv_session *inv = session->inv_session;
        struct reschedule_reinvite_data *rrd = 
reschedule_reinvite_data_alloc(session, delay);
        pj_time_val tv;
@@ -2022,7 +2043,9 @@
        /* Terminated INVITE transactions always should result in queuing 
delayed requests,
         * no matter what event caused the transaction to terminate
         */
-       if (tsx->method.id == PJSIP_INVITE_METHOD && tsx->state == 
PJSIP_TSX_STATE_TERMINATED) {
+       if (tsx->method.id == PJSIP_INVITE_METHOD &&
+               ((tsx->state == PJSIP_TSX_STATE_TERMINATED) ||
+               (tsx->state == PJSIP_TSX_STATE_PROCEEDING))) {
                queue_delayed_request(session);
        }
 }


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to