Thursday, May 5, 2011

Rebind a socket to a different interface

Is there an existing Linux/POSIX C/C++ library or example code for how to rebind a socket from one physical interface to another?

For example, I have ping transmitting on a socket that is associated with a physical connection A and I want to rebind that socket to physical connection B and have the ping packets continue being sent and received on connection B (after a short delay during switch-over).

I only need this for session-less protocols.

Thank you

Update:

I am trying to provide failover solution for use with PPP and Ethernet devices.

I have a basic script which can accomplish 90% of the functionality through use of iptables, NAT and routing table.

The problem is when the failover occurs, the pings continue being sent on the secondary connection, however, their source IP is from the old connection.

I've spoken with a couple of people who work on commercial routers and their suggestion is to rebind the socket to the secondary interface.

Update 2:

I apologise for not specifying this earlier. This solution will run on a router. I cannot change the ping program because it will run on the clients computer. I used ping as just an example, any connection that is not session-based should be capable of being switched over. I tested this feature on several commercial routers and it does work. Unfortunately, their software is proprietary, however, from various conversations and testing, I found that they are re-binding the sockets on failover.

From stackoverflow
  • I do't think that's quite a well-defined operation. the physical interfaces have different MAC addresses, so unless you have a routing layer mapping them (NAT or the like) then they're going to have different IP addresses.

    Ports are identified by a triple of <IP addr, Port number, protocol> so if your IP address changes the port is going to change.

    What are you really trying to do here?

  • I'm not at all sure what you're trying to accomplish, but I have a guess... Are you trying to do some kind of failover? If so, then there are indeed ways to accomplish that, but why not do it in the OS instead of the application?

    On one end you can use CARP, and on the other you can use interface trunking/bonding (terminology varies) in failover mode.

    Misha M : I saw CARP and bonding, but I cannot use either because of space constraints for CARP and Linux 2.6 kernel does not have bonding for Ethernet and PPP devices unfortunately.
  • As of your updated post, the problem is that changing the routing info is not going to change the source address of your ping, it will just force it out the second interface. This answer contains some relevant info.

    You'll need to change the ping program. You can use a socket-per-interface approach and somehow inform the program when to fail over. Or you will have to close the socket and then bind to the second interface.

    You can get the interface info required a couple of ways including calling ioctl() with the SIOCGIFCONF option and looping through the returned structures to get the interface address info.

    Misha M : I ended up setting proc parameter, /proc/sys/net/ipv4/netfilter/ip_conntrack_icmp_timeout, to 1 to force the icmp packet to time out, and then reset it to it's original value. This forced ping to rebind to different interface. It's a cludge, but the Ralink driver for that NIC does not support quite a few ioctl calls.

0 comments:

Post a Comment