9. 服务器的 DNS 发现 (DNS Discovery of a Server)
本节描述一种可选过程, STUN client 可使用 Domain Name System (DNS) procedures [RFC1035] 来发现 STUN server 的 IP 地址和端口.
usage 必须定义 client 应在何时使用该过程. 例如, usage 可以定义 server name 可在 client 中手动配置, 也可以定义 client 能够通过其他方式发现该名称, 例如通过 configuration protocol.
client 确定要解析的名称后, 会对该名称执行 A 或 AAAA record query. 该查询返回一个或多个 IP addresses. 如果 STUN usage 定义了单一 well-known port, client 应该使用该端口. 否则, client 对该名称执行 SRV query. SRV query 会得到一个 DNS names 列表, 以及它们的 priorities, weights, 和 ports. 随后, client 对每个 DNS name 执行 A 或 AAAA query, 以将其转换为 IP addresses.
client 获得 IP addresses 和 ports 列表后, 按 RFC 3484 [RFC3484] 中描述的过程对列表排序. 随后, client 使用排序后的 IP addresses 和 ports 列表开始联系 servers, 从最优先的地址开始. client 沿列表继续尝试, 直到找到有响应的 server 或耗尽列表.
当使用 SRV records 获取 server address 和 port 时, client 不应该使用 DNS name 与 client 查询名称不匹配的 server. 例如, 如果 client 查询 _stun._udp.example.com, 而 SRV response 包含 DNS name server1.otherdomain.com, client 不应该向该 server 发送. 这是为了防止控制某个域 DNS 的攻击者将 STUN requests 重定向到另一个域中的 server.
client 可以在 DNS record(s) 的 Time to Live (TTL) 指定的时长内缓存 DNS lookup 的结果. 如果 client 未能在合理时间内 (由 usage 定义) 从通过 DNS SRV record 获得的 server 收到 response, client 应该重新查询 DNS. client 应该遵守 DNS TTL values.
如果 STUN usage 为某个特定 transport 定义端口, 且该 transport 使用 SRV, 则该 usage 必须为该 SRV service 定义一个 symbolic name. symbolic name 由前置下划线的 service name, 一个句点, 前置下划线的 protocol name, 一个句点, 以及 domain name 组成. 例如, 如果 usage 为 STUN 定义基于 UDP 的 transport 且端口为 3478, domain name 为 example.com, 则 symbolic name 将是 _stun._udp.example.com.