STUN协议解析


和STUN协议相关的文档一共有三个:RFC 3489RFC 5389RFC 5780

引用

  1. nat-behavior-discovery-using-stun-rfc-5780
  2. stun-rfc-3489-vs-stun-rfc-5389-5780
  3. 网络地址转换
  4. STUN

Message Header

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      STUN Message Type        |         Message Length        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                            Transaction ID
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

STUN消息主要分为两种:

  • Header说明
类型 说明
STUN Message Type STUN类型
Message Lenght 去除固定头部(20Byte)的剩余的长度
Transaction ID 一个128位的标识符,客户端随机生成的,然后服务端要回复相同的标识符
  • STUN Message Type说明
MessageType值 类型
0x0001 Binding Request
0x0101 Binding Response
0x0111 Binding Error Response

Message Attributes

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Type                  |            Length             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             Value                             ....
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

一个STUN消息可以包含0个或者多个STUN属性,属性有一个通用的头部,如上。

  • Message Attributes说明
类型 说明
Type 一个uint16长度的类型,用不同的值区分不同的属性
Lenght 表示Value的长度,不包括固定头部的大小(4Byte)
Value 不固定长度,表示属性的内容
  • Type说明
类型
0x0001 MAPPED-ADDRESS
0x0002 RESPONSE-ADDRESS
0x0003 CHANGE-REQUEST
0x0004 SOURCE-ADDRESS
0x0005 CHANGED-ADDRESS
0x0006 USERNAME
0x0007 PASSWORD
0x0008 MESSAGE-INTEGRITY
0x0009 ERROR-CODE
0x000a UNKNOWN-ATTRIBUTES
0x000b REFLECTED-FROM
0x802b RESPONSE-ORIGIN
0x802c OTHER-ADDRESS

MAPPED-ADDRESS

用于表示客户端外部IP地址,如果没有NAT,那么外部IP地址和内部IP地址是相同的。前8位保留,之后8位用于表示IP类型(IPV4/6)。之后16位表示端口号。这里强制使用IPV4版本,所以Address是32位。

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |x x x x x x x x|    Family     |           Port                |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             Address                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

RESPONSE_ADDRESS

用于标示哪一个服务端的IP和Port发送发送的数据。数据格式参考MAPPED-ADDRESS

CHANGE-REQUEST

请求服务端使用不同的IP或者Port来给客户端发送消息。A表示“改变IP”标志,B表示“改变端口”标志。

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A B 0|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ERROR-CODE

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                   0                     |Class|     Number    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |      Reason Phrase (variable)                                ..
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • ERROR-CODE说明
类型 说明
Class 用于存储100的倍数,这个值只能是1~6
Number 100的余数,值的范围是0~99,Error Code的计算是:Class * 100 + Number
Reason Phrase ByteString类型,用于描述错误信息
  • Error Code说明
Error Code 说明
400 请求格式不正确
401 请求消息不包含MESSAGE-INTEGRITY属性
420 服务器不理解请求中的强制属性
430 请求消息包含MESSAGE-INTEGRITY属性,但是却使用了一个过期的共享密钥
431 请求消息包含MESSAGE-INTEGRITY属性,但是HMAC校验失败。
500 服务器遇到了一个临时错误。客户端应该重试
600 服务器拒绝满足该请求。 客户端不应重试

RESPONSE-ORIGIN

用于标示哪一个服务端的IP和Port发送的数据。数据格式参考MAPPED-ADDRESS

OTHER-ADDRESS

用于标示服务端另一个IP和Port发送的数据。数据格式参考MAPPED-ADDRESS

RFC3478 VS RFC5780

RFC3478和RFC5780主要区别在于:NAT类型和探测方式。RFC5780细化NAT类型,采用新的探测方式,为了新类型和新探测方式新增了几种对应的属性。

RFC3478 NAT类型定义

RFC3478 NAT Variations中定义了四种NAT类型:Full cone、Restricted cone、Port-Restricted cone和Symmetric。

完全圆锥形NAT(Full cone NAT)

  • 一旦一个内部地址(iAddr:port)映射到外部地址(eAddr:port),所有发自iAddr:port的包都经由eAddr:port向外发送。任意外部主机都能通过给eAddr:port发包到达iAddr:port(注:port不需要一样)
    在这里插入图片描述

受限圆锥形NAT(Address-Restricted cone NAT)

  • 内部客户端必须首先发送数据包到对方(IP=X.X.X.X),然后才能接收来自X.X.X.X的数据包。在限制方面,唯一的要求是数据包是来自X.X.X.X。
  • 内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。外部主机(hostAddr:any)能通过给eAddr:port2发包到达iAddr:port1。(注:any指外部主机源端口不受限制,但是目的端口必须是port2。只有外部主机数据包的目的IP 为 内部客户端的所映射的外部ip,且目的端口为port2时数据包才被放行。
    在这里插入图片描述

端口受限圆锥形NAT(Port-Restricted cone NAT)

类似受限制锥形NAT(Restricted cone NAT),但是还有端口限制。

  • 一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。
  • 在受限圆锥型NAT基础上增加了外部主机源端口必须是固定的。
    在这里插入图片描述

对称NAT(Symmetric NAT)

  • 每一个来自相同内部IP与端口,到一个特定目的地地址和端口的请求,都映射到一个独特的外部IP地址和端口。同一内部IP与端口发到不同的目的地和端口的信息包,都使用不同的映射
  • 只有曾经收到过内部主机数据的外部主机,才能够把数据包发回
    在这里插入图片描述

RFC5780 NAT类型

RFC5780 NAT类型主要分为两类:地址和端口隐射,地址和端口过滤。

Full cone

在这里插入图片描述

Restricted cone

在这里插入图片描述

Port-Restricted cone

在这里插入图片描述

Symmetric

在这里插入图片描述

下图显示了RFC 5780中定义的九种NAT类型和RFC 3489中定义的四种NAT类型,以及RFC 3489中的NAT类型如何与RFC 5780中的对应类型匹配。
在这里插入图片描述

RFC3478 探测算法

RFC3478 Binding Lifetime Discovery
在这里插入图片描述

一旦路经通过红色箱子的终点时,UDP的沟通是没有可能性的。一旦通过黄色或是绿色的箱子,就有连线的可能。

RFC5780 探测算法

RFC5780探测分为两种方式:NAT隐射和NAT过滤。

NAT隐射方式探测

在这里插入图片描述

没有NAT

在这里插入图片描述

端点无关的隐射NAT

在这里插入图片描述

地址相关的隐射NAT

在这里插入图片描述

地址和端口相关的隐射NAT

在这里插入图片描述

NAT过滤方式探测

在这里插入图片描述

端点无关的过滤NAT

在这里插入图片描述

地址相关的过滤NAT

在这里插入图片描述

地址和端口相关的过滤NAT

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章