summaryrefslogtreecommitdiff
path: root/res/res_pjsip_nat.c
diff options
context:
space:
mode:
authorKinsey Moore <kmoore@digium.com>2014-01-31 15:08:49 +0000
committerKinsey Moore <kmoore@digium.com>2014-01-31 15:08:49 +0000
commitd5431ed358d8e661bdb0ca7608636059f8679af8 (patch)
tree3878ea295caed099606cc5db4f45f521c9ee2502 /res/res_pjsip_nat.c
parente8eb6a9e30afb3dcffe6a0c1821ffc8b0fe380c6 (diff)
PJSIP: Fix address for ACK in NAT situations
In NAT scenarios where a call is placed to a Grandstream phone, res_pjsip will sometimes send the ACK to a 200 OK to the private address of the device behind the NAT instead of the address of the NAT device. This corrects that behavior by rewriting the address in the Contact header in the incoming 200 OK and the dialog's target address if necessary (since it has already been rewritten to the incorrect private address). (closes issue ASTERISK-23106) Review: https://reviewboard.asterisk.org/r/3168/ Reported by: Matt Jordan ........ Merged revisions 407000 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@407001 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_nat.c')
-rw-r--r--res/res_pjsip_nat.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c
index 092ff008b..30dae2b29 100644
--- a/res/res_pjsip_nat.c
+++ b/res/res_pjsip_nat.c
@@ -32,9 +32,8 @@
#include "asterisk/module.h"
#include "asterisk/acl.h"
-static pj_bool_t nat_on_rx_message(pjsip_rx_data *rdata)
+static pj_bool_t handle_rx_message(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
{
- RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
pjsip_contact_hdr *contact;
if (!endpoint) {
@@ -44,9 +43,17 @@ static pj_bool_t nat_on_rx_message(pjsip_rx_data *rdata)
if (endpoint->nat.rewrite_contact && (contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) &&
!contact->star && (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);
+ pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
pj_cstr(&uri->host, rdata->pkt_info.src_name);
uri->port = rdata->pkt_info.src_port;
+
+ /* rewrite the session target since it may have already been pulled from the contact header */
+ if (dlg && (!dlg->remote.contact
+ || pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, dlg->remote.contact->uri, contact->uri))) {
+ dlg->remote.contact = (pjsip_contact_hdr*)pjsip_hdr_clone(dlg->pool, contact);
+ dlg->target = dlg->remote.contact->uri;
+ }
}
if (endpoint->nat.force_rport) {
@@ -56,6 +63,12 @@ static pj_bool_t nat_on_rx_message(pjsip_rx_data *rdata)
return PJ_FALSE;
}
+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);
+ return handle_rx_message(endpoint, rdata);
+}
+
/*! \brief Structure which contains information about a transport */
struct request_transport_details {
/*! \brief Type of transport */
@@ -230,6 +243,12 @@ static int nat_incoming_invite_request(struct ast_sip_session *session, struct p
return 0;
}
+/*! \brief Function called when an INVITE response comes in */
+static void nat_incoming_invite_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+ handle_rx_message(session->endpoint, rdata);
+}
+
/*! \brief Function called when an INVITE comes in */
static void nat_outgoing_invite_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
{
@@ -244,6 +263,7 @@ static struct ast_sip_session_supplement nat_supplement = {
.priority = AST_SIP_SUPPLEMENT_PRIORITY_FIRST + 1,
.incoming_request = nat_incoming_invite_request,
.outgoing_request = nat_outgoing_invite_request,
+ .incoming_response = nat_incoming_invite_response,
};