定位 Android API 30 时无法绑定 () netlink 套接字
Cannot bind() netlink socket when targeting Android API 30
我已经使用以下工具创建网络link套接字已有一段时间了:
NetLinkLocalNetworkInfo::NetLinkSocket::NetLinkSocket() :
fd(0)
{
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(fd < 0)
{
throw std::runtime_error("Failed to create NetLink socket");
}
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
int err = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if(err < 0)
{
close(fd);
throw std::runtime_error("Failed to bind NetLink socket");
}
}
这用于我们现有的部分网络逻辑,以使用 ICE 执行自动 NAT 遍历。当目标 API 30 时,对 bind
的调用现在 returns -1 和 errno
是“权限被拒绝”。
针对 API 30 的应用的行为变化现在意味着 bind()
是一个受限调用。 (在 Google 开发者页面的某处有一个文档,但如果我能再次找到它,我会很高兴。它曾经存在 here, but that page has changed since I first came across this issue a few months ago.) Supposedly this is supposed to affect all apps targeting API 30, but I've found that only apps targeting API 30 and running on a device (physical or emulator) running Android 11 are affected. My notes from when I first encountered this also mention that article suggesting using ConnectivityManager,但这需要想出一些方法来通过信息到本机代码或让本机代码通过 JNI 调用 Android 平台代码。如果这是必须发生的事情,我对其中任何一个都很好,但我想知道是否还有另一种选择我'我不知道。
我也看到了this similar question,但是其中一个答案中有一个link表明它应该是可能的,至少在API 30之前。
现在我们不能调用 bind()
,还有哪些其他选项可用?
找到了解决办法。原来我们使用 NetLink 套接字来发现网络接口地址信息,因为 ifaddrs
在 Android 当时。截至 API 24 ifaddrs
可用。我们将实现切换为使用 ifaddrs
。只要您支持的最低版本是 API 24 或更高版本,您就可以这样做。
我已经使用以下工具创建网络link套接字已有一段时间了:
NetLinkLocalNetworkInfo::NetLinkSocket::NetLinkSocket() :
fd(0)
{
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(fd < 0)
{
throw std::runtime_error("Failed to create NetLink socket");
}
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
int err = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if(err < 0)
{
close(fd);
throw std::runtime_error("Failed to bind NetLink socket");
}
}
这用于我们现有的部分网络逻辑,以使用 ICE 执行自动 NAT 遍历。当目标 API 30 时,对 bind
的调用现在 returns -1 和 errno
是“权限被拒绝”。
针对 API 30 的应用的行为变化现在意味着 bind()
是一个受限调用。 (在 Google 开发者页面的某处有一个文档,但如果我能再次找到它,我会很高兴。它曾经存在 here, but that page has changed since I first came across this issue a few months ago.) Supposedly this is supposed to affect all apps targeting API 30, but I've found that only apps targeting API 30 and running on a device (physical or emulator) running Android 11 are affected. My notes from when I first encountered this also mention that article suggesting using ConnectivityManager,但这需要想出一些方法来通过信息到本机代码或让本机代码通过 JNI 调用 Android 平台代码。如果这是必须发生的事情,我对其中任何一个都很好,但我想知道是否还有另一种选择我'我不知道。
我也看到了this similar question,但是其中一个答案中有一个link表明它应该是可能的,至少在API 30之前。
现在我们不能调用 bind()
,还有哪些其他选项可用?
找到了解决办法。原来我们使用 NetLink 套接字来发现网络接口地址信息,因为 ifaddrs
在 Android 当时。截至 API 24 ifaddrs
可用。我们将实现切换为使用 ifaddrs
。只要您支持的最低版本是 API 24 或更高版本,您就可以这样做。