Can't use local channel to bridge outside caller with outside callee


I’m running Asterisk 18.2.0 with a single ITSP and a trunk with 100 numbers. When a certain number is called I’d like Asterisk to connect the caller to an outside number instead of an internal endpoint. At its most basic the setup works.

All config files are here (extensions.conf, pjsip.conf, pjsip_wizard.conf, rtp.conf)

If a caller dials my -20 extensions from the outside for example. Asterisk goes to the subDialOutgoing subroutine and does Dial(PJSIP/${ARG1}@itsp) where ${ARG1} is the external number. All great. In this case Asterisk will get out of the way and caller and callee can hear eachother fine.

An rtp set debug on in Asterisk’s console confirms, Remotely bridged 'PJSIP/SOFTPHONE_B-0000000c' and 'PJSIP/SOFTPHONE_A-0000000d' - media will flow directly between them.

Im struggling to use local channels to replicate this simple setup. I went with the “Asterisk: The Definitive Guide, 5th Edition” book (chapter 10) and Asterisk Wiki’s local channel examples but for reasons that are beyond me extension -30 from above does not correctly establish media streams, more on that in a sec. The only difference between -30 and -20 is an extra step via local channel.

If caller calls -30 the following Wireshark call flow unfolds.

  1. Call-ID: SBC*: ITSP sends SIP INVITE, says it wants -30, gives its SDP media port 29952, accepts G.722 and a-law
  2. Call-ID: SBC*: Asterisk says, SIP/2.0 100 Trying
  3. Call-ID: 986*: Asterisk calls ITSP, wants -411, gives its SDP media port 63136, accepts G.722, a-law, μ-law
  4. Call-ID: 986*: ITSP says, SIP/2.0 100 Trying
  5. Call-ID: 986*: Eventually ITSP confirms callee picked up, gives its SDP media port 31708, accepts G.722
  6. Call-ID: 986*: Asterisk ACKs
  7. Call-ID: SBC*: Asterisk confirms callee picked up, gives its SDP media port 63190, accepts G.722 and a-law
  8. Call-ID: 986*: Meanwhile callee has started its G.722 RTP stream to Asterisk’s media port 63136
  9. Call-ID: SBC*: ITSP ACKs
  10. Call-ID: SBC*: Caller starts its G.722 RTP stream as well to Asterisk’s media port 63190

Wireshark sees traffic coming from both parties. Asterisk at this time has bound UDP ports 63136 (for traffic the callee is sending) and 63190 (for traffic from the caller) but rtp set debug on in Asterisk’s console is essentially silent whereas to my understanding it would normally log all RTP packets.

-- Called PJSIP/555-external-411@itsp
-- PJSIP/itsp-00000007 is ringing
-- Local/go-outside@localDialDelay-00000003;1 is ringing
   > 0x7f29a031dd50 -- Strict RTP learning after remote address set to:
-- PJSIP/itsp-00000007 answered Local/go-outside@localDialDelay-00000003;2
-- Local/go-outside@localDialDelay-00000003;1 answered PJSIP/itsp-00000006
   > 0x7f29a03439a0 -- Strict RTP learning after remote address set to:
-- Channel PJSIP/itsp-00000007 joined 'simple_bridge' basic-bridge <771099a7-5976-4b4a-ba97-8485ad1bae2d>
-- Channel Local/go-outside@localDialDelay-00000003;2 joined 'simple_bridge' basic-bridge <771099a7-5976-4b4a-ba97-8485ad1bae2d>
-- Channel Local/go-outside@localDialDelay-00000003;1 joined 'simple_bridge' basic-bridge <41b5316c-0ba8-47aa-ab12-3d783a84491e>
-- Channel PJSIP/itsp-00000006 joined 'simple_bridge' basic-bridge <41b5316c-0ba8-47aa-ab12-3d783a84491e>
   > 0x7f29a03439a0 -- Strict RTP learning after remote address set to:
-- Channel PJSIP/itsp-00000007 left 'simple_bridge' basic-bridge <771099a7-5976-4b4a-ba97-8485ad1bae2d>
-- Channel Local/go-outside@localDialDelay-00000003;2 left 'simple_bridge' basic-bridge <771099a7-5976-4b4a-ba97-8485ad1bae2d>
== Spawn extension (subDialOutgoing, entry, 2) exited non-zero on 'Local/go-outside@localDialDelay-00000003;2'
-- Channel Local/go-outside@localDialDelay-00000003;1 left 'simple_bridge' basic-bridge <41b5316c-0ba8-47aa-ab12-3d783a84491e>
-- Channel PJSIP/itsp-00000006 left 'simple_bridge' basic-bridge <41b5316c-0ba8-47aa-ab12-3d783a84491e>
== Spawn extension (ctx-get-to-sets, 30, 4) exited non-zero on 'PJSIP/itsp-00000006'

Listening to RTP streams after the Wireshark capture confirms that voice from the callee is sent to Asterisk’s listening port on the callee’s leg (but not forwarded to the caller) and voice from caller is sent to Asterisk’s listening port on the caller’s leg (but not forwarded to the callee).

Am I missing something obvious? Did I set up my minimum local channel example incorrectly? Am I misunderstanding how a local channel works?


Is there a firewall in place such as iptables blocking the traffic from being received by Asterisk?

A firewall is in place that’s configured to allow packets through to the outside from Asterisk’s network segment and the other way 'round.

Listening on both Asterisk’s interface and the WAN interface paints the same picture in that data the callee and the caller are sending is reaching the firewall then passing through to Asterisk. At Asterisk a separate packet capture sees them coming through. Asterisk, however, does not attempt to transmit RTP packets to either the caller or callee - at least when the caller called extension -30. Essentially calling -20 from above example works perfecty (where I’m not using a Local/ channel) whereas calling -30 does not.

ITSP uses prefixes and and UDP media port range 20000-50000 so a tcpdump such as this one should show send attempts even if firewall blockage was happening.

tcpdump -i any 'dst net ( or and dst portrange (20000-50000)'

However, no packet’s captured. When calling my -20 extension Asterisk pulls itself out of the call flow and allows caller and callee to talk among eachother. When calling my -30 Asterisk receives all the traffic but doesn’t make an attempt to transmit.

Asterisk won’t send if it is not receiving. In particular, you say that nothing is showing on the RTP logging, which means that it definitely isn’t receiving.

Also, I think it is still the case that local channels won’t optimise out unless media goes through in the right direction, and the direct media that you refer to as Asterisk taking itself out of the call, wont happen until the local channel has gone. Asterisk doesn’t actually take itself out of the call, as it is still in the signalling path.

Indeed, the problem is not sending from Asterisk. The problem is receiving into Asterisk, which would point to something preventing Asterisk from seeing the packets. Packet captures, on the same system, will occur before any iptables rules or firewalls.

You could enable the “rtp_keepalive” option on the PJSIP endpoints and see if that helps. If so, then something is blocking traffic until traffic is sent .

That does sound reasonable, thanks for the input. I’ve extended above pjsip_wizard.conf with endpoint/rtp_keepalive=3 for testing and RTP streams now flow back and forth.

Asterisk’s console with rtp set debug on shows that in my example call the first comfort noise packet had sequence number 8266, also highlighted on the right-hand Wireshark side on the image. Asterisk sent this packet from its media port 63130, that’s on the callee’s call leg.

You can also see that packets were already arriving on port 63130 from the callee, for some reason RTP traffic logged by Asterisk only begins after the first comfort noise packet went out.

I’m moderately sure I’m not fully understanding something here. RTP packets are arriving at Asterisk’s media ports for both the callee’s and the caller’s leg. It only begins caring about them once it’s sent out the first comfort noise packet itself. I’ll check firewall and port forward rules again.

If Asterisk reads in an RTP packet, it will show up in “rtp set debug on”. If it’s not then it never arrived from the perspective of Asterisk and something outside stopped it. Whatever stopped it allowed it through once Asterisk sent a packet out which occurred when using “rtp_keepalive”. Without that option Asterisk won’t generate RTP packets but merely forward what it receives. It’s something outside of Asterisk doing this.

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