You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android VpnService.Builder添加IPv6 DNS服务器后触发ParcelFileDescriptor空指针异常

解决VPN接口构建时添加IPv6 DNS导致的空指针异常

我前不久刚碰到过一模一样的问题!你这个空指针的根源在于IPv4和IPv6配置的链式调用方式错误,导致establish()返回了null,最终调用getFileDescriptor()时触发异常。

问题分析

看你的代码片段:

builder.addDnsServer(dnsIp)
 .addDnsServer(dns2Ip)
 .allowFamily(OsConstants.AF_INET);
builder.addDnsServer(ssd)
 .allowFamily(OsConstants.AF_INET6)
 .establish();

你在添加IPv6 DNS后直接链式调用了establish(),这里的问题出在两点:

  1. 两次分开的链式调用会导致配置没有正确合并,allowFamily的设置可能互相覆盖
  2. 提前调用establish()会中断配置流程,前面的IPv4配置没有完全生效,最终构建失败返回null

修复方案

调整代码结构,把所有配置项设置完成后,最后统一调用establish(),同时确保正确允许IPv4和IPv6协议族:

// 初始化VPN会话
builder.setSession("MyVPNService");
// 添加IPv4地址
builder.addAddress(deviceIp, 24);
// 添加IPv4 DNS服务器
builder.addDnsServer(dnsIp)
       .addDnsServer(dns2Ip);
// 添加IPv6 DNS服务器
builder.addDnsServer("2400:cb00:f00d:dead:beef:1111:2222:3333");
// 同时允许IPv4和IPv6协议族
builder.allowFamily(OsConstants.AF_INET)
       .allowFamily(OsConstants.AF_INET6);
// 最后统一建立VPN接口
mInterface = builder.establish();

// 关键:一定要先检查mInterface是否为null
if (mInterface != null) {
    FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
    // 这里继续你的后续操作
} else {
    // 处理接口建立失败的情况,比如权限不足、系统限制等
    Log.e("VPNSetup", "Failed to create VPN interface - check permissions or configuration");
}

额外提醒

  • 永远不要忽略establish()的返回值!VPN的建立可能因为缺少BIND_VPN_SERVICE权限、系统VPN设置冲突、或者配置错误而失败,返回null
  • 如果不需要同时支持IPv4和IPv6,可以只保留对应协议族的allowFamily调用,但不要分开配置后多次调用establish()

内容的提问来源于stack exchange,提问作者jcooli

火山引擎 最新活动