Question

Boost.Asio's udp::endpoint has a member that is remote address. Because I'm listening on multiple interfaces (like this):

udp_socket(io_service, udp::endpoint(udp::v4(), port))

In my handler, I do not know which network interface received the packet.

Without iterating over network interfaces and looking for a similarity between the endpoint address and my IP on each interface, can I get my IP for the interface that I got message from?

Was it helpful?

Solution

No. Boost.Asio does not expose the ability to identify the datagram's destination address.

The socket::aync_receive_from() and socket::receive_from() operations perform the native socket operations within boost::asio::detail::socket_ops::recvfrom(). On Windows, WSARecvFrom() provides no way to extract lower layer information from the protocol stack. On Linux, the IP_PKTINFO socket option can provided to datagram oriented sockets enabling recvfrom() to populate the msghdr.msg_control buffer with ancillary information, such as the interface index on which the packet was received and the destination address in the packet header. However, the Boost.Asio implementation does not use themsg_control field:

msghdr msg = msghdr();
init_msghdr_msg_name(msg.msg_name, addr);
msg.msg_namelen = static_cast<int>(*addrlen);
msg.msg_iov = bufs;
msg.msg_iovlen = static_cast<int>(count);
signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);

As suggested in this answer, one can:

  • Use lower-level system calls. (i.e. IP_PKTINFO and recvfrom())
  • Explicitly bind a socket to each interface rather than INADDR_ANY, causing the socket::local_endpoint() to return a specific interface. The completion handlers will need some way to obtain the local endpoint on the socket for which the operation was invoked, such as passing a reference to the socket or its local endpoint via boost::bind().

OTHER TIPS

As far as I understand you have different boost::asio::ip::udp::sockets. And in case one of them recieves a message you want to know the local ip address of that socket/the interface that socket uses.

So if socket is the socket that recives the msg you should be able to get the ip in the handler by

socket.local_endpoint().address()

See local_endpoint() and address() in the boost manual.

i think you should explicit specify the address rather than simply a protocol

udp_socket(io_service, udp::endpoint(boost::asio::ip::address::from_string(""), port))

so that you can use udp_socket.local_endpoint().address() to get the ip.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top