Hi!
I've configured openser to listen on a ceratin IP address.
listen=83.xxx.32.83:5060
Nevertheless, if t_relay tries to sned via TCP, openser opens the TCP connection from the default interface.
I also tried force_send_socket(tcp:83.xxx.32.83:5060); with the same results.
Are there any known problems? IMO openser should always use the IP address on which it listens.
regards klaus
Hi Klaus,
not sure what you mean by "default interface", but here are some facts after digging thought the code:
1) when doing normal fwd (no force) on tcp, it will be used the first TCP socket from the listen list; there is a funny comment from Andrei in get_send_socket() function "on tcp just use the "main address", we don't really now the sending address (we can find it out, but we'll need also to see if we listen on it, and if yes on which port -> too complicated"
2) if force_send_socket is used on tcp...depends.... do you get the debug message: "get_send_socket: force_send_socket of different proto(1)!" ?? are you using t_relay() after?? what are the listening interfaces (all, udp and tcp)?
regards, bogdan
Klaus Darilion wrote:
Hi!
I've configured openser to listen on a ceratin IP address.
listen=83.xxx.32.83:5060
Nevertheless, if t_relay tries to sned via TCP, openser opens the TCP connection from the default interface.
I also tried force_send_socket(tcp:83.xxx.32.83:5060); with the same results.
Are there any known problems? IMO openser should always use the IP address on which it listens.
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
My server configuration: # ifconfig eth0 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.80 Bcast:x.x.32.127
eth0:3 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.83 Bcast:x.x.32.127
eth0 .80 is the default interface, openser listens on .83 This is done by putting listen=x.x.32.83:5060 into openser.cfg
openser binds to .83, verified by # netstat -anp|grep 5060 tcp 0 0 x.x.32.83:5060 0.0.0.0:* LISTEN 1390/openser udp 0 0 x.x.32.83:5060 0.0.0.0:* 1390/openser
Then I forwarded a message to a GW using TCP (lcr + t_relay): (without force_send_socket)
DEBUG: reply sent out. buf=0x8134330: SIP/2.0 1..., shmem=0x40680a90: SIP/2.0 1 DEBUG: _reply_light: finished DEBUG: mk_proxy: doing DNS lookup... build_req_from_req: id added: <;i=1>, rcv proto=2 parse_headers: flags=1000 parse_headers: flags=1000 parse_headers: flags=ffffffffffffffff clen_builder: content-length: 290 (290) check_via_address(x.x.33.3, 10.10.0.50, 0) tcp_send: no open tcp connection found, opening new one ERROR: tcp_blocking_connect: SO_ERROR (113) No route to host ERROR: tcpconn_connect: tcp_blocking_connect failed ERROR: tcp_send: connect failed msg_send: ERROR: tcp_send failed ERROR: t_forward_nonack: sending request failed
tcp_blocking_connect fails (the error message is a little bit misleading and caused by an ICMP error), as the GW accepts SIP only from .83, and not from .80: In the following tcpdump you see that openser tries to establish the TCP connection from .80 instead of .83:
IP x.x.32.80.41580 > x.x.33.4.5060: S IP x.x.33.4 > x.x.32.80: icmp 36: host x.x.33.4 unreachable - admin prohibited filter
Any hints are appreciated.
Conclusion: openser sends .80 although it is bound to .83.
regards Klaus
Bogdan-Andrei Iancu wrote:
Hi Klaus,
not sure what you mean by "default interface", but here are some facts after digging thought the code:
- when doing normal fwd (no force) on tcp, it will be used the first
TCP socket from the listen list; there is a funny comment from Andrei in get_send_socket() function "on tcp just use the "main address", we don't really now the sending address (we can find it out, but we'll need also to see if we listen on it, and if yes on which port -> too complicated"
- if force_send_socket is used on tcp...depends.... do you get the
debug message: "get_send_socket: force_send_socket of different proto(1)!" ?? are you using t_relay() after?? what are the listening interfaces (all, udp and tcp)?
regards, bogdan
Klaus Darilion wrote:
Hi!
I've configured openser to listen on a ceratin IP address.
listen=83.xxx.32.83:5060
Nevertheless, if t_relay tries to sned via TCP, openser opens the TCP connection from the default interface.
I also tried force_send_socket(tcp:83.xxx.32.83:5060); with the same results.
Are there any known problems? IMO openser should always use the IP address on which it listens.
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Hi Klaus,
I was looking through the tcp code and I found the reason. Looking at tcpconn_connect() function - which opens a new tcp connection - it seams that the newly created socket is connected to destination without any binding to a specific local interface/port. So, the OS will have the liberty to choose whatever interface to bind the socket to at connect time - probably the Linux kernel assigns the first interface.
Why not binding the socket before connect? because each time you have to use different port (a free one) for each new connection. So, IMHO, the bind is missing because you do not know what port us bind to and let the kernel choose one.
I know no way to bind only to an address but letting the kernel to choose the port (a portable solution)......
So, I would say either change the interface order, either the filter on the GW ....for the moment....
regards, bogdan
Klaus Darilion wrote:
My server configuration: # ifconfig eth0 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.80 Bcast:x.x.32.127
eth0:3 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.83 Bcast:x.x.32.127
eth0 .80 is the default interface, openser listens on .83 This is done by putting listen=x.x.32.83:5060 into openser.cfg
openser binds to .83, verified by # netstat -anp|grep 5060 tcp 0 0 x.x.32.83:5060 0.0.0.0:* LISTEN 1390/openser udp 0 0 x.x.32.83:5060 0.0.0.0:* 1390/openser
Then I forwarded a message to a GW using TCP (lcr + t_relay): (without force_send_socket)
DEBUG: reply sent out. buf=0x8134330: SIP/2.0 1..., shmem=0x40680a90: SIP/2.0 1 DEBUG: _reply_light: finished DEBUG: mk_proxy: doing DNS lookup... build_req_from_req: id added: <;i=1>, rcv proto=2 parse_headers: flags=1000 parse_headers: flags=1000 parse_headers: flags=ffffffffffffffff clen_builder: content-length: 290 (290) check_via_address(x.x.33.3, 10.10.0.50, 0) tcp_send: no open tcp connection found, opening new one ERROR: tcp_blocking_connect: SO_ERROR (113) No route to host ERROR: tcpconn_connect: tcp_blocking_connect failed ERROR: tcp_send: connect failed msg_send: ERROR: tcp_send failed ERROR: t_forward_nonack: sending request failed
tcp_blocking_connect fails (the error message is a little bit misleading and caused by an ICMP error), as the GW accepts SIP only from .83, and not from .80: In the following tcpdump you see that openser tries to establish the TCP connection from .80 instead of .83:
IP x.x.32.80.41580 > x.x.33.4.5060: S IP x.x.33.4 > x.x.32.80: icmp 36: host x.x.33.4 unreachable - admin prohibited filter
Any hints are appreciated.
Conclusion: openser sends .80 although it is bound to .83.
regards Klaus
Bogdan-Andrei Iancu wrote:
Hi Klaus,
not sure what you mean by "default interface", but here are some facts after digging thought the code:
- when doing normal fwd (no force) on tcp, it will be used the first
TCP socket from the listen list; there is a funny comment from Andrei in get_send_socket() function "on tcp just use the "main address", we don't really now the sending address (we can find it out, but we'll need also to see if we listen on it, and if yes on which port -> too complicated"
- if force_send_socket is used on tcp...depends.... do you get the
debug message: "get_send_socket: force_send_socket of different proto(1)!" ?? are you using t_relay() after?? what are the listening interfaces (all, udp and tcp)?
regards, bogdan
Klaus Darilion wrote:
Hi!
I've configured openser to listen on a ceratin IP address.
listen=83.xxx.32.83:5060
Nevertheless, if t_relay tries to sned via TCP, openser opens the TCP connection from the default interface.
I also tried force_send_socket(tcp:83.xxx.32.83:5060); with the same results.
Are there any known problems? IMO openser should always use the IP address on which it listens.
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Bogdan-Andrei Iancu wrote:
I know no way to bind only to an address but letting the kernel to choose the port (a portable solution)......
What about setting the port to 0? I tried it and it works on Linux. Do you think that this does not work on other OS?
regards klaus
So, I would say either change the interface order, either the filter on the GW ....for the moment....
regards, bogdan
Klaus Darilion wrote:
My server configuration: # ifconfig eth0 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.80 Bcast:x.x.32.127
eth0:3 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.83 Bcast:x.x.32.127
eth0 .80 is the default interface, openser listens on .83 This is done by putting listen=x.x.32.83:5060 into openser.cfg
openser binds to .83, verified by # netstat -anp|grep 5060 tcp 0 0 x.x.32.83:5060 0.0.0.0:* LISTEN 1390/openser udp 0 0 x.x.32.83:5060 0.0.0.0:* 1390/openser
Then I forwarded a message to a GW using TCP (lcr + t_relay): (without force_send_socket)
DEBUG: reply sent out. buf=0x8134330: SIP/2.0 1..., shmem=0x40680a90: SIP/2.0 1 DEBUG: _reply_light: finished DEBUG: mk_proxy: doing DNS lookup... build_req_from_req: id added: <;i=1>, rcv proto=2 parse_headers: flags=1000 parse_headers: flags=1000 parse_headers: flags=ffffffffffffffff clen_builder: content-length: 290 (290) check_via_address(x.x.33.3, 10.10.0.50, 0) tcp_send: no open tcp connection found, opening new one ERROR: tcp_blocking_connect: SO_ERROR (113) No route to host ERROR: tcpconn_connect: tcp_blocking_connect failed ERROR: tcp_send: connect failed msg_send: ERROR: tcp_send failed ERROR: t_forward_nonack: sending request failed
tcp_blocking_connect fails (the error message is a little bit misleading and caused by an ICMP error), as the GW accepts SIP only from .83, and not from .80: In the following tcpdump you see that openser tries to establish the TCP connection from .80 instead of .83:
IP x.x.32.80.41580 > x.x.33.4.5060: S IP x.x.33.4 > x.x.32.80: icmp 36: host x.x.33.4 unreachable - admin prohibited filter
Any hints are appreciated.
Conclusion: openser sends .80 although it is bound to .83.
regards Klaus
Bogdan-Andrei Iancu wrote:
Hi Klaus,
not sure what you mean by "default interface", but here are some facts after digging thought the code:
- when doing normal fwd (no force) on tcp, it will be used the first
TCP socket from the listen list; there is a funny comment from Andrei in get_send_socket() function "on tcp just use the "main address", we don't really now the sending address (we can find it out, but we'll need also to see if we listen on it, and if yes on which port -> too complicated"
- if force_send_socket is used on tcp...depends.... do you get the
debug message: "get_send_socket: force_send_socket of different proto(1)!" ?? are you using t_relay() after?? what are the listening interfaces (all, udp and tcp)?
regards, bogdan
Klaus Darilion wrote:
Hi!
I've configured openser to listen on a ceratin IP address.
listen=83.xxx.32.83:5060
Nevertheless, if t_relay tries to sned via TCP, openser opens the TCP connection from the default interface.
I also tried force_send_socket(tcp:83.xxx.32.83:5060); with the same results.
Are there any known problems? IMO openser should always use the IP address on which it listens.
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Klaus Darilion wrote:
Bogdan-Andrei Iancu wrote:
I know no way to bind only to an address but letting the kernel to
choose the port (a portable solution)......
What about setting the port to 0? I tried it and it works on Linux. Do you think that this does not work on other OS?
I reviewed the source code of netcat (which is quiet portable) and netcat also does it this way: socket() bind() connect()
When binding, the "dynamic" part (address or port) will be set to 0.
I think we should also implement this in openser. If openser listen only on one interface the bind logic is simple: take this IP address.
If openser listens to multiple IP addresses we can just use the first IP address, or we can have a logic which chooses the best IP address (e.g. the IP address, on which the request was received).
regards klaus
regards klaus
So, I would say either change the interface order, either the filter on the GW ....for the moment....
regards, bogdan
Klaus Darilion wrote:
My server configuration: # ifconfig eth0 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.80 Bcast:x.x.32.127
eth0:3 Link encap:Ethernet HWaddr 00:0B:DB:90:FA:3F inet addr:x.x.32.83 Bcast:x.x.32.127
eth0 .80 is the default interface, openser listens on .83 This is done by putting listen=x.x.32.83:5060 into openser.cfg
openser binds to .83, verified by # netstat -anp|grep 5060 tcp 0 0 x.x.32.83:5060 0.0.0.0:* LISTEN 1390/openser udp 0 0 x.x.32.83:5060 0.0.0.0:* 1390/openser
Then I forwarded a message to a GW using TCP (lcr + t_relay): (without force_send_socket)
DEBUG: reply sent out. buf=0x8134330: SIP/2.0 1..., shmem=0x40680a90: SIP/2.0 1 DEBUG: _reply_light: finished DEBUG: mk_proxy: doing DNS lookup... build_req_from_req: id added: <;i=1>, rcv proto=2 parse_headers: flags=1000 parse_headers: flags=1000 parse_headers: flags=ffffffffffffffff clen_builder: content-length: 290 (290) check_via_address(x.x.33.3, 10.10.0.50, 0) tcp_send: no open tcp connection found, opening new one ERROR: tcp_blocking_connect: SO_ERROR (113) No route to host ERROR: tcpconn_connect: tcp_blocking_connect failed ERROR: tcp_send: connect failed msg_send: ERROR: tcp_send failed ERROR: t_forward_nonack: sending request failed
tcp_blocking_connect fails (the error message is a little bit misleading and caused by an ICMP error), as the GW accepts SIP only from .83, and not from .80: In the following tcpdump you see that openser tries to establish the TCP connection from .80 instead of .83:
IP x.x.32.80.41580 > x.x.33.4.5060: S IP x.x.33.4 > x.x.32.80: icmp 36: host x.x.33.4 unreachable - admin prohibited filter
Any hints are appreciated.
Conclusion: openser sends .80 although it is bound to .83.
regards Klaus
Bogdan-Andrei Iancu wrote:
Hi Klaus,
not sure what you mean by "default interface", but here are some facts after digging thought the code:
- when doing normal fwd (no force) on tcp, it will be used the
first TCP socket from the listen list; there is a funny comment from Andrei in get_send_socket() function "on tcp just use the "main address", we don't really now the sending address (we can find it out, but we'll need also to see if we listen on it, and if yes on which port -> too complicated"
- if force_send_socket is used on tcp...depends.... do you get the
debug message: "get_send_socket: force_send_socket of different proto(1)!" ?? are you using t_relay() after?? what are the listening interfaces (all, udp and tcp)?
regards, bogdan
Klaus Darilion wrote:
Hi!
I've configured openser to listen on a ceratin IP address.
listen=83.xxx.32.83:5060
Nevertheless, if t_relay tries to sned via TCP, openser opens the TCP connection from the default interface.
I also tried force_send_socket(tcp:83.xxx.32.83:5060); with the same results.
Are there any known problems? IMO openser should always use the IP address on which it listens.
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Hi Klaus,
I already tested bind with port 0 on linux and BSD kernels and works - but I have no access other OS, like solaris for example. if same scheme is used in netcat, I would say is a good argument to for it (until proved otherwise :-/) - if no force_socket is used, the first listening TCP address will be used; otherwise the IP from forced socket.
what I'm still looking for is to try to maintain the same interface in case of forwarding from TCP2TCP - if received over TCP on interface1, use the same (if not forced) interface to fwd.
hopefully the code will be ready today.
regards, bogdan
Klaus Darilion wrote:
Klaus Darilion wrote:
Bogdan-Andrei Iancu wrote:
I know no way to bind only to an address but letting the kernel to
choose the port (a portable solution)......
What about setting the port to 0? I tried it and it works on Linux. Do you think that this does not work on other OS?
I reviewed the source code of netcat (which is quiet portable) and netcat also does it this way: socket() bind() connect()
When binding, the "dynamic" part (address or port) will be set to 0.
I think we should also implement this in openser. If openser listen only on one interface the bind logic is simple: take this IP address.
If openser listens to multiple IP addresses we can just use the first IP address, or we can have a logic which chooses the best IP address (e.g. the IP address, on which the request was received).
regards klaus
Hi Klaus,
the fix it's on cvs - any feedback will be helpful :)
regards, bogdan
Bogdan-Andrei Iancu wrote:
Hi Klaus,
I already tested bind with port 0 on linux and BSD kernels and works - but I have no access other OS, like solaris for example. if same scheme is used in netcat, I would say is a good argument to for it (until proved otherwise :-/) - if no force_socket is used, the first listening TCP address will be used; otherwise the IP from forced socket.
what I'm still looking for is to try to maintain the same interface in case of forwarding from TCP2TCP - if received over TCP on interface1, use the same (if not forced) interface to fwd.
hopefully the code will be ready today.
regards, bogdan
Klaus Darilion wrote:
Klaus Darilion wrote:
Bogdan-Andrei Iancu wrote:
I know no way to bind only to an address but letting the kernel to
choose the port (a portable solution)......
What about setting the port to 0? I tried it and it works on Linux. Do you think that this does not work on other OS?
I reviewed the source code of netcat (which is quiet portable) and netcat also does it this way: socket() bind() connect()
When binding, the "dynamic" part (address or port) will be set to 0.
I think we should also implement this in openser. If openser listen only on one interface the bind logic is simple: take this IP address.
If openser listens to multiple IP addresses we can just use the first IP address, or we can have a logic which chooses the best IP address (e.g. the IP address, on which the request was received).
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Bogdan-Andrei Iancu wrote:
Hi Klaus,
the fix it's on cvs - any feedback will be helpful :)
Hi Bogdan!
I made some tests (listen on one interface, on multiple interfaces, changing the order of the interfaces, using force_send_socket) and everything worked as I expected it - no problems.
Thanks a lot for the fix (and all the other fixes).
regards klaus
PS: It somehow wonders me that nobody found this bug before. Maybe nobody uses TCP :-(
regards, bogdan
Bogdan-Andrei Iancu wrote:
Hi Klaus,
I already tested bind with port 0 on linux and BSD kernels and works - but I have no access other OS, like solaris for example. if same scheme is used in netcat, I would say is a good argument to for it (until proved otherwise :-/) - if no force_socket is used, the first listening TCP address will be used; otherwise the IP from forced socket.
what I'm still looking for is to try to maintain the same interface in case of forwarding from TCP2TCP - if received over TCP on interface1, use the same (if not forced) interface to fwd.
hopefully the code will be ready today.
regards, bogdan
Klaus Darilion wrote:
Klaus Darilion wrote:
Bogdan-Andrei Iancu wrote:
I know no way to bind only to an address but letting the kernel to
choose the port (a portable solution)......
What about setting the port to 0? I tried it and it works on Linux. Do you think that this does not work on other OS?
I reviewed the source code of netcat (which is quiet portable) and netcat also does it this way: socket() bind() connect()
When binding, the "dynamic" part (address or port) will be set to 0.
I think we should also implement this in openser. If openser listen only on one interface the bind logic is simple: take this IP address.
If openser listens to multiple IP addresses we can just use the first IP address, or we can have a logic which chooses the best IP address (e.g. the IP address, on which the request was received).
regards klaus
Users mailing list Users@openser.org http://openser.org/cgi-bin/mailman/listinfo/users
Klaus Darilion wrote:
Bogdan-Andrei Iancu wrote:
Hi Klaus,
the fix it's on cvs - any feedback will be helpful :)
Hi Bogdan!
I made some tests (listen on one interface, on multiple interfaces, changing the order of the interfaces, using force_send_socket) and everything worked as I expected it - no problems.
Thanks a lot for the fix (and all the other fixes).
regards klaus
PS: It somehow wonders me that nobody found this bug before. Maybe nobody uses TCP :-(
maybe multiple-interface systems are not so common ! :-(
regards, bogdan
Bogdan-Andrei Iancu wrote:
Klaus Darilion wrote:
PS: It somehow wonders me that nobody found this bug before. Maybe nobody uses TCP :-(
maybe multiple-interface systems are not so common ! :-(
On our servers we have a certain IP address for each service. Thus, although the radius server, postgres db, openser, ... are all running on the same linux box, all of them bind to a certain interface.
Using this policy, shifting a service from one server to another is very easy (e.g. moving from testing to production servers).
regards klaus