[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