Hi all,
I am trying to place Kamailio between several SIP services which are differentiated by port and by the type of message they handle. To be concrete, here are the services:
Originator: - reachable on port 5060 - originates all traffic to the services
Service A: - reachable on port 5061 - handles REGISTER
Service B: - reachable on port 5062 - handles INVITE
Service C: - reachable on port 5063 - handles MESSAGE
The services, originator and Kamailio instance may all be run on the same IP or may be split onto different addresses. Previously, the originator needed to know the address and port of each service. Now I want to make Kamailio responsible for that task so it can be done more intelligently.
To start though I simply want to get traffic flowing between the services and this is where I’m struggling to climb the learning curve. In my test setup the originator and all services are on the same IP with only Kamailio running on a different IP.
Address 1 Address 2 ======================== Originator <--> Kamailio:6060 | | Service A <-------> | Service B <-------> | Service C <-------> |
My first attempt at the logic looks like this:
# HOST DEFINITIONS #!substdef "/HOST_ORIGINATOR/192.168.86.110/" #!substdef "/HOST_REGISTER/192.168.86.110/“ #!substdef "/HOST_INVITE/192.168.86.110/" #!substdef "/HOST_MESSAGE/192.168.86.110/"
# PORT DEFINITIONS #!substdef “/PORT_ORIGINATOR/5060/" #!substdef "/PORT_REGISTER/5061/“ #!substdef "/PORT_INVITE/5062/" #!substdef "/PORT_MESSAGE/5063/"
# ROUTE LOGIC route {
# ORIGINATOR sent us something if ( $(ct{nameaddr.uri}{uri.port}) == HOST_ORIGINATOR ) {
xlog("L_INFO", "ORIGINATOR: sent $rm\n”);
if (is_method("REGISTER")) { $du = "sip: HOST_REGISTER:PORT_REGISTER"; xlog("L_INFO", "ORIGINATOR -> REGISTER: Destination URI is now $du\n"); t_relay(); exit; } } …
#### END SNIPPET ####
My very newbie questions are: - Am I even on the right track here? I understand that t_relay() establishes a stateful dialog handler between the originator and register services. - Can I accomplish this bi-directional path statelessly with forward()? - Do I need to add logic to handle the messages from the REGISTER service back to ORIGINATOR?
This config currently fails because of "no corresponding socket found” when the relay triggers. I believe this is because I’m running the Kamailio instance in a Docker container so my first step today is to set up a native install.
I also looked at the dispatcher module which seems very close to what I want to do. Maybe that’s a more natural way to go?
Anyway, apologies for the lengthy explanation. I hope it is at least clear what I intend to do. I will gladly research and do trial and error to solve this but need to know I’m going down roughly the right path. I’m not sure what I should even be googling even of the time :-)
Thanks as always for your time and the great software!
Regards, -Michael
I’ve switched from a Dockerized Kamailio instance to a native installation. Here is my most recent trace when trying to forward traffic:
0(70677) INFO: <script>: ORIGINATOR -> REGISTER: Destination URI is now sip:192.168.86.110:5061 0(70677) ERROR: *** cfgtrace:request_route=[DEFAULT_ROUTE] c=[/etc/kamailio/kamailio-proxy.cfg] l=155 a=24 n=t_relay 0(70677) ERROR: <core> [core/forward.c:181]: get_out_socket(): no socket found 0(70677) ERROR: <core> [core/forward.c:183]: get_out_socket(): no corresponding socket found for(udp:192.168.86.110:5061) 0(70677) ERROR: tm [./ut.h:318]: uri2dst2(): no corresponding socket found for "192.168.86.110" af 2 (udp:192.168.86.110:5061) 0(70677) ERROR: tm [t_fwd.c:467]: prepare_new_uac(): can't fwd to af 2, proto 1 (no corresponding listening socket) 0(70677) ERROR: tm [t_fwd.c:1724]: t_forward_nonack(): failure to add branches 0(70677) ERROR: *** cfgtrace:request_route=[DEFAULT_ROUTE] c=[/etc/kamailio/kamailio-proxy.cfg] l=156 a=2 n=exit
My Kamailio instance is running on 192.168.86.107:6060. The originating service is on 192.168.86.110:5060. The REGISTER service is on 192.168.86.110:5061.
The refactor in my architecture I’m trying to make is: - previously: Originator Service -> Register Service - now: Originator -> Kamailio -> Register Service
I’m trying to get traffic from 192.168.86.110:5060 to route to 192.168.86.110:5061 but keep seeing this “no socket found” error. I didn’t think I was trying to bind that address, just rewriting the $du to point to the different host and port...
# ORIGINATOR sent us something if ( $(ct{nameaddr.uri}{uri.port}) == PORT_ORIGINATOR ) {
xlog("L_INFO", "ORIGINATOR: sent $rm\n”);
if (is_method("REGISTER")) { $du = "sip: HOST_REGISTER:PORT_REGISTER"; xlog("L_INFO", "ORIGINATOR -> REGISTER: Destination URI is now $du\n"); t_relay(); exit; } ... }
## END SNIPPET ##
Apologies if I’m missing something obvious! Thanks as always for your time.
-Michael
On Nov 19, 2019, at 10:24, Michael Iedema michael@kapsulate.com wrote:
Hi all,
I am trying to place Kamailio between several SIP services which are differentiated by port and by the type of message they handle. To be concrete, here are the services:
Originator:
- reachable on port 5060
- originates all traffic to the services
Service A:
- reachable on port 5061
- handles REGISTER
Service B:
- reachable on port 5062
- handles INVITE
Service C:
- reachable on port 5063
- handles MESSAGE
The services, originator and Kamailio instance may all be run on the same IP or may be split onto different addresses. Previously, the originator needed to know the address and port of each service. Now I want to make Kamailio responsible for that task so it can be done more intelligently.
To start though I simply want to get traffic flowing between the services and this is where I’m struggling to climb the learning curve. In my test setup the originator and all services are on the same IP with only Kamailio running on a different IP.
Address 1 Address 2
Originator <--> Kamailio:6060 | | Service A <-------> | Service B <-------> | Service C <-------> |
My first attempt at the logic looks like this:
# HOST DEFINITIONS #!substdef "/HOST_ORIGINATOR/192.168.86.110/" #!substdef "/HOST_REGISTER/192.168.86.110/“ #!substdef "/HOST_INVITE/192.168.86.110/" #!substdef "/HOST_MESSAGE/192.168.86.110/"
# PORT DEFINITIONS #!substdef “/PORT_ORIGINATOR/5060/" #!substdef "/PORT_REGISTER/5061/“ #!substdef "/PORT_INVITE/5062/" #!substdef "/PORT_MESSAGE/5063/"
# ROUTE LOGIC route {
# ORIGINATOR sent us something if ( $(ct{nameaddr.uri}{uri.port}) == HOST_ORIGINATOR ) {
xlog("L_INFO", "ORIGINATOR: sent $rm\n”);
if (is_method("REGISTER")) { $du = "sip: HOST_REGISTER:PORT_REGISTER"; xlog("L_INFO", "ORIGINATOR -> REGISTER: Destination URI is now $du\n"); t_relay(); exit; } } …
#### END SNIPPET ####
My very newbie questions are:
- Am I even on the right track here? I understand that t_relay() establishes a stateful dialog handler between the originator and register services.
- Can I accomplish this bi-directional path statelessly with forward()?
- Do I need to add logic to handle the messages from the REGISTER service back to ORIGINATOR?
This config currently fails because of "no corresponding socket found” when the relay triggers. I believe this is because I’m running the Kamailio instance in a Docker container so my first step today is to set up a native install.
I also looked at the dispatcher module which seems very close to what I want to do. Maybe that’s a more natural way to go?
Anyway, apologies for the lengthy explanation. I hope it is at least clear what I intend to do. I will gladly research and do trial and error to solve this but need to know I’m going down roughly the right path. I’m not sure what I should even be googling even of the time :-)
Thanks as always for your time and the great software!
Regards, -Michael
Hi Michael,
First, the "no corresponding socket" issue is the result of a determination by Kamailio that it has no outgoing listener (the combination of transport protocol, IP address and port) interface that can reach the destination network of the next hop.
The way that Kamailio makes this determination is influenced by this setting -- not sure if you have it on.
https://www.kamailio.org/wiki/cookbooks/5.3.x/core#mhomed
Keep in mind that the entire triplet - (transport, address, port) - matters.
Second, I noticed your comment
# ORIGINATOR sent us something
and considered this condition:
if ( $(ct{nameaddr.uri}{uri.port}) == PORT_ORIGINATOR )
it's probably worth keeping in mind that Contact is a fairly cosmetic value and can be set to just about anything, and most importantly, can be spoofed. So, if you are using this to determine whether a given component of your infrastructure sent you something, you might want to operate on the real source address and port of the SIP message instead:
https://www.kamailio.org/wiki/cookbooks/5.3.x/pseudovariables#si_-_source_ip...
https://www.kamailio.org/wiki/cookbooks/5.3.x/pseudovariables#sp_-_source_po...
Third: this is by way of philosophical commentary only, and under the aegis of "helping newbies" :-) -- others may disagree, and are free to do so.
Early on in my experience with Kamailio (then OpenSER), I was responsible for some rather unfortunately baroque platform architecture designs involving many specialised Kamailio proxies performing esoteric functions. This was based on a consistent tendency to underestimate how much traffic Kamailio can actually handle and how much work it can do. I've designed platforms with a dedicated registrar, dedicated business logic / call processing logic, and a carrier-facing element, separated into multiple instances, all deployed with redundant mates, etc.
Some of them I still have to support, and they're a nightmare, and most importantly of all, from a technical point of view they're completely unnecessary. In hindsight, it was all a mistake, and can easily be done with a single Kamailio element 99% of the time (as long as the config is manageable in its organisation), and I regret it all deeply. Cloud orchestration / deployment tooling that did not exist in those days might have made it a little easier, but also in many respects more complicated due to all the service discovery required.
I was thinking about this in the context of:
Originator:
- reachable on port 5060
- originates all traffic to the services
Service A:
- reachable on port 5061
- handles REGISTER
Service B:
- reachable on port 5062
- handles INVITE
Service C:
- reachable on port 5063
- handles MESSAGE
I could be wrong, and you might have very credible reasons for such a design, but at first glance it reminds me of some massively overcomplicated things I built when I first got started with Kamailio. :-) As I said, they were all based on a perception that this or that element can only handle so much, but it turns out one element can handle it all - and 20x more.
-- Alex
Thank you to everyone who has chimed in on this thread. I’m learning a lot! I now have some successful flows and have resolved the bind issue by setting a specific bind interface.
The reason for such specialized endpoints (one for REGISTER, one for INVITE, etc) is that they already exist. My intention is to place Kamailio in front of them to eventually accomplish the following soft migration:
1) initially just forward traffic transparently from the originator to allow the legacy endpoints to continue to serve 2) new SIP accounts will be added which are not present in the legacy endpoints’ databases 3) when Kamailio sees a 404 when passing through the traffic, it will then handle the traffic itself 4) eventually all accounts will be transitioned to use the new Kamailio-only route so the legacy endpoints can be deprecated
With all of that in mind, t_relay() doesn’t look like it’s going to get me there. I want Kamailio to be able to see everything going on between the origination and legacy endpoints but right now they respond to the originator directly without passing back through Kamailio on the return.
Apologies again for the possible rephrasing of the same technical question. I probably should have explained my design’s purpose in the beginning to clarify why I cannot let the Kamailio instance be optimized out of the path.
Thanks as always for your time, -Michael
On Nov 20, 2019, at 16:08, Alex Balashov abalashov@evaristesys.com wrote:
Hi Michael,
First, the "no corresponding socket" issue is the result of a determination by Kamailio that it has no outgoing listener (the combination of transport protocol, IP address and port) interface that can reach the destination network of the next hop.
The way that Kamailio makes this determination is influenced by this setting -- not sure if you have it on.
https://www.kamailio.org/wiki/cookbooks/5.3.x/core#mhomed
Keep in mind that the entire triplet - (transport, address, port) - matters.
Second, I noticed your comment
# ORIGINATOR sent us something
and considered this condition:
if ( $(ct{nameaddr.uri}{uri.port}) == PORT_ORIGINATOR )
it's probably worth keeping in mind that Contact is a fairly cosmetic value and can be set to just about anything, and most importantly, can be spoofed. So, if you are using this to determine whether a given component of your infrastructure sent you something, you might want to operate on the real source address and port of the SIP message instead:
https://www.kamailio.org/wiki/cookbooks/5.3.x/pseudovariables#si_-_source_ip...
https://www.kamailio.org/wiki/cookbooks/5.3.x/pseudovariables#sp_-_source_po...
Third: this is by way of philosophical commentary only, and under the aegis of "helping newbies" :-) -- others may disagree, and are free to do so.
Early on in my experience with Kamailio (then OpenSER), I was responsible for some rather unfortunately baroque platform architecture designs involving many specialised Kamailio proxies performing esoteric functions. This was based on a consistent tendency to underestimate how much traffic Kamailio can actually handle and how much work it can do. I've designed platforms with a dedicated registrar, dedicated business logic / call processing logic, and a carrier-facing element, separated into multiple instances, all deployed with redundant mates, etc.
Some of them I still have to support, and they're a nightmare, and most importantly of all, from a technical point of view they're completely unnecessary. In hindsight, it was all a mistake, and can easily be done with a single Kamailio element 99% of the time (as long as the config is manageable in its organisation), and I regret it all deeply. Cloud orchestration / deployment tooling that did not exist in those days might have made it a little easier, but also in many respects more complicated due to all the service discovery required.
I was thinking about this in the context of:
Originator:
- reachable on port 5060
- originates all traffic to the services
Service A:
- reachable on port 5061
- handles REGISTER
Service B:
- reachable on port 5062
- handles INVITE
Service C:
- reachable on port 5063
- handles MESSAGE
I could be wrong, and you might have very credible reasons for such a design, but at first glance it reminds me of some massively overcomplicated things I built when I first got started with Kamailio. :-) As I said, they were all based on a perception that this or that element can only handle so much, but it turns out one element can handle it all - and 20x more.
-- Alex
-- Alex Balashov | Principal | Evariste Systems LLC
Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) Web: http://www.evaristesys.com/, http://www.csrpswitch.com/
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Hello,
adding few notes ...
Like Alex said in another response, the get_out_socket() error is when Kamailio doesn't find a IP routing path between its listen socket and target address (sip:192.168.86.110:5061).
Then, to your initial message: t_relay() does not create/track dialogs, only SIP transactions (request-to-final-response).
If you just need to route SIP traffic without re-routing, accounting, etc... then forward() (stateless mode) is ok.
If you forward REGISTER via intermediary proxy, then you have to do Path handling (see path module).
Then, just for information, port 5061 is typically associated with TLS, however there is no restriction to use it for udp.
Cheers, Daniel
On 20.11.19 13:55, Michael Iedema wrote:
I’ve switched from a Dockerized Kamailio instance to a native installation. Here is my most recent trace when trying to forward traffic:
0(70677) INFO: <script>: ORIGINATOR -> REGISTER: Destination URI is now sip:192.168.86.110:5061 0(70677) ERROR: *** cfgtrace:request_route=[DEFAULT_ROUTE] c=[/etc/kamailio/kamailio-proxy.cfg] l=155 a=24 n=t_relay 0(70677) ERROR: <core> [core/forward.c:181]: get_out_socket(): no socket found 0(70677) ERROR: <core> [core/forward.c:183]: get_out_socket(): no corresponding socket found for(udp:192.168.86.110:5061) 0(70677) ERROR: tm [./ut.h:318]: uri2dst2(): no corresponding socket found for "192.168.86.110" af 2 (udp:192.168.86.110:5061) 0(70677) ERROR: tm [t_fwd.c:467]: prepare_new_uac(): can't fwd to af 2, proto 1 (no corresponding listening socket) 0(70677) ERROR: tm [t_fwd.c:1724]: t_forward_nonack(): failure to add branches 0(70677) ERROR: *** cfgtrace:request_route=[DEFAULT_ROUTE] c=[/etc/kamailio/kamailio-proxy.cfg] l=156 a=2 n=exit
My Kamailio instance is running on 192.168.86.107:6060. The originating service is on 192.168.86.110:5060. The REGISTER service is on 192.168.86.110:5061.
The refactor in my architecture I’m trying to make is:
- previously: Originator Service -> Register Service
- now: Originator -> Kamailio -> Register Service
I’m trying to get traffic from 192.168.86.110:5060 to route to 192.168.86.110:5061 but keep seeing this “no socket found” error. I didn’t think I was trying to bind that address, just rewriting the $du to point to the different host and port...
# ORIGINATOR sent us something if ( $(ct{nameaddr.uri}{uri.port}) == PORT_ORIGINATOR ) {
xlog("L_INFO", "ORIGINATOR: sent $rm\n”);
if (is_method("REGISTER")) { $du = "sip: HOST_REGISTER:PORT_REGISTER"; xlog("L_INFO", "ORIGINATOR -> REGISTER: Destination URI is now $du\n"); t_relay(); exit; } ... }
## END SNIPPET ##
Apologies if I’m missing something obvious! Thanks as always for your time.
-Michael
On Nov 19, 2019, at 10:24, Michael Iedema michael@kapsulate.com wrote:
Hi all,
I am trying to place Kamailio between several SIP services which are differentiated by port and by the type of message they handle. To be concrete, here are the services:
Originator:
- reachable on port 5060
- originates all traffic to the services
Service A:
- reachable on port 5061
- handles REGISTER
Service B:
- reachable on port 5062
- handles INVITE
Service C:
- reachable on port 5063
- handles MESSAGE
The services, originator and Kamailio instance may all be run on the same IP or may be split onto different addresses. Previously, the originator needed to know the address and port of each service. Now I want to make Kamailio responsible for that task so it can be done more intelligently.
To start though I simply want to get traffic flowing between the services and this is where I’m struggling to climb the learning curve. In my test setup the originator and all services are on the same IP with only Kamailio running on a different IP.
Address 1 Address 2
Originator <--> Kamailio:6060 | | Service A <-------> | Service B <-------> | Service C <-------> |
My first attempt at the logic looks like this:
# HOST DEFINITIONS #!substdef "/HOST_ORIGINATOR/192.168.86.110/" #!substdef "/HOST_REGISTER/192.168.86.110/“ #!substdef "/HOST_INVITE/192.168.86.110/" #!substdef "/HOST_MESSAGE/192.168.86.110/"
# PORT DEFINITIONS #!substdef “/PORT_ORIGINATOR/5060/" #!substdef "/PORT_REGISTER/5061/“ #!substdef "/PORT_INVITE/5062/" #!substdef "/PORT_MESSAGE/5063/"
# ROUTE LOGIC route {
# ORIGINATOR sent us something if ( $(ct{nameaddr.uri}{uri.port}) == HOST_ORIGINATOR ) {
xlog("L_INFO", "ORIGINATOR: sent $rm\n”);
if (is_method("REGISTER")) { $du = "sip: HOST_REGISTER:PORT_REGISTER"; xlog("L_INFO", "ORIGINATOR -> REGISTER: Destination URI is now $du\n"); t_relay(); exit; } } …
#### END SNIPPET ####
My very newbie questions are:
- Am I even on the right track here? I understand that t_relay() establishes a stateful dialog handler between the originator and register services.
- Can I accomplish this bi-directional path statelessly with forward()?
- Do I need to add logic to handle the messages from the REGISTER service back to ORIGINATOR?
This config currently fails because of "no corresponding socket found” when the relay triggers. I believe this is because I’m running the Kamailio instance in a Docker container so my first step today is to set up a native install.
I also looked at the dispatcher module which seems very close to what I want to do. Maybe that’s a more natural way to go?
Anyway, apologies for the lengthy explanation. I hope it is at least clear what I intend to do. I will gladly research and do trial and error to solve this but need to know I’m going down roughly the right path. I’m not sure what I should even be googling even of the time :-)
Thanks as always for your time and the great software!
Regards, -Michael
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
Hi Michael,
the mostly used model AFAIK is dispatcher cos you can define groups (also with only one member). That's more flexible if you scale up the backend services.
Also an docker newbie the macvlan driver gives you native ip access within the container.
The socket error message shows up an socket in Kamailio config like listen directive that is not available but the config generates an request for that.
can't fwd to af 2, proto 1 (no corresponding listening socket)
Did you switch protocols from udp to tcp or vice versa? Then you need also udp AND tcp enabled in Kamailio.
Cheers Karsten Horsmann
Michael Iedema michael@kapsulate.com schrieb am Di., 19. Nov. 2019, 10:30:
Hi all,
I am trying to place Kamailio between several SIP services which are differentiated by port and by the type of message they handle. To be concrete, here are the services:
Originator:
- reachable on port 5060
- originates all traffic to the services
Service A:
- reachable on port 5061
- handles REGISTER
Service B:
- reachable on port 5062
- handles INVITE
Service C:
- reachable on port 5063
- handles MESSAGE
The services, originator and Kamailio instance may all be run on the same IP or may be split onto different addresses. Previously, the originator needed to know the address and port of each service. Now I want to make Kamailio responsible for that task so it can be done more intelligently.
To start though I simply want to get traffic flowing between the services and this is where I’m struggling to climb the learning curve. In my test setup the originator and all services are on the same IP with only Kamailio running on a different IP.
Address 1 Address 2
Originator <--> Kamailio:6060 | | Service A <-------> | Service B <-------> | Service C <-------> |
My first attempt at the logic looks like this:
# HOST DEFINITIONS #!substdef "/HOST_ORIGINATOR/192.168.86.110/" #!substdef "/HOST_REGISTER/192.168.86.110/“ #!substdef "/HOST_INVITE/192.168.86.110/" #!substdef "/HOST_MESSAGE/192.168.86.110/"
# PORT DEFINITIONS #!substdef “/PORT_ORIGINATOR/5060/" #!substdef "/PORT_REGISTER/5061/“ #!substdef "/PORT_INVITE/5062/" #!substdef "/PORT_MESSAGE/5063/"
# ROUTE LOGIC route {
# ORIGINATOR sent us something if ( $(ct{nameaddr.uri}{uri.port}) == HOST_ORIGINATOR ) {
xlog("L_INFO", "ORIGINATOR: sent $rm\n”); if (is_method("REGISTER")) { $du = "sip: HOST_REGISTER:PORT_REGISTER"; xlog("L_INFO", "ORIGINATOR -> REGISTER: Destination URI is now
$du\n"); t_relay(); exit; } } …
#### END SNIPPET ####
My very newbie questions are:
- Am I even on the right track here? I understand that t_relay()
establishes a stateful dialog handler between the originator and register services.
- Can I accomplish this bi-directional path statelessly with forward()?
- Do I need to add logic to handle the messages from the REGISTER service
back to ORIGINATOR?
This config currently fails because of "no corresponding socket found” when the relay triggers. I believe this is because I’m running the Kamailio instance in a Docker container so my first step today is to set up a native install.
I also looked at the dispatcher module which seems very close to what I want to do. Maybe that’s a more natural way to go?
Anyway, apologies for the lengthy explanation. I hope it is at least clear what I intend to do. I will gladly research and do trial and error to solve this but need to know I’m going down roughly the right path. I’m not sure what I should even be googling even of the time :-)
Thanks as always for your time and the great software!
Regards, -Michael
Kamailio (SER) - Users Mailing List sr-users@lists.kamailio.org https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users