summaryrefslogtreecommitdiff
path: root/res/res_pjsip.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2015-03-27 20:46:55 +0000
committerMark Michelson <mmichelson@digium.com>2015-03-27 20:46:55 +0000
commit0b62e416541066c53088013fc99a0775f9b318e3 (patch)
tree94c712348790ee066a10e152c904f40b1d8cb320 /res/res_pjsip.c
parenta18da4eaf20223b0d20754dc51f769da53909fdb (diff)
Add stateful PJSIP response API call, and use it for out-of-dialog responses.
Asterisk had an issue where retransmissions of MESSAGE requests resulted in Asterisk processing the retransmission as if it were a new MESSAGE request. This patch fixes the issue by creating a transaction in PJSIP on the incoming request. This way, if a retransmission arrives, the PJSIP transaction layer will resend the response and Asterisk will not ever see the retransmission. ASTERISK-24920 #close Reported by Mark Michelson Review: https://reviewboard.asterisk.org/r/4532/ ........ Merged revisions 433619 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@433620 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip.c')
-rw-r--r--res/res_pjsip.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index e5af28ca8..64cd43e18 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -3298,7 +3298,7 @@ static pj_bool_t supplement_on_rx_request(pjsip_rx_data *rdata)
return PJ_FALSE;
}
-int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
+static void supplement_outgoing_response(pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
{
struct ast_sip_supplement *supplement;
pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
@@ -3306,8 +3306,7 @@ int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, s
AST_RWLIST_RDLOCK(&supplements);
AST_LIST_TRAVERSE(&supplements, supplement, next) {
- if (supplement->outgoing_response
- && does_method_match(&cseq->method.name, supplement->method)) {
+ if (supplement->outgoing_response && does_method_match(&cseq->method.name, supplement->method)) {
supplement->outgoing_response(sip_endpoint, contact, tdata);
}
}
@@ -3315,10 +3314,35 @@ int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, s
ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
ao2_cleanup(contact);
+}
+
+int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
+{
+ supplement_outgoing_response(tdata, sip_endpoint);
return pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), res_addr, tdata, NULL, NULL);
}
+int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
+{
+ pjsip_transaction *tsx;
+
+ if (pjsip_tsx_create_uas(NULL, rdata, &tsx) != PJ_SUCCESS) {
+ pjsip_tx_data_dec_ref(tdata);
+ return -1;
+ }
+ pjsip_tsx_recv_msg(tsx, rdata);
+
+ supplement_outgoing_response(tdata, sip_endpoint);
+
+ if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
+ pjsip_tx_data_dec_ref(tdata);
+ return -1;
+ }
+
+ return 0;
+}
+
int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code,
struct ast_sip_contact *contact, pjsip_tx_data **tdata)
{