写入 VpnService 输出流没有响应

2024-01-07

我的应用程序实现 VpnService 来拦截网络流量并提供量身定制的响应。目标是处理特定地址的流量,并丢弃其他请求。

目前,我成功解析传入请求并构建和发送响应。然而,问题在于这些响应并不是作为对原始请求的实际响应而到达的。使用套接字连接进行测试只会超时。

为了做出这种区分,我目前正在解析来自 VpnService 输入流的原始 IP 数据包,如下所示:

VpnService.Builder b = new VpnService.Builder();
b.addAddress("10.2.3.4", 28);
b.addRoute("0.0.0.0", 0);
b.setMtu(1500);
...
ParcelFileDescriptor vpnInterface = b.establish();
final FileInputStream in = new FileInputStream(
        vpnInterface.getFileDescriptor());
final FileOutputStream out = new FileOutputStream(
        vpnInterface.getFileDescriptor());

// Allocate the buffer for a single packet.
ByteBuffer packet = ByteBuffer.allocate(32767);

// We keep forwarding packets till something goes wrong.
try {
    while (vpnInterface != null && vpnInterface.getFileDescriptor() != null
            && vpnInterface.getFileDescriptor().valid()) {
        packet.clear();
        SystemClock.sleep(10);
        // Read the outgoing packet from the input stream.
        final byte[] data = packet.array();
        int length = in.read(data);
        if (length > 0) {
            packet.limit(length);
        /*
         1. Parse the TCP/UDP header
         2. Create an own socket with the same src/dest port/ip
         3. Use protect() on this socket so it not routed over tun0
         4. Send the packet body (excluding the header)
         5. Obtain the response
         6. Add the TCP header to the response and forward it
         */
        final IpDatagram ip = IpDatagram.create(packet);
        ...
    }
}

IpDatagram 是一个类,通过它create()将字节数组解析为 IP 数据包的表示形式,其中包含 IP 标头、选项和正文。我继续根据协议类型解析主体的字节数组。在本例中,我只对带有 TCP 有效负载的 IPv4 感兴趣 - 这里我也创建了 TCP 标头、选项和正文的表示。

获得 IpDatagram 实例后,我可以确定源和目标 IP(从 IP 标头)和端口(从 TCP 标头)。我还确认请求 TCP 的标志(例如 SYN、ACK 和 PSH)和序列号。在应用程序中:

随后,我构造一个新的 IpDatagram 作为响应,其中:

  • 源和目标IP与传入请求相反;
  • 源端口和目标端口与传入请求相反;
  • TCP 确认号设置为传入请求的序列号;
  • 提供虚拟 HTTP/1.1 有效负载作为 TCP 主体。

我将生成的 IpDatagram 转换为字节数组并将其写入 VpnServer 的输出流:

TcpDatagram tcp = new TcpDatagram(tcpHeader, tcpOptions, tcpBody);
IpDatagram ip = new Ip4Datagram(ipHeader, ipOptions, tcp);
out.write(ip.toBytes());

我的应用程序按应有的方式显示传出数据报,但尽管如此,所有连接仍然超时。

以下是十六进制传入 TCP/IP 数据包的示例:

4500003c7de04000400605f10a0203044faa5a3bb9240050858bc52b00000000a00239089a570000020405b40402080a00bfb8cb0000000001030306

以及生成的十六进制传出 TCP/IP 数据包:

450000bb30394000800613194faa5a3b0a0203040050b92400a00000858bc52b501820001fab0000485454502f312e3120323030204f4b0a446174653a2054 75652c203139204e6f7620323031332031323a32333a303320474d540a436f6e74656e742d547970653a20746578742f68746d6c0a436f6e74656e742d4 c656e6774683a2031320a457870697265733a205475652c203139204e6f7620323031332031323a32333a303320474d540a0a48656c6c6f20776f726c64 21

然而,简单的测试就会超时;我创建了一个新套接字并将其连接到上面的 IP,但上面提供的响应从未到达。

可能出了什么问题?有什么方法可以解决为什么我的回复未送达的问题吗?


此 TCP/IP 响应不包含有效的 TCP 标头校验和:

450000bb30394000800613194faa5a3b0a0203040050b92400a00000858bc52b501820001fab0000485454502f312e3120323030204f4b0a446174653a205475652c203139204e6f7620323031332031323a32333a303320474d540a436f6e74656e7 42d547970653a20746578742f68746d6c0a436f6e74656e742d4c656e6774683a2031320a457870697265733a205475652c203139204e6f762032303133 2031323a32333a303320474d540a0a48656c6c6f20776f726c6421

更一般地说,请求和响应机制非常挑剔。当然,由于网络的本质,情况就是如此,并且由于内核负责确保响应良好以及响应应发送到哪个端口,因此任何不计算的内容都将作为坏数据包被丢弃。当您在网络层上操作时,从 VpnService 的输出流进行响应时也是如此。

回到上面的具体情况:IP 数据包是正确的(包括校验和),但 TCP 数据包不正确。您不仅需要计算 TCP 数据包的 TCP 标头校验和,还需要计算伪标头前缀,如下所示:

TCP pseudo-header
(source: tcpipguide.com http://www.tcpipguide.com/free/diagrams/tcppseudoheader.png)

然后应该通过以下字节进行计算:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

写入 VpnService 输出流没有响应 的相关文章

  • Android 主机意图过滤器通配符

    是否可以在 android host 属性上使用通配符 就像是 android host site com android pathPattern android pathPrefix m android scheme http gt Or
  • 在 Android 中创建和使用 9 补丁图像

    我最近听说了 9 补丁图像 我知道它是 9 平铺的并且是可拉伸的 我想了解更多 如何创建 9 块图像 有什么工具吗 我可以通过 AndroidSDK 或代码创建它吗 9 patch 相对于普通 png 的主要优点 它是否可以根据屏幕动态 自
  • 单击 RecyclerView 内的 ImageView 时更改图像资源

    每当我单击它时 单击图像 而不是项目 我都会尝试更改回收器视图内特定位置的设备图像资源 我尝试将 setOnClickListener 放入 onBindViewHolder 方法中 但只有最后一个项目受到影响 这是我的回收者视图 http
  • 关闭 Android 中的飞行模式

    如果 num gt 50 我想关闭飞行模式 我实现了这段代码 来自在 Android 中切换飞行模式 https stackoverflow com questions 5533881 toggle airplane mode in and
  • 如何检测和管理来电(Android)?

    我想创建一个应用程序 可以检测来电并在一定数量的蜂鸣声 响铃 后启动我的自定义活动 我的意思是在 2 或 3 或 5 声蜂鸣声 响铃 后我的activity被触发 我该怎么做 Thanks 我认为您无法计算自来电开始以来电话响了多少次 无法
  • 检索子值 -firebase-

    System out println ref child email protected cdn cgi l email protection child email 我正在尝试获取 child 的值 但我始终获取该值的 URL 当我尝试使
  • 应用程序实例是否始终在任何活动之前创建?

    在 Android 中 您可以通过扩展 Application 类并在 Manifest 中声明名称来提供您自己的 Application 类实现 我的问题是 这个实现是否总是在初始活动之前创建 或者活动可以在应用程序实例有时间创建之前启动
  • Android Studio:lambda 不起作用[重复]

    这个问题在这里已经有答案了 当尝试使用 lambda 表达式时 我遇到了一些 Gradle 构建错误 错误 41 100 错误 source 1 7 不支持 lambda 表达式 使用 source 8 或更高版本来启用 lambda 表达
  • 在 WebView 中完成 AdBlock

    我即将在我的 Android 应用程序中推出 WebView AdBlocking 我想知道这是否会有效地阻止广告 或者在 Webview 本身内是否还有更多工作要做 我尚未修改 基本上我有一个存储在 Android 资产中的主机文件 其中
  • Android中不同线程的数据库访问

    我有一个在 AsyncTasks 中从互联网下载数据的服务 它解析数据并将其存储在数据库中 该服务持续运行 当服务写入数据库时 活动会尝试从数据库中读取更改 我有一个数据库助手 有多种写入和读取方法 这会导致问题吗 可能尝试从两个不同的线程
  • 获取可以共享数据的应用程序列表

    此代码显示默认共享对话框 Intent sharingIntent new Intent Intent ACTION SEND sharingIntent setType text html sharingIntent putExtra a
  • 没有调用addToBackStack,片段仍然添加到backstack,为什么?

    我正在制作我的片段更换器助手类 但我遇到了一些问题 我称之为FragmentChanger 它有一个fragmentContainer 这是一个ViewGroup 其中包含我想展示的所有片段 我已经做了我自己的replace Fragmen
  • Android 改变 ImageView / Bitmap 的颜色

    我需要找到一种方法来改变 Android 中位图的颜色 我需要在我的应用程序中平滑地替换 更改椭圆形图像的颜色 具体取决于int价值 我需要类似的东西myValue 5比改变我的图像的颜色RED and if myValue 322将颜色更
  • 在 AppAuth-Android 中注销

    我有一个用JAVA开发的Android应用程序 对于这个应用程序 我使用的是身份服务器4 https github com IdentityServer IdentityServer4作为我的 STS 一切正常 但我找不到任何注销的实现Ap
  • 通过列表视图检查动态生成的复选框时遇到问题

    我知道其他成员已经提出了这个问题 一些成员也给出了解决方案 但问题是我没有找到任何适合我的应用程序的解决方案 我正在创建一个应用程序 其中我有一个屏幕 它将显示动态列表视图 其中包含列表项 复选框和三个文本视图 一个用于候选人姓名 另外两个
  • jar 中的 apklib 有什么优点?

    我正在关注这个问题 https stackoverflow com questions 6059502 whats the difference between apklib and jar files但它并没有完全回答我的问题 jar 中
  • 删除Android所有语言中的字符串

    我有一个包含多个翻译的应用程序 我想删除一些字符串 我怎样才能重构并删除它们一次 例如在默认情况下strings xml文件并自动将删除传播到其他翻译的其他 strings xml 文件 您可以通过 Android Studio 中的 翻译
  • [cocos2d-x]当我尝试在 Windows 10 中运行“python android-build.py -p 19 cpp-tests”时出现错误

    当我尝试运行命令时python android build p cpp tests 我收到如图所示的错误 在此之前 我收到了另一条关于 Android SDK Tools 版本兼容性的错误消息 所以 我只是将 sdk 版本从 26 0 0
  • 具有矢量可绘制的 ImageView 的 Resources$NotFoundException

    我遇到了崩溃 Resources NotFoundException用于在活动创建时绘制的矢量 21 日前崩溃 安卓工作室2 1 支持库24 0 0 Gradle插件2 1 0 目标SDK 23 最小SDK 15 buildTools版本
  • 如何以编程方式创建活动转换?

    我想以编程方式创建一个动画 以从触摸屏点启动具有缩放效果的活动 接下来我模拟缩放输入效果

随机推荐