boost::asio – is it possible to bind to a local device (equivalent of SO_BINDTODEVICE) rather than local address?

huangapple go评论69阅读模式
英文:

boost::asio - is it possible to bind to a local device (equivalent of SO_BINDTODEVICE) rather than local address?

问题

我想绑定到本地接口,例如 "eth0",使用 boost::asio

使用底层套接字接口的等效代码如下:

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");
}

然而,当我尝试将本地接口传递给 boost::asio::ip::tcp::resolver 时,它无法解析它:

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, "");

这会引发异常,异常描述为 "Host not found (authoritative)"

根据错误消息的内容,似乎它正在尝试将接口解析为主机地址。

是否可以使用 boost::asio 来执行类似 SO_BINDTODEVICE 的操作呢?

英文:

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?

答案1

得分: 2

不能使用boost::asio来实现类似于SO_BINDTODEVICE的功能,但你可以像平常一样使用选项。

if (setsockopt(socket.native_handle(), SOL_SOCKET, SO_BINDTODEVICE, static_cast<void*>(&ifr), sizeof(ifr)) < 0)

你也可以定义自己的自定义选项以使其更“漂亮”,但我可能只会在这是一种经常重复的代码时才这样做。

英文:

> 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&lt;void*&gt;(&amp;ifr), sizeof(ifr)) &lt; 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.

huangapple
  • 本文由 发表于 2023年6月29日 16:16:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579230.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定