【问题标题】:STUN server xoring of IPv6IPv6的STUN服务器异或
【发布时间】:2017-03-12 02:27:17
【问题描述】:

我正在尝试根据RFC 5389 解码 STUN 成功响应:

如果 IP 地址族是 IPv6,则 X-Address 是通过获取映射的 IP 地址来计算的 按主机字节顺序,将其与魔法的串联进行异或 cookie 和 96 位交易 ID,并将结果转换为 网络字节序。

Magic cookie 是一个常数,它是 0x2112A442。

在我的例子中,交易 ID 是:0x6FA22B0D9C5F5AD75B6A4E43。

按主机字节顺序排列的我的 X-Address (IPv6) 是:

0x034A67D82F4B3657B193039A8BA8FDA1

我是否必须对主机字节顺序 X-Address 与网络或主机字节顺序中的 Magic Cookie 和事务 ID 的串联进行异或?

在第一种情况下,网络字节顺序连接等于:

0x2112A442 6FA22B0D9C5F5AD75B6A4E43

第一个字节 0x03 与 0x21 异或,最后一个字节 0xA1 与 0x43 异或

但在第二种情况下,主机字节顺序连接是:

0x434E6A5BD75A5F9C0D2BA26F 42A41221

第一个字节 0x03 与 0x43 异或,最后一个字节 0xA1 与 0x21 异或。

另一种可能的行为是,如果它将 Magic cookie 和事务 ID 单独转换为主机字节顺序,但它将它们连接起来并保留标头顺序:

0x42A41221 434E6A5BD75A5F9C0D2BA26F

第一个字节 0x03 与 0x42 异或,最后一个字节 0xA1 与 0x6F 异或。

【问题讨论】:

    标签: xor stun endianness


    【解决方案1】:

    一切都按网络字节顺序完成。

    但问题是,对于 IPv6 地址,“主机字节顺序”和“网络字节顺序”没有区别。 IPv6 地址总是被理解为一个 16 字节的数组。并且单个字节没有“字节顺序”。在“C”代码中,我们只需将 IPv6 地址表示为:

     unsigned char ipv6address[16];
    

    或者就 sockaddr_in6 结构而言;

     struct sockaddr_in6 addr;
     unsigned char* ipv6addresss = addr.sin6_addr.s6_addr; // points to a sequence of 16 bytes
    

    与 IPv4 相比,IPv4 通常在代码中作为 32 位整数传递。在 IPv4 情况下,您通常不得不调用 htonlntohl 函数。

    除非您将 IPv6 地址维护为 8 个 16 位整数的数组而不是数组字节,否则您不必过多考虑字节顺序和字节顺序。 (事实上​​,我建议您不要考虑 16 字节 IP 地址的字节顺序)。

    例子:

    我的 IPv6 地址是这样的:

    2001:0000:9d38:6abd:347d:0d08:3f57:fefd
    

    作为一个十六进制字节数组,逻辑上写成:

    200100009d386abd347d0d083f57fefd
    

    当我的 STUN 服务器收到来自这个 IPv6 地址的绑定请求时,它会应用以下 XOR 操作来发回 XOR-MAPPED-ADDRESS。假设它与您的事务 id 相同,并且它包含用于指示 RFC 5389 支持的魔术 cookie (2112A442 6FA22B0D9C5F5AD75B6A4E43)

    XOR:
         200100009D386ABD347D0D083F57FEFD
         2112A4426FA22B0D9C5F5AD75B6A4E43
    

    结果:

         0113A442F29A41B0A82257DF643DB0BE
    

    同样,接收到 STUN 绑定响应的客户端对具有相同事务 id 的字节数组应用逆 XOR 操作。

    XOR:
         0113A442F29A41B0A82257DF643DB0BE
         2112A4426FA22B0D9C5F5AD75B6A4E43
    

    结果:

         200100009D386ABD347D0D083F57FEFD
    

    如果对如何应用异或映射操作的示例有所帮助,您可以参考 Stuntman 的源代码。 XOR 操作是here on GitHub。此处的代码不区分带有魔术 cookie 的事务 id 和不带魔术 cookie 的事务 id。它只是将事务 id 视为 16 字节的逻辑序列。

    上面处理了 IPv6 地址。但是,如果将 16 位端口值视为short 或 16 位整数,则它必须进行字节翻转。在 C 代码中,这通常通过调用 ntohs 来处理。

    【讨论】:

    • 我不明白另一个问题:你是说如果我将 X-Address 作为字节数组,我不应该关心字节顺序。但是我链接的 RFC 的最后一部分说:“[...] 并将结果转换为网络字节顺序。”这样,服务器似乎以主机字节顺序工作,最后将结果转换为网络字节顺序,所以服务器获得的异或结果可能是 0x200100009D386ABD347D0D083F57FEFD 但它发送给我:0xFDFE573F080D7D34BD6A389D00000120
    • 我已经更新了我的答案,其中包含 IPv6 的 STUN 数据包跟踪的完整细分以及 XOR'ing 如何匹配。我无法比这更好地解释它。停止思考“字节顺序”,将 ipv6 地址视为字节数组。
    • 非常感谢,我一直在盲目地遵循 RFC 说明,但它们误导了我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多