4. General Behavior (通用行为)
本节包含适用于所有 TURN 消息的通用 TURN 处理规则。
TURN 是 STUN 的扩展。除 ChannelData 消息外,所有 TURN 消息都是 STUN 格式的消息。[RFC5389] 中描述的所有基本处理规则都适用于 STUN 格式的消息。这意味着本文档中的所有消息构造和消息处理描述都隐式地以 [RFC5389] 的规则为前缀。
[RFC5389] 指定了一种称为长期凭证机制 (Long-Term Credential Mechanism) 的身份验证机制。TURN 服务器和客户端必须 (MUST) 实现此机制。服务器必须 (MUST) 要求使用此机制对来自客户端的所有请求进行身份验证,或者使用同等强度或更强的客户端身份验证机制。
请注意,长期凭证机制仅适用于请求,不能用于对指示进行身份验证,因此,TURN 中的指示永远不会被身份验证。如果服务器要求对请求进行身份验证,则服务器的管理员必须 (MUST) 选择一个领域值,该值将唯一标识客户端必须使用的用户名和密码组合,即使客户端使用不同管理下的多个服务器。服务器的管理员可以 (MAY) 选择为每个客户端分配唯一的用户名,或者可以 (MAY) 选择为多个客户端分配相同的用户名(例如,对来自同一部门或公司的所有客户端)。对于每个分配,服务器应该 (SHOULD) 在首次尝试分配时生成一个新的随机随机数 (Nonce),遵循 [RFC4086] 中的随机性建议,并且应该 (SHOULD) 在分配的生存期内至少每小时使随机数过期一次。
初始 Allocate 之后的所有请求必须 (MUST) 使用与用于创建分配的用户名相同的用户名,以防止攻击者劫持客户端的分配。具体来说,如果服务器要求使用长期凭证机制,并且如果非 Allocate 请求在此机制下通过了身份验证,并且如果 5 元组标识了现有分配,但请求未使用与创建分配时使用的用户名相同的用户名,则请求必须 (MUST) 被拒绝,并返回 441(错误凭证,Wrong Credentials)错误。
当 TURN 消息从客户端到达服务器时,服务器使用消息中的 5 元组来标识关联的分配。对于所有 TURN 消息(包括 ChannelData)除 Allocate 请求外,如果 5 元组未标识现有分配,则消息必须 (MUST) 被拒绝并返回 437 分配不匹配 (Allocation Mismatch) 错误(如果它是请求),或被静默忽略(如果它是指示或 ChannelData 消息)。接收到对 Allocate 以外的请求的 437 错误响应的客户端必须 (MUST) 假设分配不再存在。
[RFC5389] 定义了许多属性,包括 SOFTWARE 和 FINGERPRINT 属性。客户端应该 (SHOULD) 在所有 Allocate 和 Refresh 请求中包含 SOFTWARE 属性,并且可以 (MAY) 在任何其他请求或指示中包含它。服务器应该 (SHOULD) 在所有 Allocate 和 Refresh 响应(成功或失败)中包含 SOFTWARE 属性,并且可以 (MAY) 在其他响应或指示中包含它。客户端和服务器可以 (MAY) 在本文档中定义的任何 STUN 格式的消息中包含 FINGERPRINT 属性。
TURN 不使用 [RFC5389] 中描述的向后兼容性机制。
根据本规范的定义,TURN 仅支持 IPv4。客户端的 IP 地址、服务器的 IP 地址以及出现在中继传输地址中的所有 IP 地址必须 (MUST) 是 IPv4 地址。
默认情况下,TURN 在与 STUN 相同的端口上运行:UDP 和 TCP 上的 TURN 为 3478,TLS 上的 TURN 为 5349。但是,TURN 有自己的一组服务记录 (Service Record, SRV) 名称:UDP 和 TCP 为"turn",TLS 为"turns"。第 6 节中描述的 SRV 过程或 ALTERNATE-SERVER 过程都可以用于在不同的端口上运行 TURN。
为了确保互操作性,TURN 服务器必须 (MUST) 支持在客户端和服务器之间使用 UDP 传输,并且应该 (SHOULD) 支持使用 TCP 和 TLS 传输。
当在客户端和服务器之间使用 UDP 传输时,如果客户端在特定超时期限内未收到响应,它将重传请求。因此,服务器可能会收到两个(或更多)具有相同 5 元组和相同事务 ID 的请求。STUN 要求服务器识别这种情况,并将请求视为幂等的(参见 [RFC5389])。某些实现可能选择通过记住所有接收到的请求和相应的响应 40 秒来满足此要求。其他实现可能选择重新处理请求,并安排这种重新处理返回基本相同的响应。为了帮助选择后一种方法(所谓的"无状态栈方法")的实现者,本规范包括一些关于如何做到这一点的实现说明。实现可以自由选择任一方法或选择给出相同结果的其他方法。
当在客户端和服务器之间使用 TCP 传输时,位错误可能会导致 TURN 数据包中的长度字段损坏,导致接收方失去与传入的 TURN 消息流的同步。在 TCP 传输上检测到长序列无效 TURN 消息的客户端或服务器应该 (SHOULD) 关闭相应的 TCP 连接,以帮助另一端更快地检测到这种情况。
为了缓解具有有效用户名和密码的客户端对服务器的有意或无意的拒绝服务攻击,推荐 (RECOMMENDED) 服务器对给定用户名同时活动的分配数量以及这些分配可以使用的带宽量都施加限制。服务器应该 (SHOULD) 拒绝将超过允许的同时活动分配数量限制的新分配,并返回 486(分配配额超出,Allocation Quota Exceeded)(参见第 6.2 节),并且应该 (SHOULD) 丢弃超过带宽配额的应用程序数据流量。