From 05a2cc129396df9d75d1dbafc040eca117f982ba Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Fri, 26 Jun 2015 10:41:05 -0500 Subject: res_pjsip_refer: Prevent sending duplicate headers. res_pjsip_refer will attempt to add Referred-By or Replaces headers to outbound INVITEs at times. If the INVITE gets challenged for authentication, then we will resend the INVITE. Prior to this patch, the Referred-By or Replaces header would be re-added to the outbound INVITE, resulting in duplicated headers. ASTERISK-25204 #close Reported by Mark Michelson Change-Id: I59fb5c08b4d253c0dba9ee3d3950b5025358222d --- res/res_pjsip_refer.c | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c index 5195177d5..4896a00e8 100644 --- a/res/res_pjsip_refer.c +++ b/res/res_pjsip_refer.c @@ -1087,10 +1087,41 @@ static int refer_incoming_request(struct ast_sip_session *session, pjsip_rx_data } } -static void refer_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata) +/*! + * \brief Use the value of a channel variable as the value of a SIP header + * + * This looks up a variable name on a channel, then takes that value and adds + * it to an outgoing SIP request. If the header already exists on the message, + * then no action is taken. + * + * \pre chan is locked. + * + * \param chan The channel on which to find the variable. + * \param var_name The name of the channel variable to use. + * \param header_name The name of the SIP header to add to the outgoing message. + * \param tdata The outgoing SIP message on which to add the header + */ +static void add_header_from_channel_var(struct ast_channel *chan, const char *var_name, const char *header_name, pjsip_tx_data *tdata) { - const char *hdr; + const char *var_value; + pj_str_t pj_header_name; + pjsip_hdr *header; + + var_value = pbx_builtin_getvar_helper(chan, var_name); + if (ast_strlen_zero(var_value)) { + return; + } + pj_cstr(&pj_header_name, header_name); + header = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_header_name, NULL); + if (header) { + return; + } + ast_sip_add_header(tdata, header_name, var_value); +} + +static void refer_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata) +{ if (pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_invite_method) || !session->channel || session->inv_session->state != PJSIP_INV_STATE_NULL) { @@ -1098,15 +1129,8 @@ static void refer_outgoing_request(struct ast_sip_session *session, struct pjsip } ast_channel_lock(session->channel); - hdr = pbx_builtin_getvar_helper(session->channel, "SIPREPLACESHDR"); - if (!ast_strlen_zero(hdr)) { - ast_sip_add_header(tdata, "Replaces", hdr); - } - - hdr = pbx_builtin_getvar_helper(session->channel, "SIPREFERREDBYHDR"); - if (!ast_strlen_zero(hdr)) { - ast_sip_add_header(tdata, "Referred-By", hdr); - } + add_header_from_channel_var(session->channel, "SIPREPLACESHDR", "Replaces", tdata); + add_header_from_channel_var(session->channel, "SIPREFERREDBYHDR", "Referred-By", tdata); ast_channel_unlock(session->channel); } -- cgit v1.2.3