res_pjsip_pubsub: Set the endpoint on SUBSCRIBE dialogs.
authorMark Michelson <>
Mon, 20 Apr 2015 19:30:47 +0000 (14:30 -0500)
committerJoshua Colp <>
Tue, 21 Apr 2015 10:01:58 +0000 (05:01 -0500)
When SUBSCRIBE dialogs were established, we never associated
the endpoint that created the subscription with the dialog
we end up creating. In most cases, this ended up not causing
any problems.

The actual bug that was observed was that when a device that
was behind NAT established a subscription with Asterisk, Asterisk
would end up sending in-dialog NOTIFY requests to the device's
private IP addres instead of the public address of the NAT router.

When Asterisk receives the initial SUBSCRIBE from the device,
res_pjsip_nat rewrites the contact to the public address on which the
SUBSCRIBE was received. This allows for the dialog to have its target
address set to the proper public address. Asterisk then would send a 200
OK response to the SUBSCRIBE, then a NOTIFY with the initial
subscription state. The device would then send a 200 OK response to
Asterisk's NOTIFY.

Here's where things went wrong. When the 200 OK arrived, res_pjsip_nat
did not rewrite the address in the Contact header. Then, when the PJSIP
dialog layer processed the 200 OK, PJSIP would perform a comparison
between the IP address in the Contact header and its saved target
address for the dialog. Since they differed, PJSIP would update the
target dialog address to be the address in the Contact header. From this
point, if Asterisk needed to send a NOTIFY to the device, the result was
that the NOTIFY would be sent to the private address that the device
placed in the Contact header.

The reason why res_pjsip_nat did not rewrite the address when it
received the 200 OK response was that it could not associate the
incoming response with a configured endpoint. This is because on a
response, the only way to associate the response to an endpoint is by
finding the dialog that the response is associated with and then finding
the endpoint that is associated with that dialog. We do not perform
endpoint lookups on responses. res_pjsip_pubsub skipped the step of
associating the endpoint with the dialog we created, so res_pjsip_nat
could not find the associated endpoint and therefore couldn't rewrite
the contact.

This commit message is like 50x longer than the actual fix.

ASTERISK 24981 #close
Reported by Mark Michelson

Change-Id: I2b963c58c063bae293e038406f7d044a8a5377cd


index e7b4b02..b209b86 100644 (file)
@@ -1019,6 +1019,7 @@ static int subscription_remove_serializer(void *obj)
         * remove the serializer will be successful.
        ast_sip_dialog_set_serializer(sub_tree->dlg, NULL);
+       ast_sip_dialog_set_endpoint(sub_tree->dlg, NULL);
        pjsip_dlg_dec_session(sub_tree->dlg, &pubsub_module);
        return 0;
@@ -1188,6 +1189,7 @@ static void subscription_setup_dialog(struct sip_subscription_tree *sub_tree, pj
        pjsip_dlg_inc_session(dlg, &pubsub_module);
        sub_tree->dlg = dlg;
        ast_sip_dialog_set_serializer(dlg, sub_tree->serializer);
+       ast_sip_dialog_set_endpoint(dlg, sub_tree->endpoint);
        pjsip_evsub_set_mod_data(sub_tree->evsub,, sub_tree);