Hi,
Another funny thing I encountered lately is this:
Client sends INVITE via kamailio (via dispatcher) to sems, gets back 100/200, sends another couple of INVITE with same CSeq (looks like retransmissions), gets back more 200, then sends ACKs for each of the 200 it got. Looks like a quite broken client to me, but anyways.
The interesting thing is that after >5000ms (which is bigger then tm.wt_timer), another 200 is sent from sems to kamailio to the client. I see the 200 coming to kamailio in a network trace, but not an according log message in the kamailio logs. What I see though is this:
Sep 14 13:51:26 sp2 /usr/sbin/kamailio[15950]: ERROR: <core> [udp_server.c:586]: ERROR: udp_send: sendto(sock,0x97ec10,1055,0,1.2.3.4:58620,16): Invalid argument(22) Sep 14 13:51:26 sp2 /usr/sbin/kamailio[15950]: ERROR: <core> [forward.h:149]: msg_send: ERROR: udp_send failed
The 1.2.3.4:58620 is obviously taken from the Vias, which looks like this:
Via: SIP/2.0/UDP 127.0.0.1:5060;rport=5060;branch=xyz Via: SIP/2.0/UDP 10.1.1.9:58620;received=1.2.3.4;rport=58620;branch=abc
The top-most Via is itself, the second is the one which reflects the destination address in the error message above.
So I'm wondering whether there is some issue with finding the proper socket after wt_timer is expired (note that the leg client<->kamailio uses a different socket (with public ip) than kamailio<->sems (which uses 127.0.0.1)). Or any other idea where this error could come from?
It's actually an educated guess that this could be related to wt_timer, but I don't know what else it could be.
Andreas
Hello,
On 9/14/11 2:41 PM, Andreas Granig wrote:
Hi,
Another funny thing I encountered lately is this:
Client sends INVITE via kamailio (via dispatcher) to sems, gets back 100/200, sends another couple of INVITE with same CSeq (looks like retransmissions), gets back more 200, then sends ACKs for each of the 200 it got. Looks like a quite broken client to me, but anyways.
The interesting thing is that after>5000ms (which is bigger then tm.wt_timer), another 200 is sent from sems to kamailio to the client. I see the 200 coming to kamailio in a network trace, but not an according log message in the kamailio logs. What I see though is this:
Sep 14 13:51:26 sp2 /usr/sbin/kamailio[15950]: ERROR:<core> [udp_server.c:586]: ERROR: udp_send: sendto(sock,0x97ec10,1055,0,1.2.3.4:58620,16): Invalid argument(22) Sep 14 13:51:26 sp2 /usr/sbin/kamailio[15950]: ERROR:<core> [forward.h:149]: msg_send: ERROR: udp_send failed
The 1.2.3.4:58620 is obviously taken from the Vias, which looks like this:
Via: SIP/2.0/UDP 127.0.0.1:5060;rport=5060;branch=xyz Via: SIP/2.0/UDP 10.1.1.9:58620;received=1.2.3.4;rport=58620;branch=abc
The top-most Via is itself, the second is the one which reflects the destination address in the error message above.
So I'm wondering whether there is some issue with finding the proper socket after wt_timer is expired (note that the leg client<->kamailio uses a different socket (with public ip) than kamailio<->sems (which uses 127.0.0.1)). Or any other idea where this error could come from?
It's actually an educated guess that this could be related to wt_timer, but I don't know what else it could be.
what happens is that when transaction is active and tm is handling the replies, they are forwarded using the same socket where the request was received (iirc).
However, the transaction is gone so the reply is sent stateless and the default rule of stateless forwarding for selecting the local socket is to use the same socket where the message was received (in this case is the reply is received on loopback interface). Try either to use mhomed parameter or force the right send socket by hand (force_send_socket(...) or $fs=...) when there is no active transaction for replies (use t_check_trans()).
Cheers, Daniel
Hi,
On 09/16/2011 09:10 AM, Daniel-Constantin Mierla wrote:
It's actually an educated guess that this could be related to wt_timer, but I don't know what else it could be.
what happens is that when transaction is active and tm is handling the replies, they are forwarded using the same socket where the request was received (iirc).
However, the transaction is gone so the reply is sent stateless and the default rule of stateless forwarding for selecting the local socket is to use the same socket where the message was received (in this case is the reply is received on loopback interface). Try either to use mhomed parameter or force the right send socket by hand (force_send_socket(...) or $fs=...) when there is no active transaction for replies (use t_check_trans()).
Actually I do a force_send_socket in my onreply_routes, but the onreply_routes to be used are chosen during request handling. I don't have a default reply route though, which I guess must be used in this case, because information about which onreply_route to use is lost after wt_timer, right?
Roughly outlined, this is what I have now. I don't use mhomed, but rather set the sockets manually:
route[REQUEST] { if(request from outside) { force_send_socket(localhost); t_on_reply("REPLY_FROM_INSIDE"); } else { # request from inside force_send_socket(public interface); t_on_reply("REPLY_FROM_OUTSIDE"); } # relay to proper destination } onreply_route[REPLY_FROM_INSIDE] { force_send_socket(public interface); } onreply_route[REPLY_FROM_OUTSIDE] { force_send_socket(localhost); }
And this is what I'd need to add if I got you right:
# the default reply route used when transaction is already gone onreply_route { if(reply from inside) force_send_socket(localhost); else force_send_socket(public interface); }
Does it look like a plan?
Andreas
Me again,
On 09/16/2011 02:46 PM, Andreas Granig wrote:
And this is what I'd need to add if I got you right:
# the default reply route used when transaction is already gone onreply_route { if(reply from inside) force_send_socket(localhost); else force_send_socket(public interface); }
I've tried to implement and test this, but there's one issue with it. If I have mhomed=1, then my injected (out of any transaction) reply hits this default route and is sent to the next hop (in my case 192.168.51.1:5060) according to the 2nd via header, so this is fine.
However if I set mhomed=0, but still call force_send_socket(192.168.51.205:5060), I get the same error, like this:
INFO: <script>: Reply without Transaction - S=200 - Alive F=sip:127.0.0.1:5062 T=sip:foo@bar.com:5060 IP=127.0.0.1:5062 ID=44217ae8-30016e50-13c4-197d78a-3921f4fc-db1e9be9
INFO: <script>: Force outbound socket - S=200 - Alive F=sip:127.0.0.1:5062 T=sip:foo@bar.com:5060 IP=127.0.0.1:5062 ID=44217ae8-30016e50-13c4-197d78a-3921f4fc-db1e9be9
ERROR: <core> [udp_server.c:586]: ERROR: udp_send: sendto(sock,0x980fa8,350,0,192.168.51.1:5060,16): Invalid argument(22) Sep 16 15:12:25 sp1 /usr/sbin/kamailio[31169]: : <core> [udp_server.c:591]: CRITICAL: invalid sendtoparameters#012one possible reason is the server is bound to localhost and#012attempts to send to the net
ERROR: <core> [forward.h:149]: msg_send: ERROR: udp_send failed
So is there actually a limitation on when I'm allowed to call force_send_socket()? Any way to force force_send_socket()? :)
Andreas
Hello,
On 9/16/11 3:19 PM, Andreas Granig wrote:
Me again,
On 09/16/2011 02:46 PM, Andreas Granig wrote:
And this is what I'd need to add if I got you right:
# the default reply route used when transaction is already gone onreply_route { if(reply from inside) force_send_socket(localhost); else force_send_socket(public interface); }
I've tried to implement and test this, but there's one issue with it. If I have mhomed=1, then my injected (out of any transaction) reply hits this default route and is sent to the next hop (in my case 192.168.51.1:5060) according to the 2nd via header, so this is fine.
However if I set mhomed=0, but still call force_send_socket(192.168.51.205:5060), I get the same error, like this:
INFO:<script>: Reply without Transaction - S=200 - Alive F=sip:127.0.0.1:5062 T=sip:foo@bar.com:5060 IP=127.0.0.1:5062 ID=44217ae8-30016e50-13c4-197d78a-3921f4fc-db1e9be9
INFO:<script>: Force outbound socket - S=200 - Alive F=sip:127.0.0.1:5062 T=sip:foo@bar.com:5060 IP=127.0.0.1:5062 ID=44217ae8-30016e50-13c4-197d78a-3921f4fc-db1e9be9
ERROR:<core> [udp_server.c:586]: ERROR: udp_send: sendto(sock,0x980fa8,350,0,192.168.51.1:5060,16): Invalid argument(22) Sep 16 15:12:25 sp1 /usr/sbin/kamailio[31169]: :<core> [udp_server.c:591]: CRITICAL: invalid sendtoparameters#012one possible reason is the server is bound to localhost and#012attempts to send to the net
ERROR:<core> [forward.h:149]: msg_send: ERROR: udp_send failed
So is there actually a limitation on when I'm allowed to call force_send_socket()? Any way to force force_send_socket()? :)
are you using a recent version of 3.1 branch? This was fixed with:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9dbf7358...
Cheers, Daniel
Hi,
On 09/20/2011 10:16 AM, Daniel-Constantin Mierla wrote:
So is there actually a limitation on when I'm allowed to call force_send_socket()? Any way to force force_send_socket()? :)
are you using a recent version of 3.1 branch? This was fixed with:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9dbf7358...
Thanks Daniel, works like charm!
Andreas
Hello,
On 9/16/11 2:46 PM, Andreas Granig wrote:
Hi,
On 09/16/2011 09:10 AM, Daniel-Constantin Mierla wrote:
It's actually an educated guess that this could be related to wt_timer, but I don't know what else it could be.
what happens is that when transaction is active and tm is handling the replies, they are forwarded using the same socket where the request was received (iirc).
However, the transaction is gone so the reply is sent stateless and the default rule of stateless forwarding for selecting the local socket is to use the same socket where the message was received (in this case is the reply is received on loopback interface). Try either to use mhomed parameter or force the right send socket by hand (force_send_socket(...) or $fs=...) when there is no active transaction for replies (use t_check_trans()).
Actually I do a force_send_socket in my onreply_routes, but the onreply_routes to be used are chosen during request handling. I don't have a default reply route though, which I guess must be used in this case, because information about which onreply_route to use is lost after wt_timer, right?
yes, a default onreply route has to be used.
Roughly outlined, this is what I have now. I don't use mhomed, but rather set the sockets manually:
route[REQUEST] { if(request from outside) { force_send_socket(localhost); t_on_reply("REPLY_FROM_INSIDE"); } else { # request from inside force_send_socket(public interface); t_on_reply("REPLY_FROM_OUTSIDE"); } # relay to proper destination } onreply_route[REPLY_FROM_INSIDE] { force_send_socket(public interface); } onreply_route[REPLY_FROM_OUTSIDE] { force_send_socket(localhost); }
And this is what I'd need to add if I got you right:
# the default reply route used when transaction is already gone onreply_route { if(reply from inside) force_send_socket(localhost); else force_send_socket(public interface); }
Does it look like a plan?
You should check first with t_check_trans() to see if transaction is gone. the default onreply route is called for all replies, no matter the transaction exists or not. Reading the logic, I find it opposite, if the reply comes from inside, you want to send it outside, via public interface, or?
Cheers, Daniel