接上一篇文章,webrtc推流之前需要找到对端和自己的公网IP以及所处位置,这就需要用到STUN协议,本片文章主要记录STUN协议的内容。
STUN(Simple Traversal of User Datagram Protocol Through Network Address Translators),即简单的用UDP穿透NAT,是个轻量级的协议,是基于UDP的完整的穿透NAT的解决方案。它允许应用程序发现它们与公共互联网之间存在的NAT和防火墙及其他类型。它也可以让应用程序确定NAT分配给它们的公网IP地址和端口号。STUN是一种Client/Server的协议,也是一种Request/Response的协议,默认端口号是3478
包结构
与一般的包封装类似,STUN包结构也是包括头和提两部分。
包头
所有的STUN消息都是以20个字节和0个或则多个属性开始。其中,头主要包括如下:
- 16位的消息类型,其中前两个位必须位00,用以标识STUN协议以区分其他协议。
- 16位的消息长度
- 32位的Magic Cookie,magic cookie字段必须以网络字节顺序包含固定值0x2112A442。在RFC3489 [RFC3489]中,该字段是事务ID的一部分;将magic cookie放置在此位置允许服务器检测客户机是否理解在此修订规范中添加的某些属性。此外,当STUN与其他协议在同一端口上复用时,它有助于区分STUN报文和其他协议的报文。
- 96位的Transaction ID, 如果在RFC3489,就是128位的事务ID,但是前32位必须是固定值0x2112A442。
消息类型
消息类型定义了下面这些:
- 0x0001:捆绑请求
- 0x0101:捆绑响应
- 0x0111:捆绑错误响应
- 0x0002:共享私密请求
- 0x0102:共享私密响应
- 0x0112:共享私密错误响应
消息长度
消息长度,是消息大小的字节数,但不包括20字节的头部。
事务ID
事务ID,128位的标识符,用于随机请求和响应,请求与其相应的所有响应具有相同的标识符。
包体
消息头之后是0或多个属性,每个属性进行TLV编码,包括:
- 16位的属性类型
- 16位的属性长度和变长属性值。
属性的类型定义如下:- 0x0001: MAPPED-ADDRESS
- 表示映射过的IP地址和端口。它包括8位的地址族,16位的端口号及长度固定的IP地址。
- 0x0002: RESPONSE-ADDRESS
- 表示响应的目的地址
- 0x0003: CHANGE-REQUEST
- 表示客户使用32位的CHANGE-REQUEST属性来请求服务器使用不同的地址或端口号来发送响应。
- 0x0004: SOURCE-ADDRESS
- 出现在捆绑响应中,它表示服务器发送响应的源IP地址和端口。
- 0x0005: CHANGED-ADDRESS
- 如果捆绑请求的CHANGE-REQUEST属性中的“改变IP”和“改变端口”标志设置了,则CHANGED-ADDRESS属性表示响应发出的IP地址和端口号。
- 0x0006: USERNAME
- USERNAME属性用于消息的完整性检查,用于消息完整性检查中标识共享私密。USERNAME通常出现在共享私密响应中,与PASSWORD一起。当使用消息完整性检查时,可有选择地出现在捆绑请求中。
- 0x0007: PASSWORD
- PASSWORD属性用在共享私密响应中,与USERNAME一起。PASSWORD的值是变长的,用作共享私密,它的长度必须是4字节的倍数,以保证属性与边界对齐。
- 0x0008: MESSAGE-INTEGRITY
- MESSAGE-INTEGRITY属性包含STUN消息的HMAC-SHA1,它可以出现在捆绑请求或捆绑响应中;MESSAGE-INTEGRITY属性必须是任何STUN消息的最后一个属性。它的内容决定了HMAC输入的Key值。
- 0x0009: ERROR-CODE
- ERROR-CODE属性出现在捆绑错误响应或共享私密错误响应中。它的响应号数值范围从100到699。
- 0x000a: UNKNOWN-ATTRIBUTES
- UNKNOWN-ATTRIBUTES属性只存在于其ERROR-CODE属性中的响应号为420的捆绑错误响应或共享私密错误响应中。
- 0x000b: REFLECTED-FROM
- REFLECTED-FROM属性只存在于其对应的捆绑请求包含RESPONSE-ADDRESS属性的捆绑响应中。属性包含请求发出的源IP地址,它的目的是提供跟踪能力,这样STUN就不能被用作DOS攻击的反射器。
- 0x0001: MAPPED-ADDRESS