Hello,
I am trying to implement the following configuration :
- Kamailio as a SIP proxy/registrar behind a one-to-one NAT (port number is not modified) listening on ports 5060 and 53 (and more ports in the future) - aliases correctly configured : alias= udp: public_ip:53 alias= udp: public_ip:5060 alias= udp: hostname:53 alias= udp: hostname:5060 - listen directive correctly on private ip address and both ports : listen=udp:private_ip:53 listen=udp:private_ip:5060 - advertised_address=public_ip - record_route_preset("public_ip") is used to announce the public IP address in the RR header - user A : registered on port 5060 - user B : registered on port 53
Suppose user A tries to call user B.
The Record-Route header in the INVITE forwarded from Kamailio to user B should contain the port number on which user B is connected (53), to force user B to send future requests to that port number. But I have no method to know which port user B is connected to, and that problem is aggravated when user B has multiple registrations on different port numbers and parralel forking is done. Declaring advertised_port doesn't solve the problem. I cannot force port number 53 in record_route_preset("public_ip:53") since it wouldn't work when user B calls user A. Using the record_route( ) function, Kamailio doesn't use the advertised_address to construct the RR header.
Another problem is that the record_route_preset function clears the DID cookie set by the dialog module, which makes Kamailio fallback to SIP elements to match the request to an existing dialog, thus dialog matching becomes slower, and performance is an issue for me.
Any suggestions? I know that one solution would be to run Kamailio with a public IP address and no NAT, but unfortunately it's not possible.
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the private IP address on which Kamailio listens with a public IP address. Or that the record_route( ) function uses the advertised_address to construct the RR header.
Thank you RA
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote:
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the private IP address on which Kamailio listens with a public IP address. Or that the record_route( ) function uses the advertised_address to construct the RR header.
maybe you are looking for the function record_route_advertised_address() which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
I know about record_route_advertised_address("ip:port") function. If I understood correctly, it inserts a top-most RR header with the public IP if double RR is enabled. But that doesn't solve the multiple ports problem. I would get in the SIP header :
Record-Route: <public_ip;lr=on> Record-Route: <private_ip:port;lr=on>
If user B sees the first Record-Route header, it remembers port=5060 for future requests. I cannot manually set the port in the config file since it depends on which port user B is registered, which I don't have a way to find it.
RA
On Mon, Jan 16, 2012 at 15:51, Andrew Pogrebennyk apogrebennyk@sipwise.comwrote:
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote:
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the private IP address on which Kamailio listens with a public IP address. Or that the record_route( ) function uses the advertised_address to construct the RR header.
maybe you are looking for the function record_route_advertised_address() which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
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
I just tried the record_route_advertised_address("public_ip"). It doesn't add the port number of the outgoing socket.
Any suggestions?
RA
On Mon, Jan 16, 2012 at 15:57, Reda Aouad reda.aouad@gmail.com wrote:
I know about record_route_advertised_address("ip:port") function. If I understood correctly, it inserts a top-most RR header with the public IP if double RR is enabled. But that doesn't solve the multiple ports problem. I would get in the SIP header :
Record-Route: <public_ip;lr=on> Record-Route: <private_ip:port;lr=on>
If user B sees the first Record-Route header, it remembers port=5060 for future requests. I cannot manually set the port in the config file since it depends on which port user B is registered, which I don't have a way to find it.
RA
On Mon, Jan 16, 2012 at 15:51, Andrew Pogrebennyk < apogrebennyk@sipwise.com> wrote:
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote:
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the private IP address on which Kamailio listens with a public IP address. Or that the record_route( ) function uses the advertised_address to construct the RR header.
maybe you are looking for the function record_route_advertised_address() which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
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
When you route through usrloc, there is a PV that should be set - forced socket: http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#forced_socket You can check the socket via 'kamctl ul show' command. If the PV is not populated, check the send attributes: http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#send_address_at... Based on that, you should know through which interface the INVITE should be sent and therefore you should be able to set the proper Record-Route header.
Regards, Ovidiu Sas
-- VoIP Embedded, Inc. http://www.voipembedded.com
On Tue, Jan 17, 2012 at 3:01 PM, Reda Aouad reda.aouad@gmail.com wrote:
I just tried the record_route_advertised_address("public_ip"). It doesn't add the port number of the outgoing socket.
Any suggestions?
RA
On Mon, Jan 16, 2012 at 15:57, Reda Aouad reda.aouad@gmail.com wrote:
I know about record_route_advertised_address("ip:port") function. If I understood correctly, it inserts a top-most RR header with the public IP if double RR is enabled. But that doesn't solve the multiple ports problem. I would get in the SIP header :
Record-Route: <public_ip;lr=on> Record-Route: <private_ip:port;lr=on>
If user B sees the first Record-Route header, it remembers port=5060 for future requests. I cannot manually set the port in the config file since it depends on which port user B is registered, which I don't have a way to find it.
RA
On Mon, Jan 16, 2012 at 15:51, Andrew Pogrebennyk apogrebennyk@sipwise.com wrote:
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote:
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the private IP address on which Kamailio listens with a public IP address. Or that the record_route( ) function uses the advertised_address to construct the RR header.
maybe you are looking for the function record_route_advertised_address() which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
Thank you for your reply. I tried what you suggested.
The problem is when there are multiple locations/registrations per AOR on different ports and doing parallel forking. Accessing $fs only gives one of the sockets (first or last?), not all of them. Accessing $sndfrom gives all of the used outgoing sockets, because it's populated in the onsedn_route route, which is called for every outgoing packet, but in onsend_route I can't use record_route functions, neither mangle with the SIP header anymore in any way. It's too late by the time I get to onsend_route...
No solution so far..
Reda
On Tue, Jan 17, 2012 at 21:47, Ovidiu Sas osas@voipembedded.com wrote:
When you route through usrloc, there is a PV that should be set - forced socket: http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#forced_socket You can check the socket via 'kamctl ul show' command. If the PV is not populated, check the send attributes:
http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#send_address_at... Based on that, you should know through which interface the INVITE should be sent and therefore you should be able to set the proper Record-Route header.
Regards, Ovidiu Sas
-- VoIP Embedded, Inc. http://www.voipembedded.com
On Tue, Jan 17, 2012 at 3:01 PM, Reda Aouad reda.aouad@gmail.com wrote:
I just tried the record_route_advertised_address("public_ip"). It doesn't add the port number of the outgoing socket.
Any suggestions?
RA
On Mon, Jan 16, 2012 at 15:57, Reda Aouad reda.aouad@gmail.com wrote:
I know about record_route_advertised_address("ip:port") function. If I understood correctly, it inserts a top-most RR header with the public
IP if
double RR is enabled. But that doesn't solve the multiple ports
problem. I
would get in the SIP header :
Record-Route: <public_ip;lr=on> Record-Route: <private_ip:port;lr=on>
If user B sees the first Record-Route header, it remembers port=5060 for future requests. I cannot manually set the port in the config file since it depends on which port user B is registered, which I don't have a way to find it.
RA
On Mon, Jan 16, 2012 at 15:51, Andrew Pogrebennyk apogrebennyk@sipwise.com wrote:
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote:
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the
private
IP address on which Kamailio listens with a public IP address. Or
that
the record_route( ) function uses the advertised_address to construct the RR header.
maybe you are looking for the function
record_route_advertised_address()
which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
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
Test them in branch_route: http://www.kamailio.org/wiki/cookbooks/3.2.x/core#branch_route and set the Record-Route header there, for each individual branch.
Regards, Ovidiu Sas
-- VoIP Embedded, Inc. http://www.voipembedded.com
On Wed, Jan 18, 2012 at 5:37 PM, Reda Aouad reda.aouad@gmail.com wrote:
Thank you for your reply. I tried what you suggested.
The problem is when there are multiple locations/registrations per AOR on different ports and doing parallel forking. Accessing $fs only gives one of the sockets (first or last?), not all of them. Accessing $sndfrom gives all of the used outgoing sockets, because it's populated in the onsedn_route route, which is called for every outgoing packet, but in onsend_route I can't use record_route functions, neither mangle with the SIP header anymore in any way. It's too late by the time I get to onsend_route...
No solution so far..
Reda
On Tue, Jan 17, 2012 at 21:47, Ovidiu Sas osas@voipembedded.com wrote:
When you route through usrloc, there is a PV that should be set - forced socket: http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#forced_socket You can check the socket via 'kamctl ul show' command. If the PV is not populated, check the send attributes:
http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#send_address_at... Based on that, you should know through which interface the INVITE should be sent and therefore you should be able to set the proper Record-Route header.
Regards, Ovidiu Sas
-- VoIP Embedded, Inc. http://www.voipembedded.com
On Tue, Jan 17, 2012 at 3:01 PM, Reda Aouad reda.aouad@gmail.com wrote:
I just tried the record_route_advertised_address("public_ip"). It doesn't add the port number of the outgoing socket.
Any suggestions?
RA
On Mon, Jan 16, 2012 at 15:57, Reda Aouad reda.aouad@gmail.com wrote:
I know about record_route_advertised_address("ip:port") function. If I understood correctly, it inserts a top-most RR header with the public IP if double RR is enabled. But that doesn't solve the multiple ports problem. I would get in the SIP header :
Record-Route: <public_ip;lr=on> Record-Route: <private_ip:port;lr=on>
If user B sees the first Record-Route header, it remembers port=5060 for future requests. I cannot manually set the port in the config file since it depends on which port user B is registered, which I don't have a way to find it.
RA
On Mon, Jan 16, 2012 at 15:51, Andrew Pogrebennyk apogrebennyk@sipwise.com wrote:
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote:
I suggest that the function record_route( ) takes a public IP address as a parameter, still doing what it does (correct record routing and cookie addition did=xxx and loose route lr=on), but only replacing the private IP address on which Kamailio listens with a public IP address. Or that the record_route( ) function uses the advertised_address to construct the RR header.
maybe you are looking for the function record_route_advertised_address() which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
Okay, it seems we're on the right track.. BUT
This is my code in the branch_route
if (is_method("INVITE|SUBSCRIBE")){ $avp(s:fs) = $fs; $avp(s:Rp) = $Rp; avp_subst("$avp(s:fs)", "/(.*):(.*):(.*)/\3/"); #xlog("fs: $avp(s:fs) | Rp: $avp(s:Rp)"); if ($avp(s:fs) == $avp(s:Rp)) { record_route_preset("PUBLIC_IP:$avp(s:fs)"); return; } record_route_preset("PUBLIC_IP:$avp(s:fs)", "PUBLIC_IP:$avp(s:Rp)"); } return;
$avp(s:fs) is the outbound socket, on which I apply the avp_subst function to extract only the outbound port number Kamailio should send from. $avp(s:Rp) is the inbound port, the port on which Kamailio received the INVITE. Then if the above port numbers are equal, I do only one record route. If not, I do double record routing, one per port number.
The problem is that for the first branch, everything works fine. But for the subsequent branches, I get the following error : ERROR: rr [rr_mod.c:256]: Duble attempt to record-route
It seems that for subsequent branches, Kamailio detects that it already record routed the first branch, so gives an error and doesn't record route.
Reda
On Wed, Jan 18, 2012 at 23:45, Ovidiu Sas osas@voipembedded.com wrote:
Test them in branch_route: http://www.kamailio.org/wiki/cookbooks/3.2.x/core#branch_route and set the Record-Route header there, for each individual branch.
Regards, Ovidiu Sas
-- VoIP Embedded, Inc. http://www.voipembedded.com
On Wed, Jan 18, 2012 at 5:37 PM, Reda Aouad reda.aouad@gmail.com wrote:
Thank you for your reply. I tried what you suggested.
The problem is when there are multiple locations/registrations per AOR on different ports and doing parallel forking. Accessing $fs only gives one of the sockets (first or last?), not all of them. Accessing $sndfrom gives all of the used outgoing sockets, because it's populated in the onsedn_route route, which is called for every outgoing packet, but in onsend_route I can't use record_route functions, neither mangle with the SIP header anymore in any way. It's too late by the time
I
get to onsend_route...
No solution so far..
Reda
On Tue, Jan 17, 2012 at 21:47, Ovidiu Sas osas@voipembedded.com wrote:
When you route through usrloc, there is a PV that should be set - forced socket:
http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#forced_socket
You can check the socket via 'kamctl ul show' command. If the PV is not populated, check the send attributes:
http://www.kamailio.org/wiki/cookbooks/devel/pseudovariables#send_address_at...
Based on that, you should know through which interface the INVITE should be sent and therefore you should be able to set the proper Record-Route header.
Regards, Ovidiu Sas
-- VoIP Embedded, Inc. http://www.voipembedded.com
On Tue, Jan 17, 2012 at 3:01 PM, Reda Aouad reda.aouad@gmail.com
wrote:
I just tried the record_route_advertised_address("public_ip"). It doesn't add the port number of the outgoing socket.
Any suggestions?
RA
On Mon, Jan 16, 2012 at 15:57, Reda Aouad reda.aouad@gmail.com
wrote:
I know about record_route_advertised_address("ip:port") function. If
I
understood correctly, it inserts a top-most RR header with the public IP if double RR is enabled. But that doesn't solve the multiple ports problem. I would get in the SIP header :
Record-Route: <public_ip;lr=on> Record-Route: <private_ip:port;lr=on>
If user B sees the first Record-Route header, it remembers port=5060 for future requests. I cannot manually set the port in the config file since it depends on which port user B is registered, which I don't have a way to find it.
RA
On Mon, Jan 16, 2012 at 15:51, Andrew Pogrebennyk apogrebennyk@sipwise.com wrote:
Hi,
On 01/16/2012 03:41 PM, Reda Aouad wrote: > I suggest that the function record_route( ) takes a public IP > address > as > a parameter, still doing what it does (correct record routing and > cookie > addition did=xxx and loose route lr=on), but only replacing the > private > IP address on which Kamailio listens with a public IP address. Or > that > the record_route( ) function uses the advertised_address to > construct > the RR header.
maybe you are looking for the function record_route_advertised_address() which is available in git master: http://web.archiveorange.com/archive/v/jZFTGE0yjPqCTTcAkzuf
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
After endless tests, I tried to replace record_route_preset with insert_hf, writing the complete record route headers. A light started to come out of the tunnel.....
Suppose User A is registered to port 53, User B to port 5060.
In the case of double record route, when A sends an INVITE to B, I write the following in the SIP header of the INVITE forwarded to B : Record-Route: sip:public_ip:5060;r2=on;lr=on Record-Route: sip:public_ip:53;r2=on;lr=on
The first transaction, INVITE / 200OK goes well, with Kamailio forwarding packets correctly from the corresponding socket of each user.
The problem arises when User B sends BYE to the 5060 port, with both route headers in the SIP header of the BYE. I get the following error : WARNING: rr [loose.c:747]: no socket found for match second RR
after which Kamailio forwards the BYE from the 5060 socket to User A. User A being registered on port 53, ignores the packet coming with source port 5060. The BYE is never replied to.
I guess that means that Kamailio is not able to find the private_ip:53 socket from the public_ip:53 record-route header. I hope it was clear.
I think there's a fundamental issue with running Kamailio behind NAT and listening on multiple port numbers. Am I the only one suffering from this type of configuration?
(Part of the problem is also tied to dumb ALG NAT routers which try to out-smart SIP servers, without which I wouldn't run Kamailio on multiple ports, and life would be much easier)
RA
On Thu, Jan 19, 2012 at 01:00, Reda Aouad reda.aouad@gmail.com wrote:
Okay, it seems we're on the right track.. BUT
This is my code in the branch_route
if (is_method("INVITE|SUBSCRIBE")){ $avp(s:fs) = $fs; $avp(s:Rp) = $Rp; avp_subst("$avp(s:fs)", "/(.*):(.*):(.*)/\3/"); #xlog("fs: $avp(s:fs) | Rp: $avp(s:Rp)"); if ($avp(s:fs) == $avp(s:Rp)) { record_route_preset("PUBLIC_IP:$avp(s:fs)"); return; } record_route_preset("PUBLIC_IP:$avp(s:fs)",
"PUBLIC_IP:$avp(s:Rp)"); } return;
$avp(s:fs) is the outbound socket, on which I apply the avp_subst function to extract only the outbound port number Kamailio should send from. $avp(s:Rp) is the inbound port, the port on which Kamailio received the INVITE. Then if the above port numbers are equal, I do only one record route. If not, I do double record routing, one per port number.
The problem is that for the first branch, everything works fine. But for the subsequent branches, I get the following error : ERROR: rr [rr_mod.c:256]: Duble attempt to record-route
It seems that for subsequent branches, Kamailio detects that it already record routed the first branch, so gives an error and doesn't record route.
Reda
Hi Reda
A bit late for a reply but I found your post recently and it helped me to solve a similar problem, so I wanted to share one possible solution.
On 21 January 2012 23:19, Reda Aouad reda.aouad@gmail.com wrote:
After endless tests, I tried to replace record_route_preset with insert_hf, writing the complete record route headers. A light started to come out of the tunnel.....
Suppose User A is registered to port 53, User B to port 5060.
In the case of double record route, when A sends an INVITE to B, I write the following in the SIP header of the INVITE forwarded to B : Record-Route: sip:public_ip:5060;r2=on;lr=on Record-Route: sip:public_ip:53;r2=on;lr=on
The first transaction, INVITE / 200OK goes well, with Kamailio forwarding packets correctly from the corresponding socket of each user.
The problem arises when User B sends BYE to the 5060 port, with both route headers in the SIP header of the BYE. I get the following error : WARNING: rr [loose.c:747]: no socket found for match second RR
after which Kamailio forwards the BYE from the 5060 socket to User A. User A being registered on port 53, ignores the packet coming with source port 5060. The BYE is never replied to.
I guess that means that Kamailio is not able to find the private_ip:53 socket from the public_ip:53 record-route header. I hope it was clear.
One way to get around this is to populate the RR with a hostname instead of an address. Then you can configure it so that the external clients resolve public_ip but the Kamailio server itself resolves private_ip. This can be done through an entry in /etc/hosts to override the public DNS entry.
Not exactly elegant but it works for me.
I think there's a fundamental issue with running Kamailio behind NAT and listening on multiple port numbers. Am I the only one suffering from this type of configuration?
(Part of the problem is also tied to dumb ALG NAT routers which try to out-smart SIP servers, without which I wouldn't run Kamailio on multiple ports, and life would be much easier)
Regards, Richard
Thanks Richard for the tip :)
Reda
On Sun, Jun 24, 2012 at 7:28 PM, Richard Brady rnbrady@gmail.com wrote:
Hi Reda
A bit late for a reply but I found your post recently and it helped me to solve a similar problem, so I wanted to share one possible solution.
On 21 January 2012 23:19, Reda Aouad reda.aouad@gmail.com wrote:
After endless tests, I tried to replace record_route_preset with
insert_hf,
writing the complete record route headers. A light started to come out of the tunnel.....
Suppose User A is registered to port 53, User B to port 5060.
In the case of double record route, when A sends an INVITE to B, I write
the
following in the SIP header of the INVITE forwarded to B : Record-Route: sip:public_ip:5060;r2=on;lr=on Record-Route: sip:public_ip:53;r2=on;lr=on
The first transaction, INVITE / 200OK goes well, with Kamailio forwarding packets correctly from the corresponding socket of each user.
The problem arises when User B sends BYE to the 5060 port, with both
route
headers in the SIP header of the BYE. I get the following error : WARNING: rr [loose.c:747]: no socket found for match second RR
after which Kamailio forwards the BYE from the 5060 socket to User A.
User A
being registered on port 53, ignores the packet coming with source port 5060. The BYE is never replied to.
I guess that means that Kamailio is not able to find the private_ip:53 socket from the public_ip:53 record-route header. I hope it was clear.
One way to get around this is to populate the RR with a hostname instead of an address. Then you can configure it so that the external clients resolve public_ip but the Kamailio server itself resolves private_ip. This can be done through an entry in /etc/hosts to override the public DNS entry.
Not exactly elegant but it works for me.
I think there's a fundamental issue with running Kamailio behind NAT and listening on multiple port numbers. Am I the only one suffering from this type of configuration?
(Part of the problem is also tied to dumb ALG NAT routers which try to out-smart SIP servers, without which I wouldn't run Kamailio on multiple ports, and life would be much easier)
Regards, Richard
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