Handling Flowroute bugs in session timers and codec negotiation

After 15 minutes, calls to my Flowroute endpoint stop receiving audio; the calls don’t drop, there’s just no incoming RTP packets. I’ve confirmed this with wireshark, incoming RTP packets stop, but outgoing RTP packets continue.

Flowroute tech support has told me that “Session Media Timers” are responsible for this and will time out after 15 minutes unless they are re-upped by INVITEs (I suspect that UPDATEs may work as well). I think that calling PJSIP_SEND_SESSION_REFRESH() periodically should accomplish this, but I don’t know enough about calling plans to accomplish this. Would someone point me in the right direction?

I’m using Asterisk 20.5.2 on an embedded device (but I don’t think that’s the issue).

;extensions.conf

[internal]
exten = _X.,1,NoOp()
same = n,Dial(PJSIP/${EXTEN}@Flowroute,60)
same = n,Answer()
same = n,Hangup()

;pjsip.conf

[Flowroute]
type=endpoint
transport=udp
timers=yes
timers_sess_expires=6000
context=external
disallow=all
allow=g729,ulaw,alaw
direct_media=yes        ; doesnt take, perhaps GigasetC470IP ?
from_user=*mynumber*
;from_domain=eu-central-fra.sip.flowroute.com
outbound_auth=Flowroute
aors=Flowroute

[Flowroute]
type=registration
transport=udp
outbound_auth=Flowroute
server_uri=sip:eu-central-fra.sip.flowroute.com:5060
client_uri=sip:*FlowrouteAccont*@eu-central-fra.sip.flowroute.com:5060
auth_rejection_permanent=no
contact_user=*FlowrouteAccount*

[Flowroute]
type=auth
auth_type=userpass
username=*FlowrouteAccount*
password=*FlowroutePassword*

[Flowroute]
type=aor
max_contacts=3
contact=sip:eu-central-fra.sip.flowroute.com

[GigasetC470IP]
type=endpoint
context=internal
disallow=all
allow=g729,ulaw,alaw
auth=GigasetC470IP
aors=GigasetC470IP

[GigasetC470IP]
type=auth
auth_type=userpass
username=GigasetC470IP
password=*GigasetC470IPpassword*

[GigasetC470IP]
type=aor
max_contacts=3

[GigasetC470IP]
type=identify
endpoint=GigasetC470IP
match=*ExternalIP*

[udp]
type=transport
protocol=udp
bind=0.0.0.0

[wss]
type=transport
protocol=wss
bind=0.0.0.0

That’s a lot more than 15 minutes. However, they should have negotiated it down if they didn’t like it.

timers_sess_expires doesn’t directly affect the problem. I had it set to 600, which is the lowest they allowed me to, and it hung up the call at 10 minutes. When I have it set higher, after 15 minutes, incoming audio stops but the call does not hang up, at least not for another minute. I didn’t try to let continue for longer.

I’d suggest the problem lies with your router deleting temporary NAT or firewall rules. The best fix is to make those rules static. Session timers address your headline question.

Thanks for suggestion about the router rules, I’ll definitely try that. The reason I haven’t before is that I’ve used other sip trunk providers without running into this 15 minute problem. And, then Flowroute tech support told me about the need for sending repeated INVITEs during calls. I’m close to having a dialplan that should do just that, so I’ll try that out as well. I’m new to Asterisk, so it’s been slow going for me.

However, I am confused about how session timers address my headline question. I did try using timers_sess_expires=600 and I didn’t see any INVITEs or UPDATEs generated during calls, rather I saw BYEs generated after 10 minutes which ended the call. If I use timers_sess_expires=900 or more, the RTP packets stop coming after 15 minutes, just like before. I can’t see how session timers can generate additional INVITEs or UPDATEs during calls to keep them going, rather they terminate calls with BYEs once the timer times out.

Session timers require one end to send INVITE or UPDATE more frequently than the expiry time so they force the sending of INVITE or UPDATE, which is what you asked for in the headline. The timers are reset using these types of request.

I got my port redirects set up on my routers, so I’ll do some testing to see if that helps the situation. I hope it does because I still have some learning to do when it comes to dialplans.

I wasn’t aware that the session timer should cause INVITE or UPDATE to be sent more frequently. But that does give me something else to think about, because it’s not happening in my system. When I set the session timer to 10 minutes, it simply ends the session at 10 minutes.

I’ll do some more logging to see if the session timers are working properly now and the RTP packets keep coming after 15 minutes.

I wonder if each end thinks it’s up to the other end to do the sending.

The starting point is that the other end sends. If you go to the full 10 minutes, it is most likely that the connection has already been broken, and the refresh isn’t getting through. The refresh is attempted significantly before the expiry time. Might be 50%.

A SIP trace (pjsip set logger on) would show what was actually negotiated for session timers.

So, once I got my redirects set up, I started to get a deluge of REGISTER requests from various IPs. The responses were 401 Unauthorized, but there were enough of them to choke my device. Putting IP filtering into the firewall rule fixed that. Unfortunately everything is behaving pretty much the same as before, which is that when I set timers_sess_expires=600, I get BYEs from Asterisk at 10 minutes that end the session, and when I set timers_sess_expires=6000, I stop receiving audio at 15 minutes from the remote.

The INVITEs from Asterisk contain Session-Expires: 600\n Min-SE: 90 or Session-Expires: 6000\n Min-SE: 90 according to the setting of timers_sess_expires. However, in both cases the received OK has Session-Expires: 1800;refresher=uas

In the 10 minute case, the call is hung up with BYEs from Asterisk. In the 15 minute case, RTP packets aren’t received anymore, but they are sent. The call got hung up 3 minutes later in one case (I usually didn’t wait to see what happened after the audio stopped).

I confirmed all of the above by looking at pcap files with wireshark. I used pjsip set logger most of the time, but also tcpdump when I wanted to see the RTPs.

For what it’s worth, I’ve been using a GigasetC470IPC for many years. At first I had it behind the firewall and used it for 60 minute+ calls over Future Nine. After they stopped functioning, I switched to Flowroute which works fine except for the audio cutoff after 15 minutes. I was hoping to solve the 15 Minute problem with Asterisk, but at this point I have the same problem with and without it. Also with and without the redirects on the firewall.

I haven’t investigated much about the functioning of the firewall yet, but I have another device that I could set up with a VPN that would make it appear on the outside of the firewall and take it from there. So far, I have no reason to believe that there is a problem with the firewall.

I seem to have deleted my 15 minute pcap, so I’ll go about capturing another now that I have the firewall in place.

The response I got from Flowroute support makes me think that regardless of who initiated the call, it should be Asterisk that sends the reINVITEs:

15 minutes is a fairly common default session media timer length. If your system is not sending INVITEs to re-up that timer then you can experience issues similar to what you are experiencing. You’d want to review your PBX manufacturer’s documentation to determine where in your deployment you can check those options.

Also is the “session media timer” really the same thing as a “session timer?”

You’d have to ask Flowroute, but session timers are the only ones you would set to the order of 15 minutes, and the only ones that would generate periodic INVITEs or UPDATEs.

I think your problem is in your, or your provider’s, routers.

Well, I have a solution, which is great, but somehow not satisfying. It turns out the problem doesn’t involve port redirects or anything else to do with the firewall. Also the session timer is not involved either.

It turns out that if I only allow the g711u codec, it works fine, I tested it for 40 minutes which included 2 rounds of reINVITEs. If I allow g729, g711u and g711a the audio gets lost during the first round of reINVITE. This works the same whether I use Asterisk or my GigasetC470IP.

Flowroute claims to support g729, g711u and g711a but from what I’ve seen it always replies with g711u by itself in Session Progress and OK, then it fails after the reINVITE. If the initial INVITE contains g711u by itself, everything is fine.

BTW, it always responds with Session-Expires: 1800 regardless of the value of Session-Expires Asterisk puts into the INVITE. However, Asterisk then times out after the value of the session timer it offered. For example, when I set timers_sess_expires=600, INVITEs contain Session-Expires: 600 and the returned OK contains Session-Expires: 1800;refresher=uas but Asterisk times out after 10 minutes, before the reINVITE comes at 15 minutes. Is this an Asterisk bug?

Edit: corrected the 6000 to 600 in the last paragraph

Without a full SIP trace can’t say one way or the other. We’re relying on bits and pieces and your interpretation of things.

I can say from a general re-INVITE perspective they should respond with an answer of whatever they wish (only ulaw most likely) and life should go on.

Right, the reINVITEs come from them at 15 min and with ulaw only. Life goes on if the original INVITE sent to them at 0 min had only ulaw, if it had g729, g711u and g711a audio stops coming during the reINVITEs at 15 min.

If you’re interested in seeing the traces, I’ll send them to you. They’re not secret, I’d just rather not post them anywhere public. I can also point out what I mean by the Session-Expires headers.

If the negotiation has resulted in them being responsible for sending the re-INVITE, and they don’t or it fails in some way on their side such that audio stops, then I don’t see how that is itself a bug in Asterisk.

I don’t accept private submission of information for this stuff.

I don’t think that the issue with the re-invites and the audio is a bug in Asterisk. Sorry that I was unclear about that. What I meant was the session timer negotiation:

Asterisk (a) → Remote (r) INVITE - Session-Expires: 600
r → a 100 Trying - Session-Expires not present
r → a 183 Session Progress - Session-Expires not present
r → a 200 OK - Session-Expires: 1800;refresher=uas
a → r ACK - Session-Expires not present

At this point which value is the agreed one? I don’t know how it should be, but a believes that it is 600 and r believes that it is 1800. This causes a problem because r sends the reINVITE at 900, meanwhile a times out at 600 which ends the session before then. If the first value in the INVITE should be the accepted one, then r is getting it wrong. If the value in the OK is the accepted one, then a is getting it wrong. A work around is setting it to 1800 in a and they both agree.

That would be defined within the RFC[1]. I don’t know the session timers RFC.

[1] RFC 4028 - Session Timers in the Session Initiation Protocol (SIP)

The rules are complicated, because of the possible involvement of proxies, but I think the UAS has to reject the request, with 422, and a Min-SE header, if it wants to raise the Session -Expires value.

You should probably check that you haven’t got SIP ALG enabled on your router, in case that is deleting the outbound Session-Expires

I have SIP ALG disabled, but that reminds me of earlier on, when I first started looking into this. The reason I had timers_sess_expires=600 set is that any lower, and it did get rejected with 422, and a Min-SE header I think. That’s how I found out that I can’t set it lower than 600. That also shows that the outbound Session-Expires header is making it through.

At this point, this isn’t causing me a problem. And, it doesn’t seem like it’s a Asterisk issue either.

I can’t seem to edit the title, but I would change it to “Handling Flowroute bugs in session timers and codec negotiation”