Hi all, I have a scenario where it's not clear to me what the best approach should be (Kamailio 3.2.0 on Squeeze, although I think it's a matter of routing logic only).
I have a client behind NAT that sends an initial REGISTER request with a Contact containing private ip:port (e.g. Contact: "GV" sip:12345@192.168.1.2:54321;transport=tcp ) However, after it's challenged for authentication with a 401, it sends the following REGISTER request with Authorization header and with a Contact containing ip:port equal to the 'received' SIP URI (with a combination of 'rport' and 'received' parameters (e.g. Contact: "GV" sip:12345@[receivedIP]:[rport];transport=tcp ) In this case kamailio's routing logic is not marking the REGISTER as natted (no Received field in location and no NAT flags set).
You can imagine I have a fairly standard NAT handling:
route[NATDETECT] { force_rport(); if (nat_uac_test("19")) { if (is_method("REGISTER")) { fix_nated_register(); } else { fix_nated_contact(); } setflag(FLT_NATS); } return; }
FLT_NATS won't be set, and so it won't FLB_NATB in the following processing.
This client receives a call: Kamailio relays the INVITE to it using the stored Contact. The INVITE is correctly received by the client, because the stored Contact refers to the connected socket ([received]:rport). The trouble starts when then the client replies with a 200 OK containing the private ip:port in the Contact header field (again 192.168.1.2:54321). The ACK will then have that private ip:port in the R-URI, and its relaying will fail.
One of the solutions I've found is using always add_contact_alias() in onreply_route when handling the 200 OK, and then use handle_ruri_alias() when defining the destination for the ACK.
I know that without traces and the full .cfg this is quite a broad question, but I wonder if you have already had to deal with this kind of client behaviour and can provide advice on the best practices. This is in particular useful for the re-use of TCP-based connections.
Thanks in advance, Giacomo
Truphone Limited is a limited liability company registered in England & Wales, registered office: 4 Royal Mint Court, London, EC3N 4HJ. Registered No. 04187081. VAT No. GB 851 5278 19. Tru is a brand name of Truphone and is a Truphone Communications Service. Truphone is a trading name for a number of distinct legal entities that operate in combination. www.truphone.comhttp://www.truphone.com.
This e-mail, and any attachment(s), may contain information which is confidential and/or privileged, and is intended for the addressee only. If you are not the intended recipient, you may not use, disclose, copy or distribute this information in any manner whatsoever. If you have received this e-mail in error, please contact the sender immediately and delete it.
Hello,
you can do nat_uac_test() for reply and it will detect is it natted, then you can call fix_nated_contact() -- this being another option.
Cheers, Daniel
On Fri, Mar 9, 2012 at 8:56 PM, Giacomo Vacca Giacomo.Vacca@truphone.comwrote:
Hi all,
I have a scenario where it’s not clear to me what the best approach should be (Kamailio 3.2.0 on Squeeze, although I think it’s a matter of routing logic only).
I have a client behind NAT that sends an initial REGISTER request with a Contact containing private ip:port (e.g.
Contact: “GV” sip:12345@192.168.1.2:54321;transport=tcp
)
However, after it’s challenged for authentication with a 401, it sends the following REGISTER request with Authorization header and with a Contact containing ip:port equal to the ‘received’ SIP URI (with a combination of ‘rport’ and ‘received’ parameters (e.g.
Contact: “GV” sip:12345@[receivedIP]:[rport];transport=tcp
)
In this case kamailio’s routing logic is not marking the REGISTER as natted (no Received field in location and no NAT flags set).
You can imagine I have a fairly standard NAT handling:
route[NATDETECT] {
force_rport(); if (nat_uac_test("19")) { if (is_method("REGISTER")) { fix_nated_register(); } else { fix_nated_contact(); } setflag(FLT_NATS); } return;
}
FLT_NATS won’t be set, and so it won’t FLB_NATB in the following processing.
This client receives a call: Kamailio relays the INVITE to it using the stored Contact. The INVITE is correctly received by the client, because the stored Contact refers to the connected socket ([received]:rport).
The trouble starts when then the client replies with a 200 OK containing the private ip:port in the Contact header field (again 192.168.1.2:54321).
The ACK will then have that private ip:port in the R-URI, and its relaying will fail.
One of the solutions I’ve found is using *always *add_contact_alias() in onreply_route when handling the 200 OK, and then use handle_ruri_alias() when defining the destination for the ACK.
I know that without traces and the full .cfg this is quite a broad question, but I wonder if you have already had to deal with this kind of client behaviour and can provide advice on the best practices.
This is in particular useful for the re-use of TCP-based connections.
Thanks in advance,
Giacomo
Truphone Limited is a limited liability company registered in England & Wales, registered office: 4 Royal Mint Court, London, EC3N 4HJ. Registered No. 04187081. VAT No. GB 851 5278 19.
Tru is a brand name of Truphone and is a Truphone Communications Service. Truphone is a trading name for a number of distinct legal entities that operate in combination. www.truphone.com.
This e-mail, and any attachment(s), may contain information which is confidential and/or privileged, and is intended for the addressee only. If you are not the intended recipient, you may not use, disclose, copy or distribute this information in any manner whatsoever. If you have received this e-mail in error, please contact the sender immediately and delete it.
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list sr-users@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
Am 09.03.2012 20:56, schrieb Giacomo Vacca:
One of the solutions I've found is using /always /add_contact_alias() in onreply_route when handling the 200 OK, and then use handle_ruri_alias() when defining the destination for the ACK.
Yes, that the pragmatic approach I always use. IMO it is also a bit of security. I do not like to blindly trust user provided data (e.g. contact header), thus I always use the IP:port from where the message was received.
regards Klaus
Thanks for your answers. I thought I could make an example with your suggestions, for documentation (I see others are interested at the moment).
Using add_contact_alias, when the 200 OK for an INVITE is received, e.g. from 10.0.9.49:61756:
SIP/2.0 200 OK [...] Contact: sip:giacomo@10.0.9.49:61750;transport=tcp
add_contact_alias detects that received ip:port is different than the one in the Contact, so it appends an alias before relaying the 200 OK:
SIP/2.0 200 OK [...] Contact: sip:giacomo@10.0.9.49:61750;alias=10.0.9.49~61756~2;transport=tcp
This will then be used when generating the ACK:
ACK sip:giacomo@10.0.9.49:61750;alias=10.0.9.49~61756~2;transport=tcp SIP/2.0 [...]
which Kamailio will change with handle_uri_alias(), removing the alias and setting the received ip:port as destination:
ACK sip:giacomo@10.0.9.49:61750;transport=tcp SIP/2.0
sent correctly to 10.0.9.49:61756.
With fix_nated_contact, same scenario, Kamailio would modify the Contact before relaying the 200 OK: SIP/2.0 200 OK [...] Contact: sip:giacomo@10.0.9.49:61756;transport=tcp
Which will then be used as R-URI for the ACK:
ACK sip:giacomo@10.0.9.49:61756;transport=tcp SIP/2.0 [...]
And sent without modifications to 10.0.9.49:61756.
As stated in other references, the difference is that with the add_contact_alias approach the invited client sees its published Contact in the ACK's R-URI.
I hope this is useful. Regards, Giacomo
From: Klaus Darilion [mailto:klaus.mailinglists@pernau.at] Sent: 11 March 2012 13:10 To: SIP Router - Kamailio (OpenSER) and SIP Express Router (SER) - Users Mailing List Cc: Giacomo Vacca Subject: Re: [SR-Users] Best approach for TCP/TLS connection re-use for nated Contacts
Am 09.03.2012 20:56, schrieb Giacomo Vacca: One of the solutions I've found is using always add_contact_alias() in onreply_route when handling the 200 OK, and then use handle_ruri_alias() when defining the destination for the ACK.
Yes, that the pragmatic approach I always use. IMO it is also a bit of security. I do not like to blindly trust user provided data (e.g. contact header), thus I always use the IP:port from where the message was received.
regards Klaus Truphone Limited is a limited liability company registered in England & Wales, registered office: 4 Royal Mint Court, London, EC3N 4HJ. Registered No. 04187081. VAT No. GB 851 5278 19. Tru is a brand name of Truphone and is a Truphone Communications Service. Truphone is a trading name for a number of distinct legal entities that operate in combination. www.truphone.comhttp://www.truphone.com.
This e-mail, and any attachment(s), may contain information which is confidential and/or privileged, and is intended for the addressee only. If you are not the intended recipient, you may not use, disclose, copy or distribute this information in any manner whatsoever. If you have received this e-mail in error, please contact the sender immediately and delete it.