summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2016-06-22 17:26:38 -0500
committerRichard Mudgett <rmudgett@digium.com>2016-06-30 15:40:39 -0500
commit9f2c00725409a462935f343813fb10aba0c449ca (patch)
treead13474c9e48b47204235c493c16cf4017e1063d /res
parent08d3b9a89ef521e84e61ea1d6110b000454076cd (diff)
res_pjsip_session.c: Don't send extra BYE if SDP invalid.
When an answer SDP is invalid we were disconnecting the outgoing call and sending two BYE requests. The first BYE was sent by PJPROJECT because of the invalid SDP answer. The second BYE was sent by Asterisk because it thought the canceled call was the result of the RFC5407 section 3.1.2 race condition. * Made not send the BYE on a canceled session if the SDP negotiation is incomplete because PJPROJECT has already sent a BYE for the failed negotiation. ASTERISK-25772 #close Reported by: Dmitriy Serov Change-Id: I44ad0bd0605e8eeb7035c890d6f97a1331f1a836
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip_session.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 405fdf839..9f98e34b8 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -46,6 +46,7 @@
#include "asterisk/acl.h"
#include "asterisk/features_config.h"
#include "asterisk/pickup.h"
+#include "asterisk/test.h"
#define SDP_HANDLER_BUCKETS 11
@@ -2687,14 +2688,49 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
}
} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
if (inv->cancelling && tsx->status_code == PJSIP_SC_OK) {
- /* This is a race condition detailed in RFC 5407 section 3.1.2.
- * We sent a CANCEL at the same time that the UAS sent us a 200 OK for
- * the original INVITE. As a result, we have now received a 200 OK for
- * a cancelled call. Our role is to immediately send a BYE to end the
- * dialog.
+ int sdp_negotiation_done =
+ pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_DONE;
+
+ /*
+ * We can get here for the following reasons.
+ *
+ * 1) The race condition detailed in RFC5407 section 3.1.2.
+ * We sent a CANCEL at the same time that the UAS sent us a
+ * 200 OK with a valid SDP for the original INVITE. As a
+ * result, we have now received a 200 OK for a cancelled
+ * call and the SDP negotiation is complete. We need to
+ * immediately send a BYE to end the dialog.
+ *
+ * 2) We sent a CANCEL and hit the race condition but the
+ * UAS sent us an invalid SDP with the 200 OK. In this case
+ * the SDP negotiation is incomplete and PJPROJECT has
+ * already sent the BYE for us because of the invalid SDP.
+ *
+ * 3) We didn't send a CANCEL but the UAS sent us an invalid
+ * SDP with the 200 OK. In this case the SDP negotiation is
+ * incomplete and PJPROJECT has already sent the BYE for us
+ * because of the invalid SDP.
*/
- if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS
+ ast_test_suite_event_notify("PJSIP_SESSION_CANCELED",
+ "Endpoint: %s\r\n"
+ "Channel: %s\r\n"
+ "Message: %s\r\n"
+ "SDP: %s",
+ ast_sorcery_object_get_id(session->endpoint),
+ session->channel ? ast_channel_name(session->channel) : "",
+ pjsip_rx_data_get_info(e->body.tsx_state.src.rdata),
+ sdp_negotiation_done ? "complete" : "incomplete");
+ if (!sdp_negotiation_done) {
+ ast_debug(1, "Endpoint '%s(%s)': Incomplete SDP negotiation cancelled session. %s\n",
+ ast_sorcery_object_get_id(session->endpoint),
+ session->channel ? ast_channel_name(session->channel) : "",
+ pjsip_rx_data_get_info(e->body.tsx_state.src.rdata));
+ } else if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS
&& tdata) {
+ ast_debug(1, "Endpoint '%s(%s)': Ending session due to RFC5407 race condition. %s\n",
+ ast_sorcery_object_get_id(session->endpoint),
+ session->channel ? ast_channel_name(session->channel) : "",
+ pjsip_rx_data_get_info(e->body.tsx_state.src.rdata));
ast_sip_session_send_request(session, tdata);
}
}