Call redirection: no audio depending on target number

My setup is as follows:

  • Asterisk 13.38.1 (PJSIP) behind a router
  • SIP from Telekom Germany
  • IP desk phone (Snom D375) connected to the Asterisk that does call forwarding

In certain cases, call forwarding does not work: the call is signalled as successfully established, but no audio is transferred.
This depends on to which (public) number number the call is forwarded.

I did a packet trace, here you can see the (quite different) course of actions between the Asterisk (0.0.0.0) and the public telephony gateway of Telekom Germany:

On the left hand side, you see the working case, on the right hand side there is the non-working case.

Target numbers where call forwarding does work:

  • Mobile number from T-Mobile Germany
  • A PBX working at a real ISDN PtP line from vodafone Germany

Target numbers where call forwarding does not work:

  • SIP number of sipgate
  • PBX behind a SIP trunk provider (Deutsche Telefon Standard)
  • Telekom Germany’s customer hotline (0800/3301000)

I can further tell that:

  • Regular calls between the Asterisk and all affected numbers work totally fine
  • Actually, no RTP packets are sent in the non-working case. On my router’s WAN interface, no packets are received and on the LAN interface, no packets are transferred by Asterisk either
  • Setting strictrtp=no in rtp.conf didn’t make any difference

When reading what Asterisk prints on the CLI, I found out that the following happens in the working case:

Channel PJSIP/OriginatingCall joined 'simple_bridge' basic-bridge <ONE>
Channel Local/CallForwardTarget;2 joined 'simple_bridge' basic-bridge <ONE>

Channel Local/CallForwardTarget;1 joined 'simple_bridge' basic-bridge <TWO>
Channel PJSIP/IncomingCall joined 'simple_bridge' basic-bridge <TWO>

> Strict RTP switching to RTP target address (...) as source
> Move-swap optimizing Local/CallForwardTarget;2 <-- PJSIP/IncomingCall

Channel PJSIP/IncomingCall left 'simple_bridge' basic-bridge <TWO>
Channel Local/CallForwardTarget;2 left 'simple_bridge' basic-bridge <ONE>
Channel PJSIP/IncomingCall swapped with Local/CallForwardTarget;2 into 'simple_bridge' basic-bridge <ONE>
Channel Local/CallForwardTarget;1 left 'simple_bridge' basic-bridge <TWO>

So, Asterisk has first the two calls in two bridges and then swaps the members of the bridges so that only one bridge is used, connecting the PJSIP channel from the incoming and the outgoing call, which makes sense to me.

However, in the non-working case, this does not happen.

Sometimes, as you can also tell by the call flow screen shot, the call is terminated actively by the Asterisk. Sadly, in the CLI, now reason is given.

So, as far as I can tell, there does not seem to be a networking (i.e. routing, firewall, NAT) problem, but a “logical” problem. It seems as if both sides seem to wait for each other to do something, maybe sending the first RTP packet?

Does anyone know that problem?
What can I do to further trace that problem down?

You wrote a lot, but the info that is required to help you is missing.

First, German Telekom is selling different VoIP products. It makes a difference whether you are using an ALL-IP or a SIP-Trunk product. Your problem description points into a different direction, though.

In order to nail down the problem one would need the complete log files and pcap traces for the failing and non-failing cases.

You might need to also capture the signalling on the WAN side of your router, especially if you are using a consumer router like a FritzBox.

Asterisk has no problems with call forwarding. It’s probably a configuration problem. In case it is the router, you may or may not be able to solve it.

Thanks for your reply.
It is a consumer DSL contract with included SIP numbers (no SIP trunk). I don’t know what their marketing term for this kind of product currently is. It has been marketed as “AllIP” for quite some time.

The Asterisk indeed is behind a Fritzbox (7490, FritzOS 7.21).
In an upcoming post, I will provide

  • Asterisk log file
  • trace LAN side
  • trace WAN side

both for working and non-working case, of course.

I have the traces ready. Which tooling can I use to anonymize them?

Do not use Asterisk behind a FritzBox, or you’ll regret it. The plastic router has its own little PBX, which is actually not that bad.

Actually, the Asterisk was introduced because the internal PBX of the Fritzbox lacked too much features. And it works reliable and stable since ~six years now. This call forwarding problem is actually the real first “issue” this installation has.

Especially because of this I’m afraid that “We have to buy another router because the Fritzbox does not work well” will be seen as an insufficient argument, at least as far as I am not able to provide details :slight_smile:

As soon as I know how to anonymize the LAN/WAN-traces, I will provide them here.
For now, I can provide Asterisk’s FULL log with high verbosity:
asterisk-log.txt (14.9 KB)

Some findings when looking at the traces:
In the failing case, the Asterisk tends to end the call, giving reasn Q.850;cause=41.

As far as I can tell, especially in the failing case, all SIP messages for the calls sent inside the LAN are sent out via WAN and all messages received from the WAN side are sent to the Asterisk.

Telling from the SDP part the Telekom gateway sends (in both cases from the same IP), when forwarding to a “failing” number, the SDP looks a bit different than in the working case. In the working case, the SDP session is named "-" while in the failing case, it is named "TELES-SBC". So it looks like internally in both cases the calls are processed by different systems on Telekom side.

You seem to have some non-trivial dialplan; we’ll need that as well.

People redact traces using a text editor. I don’t know of any specific tools.

You do have a syntax error in your dialplan. Please check for the correct PJSIP channel specification, when the forwarded call enters the dialplan again.

You only need to buy a router that is useful. You will see later what the real problems with your setup are…

Thank you for your replies.

First of all, another finding:
When I add an Answer() to my outgoing call context, just to see what happens, audio works in the failing case.

I further provide the traces. Each captured on the LAN and also the WAN side of the Fritzbox.
In the failing case:

failing-lan.txt (155.0 KB)
failing-wan.txt (169.5 KB)

And the working case:
working-lan.txt (134.8 KB)
working-wan.txt (146.2 KB)
I also provide the part from the dialplan, as requested.
Regarding the PJSIP syntax error:

In the context for outgoing calls, I have a check that reads the PJSIP Privacy header from the calling channel (i.e. a SIP desk phone) to eventually add that header also to the outgoing call to indicate CLIR.

When the forwarded call is made, this is of course of channeltype Local, so that querying a PJSIP header leads to a syntax error. In the meantime, I fixed it by additionally checking the channeltype. The error is gone now.

extensions_excerpt.conf.txt (2.4 KB)

I suspect one destination is using comedia to work round the incorrect media address in your response and the other isn’t.

You are using a NAT router, but you have not told Asterisk what its public signalling and media addresses are. It is therefore sending 192.168… in both the Contact header and the c line in the SDP, when it should be sending its public address.

Note that the above is based on the first two messages on the inbound leg. I didn’t get around to looking at the outbound leg (there is too much noise from wireshark), but things were already going badly by the second packet.

Ernsthaft? Do you really think someone will read 600 KB? Your friend is pjsip set logger on.

My remark referred to something I saw in your original posting. Setting the privacy header manually cannot be the problem.

My original posting had nothing in it regarding an error message. I assume you refer to asterisk-log.txt I posted later-on.
In this file you can see errors like this one:

[Mar 16 14:54:17] ERROR[26232][C-00000037] res_pjsip_header_funcs.c: This function requires a PJSIP channel.

The problem indeed is not setting the header, but reading it from the calling channel. As I explained above, I had the error in a dialplan that it executed PJSIP_HEADER(read,Privacy) unconditionally. This does not work when Asterisk places the outgoing call to the redirect target, since the originating channeltype is Local then (as one can also tell from the surrounding lines of asterisk-log.txt.

Regarding size of the logs:

“Complete pcap traces” were requested. I got no hint (neither here nor did I find any usable tooling via googling) of how to anonymize pcap trace files.
I did try editing the pcap file using a text editor (Sublime Text), but after saving it and opening the edited file using Wireshark, it immediately told me that the file is not a pcap file.
So, I did export the pcap data using Wireshark’s “Export Packet Dissections” function and then using a text editor to redact it.

The trace data is already as narrowed down as possible.
The SIP flow screenshot being part of my first post in this thread is actually generated by Wireshark, showing only the call to the redirect target. In the working case, there are 17 packets.
As complete data was requested, I traced the complete flow, so the incoming call that is going to be forwarded is now also included.
@david551: With “too much noise”, do you mean “too much packets” or “text output too verbose”?
You can easily cycle through the packets and immediately jump to the more SIP-payloady parts when you just search for the term “Message Header”.
One can also get more overview when opening in a diff tool (WinMerge, Meld, Kaleidoscope), which will automatically highlight the differences in the traces. There aren’t that much differences actually, especially when you neglect different CallIDs, branch IDs, etc. for two different calls.
The trace text files contain ~20-30 packets. As the files also contain meta information like a packet enumeration headed by "No. ", I did a crosscheck comparing the number of occurrences of "No. " and “Message Header”, both having the same count in all files.

I tested that and did set external_media_address to my public IP for the transport. That did not help.

Now, here are also logs written by using pjsip set logger on for both the failing and the working cases.
pjsip-log-failing.txt (23.0 KB)
pjsip-log-working.txt (19.3 KB)

I hope the information provided now makes debugging more feasible.

You are still sending the wrong address in both the Contact header and the SDP c= line.

Your description says that you set the media address, but doesn’t say you set the signalling address. That would directly explain the Contact header, but it may be that setting the signalling address is the master key to enabling NAT processing, and the media address is ignored without it. (Or you didn’t reload the configuration.)

I did only set the external media address temporarily to check if that does help. In all of the config editing, restarting Asterisk, etc. stuff I apparently have restored to have the original behavior again.
Since my public IP is dynamic, I wanted to avoid running in additional trouble when trying to get STUN or similar to work.

I will set signaling AND media address to my public IP, test and come back with fresh logs again.

Finally, we are getting close :slight_smile:
Thank you for your information.

I set both addresses to my public IP, now everything works as expected!

Or let’s say “one problem solved, one new problem arises”, since I still have a dynamic public IP and I now need to let Asterisk know when the public IP has changed.
Luckily enough, I don’t have a provider-enforced DSL disconnect every 24 hrs or so, but still the IP address can change at any time (i.e. when they restart the DSLAM or what else).

I did some research and understand that STUN is not what I need, but I need to set my DDNS hostname for external_signaling_address and external_media_address and then take care that the IP address mapping gets updated.
I found out that dnsmgr is able to update the above mentioned settings (https://gerrit.asterisk.org/c/asterisk/+/6069). I have set this up now. It works fine, but there is a problem with PJSIP not triggering a re-registration after the address has changed.

I did / observe the following:

  • Asterisk connected, everything works fine
  • Trigger a DSL re-connect via Fritzbox webinterface, leading to a new public IP address
  • Trigger dnsmgr refresh manually for not having to wait for its refresh interval
  • IP address gets updated correctly.
  • SIP OPTIONS packets sent by Asterisk (having the correctly updated IP in the Contact header) to Telekom are answered with 403 Forbidden

I thought that forbidden_retry_interval comes into place here, but that does not seem to be the case. Asterisk keeps sending OPTIONS packets, all replied with 403 Forbidden, apparently until expiration period is up and the next regular re-registration is triggered.

The respective registration of my PJSIP configuration looks as follows:

 ParameterName            : ParameterValue
 ===========================================================
 @pjsip_wizard            : telekomSipNumber9
 auth_rejection_permanent : false
 client_uri               : sip:telekomSipNumber9@tel.t-online.de
 contact_user             : telekomSipNumber9
 endpoint                 : 
 expiration               : 480
 fatal_retry_interval     : 0
 forbidden_retry_interval : 10
 line                     : false
 max_retries              : 10
 outbound_auth            : telekomSipNumber9-oauth
 outbound_proxy           : 
 retry_interval           : 60
 server_uri               : sip:tel.t-online.de
 support_path             : false
 transport                : transport-udp

You do not need to set any external addresses. Setting local_net is sufficient.

Forget about STUN, DDNS, dnsmgr, etc. Not needed either.

The Telekom servers use whatever turns out be present at registration time. I haven’t checked the UDP transport for a long time, but this is what you get when you use TCP. You can easily check that when you look at the state table in your router. Furthermore, registering and re-registering is a single SIP session. You basically need to start from scratch, in case something changes and there are several ways to do that. German Telekom changes the IPs currently with an interval of 30 to 90 days and always at night, unless you restart the connection manually.

So far, you are not even close to what the real problem with the Telekom ALL-IP accounts are, :innocent:

Whilst the ITSP may be partially ignoring the Contact header, and using the source IP address as the domain part of the registration contact, the OPs problem is clearly that, for some destinations, they are neither ignoring the media address, nor forcing comedia processing.

It isn’t possible for Asterisk to fully enable NAT handling if you specify local net without any external addresses (and local net is actually optional, in simple cases, as the direct interface networks are assumed to be local, anyway). It isn’t sufficient, because it doesn’t provide any means for Asterisk to find out the correct external addresses to use.

I think you are relying on workarounds applied by some ITSPs, but which are not fully working here. In general, it is always better to comply with the protocol than to rely on the other side correctly working round your violation.

I always set up some outbound NAT rules in the router, which has so far not lead to any problems. Other than that I specify a specific endpoint to trunks and enable the line feature. There’s a German VoIP forum with a couple of comments that Telekom server never use the contact addresses. So it’s always comedia, but I am not sure whether both directions are handled the same way. Maybe it’s time to look at the details again.

I’ve hooked up a HOMER server to one of my Asterisk boxes for easier analysis. When I have time I’ll play with the various fields to see what will change.

Comedia applies to the c= line in the SDP, not the Contact address in the SIP header.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.