From 9deb416397ff8df1fe9a4bd13da88c7bb6002db8 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Fri, 13 Sep 2013 14:50:38 +0000 Subject: [PATCH] Create more accurate Contact headers for dialogs when we are the UAS. (closes issue AST-1207) reported by John Bigelow Review: https://reviewboard.asterisk.org/r/2842 ........ Merged revisions 399083 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@399084 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/res_pjsip.h | 12 ++++++++++-- res/res_pjsip.c | 34 +++++++++++++++++++++++++++++++++- res/res_pjsip.exports.in | 3 ++- res/res_pjsip_pubsub.c | 4 ++-- res/res_pjsip_session.c | 5 +++-- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index d25a1d4fdd..df4ba7decb 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -1188,7 +1188,7 @@ struct ast_sip_body { }; /*! - * \brief General purpose method for creating a dialog with an endpoint + * \brief General purpose method for creating a UAC dialog with an endpoint * * \param endpoint A pointer to the endpoint * \param aor_name Optional name of the AOR to target, may even be an explicit SIP URI @@ -1197,7 +1197,15 @@ struct ast_sip_body { * \retval non-NULL success * \retval NULL failure */ - pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *aor_name, const char *request_user); +pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *aor_name, const char *request_user); + +/*! + * \brief General purpose method for creating a UAS dialog with an endpoint + * + * \param endpoint A pointer to the endpoint + * \param rdata The request that is starting the dialog + */ +pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata); /*! * \brief General purpose method for creating a SIP request diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 2af6a331b2..d579d0cbdb 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1324,7 +1324,7 @@ static int sip_get_tpselector_from_uri(const char *uri, pjsip_tpselector *select return 0; } -pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user) +pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user) { pj_str_t local_uri = { "sip:temp@temp", 13 }, remote_uri; pjsip_dialog *dlg = NULL; @@ -1386,6 +1386,38 @@ pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, con return dlg; } +pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata) +{ + pjsip_dialog *dlg; + pj_str_t contact; + pjsip_transport_type_e type = rdata->tp_info.transport->key.type; + pj_status_t status; + + contact.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE); + contact.slen = pj_ansi_snprintf(contact.ptr, PJSIP_MAX_URL_SIZE, + "<%s:%s%.*s%s:%d%s%s>", + (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip", + (type & PJSIP_TRANSPORT_IPV6) ? "[" : "", + (int)rdata->tp_info.transport->local_name.host.slen, + rdata->tp_info.transport->local_name.host.ptr, + (type & PJSIP_TRANSPORT_IPV6) ? "]" : "", + rdata->tp_info.transport->local_name.port, + (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "", + (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : ""); + + status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg); + if (status != PJ_SUCCESS) { + char err[PJ_ERR_MSG_SIZE]; + + pjsip_strerror(status, err, sizeof(err)); + ast_log(LOG_ERROR, "Could not create dialog with endpoint %s. %s\n", + ast_sorcery_object_get_id(endpoint), err); + return NULL; + } + + return dlg; +} + /* PJSIP doesn't know about the INFO method, so we have to define it ourselves */ static const pjsip_method info_method = {PJSIP_OTHER_METHOD, {"INFO", 4} }; static const pjsip_method message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7} }; diff --git a/res/res_pjsip.exports.in b/res/res_pjsip.exports.in index f3b4f0eece..a4b23bc7e4 100644 --- a/res/res_pjsip.exports.in +++ b/res/res_pjsip.exports.in @@ -32,7 +32,8 @@ LINKER_SYMBOL_PREFIXast_sip_get_endpoints; LINKER_SYMBOL_PREFIXast_copy_pj_str; LINKER_SYMBOL_PREFIXast_sip_get_sorcery; - LINKER_SYMBOL_PREFIXast_sip_create_dialog; + LINKER_SYMBOL_PREFIXast_sip_create_dialog_uac; + LINKER_SYMBOL_PREFIXast_sip_create_dialog_uas; LINKER_SYMBOL_PREFIXast_sip_location_retrieve_aor; LINKER_SYMBOL_PREFIXast_sip_location_retrieve_first_aor_contact; LINKER_SYMBOL_PREFIXast_sip_location_retrieve_contact_from_aor_list; diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index ecc0059964..4daacd42c3 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -282,7 +282,7 @@ struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_su } sub->role = role; if (role == AST_SIP_NOTIFIER) { - pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg); + dlg = ast_sip_create_dialog_uas(endpoint, rdata); } else { RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup); @@ -293,7 +293,7 @@ struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_su ao2_ref(sub, -1); return NULL; } - dlg = ast_sip_create_dialog(endpoint, contact->uri, NULL); + dlg = ast_sip_create_dialog_uac(endpoint, contact->uri, NULL); } if (!dlg) { ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n"); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 226e43f3ea..c6c3953610 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -1185,7 +1185,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint return NULL; } - if (!(dlg = ast_sip_create_dialog(endpoint, uri, request_user))) { + if (!(dlg = ast_sip_create_dialog_uac(endpoint, uri, request_user))) { return NULL; } @@ -1337,7 +1337,8 @@ static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct a } return NULL; } - if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg) != PJ_SUCCESS) { + dlg = ast_sip_create_dialog_uas(endpoint, rdata); + if (!dlg) { pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL); return NULL; }