views:

29

answers:

1

Hi.

I have a Linux box with a virtual IP set up. Here's part of the output from ip addr:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether e4:1f:13:60:10:34 brd ff:ff:ff:ff:ff:ff
    inet 212.179.158.220/25 brd 212.179.158.255 scope global eth0
    inet 212.179.158.221/32 scope global eth0
    inet6 fe80::e61f:13ff:fe60:1034/64 scope link
       valid_lft forever preferred_lft forever

On this machine, I create a DatagramSocket bound to new InetSocketAddress(port), which should bind to the wildcard IP.

The application then receives messages sent to either 212.179.158.220 or 212.179.158.221, but when it responds the response is always seen as coming from 212.179.158.220, whereas I'd like the remote address of the response to reflect the IP that received the original message.

I can create a socket for each IP and listen on both; that gives me the behavior that I want, but it means that if the virtual IP comes up while the app is running it will ignore messages sent to the VIP.

So, now that I've laid this out: Is there a way to get the remote host of the response message to be the same as the one the original message came in on? I wouldn't expect it to be automatic, since how should the socket know to connect this response with that message? But perhaps there's a way to force it?

Thanks in advance.

Michael

A: 

If you set the IP_PKTINFO socket option, then use recvmsg() to recieve the datagram and provide a msg_control buffer, an IP_PKTINFO control message will be included with the recieved datagrams that contains a struct in_pktinfo structure:

struct in_pktinfo {
    unsigned int   ipi_ifindex;  /* Interface index */
    struct in_addr ipi_spec_dst; /* Local address */
    struct in_addr ipi_addr;     /* Header Destination address */
};

This control message tells you the local destination address. You can then supply the same control message with the response, using sendmsg(), and the original destination address will be used as the source.

caf