android - 以 Android API 30 为目标时无法绑定(bind) () netlink 套接字

标签 android android-ndk netlink

我已经使用以下方法创建一个 netlink 套接字已有一段时间了:

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 的调用现在返回 -1 并且 errno 为“Permission Denied”。

针对 API 30 的应用的行为变化现在意味着 bind() 是一个受限调用。 (在 Google 开发者页面的某处有一份文档,但如果我能再次找到它,我会很高兴。它曾经存在 here,但自从几个月前我第一次遇到这个问题以来,该页面已经发生了变化。)据说这应该会影响所有以 API 30 为目标的应用程序,但我发现只有以 API 30 为目标的应用程序在运行 Android 11 的设备(物理或模拟器)上运行会受到影响。我第一次遇到这个问题时的笔记也提到了建议使用 ConnectivityManager 的文章,但这需要想出某种方法将信息向下传递给 native 代码,或者让 native 代码通过 JNI 调用 Android 平台代码。如果这是必须发生的事情,我对其中任何一个都没有意见,但我想知道是否还有我不知道的另一种选择。

我还看到了this similar question ,但其中一个答案中有一个链接表明它应该是可能的,至少在 API 30 之前是这样。

既然我们不允许调用 bind(),还有哪些其他选项可用?

最佳答案

找到了解决办法。结果我们使用 NetLink 套接字来发现网络接口(interface)地址信息,因为 ifaddrs 不可用(或者,没有完全实现,或者类似的东西 - 这里没有人能确切记得我们为什么不能使用它)当时在安卓上。从 API 24 开始,ifaddrs 现已可用。我们将实现切换为使用 ifaddrs。只要您支持的最低版本是 API 24 或更高版本,您就可以执行相同的操作。

关于android - 以 Android API 30 为目标时无法绑定(bind) () netlink 套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64884994/

相关文章:

android - Android Studio 3.1.x 中的 Constraint Layout Editor 是否已经支持 AndroidX?

android - 如何使用 .so 文件在 android 应用程序中为我的自定义视频编解码器创建 .apk 文件

c - 允许创建多少个 netlink 协议(protocol)?

android-studio - Android ndk 示例原生音频错误

android - Vulkan API 示例构建失败

c - Netlink 套接字创建返回 NULL

c++ - 从 netlink 套接字请求连接设备列表

java - 尽管变量已初始化,但我得到可能未初始化错误

android - Android Gradle:获取选定的构建变体/构建类型

android - 在 Android M 上通过 wifi 请求