[Home]

Summary:ASTERISK-29257: "Received a REFER without a parseable Refer-To" from a technicolor gateway
Reporter:Andrea Rossato (gattocarlo)Labels:patch
Date Opened:2021-01-21 10:14:56.000-0600Date Closed:
Priority:MinorRegression?
Status:Open/NewComponents:Channels/chan_pjsip Resources/res_pjsip_refer
Versions:18.1.0 Frequency of
Occurrence
Constant
Related
Issues:
Environment:LinuxAttachments:( 0) asterisk-29257_revert_asterisk-25508.patch
Description:Hello,

I have a Technicolor gateway which, for transferring a call, is sending a SIP REFER which is rejected by asterisk with a "400 Bad Request" answer, complaining for the lack of a parseable "Refer-To" header in the REFER:
{noformat}
DEBUG[21954] res_pjsip_refer.c: Received a REFER without a parseable Refer-To ('<sip:4@music.lan?Replaces=1972040-fedd8a9-9f53d9ac-ae2996b-9e80bdf-9E1BB4%3Bto-tag%3Dc372857e-4e48-4a70-87f3-792c0838c99d%3Bfrom-tag%3D1966a38-1b1bd16e-14d61b13-17e012b9-9e80bdf-9E1BB4>;user=phone') on channel 'PJSIP/operator-pen-00000000' from endpoint 'operator-pen'
{noformat}
This is the offending packet:
{noformat}
REFER sip:192.168.0.6:5060;user=phone SIP/2.0
From: "penedallo"<sip:operator-pen@music.lan:5060;user=phone>;tag=1966558-25eae75e-c3a507af-559fc1f7-9e7e290-9E1BB4
To: "3"<sip:3@music.lan;user=phone>;tag=92441fad-6496-49ab-8260-faff2c9af10e
Call-ID: 1972430-741f96ac-3d10d59-5aad30c9-9e7e290-9E1BB4
CSeq: 4 REFER
Via: SIP/2.0/UDP 192.168.0.254:5060;branch=z9hG4bK-28940-9e823f6-4c871a8e
Refer-To: <sip:4@music.lan?Replaces=1972040-fedd8a9-9f53d9ac-ae2996b-9e80bdf-9E1BB4%3Bto-tag%3Dc372857e-4e48-4a70-87f3-792c0838c99d%3Bfrom-tag%3D1966a38-1b1bd16e-14d61b13-17e012b9-9e80bdf-9E1BB4>;user=phone
Referred-By: <sip:operator-pen@music.lan:5060>
Max-Forwards: 70
Supported: replaces,100rel
User-Agent: Technicolor / VANT-6 / AGTOT_1.0.1 / AGTOT_1.0.1
Contact: <sip:operator-pen@192.168.0.254:5060;user=phone>
Authorization: Digest username="operator-pen",realm="asterisk",nonce="1611229094/fe236d06961039f14c0dbb0c17920968",uri="sip:192.168.0.6:5060;user=phone",response="43c4b80877a443ca941bb369346f0f66",algorithm=MD5,cnonce="9e823f6",opaque="2d5a29c968283ecf",qop=auth,nc=00000003
X-Serialnumber: CP1634RAYPH
Accept: application/dtmf-relay, x-application/dtmf-relay, application/sdp
Content-Length: 0
{noformat}
Something similar has been already reported:
pjsip - REFER request from SNOM is rejected with "400 bad request" - DEBUG shows "Received a REFER without a parseable Refer-To"
ASTERISK-24508

In that case, though, the offending "Refer-To" header was slightly different:
{noformat}
DEBUG[1748] res_pjsip_refer.c: Received a REFER without a parseable Refer-To ('sip:603@192.168.1.8;user=phone?Replaces=545ce68db624-gdhc4gp41882%3Bto-tag%3Da0b21fa1-e26d-4a56-b553-a79f329e58f2%3Bfrom-tag%3D2mlnkcxazi') on channel 'PJSIP/601-00000006' from endpoint '601'
{noformat}
Comments:By: Asterisk Team (asteriskteam) 2021-01-21 10:14:56.597-0600

Thanks for creating a report! The issue has entered the triage process. That means the issue will wait in this status until a Bug Marshal has an opportunity to review the issue. Once the issue has been reviewed you will receive comments regarding the next steps towards resolution. Please note that log messages and other files should not be sent to the Sangoma Asterisk Team unless explicitly asked for. All files should be placed on this issue in a sanitized fashion as needed.

A good first step is for you to review the [Asterisk Issue Guidelines|https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines] if you haven't already. The guidelines detail what is expected from an Asterisk issue report.

Then, if you are submitting a patch, please review the [Patch Contribution Process|https://wiki.asterisk.org/wiki/display/AST/Patch+Contribution+Process].

Please note that once your issue enters an open state it has been accepted. As Asterisk is an open source project there is no guarantee or timeframe on when your issue will be looked into. If you need expedient resolution you will need to find and pay a suitable developer. Asking for an update on your issue will not yield any progress on it and will not result in a response. All updates are posted to the issue when they occur.

Please note that by submitting data, code, or documentation to Sangoma through JIRA, you accept the Terms of Use present at [https://www.asterisk.org/terms-of-use/|https://www.asterisk.org/terms-of-use/].

By: Sean Bright (seanbright) 2021-01-21 10:58:32.936-0600

Did you have a question?

By: Sean Bright (seanbright) 2021-01-21 11:09:34.986-0600

My mistake, this header looks to be valid according to RFC 3515

By: George Joseph (gjoseph) 2021-01-22 09:31:12.401-0600

{code}
Refer-To: <sip:4@music.lan?Replaces=1972040-fedd8a9-9f53d9ac-ae2996b-9e80bdf-9E1BB4%3Bto-tag%3Dc372857e-4e48-4a70-87f3-792c0838c99d%3Bfrom-tag%3D1966a38-1b1bd16e-14d61b13-17e012b9-9e80bdf-9E1BB4>;user=phone
{code}

So I guess the intent was to send a single "Replaces" with the value {{"1972040-fedd8a9-9f53d9ac-ae2996b-9e80bdf-9E1BB4%3Bto-tag%3Dc372857e-4e48-4a70-87f3-792c0838c99d%3Bfrom-So tag%3D1966a38-1b1bd16e-14d61b13-17e012b9-9e80bdf-9E1BB4"}} in subsequent requests.  I wonder if pjproject is decoding the %3B (;) and %3D (=) and thinking it's a uri parameter coming after the headers which _would_ be invalid.

Investigating.




By: Sean Bright (seanbright) 2021-01-22 09:33:22.867-0600

It's just trying to parse the header value as a URI which fails because the code that parses the URI expects to exhaust the input (which doesn't happen here because of the {{;user=phone}} bit on the end).


By: George Joseph (gjoseph) 2021-01-22 10:21:21.420-0600

That's weird since the ?header is part of the URI but user=phone is a header parameter not a URI parameter.  But that's neither here nor there.




By: Andrea Rossato (gattocarlo) 2021-01-23 08:41:13.858-0600

I'm puzzled but I'm leaning to think this is not a pjproject issue, but something related to the fact that refer_incoming_refer_request(), in res_pjsip_refer, is using pjsip_parse_uri() for actually parsing a header.

in a case like this pjsip_parse_uri() uses int_parse_name_addr() which looks for brackets ('<' and '>') to get the display name and then parses the url -- what's enclosed in brackets, if present.

The ulr is passed to int_parse_sip_url() which will look, in this order, for the following fields: user, password, host, port, header parameters (starting with ';') and, finally, url parameters (starting with '?').

So, something like this is successfully parsed:

{noformat}
'name <sip:user@domain.lan;header_parameter=1?url_parameter=1>'
{noformat}

The same for:

{noformat}
'sip:user@domain.lan;header_parameter=1?url_parameter=1'
{noformat}

Something like this:

{noformat}
'name <sip:user@domain.lan?url_parameter=1;header_parameter=1>'
{noformat}

or like this:

{noformat}
'sip:user@domain.lan?url_parameter=1;header_parameter=1'
{noformat}

would fail because the parser for getting header parameters fails, the parser for url parameter succeeds, but the last part of the output is not consumed (";header_...").

In the issue I reported we hit 2 problems. The header I reported is something like this::

{noformat}
Refer-To: name <sip:user@domain.lan?url_parameter=1>;header_parameter=1
{noformat}

everything after the '>' is not parsed.

chan_sip deals with it correctly, and pjsip_parse_hdr() parses it successfully but it would require non-trivial changes to sip_parser.c to get pjsip_parse_uri() deal with it.

hope this helps.


By: Andrea Rossato (gattocarlo) 2021-01-24 07:24:51.541-0600

Sorry if in my previous comment I was referring to comments which were later edited (I'm talking about the possibility of a pjproject bug).

I came to the conclusion that this is a regression introduced by the fixed adopted for ASTERISK-24508

I'm attaching a patch that reverts those changes and fixes my problem. This is not a solution proposal: I've just reverted the changes without changing variable names, and checking if a NULL terminated string is actually needed for pjsip_parse_hdr(). This is just a proof of concept.

Now, the offending header in ASTERISK-24508 was:

{noformat}
DEBUG[1748] res_pjsip_refer.c: Received a REFER without a parseable Refer-To ('sip:603@192.168.1.8;user=phone?Replaces=545ce68db624-gdhc4gp41882%3Bto-tag%3Da0b21fa1-e26d-4a56-b553-a79f329e58f2%3Bfrom-tag%3D2mlnkcxazi') on channel 'PJSIP/601-00000006' from endpoint '601'
{noformat}

So I suspect that that header was not correctly parsed by pjsip_parse_hdr(). I've been using asterisk for less than a month and I do not know its code base, nor the testing infrastructure, so I'm not presently able to test my fix with that header. But I tried it with this simple test code, linked with pjproject-2.10:

{noformat}
#include <pjsip.h>

int main(int argc, char** argv) {
 if (argc < 2) {
   fprintf(stderr, "Missing header\n");
   return 1;
 }

 pj_init();

 pj_caching_pool cp;
 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
 pj_pool_t* pool = pj_pool_create(
   &cp.factory, // pool factory
   "test",      // pool name
   4096,        // init size
   512,         // increment size
   NULL         // callback on error
 );

 
 pjsip_endpoint* endpt;
 pjsip_endpt_create(&cp.factory, "test", &endpt);

 char* hdr = argv[1];
 printf("Trying to parse (%d): %s\n", strlen(hdr), hdr);

 pj_str_t hname;
 pjsip_hdr *parsed_hdr=NULL;
 pjsip_fromto_hdr *fromto_hdr;
 
 hname = pj_str("Refer-To");
 fromto_hdr = (pjsip_fromto_hdr*) pjsip_parse_hdr(pool, &hname, hdr, strlen(hdr),0);

 if (fromto_hdr)
     printf("success\n");
 else
     printf("failure\n");
 return 0;
{noformat}

If I run this with the offending header of ASTERISK-24508 I get:

{noformat}
$ ./pjsip_test 'sip:603@192.168.1.8;user=phone?Replaces=545ce68db624-gdhc4gp41882%3Bto-tag%3Da0b21fa1-e26d-4a56-b553-a79f329e58f2%3Bfrom-tag%3D2mlnkcxazi'
Trying to parse (137): sip:603@192.168.1.8;user=phone?Replaces=545ce68db624-gdhc4gp41882%3Bto-tag%3Da0b21fa1-e26d-4a56-b553-a79f329e58f2%3Bfrom-tag%3D2mlnkcxazi
success

{noformat}

and this is with mine:

{noformat}
$ ./pjsip_test '<sip:4@music.lan?Replaces=1972040-fedd8a9-9f53d9ac-ae2996b-9e80bdf-9E1BB4%3Bto-tag%3Dc372857e-4e48-4a70-87f3-792c0838c99d%3Bfrom-tag%3D1966a38-1b1bd16e-14d61b13-17e012b9-9e80bdf-9E1BB4>;user=phone'
Trying to parse (196): <sip:4@music.lan?Replaces=1972040-fedd8a9-9f53d9ac-ae2996b-9e80bdf-9E1BB4%3Bto-tag%3Dc372857e-4e48-4a70-87f3-792c0838c99d%3Bfrom-tag%3D1966a38-1b1bd16e-14d61b13-17e012b9-9e80bdf-9E1BB4>;user=phone
success
{noformat}

I do not have the time to check it, but I believe that in ASTERISK-24508 you were hitting a pjsip bug, and your fix was not correct.