跳到主要内容

15. 语法 (Grammar)

本规范定义七个新的 SDP 属性: "candidate", "remote-candidates", "ice-lite", "ice-mismatch", "ice-ufrag", "ice-pwd" 和 "ice-options" 属性.

15.1. "candidate" 属性

candidate 属性仅是 media-level 属性. 它包含 candidate 的 transport address, 可用于 connectivity checks.

该属性的语法使用 RFC 5234 [RFC5234] 中定义的 Augmented BNF 来定义:

candidate-attribute   = "candidate" ":" foundation SP component-id SP
transport SP
priority SP
connection-address SP ;from RFC 4566
port ;port from RFC 4566
SP cand-type
[SP rel-addr]
[SP rel-port]
*(SP extension-att-name SP
extension-att-value)

foundation = 1*32ice-char
component-id = 1*5DIGIT
transport = "UDP" / transport-extension
transport-extension = token ; from RFC 3261
priority = 1*10DIGIT
cand-type = "typ" SP candidate-types
candidate-types = "host" / "srflx" / "prflx" / "relay" / token
rel-addr = "raddr" SP connection-address
rel-port = "rport" SP port
extension-att-name = byte-string ;from RFC 4566
extension-att-value = byte-string
ice-char = ALPHA / DIGIT / "+" / "/"

该 grammar 编码了 candidate 的主要信息: 其 IP 地址, 端口和 transport protocol, 以及其属性: foundation, component ID, priority, type 和 related transport address:

<connection-address>: 取自 RFC 4566 [RFC4566]. 它是 candidate 的 IP 地址, 允许 IPv4 地址, IPv6 地址和 fully qualified domain names (FQDNs). 解析该字段时, agent 可以通过其值中是否存在冒号来区分 IPv4 地址和 IPv6 地址: 存在冒号表示 IPv6.agent 必须忽略包含不支持或无法识别的 IP 地址版本的 candidates 的 candidate lines. 应该使用 IP 地址, 但 可以使用 FQDN 代替 IP 地址. 在这种情况下, 当收到包含 FQDN 的 a=candidate 属性的 offer 或 answer 时, 首先在 DNS 中使用 AAAA record 查询该 FQDN (假设 agent 支持 IPv6), 如果没有找到结果或 agent 仅支持 IPv4, 则使用 A record. 如果 DNS 查询返回多个 IP 地址, 则选择其中一个, 并在 ICE 处理的剩余部分中使用.

<port>: 同样取自 RFC 4566 [RFC4566]. 它是 candidate 的端口.

<transport>: 指示 candidate 的 transport protocol. 本规范仅定义 UDP. 但是, 这里提供了扩展能力, 允许未来将其他 transport protocols 与 ICE 一起使用, 例如 TCP 或 Datagram Congestion Control Protocol (DCCP) [RFC4340].

<foundation>: 由 1 到 32 个 <ice-char> 组成. 它是一个标识符, 对于类型相同, 共享相同 base, 并来自同一个 STUN server 的两个 candidates, 该标识符相同. foundation 用于在 Frozen algorithm 中优化 ICE 性能.

<component-id>: 是 1 到 256 之间的正整数, 标识该 candidate 所属媒体流中的具体 component. 它 必须从 1 开始, 并且对于某个特定 candidate 的每个 component, 必须递增 1. 对于基于 RTP 的媒体流, 实际 RTP 媒体的 candidates 必须具有 component ID 1, RTCP 的 candidates 必须具有 component ID 2. 需要多个 components 的其他类型媒体流 必须制定规范, 定义 components 到 component IDs 的映射. 关于将 ICE 扩展到新媒体流的更多讨论见第 14 节.

<priority>: 是 1 到 (2**31 - 1) 之间的正整数.

<cand-type>: 编码 candidate 的类型. 本规范分别为 host, server reflexive, peer reflexive 和 relayed candidates 定义值 "host", "srflx", "prflx" 和 "relay". candidate 类型集合未来可扩展.

<rel-addr><rel-port>: 传递与 candidate 相关的 transport addresses, 可用于诊断和其他目的. 对于 server reflexive, peer reflexive 和 relayed candidates, <rel-addr><rel-port> 必须存在. 如果 candidate 是 server reflexive 或 peer reflexive, 则 <rel-addr><rel-port> 等于该 server reflexive 或 peer reflexive candidate 的 base. 如果 candidate 是 relayed, 则 <rel-addr><rel-port> 等于向客户端提供该 relayed candidate 的 Allocate response 中的 mapped address (其用途见附录 B.3). 如果 candidate 是 host candidate, 则 <rel-addr><rel-port> 必须省略.

candidate 属性本身可以扩展. grammar 允许在属性末尾添加新的 name/value pairs. 实现 必须忽略其不理解的任何 name/value pairs.

15.2. "remote-candidates" 属性

"remote-candidates" 属性的语法使用 RFC 5234 [RFC5234] 中定义的 Augmented BNF 来定义. remote-candidates 属性仅是 media-level 属性.

remote-candidate-att = "remote-candidates" ":" remote-candidate
0*(SP remote-candidate)
remote-candidate = component-ID SP connection-address SP port

该属性包含每个 component 的 connection-address 和 port. components 的顺序无关紧要. 但是, 媒体流的每个 component 都 必须存在一个值. 对于处于 Completed 状态的媒体流, controlling agent 必须在 offer 中包含此属性, 并且在任何其他情况下 不得包含此属性.

15.3. "ice-lite" 和 "ice-mismatch" 属性

"ice-lite" 和 "ice-mismatch" 属性的语法如下, 二者都是 flags:

ice-lite               = "ice-lite"
ice-mismatch = "ice-mismatch"

"ice-lite" 仅是 session-level 属性, 指示 agent 是 lite 实现."ice-mismatch" 仅是 media-level 属性, 当它出现在 answer 中时, 指示收到的 offer 为某个媒体 component 提供的 default destination 没有对应的 candidate 属性.

15.4. "ice-ufrag" 和 "ice-pwd" 属性

"ice-ufrag" 和 "ice-pwd" 属性传递 ICE 用于 message integrity 的 username fragment 和 password. 其语法为:

ice-pwd-att           = "ice-pwd" ":" password
ice-ufrag-att = "ice-ufrag" ":" ufrag
password = 22*256ice-char
ufrag = 4*256ice-char

"ice-pwd" 和 "ice-ufrag" 属性可以出现在 session-level 或 media-level. 当二者同时存在时, media-level 的值优先. 因此, session-level 的值实际上是适用于所有媒体流的默认值, 除非被 media-level 值覆盖. 无论出现在 session-level 还是 media-level, 每个媒体流都 必须有 ice-pwd 和 ice-ufrag 属性. 如果两个媒体流具有相同的 ice-ufrag, 它们 必须具有相同的 ice-pwd.

ice-ufrag 和 ice-pwd 属性 必须在会话开始时随机选择. ice-ufrag 属性 必须至少包含 24 bits 的随机性, ice-pwd 属性 必须至少包含 128 bits 的随机性. 这意味着 ice-ufrag 属性长度至少为 4 个字符, ice-pwd 至少为 22 个字符, 因为这些属性的 grammar 允许每个字符承载 6 bits 的随机性. 当然, 这些属性 可以分别长于 4 和 22 个字符, 最多可达 256 个字符. 上限允许实现进行缓冲区大小规划. 较大的上限还允许随时间增加更多随机性.

15.5. "ice-options" 属性

"ice-options" 属性是 session-level 属性. 它包含一系列 tokens, 标识 agent 支持的 options. 其 grammar 为:

ice-options           = "ice-options" ":" ice-option-tag
0*(SP ice-option-tag)
ice-option-tag = 1*ice-char