[asterisk-dev] Asterisk / pjsip: Bug or feature? TCP/TLS connection is endless after unregistering the last trunk to the destination
Michael Maier
m1278468 at mailbox.org
Sun Jan 10 12:45:49 CST 2021
On 09.01.21 at 11:37 Joshua C. Colp wrote:
> On Sat, Jan 9, 2021 at 1:38 AM Michael Maier <m1278468 at mailbox.org> wrote:
>
>>
>> Hello!
>>
>> I'm not sure if the following finding is a bug or a feature. Given is a
>> trunk to a registered destination:
>>
>>
>> virtast*CLI> pjsip show registrations
>>
>> <Registration/ServerURI..............................>
>> <Auth..........> <Status.......>
>>
>> ==========================================================================================
>>
>> easybellPJSIP/sip:secure.sip.easybell.de easybellPJSIP
>> Registered
>>
>> Objects found: 1
>>
>>
>> The related connection:
>> # netstat -n | grep 5061
>> tcp 0 0 192.168.122.174:58709 212.172.58.207:5061
>> ESTABLISHED
>>
>> => That's expected.
>>
>>
>> Now doing an unregister
>>
>> pjsip send unregister *all
>>
>> gives:
>>
>> virtast*CLI> pjsip show registrations
>>
>> <Registration/ServerURI..............................>
>> <Auth..........> <Status.......>
>>
>> ==========================================================================================
>>
>> easybellPJSIP/sip:secure.sip.easybell.de easybellPJSIP
>> Unregistered
>>
>> Objects found: 1
>>
>> So far so good.
>>
>>
>> But (even after hours - pjsip sends per default tcp/tls keep alives each
>> 90 s):
>> # netstat -n | grep 5061
>> tcp 0 0 192.168.122.174:58709 212.172.58.207:5061
>> ESTABLISHED
>>
>> => That's not what I expect.
>>
>> Shouldn't the connection been closed after the last trunk to a destination
>> has been closed (there could be more than one numbers / trunks use the same
>> destination / connection -
>> therefore this would have to be checked before).
>>
>> What could be the use case to hold the connection forever even if it is
>> unused?
>>
>>
>> This behavior can be found with Asterisk 18.x (not tested with 16.x).
>>
>
> I believe PJSIP doesn't care or know whether there's anything currently
> "active" over the connection, and thus it is kept open for when it may be
> used again. To do otherwise and try to be intelligent is likely a ton of
> work, which is probably why it was never done. From an Asterisk level we
> don't really manage the connections and let PJSIP do it.
That's a pretty problematic behavior. ISPs (especially Deutsche Telekom e.g.) want to tear down a tls connection if it isn't used any more (why should a connection be hold active if
nobody uses it?). Therefore, after each unregister of a number, the connection is teared down after 10s by ISP. Now, asterisk or probably pjsip, reopens this connection again after
about 12s. Therefore, the ISP disconnects the connection automatically after 30s again. And Asterisk reopens it again after 1 minute - and so on. That's pretty broken.
Register multiple numbers to one destination (Asterisk 18.0.1)
--------------------------------------------------------------
If you register more than one number to the same destination, asterisk handles all registers through the same connection. This doesn't work (well) with all ISPs. Deutsche Telekom /
AllIP e.g. supports it partly - means, you can register more than one number - but if you deregister one of it, the complete connection is dropped (because normally, they want to
have for each register an own connection). Besides that, there are problems during reRegistration, if they are reRegistered all at the same time (if they are reRegistered serially,
it's working - maybe Asterisk can't properly handle mutliple Registers to the same destination via same connection).
To work around this problem, that asterisk handles all Registers to one destination through the same connection, I added dedicated transports - for each trunk an own transport (each
getting an own listener port). Therefore my transports now looks like:
myfw*CLI> pjsip show transports
Transport: <TransportId........> <Type> <cos> <tos> <BindAddress....................>
==========================================================================================
Transport: 0.0.0.0-tls tls 3 184 0.0.0.0:5061
Transport: 0.0.0.0-tls2 tls 3 184 0.0.0.0:5062
Transport: 0.0.0.0-tls3 tls 3 184 0.0.0.0:5063
Transport: 0.0.0.0-udp udp 3 184 0.0.0.0:5060
I'm running 4 trunks - the following 2 as example for the next problem:
myfw*CLI> pjsip show registration telekomPJSIP-001
<Registration/ServerURI..............................> <Auth..........> <Status.......>
==========================================================================================
telekomPJSIP-001/sip:tel.t-online.de telekomPJSIP-001 Registered
ParameterName : ParameterValue
============================================================
auth_rejection_permanent : true
client_uri : sip:+49... at tel.t-online.de
contact_header_params :
contact_user : +49...
endpoint : telekomPJSIP-001
expiration : 660
fatal_retry_interval : 0
forbidden_retry_interval : 10
line : true
max_retries : 10000
outbound_auth : telekomPJSIP-001
outbound_proxy :
retry_interval : 60
server_uri : sip:tel.t-online.de
support_mediasec : true
support_outbound : no
support_path : false
transport : 0.0.0.0-tls
myfw*CLI> pjsip show registration telekomPJSIP-002
<Registration/ServerURI..............................> <Auth..........> <Status.......>
==========================================================================================
telekomPJSIP-002/sip:tel.t-online.de telekomPJSIP-002 Registered
ParameterName : ParameterValue
=============================================================
auth_rejection_permanent : true
client_uri : ...
contact_header_params :
contact_user : ...
endpoint : telekomPJSIP-002
expiration : 660
fatal_retry_interval : 0
forbidden_retry_interval : 10
line : true
max_retries : 10000
outbound_auth : telekomPJSIP-002
outbound_proxy :
retry_interval : 60
server_uri : sip:tel.t-online.de
support_mediasec : true
support_outbound : no
support_path : false
transport : 0.0.0.0-tls2
myfw*CLI> pjsip show endpoint telekomPJSIP-001
Endpoint: telekomPJSIP-001 Not in use 0 of inf
OutAuth: telekomPJSIP-001/+49...
Aor: telekomPJSIP-001 0
Contact: telekomPJSIP-001/sip:+49... at tel.t-o 88c72b9045 Avail 13.944
Transport: 0.0.0.0-tls tls 3 184 0.0.0.0:5061
Identify: telekomPJSIP-001/telekomPJSIP-001
Match: 127.0.0.10/32
myfw*CLI> pjsip show endpoint telekomPJSIP-002
Endpoint: telekomPJSIP-002 Not in use 0 of inf
OutAuth: telekomPJSIP-002/+49...
Aor: telekomPJSIP-002 0
Contact: telekomPJSIP-002/sip:+49... at tel.t- 7f03d717f5 Avail 13.425
Transport: 0.0.0.0-tls2 tls 3 184 0.0.0.0:5062
Identify: telekomPJSIP-002/telekomPJSIP-002
Match: 127.0.0.10/32
[root at myfw ~]# netstat -n | grep 506
tcp 0 0 3.2.1.5:53527 217.0.20.195:5061 ESTABLISHED
tcp 0 0 3.2.1.5:49161 217.0.20.195:5061 ESTABLISHED
tcp 0 0 3.2.1.5:56727 217.0.20.195:5061 ESTABLISHED
I verified via tcpdump, that each Register now uses its own connection.
Next, I checked the Register packets - to telekomPJSIP-001, e.g:
Via: SIP/2.0/TLS 3.2.1.5:5062;rport;branch=...
^^^^
Contact: <sip:+49... at 3.2.1.5:5062;transport=TLS;line=...>
^^^^
=> this should be 5061 (because of transport 0.0.0.0-tls which refers to 5061) - not 5062 ...
=> It turns out, that *all* Registers of all trunks are using port 5062 now. Why that? 5061 and 5063 is ignored completely.
It doesn't change anything if rewrite_contact is on or off.
There is one more point I don't understand at the moment. Each configured transport opens a listener port (you can't configure a transport w/o a listener), like 5061 e.g. Each
configured trunk needs a transport. For a trunk, which only registers to an ISP, you never need this listener, because the complete signaling in both directions (in- and outbound
calls) is handled through the existing connection from asterisk / random local port -> ISP / 5061 (that's why it's working anyway though the Via-entry is totally broken). Why isn't
it possible to create transports w/o any listener port?
Thanks
Michael
More information about the asterisk-dev
mailing list