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?
When IP delivers a UDP datagram, the host checks the port number and delivers the data to the corresponding application. In this way, UDP provides simple multiplexing over IP to allow a host to send and receive data on multiple distinct ports.
UDP: a UDP endpoint is a combination of the IP address and the UDP port used, so different UDP ports on the same IP address are different UDP endpoints.
The IP address is available in most locations the endpoint name is displayed, including lists and tool tips. In some lists, such as the Endpoint Diary, you can choose to view the Endpoint/Client Name or Endpoint/Client IP Address by clicking the toggle next to the column header.
According to "Computer networking: a top-down approach", Kurose et al., a UDP socket is fully identified by destination IP and destination port.
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:
IP_PKTINFO
and recvfrom()
)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()
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With