it is not my lucky day. anything new that i try, does not work.
in proxy 1, i call add_path_received() on register request, which results into this kind of path header:
Path: sip:192.98.102.10;transport=tcp;lr;received='sip:192.98.102.10:58022;transport=tcp'.
then i forward the request to proxy 2 and call save() on it. it results in error:
Apr 7 14:01:44 wheezy1 /usr/sbin/sip-proxy[8709]: ERROR: registrar [save.c:887]: Failed to parse Path: URI
looks like kamailio is not able to parse path uri that it added itself.
perhaps the quotes should be double ones?
-- juha
Juha Heinanen writes:
Path: sip:192.98.102.10;transport=tcp;lr;received='sip:192.98.102.10:58022;transport=tcp'.
according to rfc3261
pvalue = 1*paramchar paramchar = param-unreserved / unreserved / escaped param-unreserved = "[" / "]" / "/" / ":" / "&" / "+" / "$" unreserved = aphanum / mark mark = "-" / "_" / "." / "!" / "̃" / "*" / "’" / "(" / ")"
my conclusion is that ; and = in received value needs to be escaped.
am i the only one who has ever used add_path_received function or is this a newly introduced bug?
-- juha
Juha Heinanen writes:
my conclusion is that ; and = in received value needs to be escaped.
i escaped them, but it didn't help. path header now looks like:
Path: sip:192.98.102.10;transport=tcp;lr;received='sip:192.98.102.10:58156%3Btransport%3Dtcp'.
and i still get the same error:
Apr 7 14:49:47 wheezy1 /usr/sbin/sip-proxy[8709]: ERROR: registrar [save.c:887]: Failed to parse Path: URI
any other ideas?
-- juha
i also tried by removing single quotes from received value:
Path: sip:192.98.102.10;transport=tcp;lr;received=sip:192.98.102.10:58222%3Btransport%3Dtcp
since they are not serving any purpose, but that didn't help either.
-- juha
Hi Juha,
On 04/07/2013 01:51 PM, Juha Heinanen wrote:
I don't see why you think that ; and = should be escaped.
rfc3327 chapter 4 says:
The syntax for Path is defined as follows:
Path = "Path" HCOLON path-value *( COMMA path-value )
path-value = name-addr *( SEMI rr-param )
Note that the Path header field values conform to the syntax of a Route element as defined in [1]. As suggested therein, such values MUST include the loose-routing indicator parameter ";lr" for full compliance with [1].
The rules for Route element are as follows:
Route = "Route" HCOLON route-param *(COMMA route-param) route-param = name-addr *( SEMI rr-param ) name-addr = [ display-name ] LAQUOT addr-spec RAQUOT addr-spec = SIP-URI / SIPS-URI / absoluteURI
rr-param = generic-param generic-param = token [ EQUAL gen-value ] gen-value = token / host / quoted-string
Why would someone want to escape semicolor (SEMI) which separated either Route or URI parameters?
Also EQUAL used in pname=pvalue does not need escaping.
We've already had a closer look at add_path_received() here at sipwise when we found double quotes in Route param value to be invalid and changed them to single ones. We have not observed the error in save() you have posted in kamailio 3.3.. Moreover, the ibc's Ragel-SIP-Parser suggests that the Path header above is correct :)
So, from my PoV: - the ;transport=tcp;lr;received=... part are route-param's which follow the above rules. - the 'sip:192.98.102.10:58156;transport=tcp' part contains URI parameters. It is still fine according to definition of Path/Route element above - and agrees with the definition of other-param too:
SIP-URI = "sip:" [ userinfo ] hostport uri-parameters [ headers ] uri-parameters = *( ";" uri-parameter) uri-parameter = transport-param / user-param / method-param / ttl-param / maddr-param / lr-param / other-param other-param = pname [ "=" pvalue ] pvalue = 1*paramchar paramchar = param-unreserved / unreserved / escaped param-unreserved = "[" / "]" / "/" / ":" / "&" / "+" / "$" unreserved = alphanum / mark mark = "-" / "_" / "." / "!" / "~" / "*" / "'" / "(" / ")" alphanum = ALPHA / DIGIT escaped = "%" HEXDIG HEXDIG
Do you also have the save() problem in 3.3?
Andrew
Andrew Pogrebennyk writes:
because path-value starts with name-addr and my interpretation is that since there are <>s around this path header body:
Path: sip:192.98.102.10;transport=tcp;lr;received='sip:192.98.102.10:58156%3Btransport%3Dtcp'
solely consists of name-addr and does not include any rr-params. sip uri included in name-addr in turn cannot have ; and = in its param values.
it turned out that save error had nothing to do with syntax of path header, but was due to a bug that i fixed.
-- juha
On 04/09/2013 11:59 AM, Juha Heinanen wrote:
I see, probably you are right. We've had base64 encode/decode on our todo list for some time already (for broken UAs, e.g. some of them cut everything after "'"), so maybe we should offer user a choice of proper escaping and base64 encoding here.
2013/4/9 Juha Heinanen jh@tutpro.com:
In the above Path there is NO header params but JUST URI params (header params would be placed after the ">"). And indeed the above usage is INCORRECT. This is what happens when parsing a Route or Path header as the above:
Path: sip:192.98.102.10;transport=tcp;lr;received='sip:192.98.102.10:58156%3Btransport%3Dtcp'
Parsing result:
- display name: null - schema: sip - user: null - host: "192.98.102.10" (ipv4) - port: null - params: { "transport"=>"tcp'", "lr"=>null, "received"=>"'sip:192.98.102.10:58156", "transport"=> "tcp'" }
Do you see it? the above Path is BNF valid but 100% unexpected as there are the following URI params/values (now without double quotes):
transport : tcp lr : received : 'sip:192.98.102.10:58156 <-- note the initial ' !!! transport : tcp' <-- note the final ' !!!!
So the "received" value added by Kamailio is invalid. Such a value cannot be the value of a SIP URI parameter at all. I strongly propose encoding it in base64 or escaping the "=" and the ";" symbols when in a SIP URI param value as Juha suggests.
Regards.
-- Iñaki Baz Castillo ibc@aliax.net
2013/4/9 Richard Fuchs rfuchs@sipwise.com:
No. SIP already requires hex-(un)escaping in various places (i.e. the Replaces header requires it, a URI username could require it, etc), so it's expected that SIP libraries/clients/servers already include hex-(un)escaping support.
In the other side I don't remember any place in core SIP protocol in which Base64 is used, neither I know wheter Kamailio has built-in code for it or not (well, it's an easy addition anyhow...).
IMHO using the SIP core mechanisms for these kinds of needs (thus hex-(un)escaping) is the correct choice, but since the ;received URI param is a non standard hack which just Kamailio needs and understands, it can be done in any way.
Regards.
-- Iñaki Baz Castillo ibc@aliax.net
Although slightly off topic, I've been trying to craft a Path header that will work with FreeSWITCH.
See: http://jira.freeswitch.org/browse/FS-4989
It would be great if the Path header was compatible with what they want as well.
BR, Spencer
On Apr 9, 2013, at 4:05 PM, Iñaki Baz Castillo wrote:
As I said before, this Path header
Path: sip:10.59.1.195;lr;received='sip:10.59.1.241:5079;transport=tcp'
has a URI with these params:
- lr : no value - received : 'sip:10.59.1.241:5079 - transport : tcp'
And this is because quoting a *URI param* between single quotes is a bug in Kamailio.
Due to this bug, FreeSwitch finds a "transport" param in the Path URI with value tcp' (note the single quote ' at the end of "tcp") and, maybe, it parses it as "tcp" so chooses TCP for sending the initial requests.
Indeed, the Route header added by FS is:
Route: sip:10.59.1.195;lr;received=sip:10.59.1.241:5079;transport=tcp
Which means that it has "transport=tcp" and, of course, it tries TCP.
I insist, this is a bug in Kamailio since single quote and "=" symbols should be escaped when present a SIP URI parameter value.
2013/4/10 Spencer Thomason spencer@5ninesolutions.com:
below is patch that fixes receiced param value. i have not tested if kamalio that gets such a value is able to unescape the escaped chars. if not, that is a bug too.
-- juha
*** path.c Fri Mar 29 19:14:46 2013 --- /usr/src/sip-router/modules/path/path.c Wed Apr 10 08:09:43 2013 *************** *** 145,171 **** if (param == PATH_PARAM_RECEIVED) { /* TODO: agranig: optimize this one! */ src_ip = ip_addr2a(&_m->rcv.src_ip); ! rcv_addr.s = pkg_malloc(6 + IP_ADDR_MAX_STR_SIZE + 22); /* 'sip:<ip>:<port>;transport=sctp'\0 */ if(!rcv_addr.s) { LM_ERR("no pkg memory left for receive-address\n"); goto out3; } switch (_m->rcv.proto) { case PROTO_UDP: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 6, "'sip:%s:%u'", src_ip, _m->rcv.src_port); break; case PROTO_TCP: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 20, "'sip:%s:%u;transport=tcp'", src_ip, _m->rcv.src_port); break; case PROTO_TLS: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 20, "'sip:%s:%u;transport=tls'", src_ip, _m->rcv.src_port); break; case PROTO_SCTP: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 21, "'sip:%s:%u;transport=sctp'", src_ip, _m->rcv.src_port); break; case PROTO_WS: case PROTO_WSS: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 19, "'sip:%s:%u;transport=ws'", src_ip, _m->rcv.src_port); break; }
--- 145,171 ---- if (param == PATH_PARAM_RECEIVED) { /* TODO: agranig: optimize this one! */ src_ip = ip_addr2a(&_m->rcv.src_ip); ! rcv_addr.s = pkg_malloc(6 + IP_ADDR_MAX_STR_SIZE + 24); /* sip:<ip>:<port>%3Btransport%3Dsctp\0 */ if(!rcv_addr.s) { LM_ERR("no pkg memory left for receive-address\n"); goto out3; } switch (_m->rcv.proto) { case PROTO_UDP: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 4, "sip:%s:%u", src_ip, _m->rcv.src_port); break; case PROTO_TCP: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 22, "sip:%s:%u%%3Btransport%%3Dtcp", src_ip, _m->rcv.src_port); break; case PROTO_TLS: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 22, "sip:%s:%u%%3Btransport%%3Dtls", src_ip, _m->rcv.src_port); break; case PROTO_SCTP: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 23, "sip:%s:%u%%3Btransport%%3Dsctp", src_ip, _m->rcv.src_port); break; case PROTO_WS: case PROTO_WSS: ! rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 21, "sip:%s:%u%%3Btransport%%3Dws", src_ip, _m->rcv.src_port); break; }
Juha, could you please paste here how the Path above looks with your change?
Thanks a lot.
2013/4/10 Juha Heinanen jh@tutpro.com:
BTW not sure if your patch does it but I strongly suggest removing the useless and wrong single quotes around the received value (once such a value is properly hex-escaped it becomes a valid URI param value). Please remember that single quote is NOT a valid delimitator AT ALL for a SIP URI parameter value.
Regards.
2013/4/10 Iñaki Baz Castillo ibc@aliax.net:
Iñaki Baz Castillo writes:
Juha, could you please paste here how the Path above looks with your change?
here is an example:
Path: sip:192.98.102.10:5070;transport=tcp;lr;received=sip:192.98.102.11:35449%3Btransport%3Dtcp.
as you see, single quotes are gone, because they don't serve any purpose after escape.
-- juha
2013/4/10 Juha Heinanen jh@tutpro.com:
here is an example:
Path: sip:192.98.102.10:5070;transport=tcp;lr;received=sip:192.98.102.11:35449%3Btransport%3Dtcp.
Perfect.
as you see, single quotes are gone, because they don't serve any purpose after escape.
Not exactly, I want to insist on this: Single quotes did not server any purpose previously because using single quotes to delimit an URI param value is 100% wrong. As said in a previous mail, a perfect SIP parser would parse the initial wrong Path as follows (just info about URI params):
transport : tcp lr : (no value) received : 'sip:192.98.102.10:58156 <-- note the initial ' !!! transport : tcp' <-- note the final ' !!!!
So the single quote means nothing. There could be zero or N single quotes within or around an URI param value.
-- Iñaki Baz Castillo ibc@aliax.net
i tested and even when url path field contains escaped chars. however, i started to get these to syslog every 20 seconds
Apr 10 12:17:08 wheezy1 /usr/sbin/sip-proxy[3900]: ERROR: nathelper [nathelper.c:2018]: can't parse contact uri
most likely due to nat pinging. i haven't checked yet where they come from. contact field of the ua does not have any escaped chars in it.
-- juha
Juha Heinanen writes:
i added the uri to the error message and got:
nathelper [nathelper.c:2019]: can't parse contact uri 'sip:192.98.102.11:35453%3Btransport%3Dtcp'
single quotes are from my LM_ERR below, i.e., they are not in the uri itself. the uri in question is received uri and the call in nathelper.c is this:
if (parse_uri(c.s, c.len, &curi) < 0) { LM_ERR("can't parse contact uri '%.*s'\n", c.len, c.s);
so there clearly is a bug in parse_uri function. it cannot handle escaped chars.
when i have time, i'll add tracker issue about it.
-- juha
Hi,
2013/4/10 Juha Heinanen jh@tutpro.com
That is a wrong formed URI but a right formed URI parameter. The right URI format for the above is:
sip:192.98.102.11:35453;transport=tcp
While the right format for the same info when it is used as an URI parameter is:
sip:192.98.102.11:35453%3Btransport%3Dtcp
Of course I assume that modules dont implement unescaping uris encoded as URI param value. That needs to be coded.
Anyhow, why is the received stuff required at all? IMHO it is time for dropping custom/proprietary hacks and use rfc 5626 Outbound instead. Otherwise we must live with hacks in lot of places of the code and modules.
-- Iñaki Baz Castillo ibc@aliax.net El 10/04/2013 11:31, "Juha Heinanen" jh@tutpro.com escribió:
Peter Dunkley writes:
You can use the force_outbound option in the outbound module to make path and rr add flow-tokens even when the client isn't doing outbound.
thank for info. it may not work though, if registrar and edge proxy are combined. in my current test, i have two proxies/registrars each serving serving as edge proxy for the other. when ua registers with p1, p1 can force outbound when it forwards register to p2, but it cannot add those when it processes the register itself.
perhaps there could be an option to take path and rr flow tokens from pseudo vars instead of the headers?
-- juha
Single server outbound is on my todo list. I have put the details of what is needed here: http://www.kamailio.org/wiki/devel/completing_outbound
Don't know if or when I'll get time to do it though.
Regards,
Peter
On 10/04/13 11:54, Juha Heinanen wrote:
10 apr 2013 kl. 12:54 skrev Juha Heinanen jh@tutpro.com:
Can't you add and forward to yourself again? I do crazy stuff like that in many places. Just loop around to force a new transaction with new headers.
Just an idea. Maybe totally stupid.
/O
2013/4/10 Juha Heinanen jh@tutpro.com:
And hopefully received stuff is removed forever.
So now in the above scenario the registrar sends an initial INVITE to Kamailio with a top Route like:
Route: sip:192.98.102.10:5070;transport=tcp;lr;received=sip:192.98.102.11:35449%3Btransport%3Dtcp
and Kamailio must decode the received param, parse the URI and forward the request to it. This is a annoying loose-routing mechanism XDDD
Please, RFC 5626 is the solution for NAT.
-- Iñaki Baz Castillo ibc@aliax.net
There is no need at all for clients to be Outbound aware. The proxy can force it in the same way current "alias" / "contact mangling" / "received stuff" is used.
-- Iñaki Baz Castillo ibc@aliax.net El 10/04/2013 12:44, "Juha Heinanen" jh@tutpro.com escribió:
10 apr 2013 kl. 14:53 skrev Klaus Darilion klaus.mailinglists@pernau.at:
Outbound puts all the client connection management burden upon the client.
/O
10 apr 2013 kl. 15:32 skrev Peter Dunkley peter.dunkley@crocodile-rcs.com:
And we clearly know who supports outbound by the supported header.
Just noticed that Patton support half-outbound. One connection only (which of course limits failover) but the rest - keepalives and connection reuse.
/O
Remember that Outbound also works for UDP. In that case:
a) The Outbound Flow Token (the URI username in the Record-Route) must encode the public source IP:port of the request, and the Outbound proxy must be capable of encoding and decoding it for routing the request to the client (OverSIP does it).
b) The client should keepalive via STUN PING requests.
Anyhow, nothing prevents Kamailio to mantain the keepalive by sending OPTIONS or whatever, as currently it does when using other NAT-fix custom mechanisms.
Regards.
2013/4/10 Peter Dunkley peter.dunkley@crocodile-rcs.com:
i find and fixed the bug that caused parsing of path uri to fail when save() was called.
it still holds true that the path uri generated by add_path_received() is syntactically bogus. if the receiver is not kamailio, parsing of path uri would thus most likely fail.
what should be done about it? does kamailio support escaped chars in uri param values?
-- juha
Thanks for the bug-fix as the parsing should always work, but I am having difficulty understanding the configuration in use here.
This particular parsing problem only occurs when outbound is enabled in registrar and you have a received parameter to the Path: header. However, when using outbound I would not expect there to be a received parameter on the Path: header as the outbound flow-token does the same job.
Regards,
Peter