[Home]

Summary:ASTERISK-27147: Either asterisk or pjproject isn't re-using tcp connections (again)
Reporter:George Joseph (gjoseph)Labels:pjsip
Date Opened:2017-07-19 14:32:58Date Closed:2017-08-14 18:02:14
Priority:MajorRegression?
Status:Closed/CompleteComponents:Resources/res_pjsip
Versions:13.17.0 14.6.0 GIT Frequency of
Occurrence
Related
Issues:
is related toASTERISK-27192 res_pjsip: Loss of SIP registrations causing unavailable endpoints
Environment:Attachments:( 0) client_pjsip_wizard.conf
( 1) client_pjsip.conf
( 2) server_pjsip_wizard.conf
( 3) server_pjsip.conf
Description:Last year we submitted patches to pjproject to fix not re-using tcp connections.  It looks like it's broke again.

Asterisk A and B have a "trunk" between them.  A registers to B.
After A registers, there is 1 open TCP connection between them.
B sends a call to A.
Instead of re-using the existing connection, B establishes a new cconnection back to A.
Now there are 2 tcp connections open.

If A were behind a firewall that didn't allow inbound new connections, there'd be an issue.

Comments:By: Richard Mudgett (rmudgett) 2017-08-04 17:58:20.254-0500

The connections are being reused.  We're just not telling the other side the right contact address and port for there to be only one connection.  When Asterisk A registers with Asterisk B then the connection on A is IP-A:random-port (say port 56789) to IP-B:5060.  Asterisk A says contact it at IP-A:5060.  So when B wants to send A a call, it has no connection to A at IP-A:5060.  It does have one for IP-A:56789 but it wasn't told to use that address as a contact address.  When A responds to the INVITE it sends the responses over the incoming transport.  When A later sends a request to B (say a COLP UPDATE), it uses B's contact address which is IP-B:5060.  Asterisk A does find such a connection created by the registration and uses it.  However, this isn't the connection that B sent the original INVITE over.  This call is now using two different connections.  I'd think that if A had registered with a contact address of IP-A:56789 then B would use that existing connection and then there would be only one connection being used.

With rewrite_contact enabled only on A's side, when A sends the UPDATE request in the scenario above, it sends the UPDATE to the source address of the connection created by the incoming INVITE instead of where the contact header stated.  The register connection isn't used for the call.

With rewrite_contact enabled only on B's side, the above scenario only uses one connection and B doesn't create a new connection.

The rewrite_contact option is intended for B's server side situation.  However, it does have some potential benefit on A's client side situation.  The benefit is if B initiates a call with A because B doesn't have the rewrite_contact functionality or its not enabled.  Asterisk A will reuse the connection established by the incoming call for the duration of the call.

A problem does crop up on B's side with rewrite_contact enabled.  If the TCP connection gets disconnected or if B is restarted then the rewritten register contact for A is now invalid and won't go away until it expires.  If B tries to send a call to A using the invalid connection then A is not likely to see the request.  Asterisk A either won't be listening on that port for new connections or a NAT/firewall will block it.

A problem also crops up on A's side when the TCP connection gets disconnected.  Now A cannot receive incoming calls from B until it normally attempts to re-register.  If B also has max_contacts=1 set and remove_existing=no then the invalid register contact on B will cause A's register attempts to be rejected.  Asterisk A may give up registration attempts until manually prodded to resume.


By: Ross Beer (rossbeer) 2017-08-10 04:23:34.734-0500

When the connection disconnects, should any BLF/MWI subscriptions be removed also?

By: Richard Mudgett (rmudgett) 2017-08-10 10:03:07.068-0500

[~rossbeer] That should not be necessary.  The contact should be remade soon anyway.

By: Ross Beer (rossbeer) 2017-08-10 11:04:49.321-0500

If the phone goes offline for some other reason and stays offline, won't the BLF/MWI persist?

When a voicemail is left or BLF state change happen, wouldn't Asterisk attempt to contact the endpoint in the same way as calling the endpoint would? This would fail as per the above description.

By: Richard Mudgett (rmudgett) 2017-08-10 11:30:00.307-0500

[~rossbeer] Yes the subscription will persist because it is supposed to persist even across Asterisk restarts.  Yes any subsequent notify will fail until the endpoint re-registers because there is no valid contact address.  These are two separate things.  It would be bad to cancel any subscriptions because of a temporary unreachable condition.

By: Friendly Automation (friendly-automation) 2017-08-16 06:32:42.742-0500

Change 6225 merged by Jenkins2:
res_pjsip: Fix prune_on_boot to remove only contacts for the host.

[https://gerrit.asterisk.org/6225|https://gerrit.asterisk.org/6225]

By: Friendly Automation (friendly-automation) 2017-08-16 06:44:48.819-0500

Change 6226 merged by Jenkins2:
res_pjsip: Fix prune_on_boot to remove only contacts for the host.

[https://gerrit.asterisk.org/6226|https://gerrit.asterisk.org/6226]

By: Friendly Automation (friendly-automation) 2017-08-16 06:47:05.649-0500

Change 6227 merged by Jenkins2:
res_pjsip: Fix prune_on_boot to remove only contacts for the host.

[https://gerrit.asterisk.org/6227|https://gerrit.asterisk.org/6227]

By: Friendly Automation (friendly-automation) 2017-08-16 07:04:39.031-0500

Change 6228 merged by Joshua Colp:
res_pjsip: Fix prune_on_boot to remove only contacts for the host.

[https://gerrit.asterisk.org/6228|https://gerrit.asterisk.org/6228]