I would like to bind to a local interface, eg "eth0"
, using boost::asio
.
The equivalent code using the low level socket interface would be:
const std::string ifc = "eth0";
struct ifreq ifr;
bzero(&ifr, sizeof(ifr));
memcpy(ifr.ifr_name, ifc.c_str(), ifc.length());
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, static_cast<void*>(&ifr), sizeof(ifr)) < 0)
{
throw std::runtime_error("bind to local interface failed");
}
However, when I attempt to pass a local interface to the boost::asio::ip::tcp::resolver
, it can't resolve it:
using tcp = boost::asio::ip::tcp;
const std::string ifc = "eth0";
auto ctx = socket.get_executor();
tcp::resolver resolver(ctx);
tcp::resolver::results_type results = resolver.resolve(ifc, "");
This throws an exception, with description "Host not found (authoritative)"
By the content of the error message it does sound like it's attempting to resolve the interface as a host address.
Is it possible to do the equivalent of SO_BINDTODEVICE
using boost::asio
?
Is it possible to do the equivalent of SO_BINDTODEVICE using boost::asio?
No, but you can use the option like you're used to.
if (setsockopt(socket.native_handle(), SOL_SOCKET, SO_BINDTODEVICE, static_cast<void*>(&ifr), sizeof(ifr)) < 0)
You could also define your own custom option to make it "prettier", but I would probably only do this if this is somehow oft-repeating code.