Re: [asterisk-dev] Wrong IP-address in SDP when on NAT in challenged Invite

2021-05-07 Thread Michael Maier


On 07.05.21 at 00:12 Michael Maier wrote:

Hello Joshua,

On 06.05.21 at 20:21 Joshua C. Colp wrote:

On Wed, May 5, 2021 at 4:40 PM Michael Maier  wrote:


Hello!

When running asterisk on a system holding WAN and local IP, the IP used
for SDP in an outgoing call in the challenged INVITE is the local one
instead of the WAN IP when using a NATed transport instead of a
transport bound to the WAN IP.

The SDP in the initial INVITE is absolutely correct. But the following
Invite with the Auth header contains the wrong IP in SDP (the IP in the
SIP Contact and Via header are correct).

After digging in the code, I could see, that in
session_outgoing_nat_hook (res_pjsip_session.c) the nat rewrite is
stopped, because of an existing hook (I figured it out by some
additional debug outputs):

 /* SDP produced by us directly will never be multipart */
 if (!transport_state || hook || !tdata->msg->body ||

!ast_sip_is_content_type(>msg->body->content_type, "application",
"sdp") ||
 ast_strlen_zero(transport->external_media_address)) {
 return;
 }



[...]


The only thing that comes to mind is the code in
res/res_pjsip/pjsip_message_filter.c that alters the SDP in some scenario
to update it for the transport the message is going out on.


True - there is a dedicated function checking for multihomed
environments. Maybe this one changes back the IP (not tested though).
Meanwhile I modified the above check for aborting the nat rewrite this
way, that the check for an existing hook follows after the execution of
the NAT rewrite. Now, it's working.

Another question follows now, which is firewall related: At which point
exactly starts asterisk to send outgoing RTP?


Problem disappeared after restarting of asterisk. This happened quite often unfortunately, that restart solved strange behavior after doing reloads in consequence of doing changes in FreePBX - 
even if they are not transport related.


The DNAT rules are needed anyway, but now it's possible to add a established 
INPUT rule, so things are working as expected.

Finally I can say, that I got it working after applying two patches to 
correctly get NAT working on a multihomed server (including WAN IPv4):


res/res_pjsip_nat.c @find_transport_state_in_use

if (transport_state && ((details->transport && details->transport == 
transport_state->transport) ||
(details->factory && details->factory == 
transport_state->factory) ||
((details->type == transport_state->type) && (transport_state->factory) 
&&
!pj_strcmp(_state->factory->addr_name.host, 
>local_address) &&
-   transport_state->factory->addr_name.port == 
details->local_port))) {
+   (transport_state->factory->addr_name.port == 
details->local_port || transport_state->factory->addr_name.port == 0 {
return CMP_MATCH;
}

=> This ensures, that transports used as client can be found, too if they can't 
be directly found.

This patch solves the problem, that the ACK sent by asterisk after a received 
407 during INVITE sequence gets the correct IP in the Via header.


The second patch is needed to ensure, that the INVITE after the 407 containing 
the auth header gets the correct IP (= WAN) in the SDP:

res/res_pjsip_session.c session_outgoing_nat_hook(pj

/* SDP produced by us directly will never be multipart */
-   if (!transport_state || hook || !tdata->msg->body ||
+   if (!transport_state || !tdata->msg->body ||
!ast_sip_is_content_type(>msg->body->content_type, "application", 
"sdp") ||
ast_strlen_zero(transport->external_media_address)) {
return;
}


Move the check for the hook after executing the NAT functionality:

@@ -5492,6 +5512,12 @@ static void session_outgoing_nat_hook(pj
}
}

+   /* There is a hook - don't do it again */
+   if (hook) {
+   ast_debug(5, "stop - hook\n");
+   return;
+   }
+
for (stream = 0; stream < sdp->media_count; ++stream) {
/* See if there are registered handlers for this media stream 
type */
char media[20];


If there are others having problems during NAT they may try those patches. I know of at least one provider which doesn't care about those errors, but there are others which care and therefore 
calls are failing.


Some more information:
It's important to add to *all* transports the following parameters:

external_media_address=external.mydom.org
external_signaling_address=external.mydom.org
local_net=192.168.0.0/16 or whatever you need

I enabled dnsmgr, which should take care of always correct WAN IP via periodic 
lookups of external.mydom.org. But not yet tested, if it finally works (if the 
WAN IP changed).

That's finally the reason I'm trying to use NAT because this way I can bind asterisk to a static local IP 

Re: [asterisk-dev] Wrong IP-address in SDP when on NAT in challenged Invite

2021-05-07 Thread Joshua C. Colp
On Thu, May 6, 2021 at 7:12 PM Michael Maier  wrote:



Another question follows now, which is firewall related: At which point
> exactly starts asterisk to send outgoing RTP?
>
> Why am I asking? Given is an outbound call e.g. Portfilter opens
> incoming port as soon as it has seen an outgoing packet. If there is no
> outgoing RTP, the incoming RTP packages will be dropped because
> portfilter doesn't know what to do with them (no conntrack information
> there).
>
> After applying a DNAT-rule, things are working fine - but that's not a
> good solution.
>
> Now I'm wondering why asterisk doesn't always start sending RTP after a
> 200 OK sdp (or an any other arbitrary SDP) containing a=sendrecv and
> correct media and dest port.
>
> Sometimes asterisk begins to send RTP not until it receives RTP from
> Callee - though the Caller already sends RTP - therefore there is no
> reason to not send anything. I'm quite puzzled.
>
> This behavior is 100% reproducible for certain numbers.
>
>
> Do you by chance have any idea?
>

As soon as Asterisk has received media and the media has gotten past strict
RTP protection, it should then forward that media outward to the target in
the SDP. RTP debug and core debug shows when this is happening.

--
Joshua C. Colp
Asterisk Technical Lead
Sangoma Technologies
Check us out at www.sangoma.com and www.asterisk.org
-- 
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Re: [asterisk-dev] Wrong IP-address in SDP when on NAT in challenged Invite

2021-05-06 Thread Michael Maier
Hello Joshua,

On 06.05.21 at 20:21 Joshua C. Colp wrote:
> On Wed, May 5, 2021 at 4:40 PM Michael Maier  wrote:
> 
>> Hello!
>>
>> When running asterisk on a system holding WAN and local IP, the IP used
>> for SDP in an outgoing call in the challenged INVITE is the local one
>> instead of the WAN IP when using a NATed transport instead of a
>> transport bound to the WAN IP.
>>
>> The SDP in the initial INVITE is absolutely correct. But the following
>> Invite with the Auth header contains the wrong IP in SDP (the IP in the
>> SIP Contact and Via header are correct).
>>
>> After digging in the code, I could see, that in
>> session_outgoing_nat_hook (res_pjsip_session.c) the nat rewrite is
>> stopped, because of an existing hook (I figured it out by some
>> additional debug outputs):
>>
>> /* SDP produced by us directly will never be multipart */
>> if (!transport_state || hook || !tdata->msg->body ||
>>
>> !ast_sip_is_content_type(>msg->body->content_type, "application",
>> "sdp") ||
>> ast_strlen_zero(transport->external_media_address)) {
>> return;
>> }
>>

[...]

> The only thing that comes to mind is the code in
> res/res_pjsip/pjsip_message_filter.c that alters the SDP in some scenario
> to update it for the transport the message is going out on.

True - there is a dedicated function checking for multihomed
environments. Maybe this one changes back the IP (not tested though).
Meanwhile I modified the above check for aborting the nat rewrite this
way, that the check for an existing hook follows after the execution of
the NAT rewrite. Now, it's working.

Another question follows now, which is firewall related: At which point
exactly starts asterisk to send outgoing RTP?

Why am I asking? Given is an outbound call e.g. Portfilter opens
incoming port as soon as it has seen an outgoing packet. If there is no
outgoing RTP, the incoming RTP packages will be dropped because
portfilter doesn't know what to do with them (no conntrack information
there).

After applying a DNAT-rule, things are working fine - but that's not a
good solution.

Now I'm wondering why asterisk doesn't always start sending RTP after a
200 OK sdp (or an any other arbitrary SDP) containing a=sendrecv and
correct media and dest port.

Sometimes asterisk begins to send RTP not until it receives RTP from
Callee - though the Caller already sends RTP - therefore there is no
reason to not send anything. I'm quite puzzled.

This behavior is 100% reproducible for certain numbers.


Do you by chance have any idea?


Thanks
Michael

-- 
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Re: [asterisk-dev] Wrong IP-address in SDP when on NAT in challenged Invite

2021-05-06 Thread Joshua C. Colp
On Wed, May 5, 2021 at 4:40 PM Michael Maier  wrote:

> Hello!
>
> When running asterisk on a system holding WAN and local IP, the IP used
> for SDP in an outgoing call in the challenged INVITE is the local one
> instead of the WAN IP when using a NATed transport instead of a
> transport bound to the WAN IP.
>
> The SDP in the initial INVITE is absolutely correct. But the following
> Invite with the Auth header contains the wrong IP in SDP (the IP in the
> SIP Contact and Via header are correct).
>
> After digging in the code, I could see, that in
> session_outgoing_nat_hook (res_pjsip_session.c) the nat rewrite is
> stopped, because of an existing hook (I figured it out by some
> additional debug outputs):
>
> /* SDP produced by us directly will never be multipart */
> if (!transport_state || hook || !tdata->msg->body ||
>
> !ast_sip_is_content_type(>msg->body->content_type, "application",
> "sdp") ||
> ast_strlen_zero(transport->external_media_address)) {
> return;
> }
>
> The same behavior can be seen on the system which doesn't contain a
> global IP - but the outgoing SDP IP is still correct here.
>
> I'm wondering now, why the IP in the first case is wrong and in the
> second case ok? What changes the IP? I couldn't find any point in
> Asterisk. I'm suspecting pjsip changes something under the hood?
>
> Would be glad if somebody could shed some light on this strange
> behavior. Maybe an idea where to look at.
>

The only thing that comes to mind is the code in
res/res_pjsip/pjsip_message_filter.c that alters the SDP in some scenario
to update it for the transport the message is going out on.

-- 
Joshua C. Colp
Asterisk Technical Lead
Sangoma Technologies
Check us out at www.sangoma.com and www.asterisk.org
-- 
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev