RFC5764/STUN
struct STUNHeader
{
uint16_t type;
uint16_t length;
uint8_t magicCookie[4];
uint8_t transactionId[12];
struct Attribute attr;
}
struct Attribute
{
uint16_t attrType;
uint16_t attrLength;
uint8_t attrValue[N]; // N=attrLength
}
-
type 消息类型。
type[0]<3
,type细节详解下面代码段 - length 消息长度,不包含消息头的长度
- magicCookie 魔法数字0x2112A442,用来确定一定是STUN消息
- transactionId 发送,返回的id是一致的
/* STUNHeader.type 图解,前两个bit一定是0,下面就没列出来
0 1
2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
*/
enum klass
{
REQUEST = 0, // 绑定请求消息。C1=0,C0=0;type=0x0001
INDICATION = 1, // 表示标志。C1=0,C0=1
SUCCESS_RESPONSE = 2, // 表示请求成功的响应。C1=1,C0=0;type=0x0101
ERROR_RESPONSE = 3 // 表示请求错误的响应。C1=1,C0=1;type=0x0111
};
enum method
{
BINDING = 1 // 绑定消息,M0=1
};
STUN body
struct Attribute
{
uint16_t attrType; // attrType=attr
uint16_t attrLength;
uint8_t attrValue[N]; // N=attrLength
}
enum attr
{
MAPPED_ADDRESS = 0x0001, // 获取客户端映射地址
RESPONSE_ADDRESS = 0x0002, // 表示响应的目的地址
CHANGE_REQUEST = 0x0003, // 请求服务器使用不同的ip或端口号来发送响应
SOURCE_ADDRESS = 0x0004, // 指定服务器的ip和端口
CHANGED_ADDRESS = 0x0005, // CHASNGE_REQUEST请求的响应
USERNAME = 0x0006, // 用于安全验证
PASSWORD = 0x0007, // 用于安全验证
MESSAGE_INTEGRITY = 0x0008, // 消息完整性验证
ERROR_CODE = 0x0009, // 错误码
UNKNOWN_ATTRIBUTES = 0x000A, // 未知属性
REFLECTED_FROM = 0x000B, // 拒约
REALM = 0x0014,
NONCE = 0x0015,
XOR_MAPPED_ADDRESS = 0x0020,
PRIORITY = 0x0024,
USE_CANDIDATE = 0x0025,
SOFTWARE = 0x8022,
ALTERNATE_SERVER = 0x8023,
FINGERPRINT = 0x8028,
ICE_CONTROLLED = 0x8029,
ICE_CONTROLLING = 0x802A
};
// Authentication result.
enum class Authentication
{
OK = 0,
UNAUTHORIZED = 1,
BAD_REQUEST = 2
};