跳到主要内容

4. 一般行为

本章包含适用于所有 TURN 消息的一般 TURN 处理规则.

TURN 是 STUN 的扩展. 除 ChannelData message 外, 所有 TURN 消息都是 STUN 格式的消息. [RFC5389] 中描述的所有基本处理规则都适用于 STUN 格式的消息. 这意味着, 本文档中所有关于消息构造和消息处理的描述, 都隐含地以前置适用 [RFC5389] 的规则为前提.

[RFC5389] 规定了一种称为 long-term credential mechanism (长期凭据机制) 的认证机制. TURN server 和 client 必须实现该机制. server 必须要求 client 的所有请求都使用该机制认证, 或使用强度相当或更强的机制认证.

注意, long-term credential mechanism 只适用于 request (请求), 不能用于认证 indication (指示); 因此, TURN 中的 indication 从不认证. 如果 server 要求请求经过认证, 则 server 管理员必须选择一个 realm 值, 该值能够唯一标识 client 必须用来认证请求的用户名和密码组合, 即使 client 使用由不同管理域管理的多个 server 也是如此. server 管理员可以为每个 client 分配唯一用户名, 也可以为多个 client 分配同一个用户名 (例如, 同一部门或公司的所有 client). 对于每个 allocation, server 应该在首次尝试创建 allocation 时生成一个新的随机 nonce, 遵循 [RFC4086] 中的随机性建议, 并且应该在 allocation 生命周期内至少每小时使 nonce 过期一次.

初始 Allocate 之后的所有请求必须使用与创建 allocation 时相同的用户名, 以防攻击者劫持 client 的 allocation. 具体而言, 如果 server 要求使用 long-term credential mechanism, 且某个非 Allocate 请求通过了该机制的认证, 并且 5-tuple 标识了一个现有 allocation, 但该请求使用的用户名与创建 allocation 时使用的用户名不同, 则该请求必须以 441 (Wrong Credentials) 错误拒绝.

当 server 从 client 收到 TURN 消息时, server 使用消息中的 5-tuple 来标识关联的 allocation. 对于除 Allocate request 之外的所有 TURN 消息 (包括 ChannelData), 如果 5-tuple 未标识现有 allocation, 则该消息必须以 437 (Allocation Mismatch) 错误拒绝 (如果它是 request), 或静默忽略 (如果它是 indication 或 ChannelData message). client 在对非 Allocate 请求收到 437 错误响应时, 必须假定 allocation 已不复存在.

[RFC5389] 定义了若干属性, 包括 SOFTWARE 和 FINGERPRINT 属性. client 应该在所有 Allocate 和 Refresh 请求中包含 SOFTWARE 属性, 并可以在任何其他请求或 indication 中包含该属性. server 应该在所有 Allocate 和 Refresh 响应 (成功或失败) 中包含 SOFTWARE 属性, 并可以在其他响应或 indication 中包含该属性. client 和 server 可以在本文档定义的任何 STUN 格式消息中包含 FINGERPRINT 属性.

TURN 不使用 [RFC5389] 中描述的 backwards-compatibility mechanism (向后兼容机制).

按当前定义, TURN 仅支持 IPv4. client, server 的 IP 地址, 以及 relayed transport address 中出现的所有 IP 地址必须是 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 server 必须支持在 client 与 server 之间使用 UDP transport, 并应该支持使用 TCP 和 TLS transport.

当 client 与 server 之间使用 UDP transport 时, 如果 client 在某个超时时间内没有收到响应, 它会重传请求. 因此, server 可能收到两个 (或更多) 具有相同 5-tuple 和相同 transaction id 的请求. STUN 要求 server 识别这种情况, 并将该请求视为 idempotent (幂等) (见 [RFC5389]). 某些实现可能选择通过记住所有已收到请求及其对应响应 40 秒来满足此要求. 其他实现可能选择重新处理请求, 并安排这种重新处理返回实质上相同的响应. 为帮助选择后一种方法 (所谓 "stateless stack approach" (无状态栈方法)) 的实现者, 本规范包含了一些关于如何做到这一点的实现说明. 实现可以自由选择任一方法, 也可以选择能给出相同结果的其他方法.

当 client 与 server 之间使用 TCP transport 时, bit errors (比特错误) 可能导致 TURN packet 中的 length field 损坏, 从而使接收方与传入 TURN 消息流失去同步. 检测到 TCP transport 上存在一长串无效 TURN 消息的 client 或 server 应该关闭相应的 TCP connection, 以帮助另一端更快地检测到这种情况.

为缓解拥有有效用户名和密码的 client 对 server 发起有意或无意 denial-of-service attacks (拒绝服务攻击), 推荐的做法是 server 同时对某个给定用户名可同时活跃的 allocation 数量设置限制, 并对这些 allocation 可使用的带宽量设置限制. 对于会超过允许的并发活跃 allocation 数量限制的新 allocation, server 应该以 486 (Allocation Quota Exceeded) 拒绝 (见第 6.2 节), 并应该丢弃超过带宽配额的应用数据流量.