From 4d760694b21b317c36aed48a5025ace9dc561fd3 Mon Sep 17 00:00:00 2001 From: Joshua Colp Date: Mon, 9 Dec 2013 16:41:43 +0000 Subject: res_pjsip_nat: Add NAT module to session dialogs. Due to the way pjproject internally works it was possible for the NAT module to not be invoked on messages with-in a session dialog. This means that the various parts of the message would not get rewritten with the source IP address and port. This change uses a session supplement to add the NAT module to the dialog on the first incoming or outgoing INVITE. (closes issue ASTERISK-22941) Reported by: Leif Madsen ........ Merged revisions 403510 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403511 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/res_pjsip_nat.c | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) (limited to 'res') diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c index d04505107..9a3f500b9 100644 --- a/res/res_pjsip_nat.c +++ b/res/res_pjsip_nat.c @@ -28,10 +28,11 @@ #include #include "asterisk/res_pjsip.h" +#include "asterisk/res_pjsip_session.h" #include "asterisk/module.h" #include "asterisk/acl.h" -static pj_bool_t nat_on_rx_request(pjsip_rx_data *rdata) +static pj_bool_t nat_on_rx_message(pjsip_rx_data *rdata) { RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup); pjsip_contact_hdr *contact; @@ -213,23 +214,62 @@ static pjsip_module nat_module = { .name = { "NAT", 3 }, .id = -1, .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 2, - .on_rx_request = nat_on_rx_request, + .on_rx_request = nat_on_rx_message, + .on_rx_response = nat_on_rx_message, .on_tx_request = nat_on_tx_message, .on_tx_response = nat_on_tx_message, }; -static int load_module(void) +/*! \brief Function called when an INVITE goes out */ +static int nat_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata) { - ast_sip_register_service(&nat_module); - return AST_MODULE_LOAD_SUCCESS; + if (session->inv_session->state == PJSIP_INV_STATE_INCOMING) { + pjsip_dlg_add_usage(session->inv_session->dlg, &nat_module, NULL); + } + + return 0; } +/*! \brief Function called when an INVITE comes in */ +static void nat_outgoing_invite_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata) +{ + if (session->inv_session->state == PJSIP_INV_STATE_NULL) { + pjsip_dlg_add_usage(session->inv_session->dlg, &nat_module, NULL); + } +} + +/*! \brief Supplement for adding NAT functionality to dialog */ +static struct ast_sip_session_supplement nat_supplement = { + .method = "INVITE", + .priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_FIRST + 1, + .incoming_request = nat_incoming_invite_request, + .outgoing_request = nat_outgoing_invite_request, +}; + + static int unload_module(void) { + ast_sip_session_unregister_supplement(&nat_supplement); ast_sip_unregister_service(&nat_module); return 0; } +static int load_module(void) +{ + if (ast_sip_register_service(&nat_module)) { + ast_log(LOG_ERROR, "Could not register NAT module for incoming and outgoing requests\n"); + return AST_MODULE_LOAD_FAILURE; + } + + if (ast_sip_session_register_supplement(&nat_supplement)) { + ast_log(LOG_ERROR, "Could not register NAT session supplement for incoming and outgoing INVITE requests\n"); + unload_module(); + return AST_MODULE_LOAD_FAILURE; + } + + return AST_MODULE_LOAD_SUCCESS; +} + AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP NAT Support", .load = load_module, .unload = unload_module, -- cgit v1.2.3