I have a Linux box with a virtual IP set up. Here's part of the output from ip addr
开发者_如何学Go:
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
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.
精彩评论