diff --git a/easytier/src/dns/plan.md b/easytier/src/dns/plan.md index 18da96b7..43345b28 100644 --- a/easytier/src/dns/plan.md +++ b/easytier/src/dns/plan.md @@ -66,21 +66,19 @@ listeners = [ - `ZoneConfigPb`:包含所有 Zone 配置,以及一个 ID,该 ID 在读取 TOML 时生成 - `DnsConfigPb`:包含 `name`、`domain` 和需要广播的 `ZoneConfigPb` -- `DnsMessageId`: 标记 DnsClient 和它发送的 RPC 消息,避免乱序,包含:instance id, sequence number -- `DnsEphemeralConfig`: 用于 DnsServer 的短期接口,包含:id、需要注册/更新的 Zone、需要删除的 Zone ID -- `DnsPersistentConfig`: 用于 DnsServer 的长期接口,包含:id、listeners 和 addresses -- `DnsHeartbeat`: DnsClient 发送的心跳,包含:id +- `DnsHeartbeat`: DnsClient 发送的心跳,包含:id、checksum、`Option` +- `DnsSnapshot`: 所有 DnsServer 需要的配置,以及与上一次 Snapshot 之间的变化 `delta` ## DnsClient 对于每个实例,它启动时读取 TOML 配置,然后用这个配置启动一个 DnsClient ,它需要做到: -1. 启动时(配置更新时?)向 DnsServer 发送 listeners 和 addresses +1. 启动时(配置更新时?)将 listeners 和 addresses 添加进 delta 2. 使用自己的 name 和 domain 创建一个专用 zone,让 name 指向自身 IP,并监听 IP 地址变化事件(为 DNS 一致性避免使用 127.0.0.1 作为 IP,若没有 IP 则不创建这个 zone) 3. 每次获得 PeerRouteInfo 时,读取其中的 dns 字段(和一些别的身份标记字段),这是个 protobuf message (DnsConfigPb),保存了远程 Peer 的 dns 配置(不含 addresses 和 listeners),接收后它需要: 1. 用远程配置中的 name 和 domain 创建远程 peer 的专用 zone,让这个 name 指向 peer 的 ip(这些 ip 是在 PeerRouteInfo 中的) - 2. 检查 2., 3.i. 中得到的 zone、PeerRouteInfo 报告的 zone、本机 TOML 配置中的 zone 是否有变化,将所有有变化的 zone 报告给 DnsServer,如果没变化就不要上报 -4. 每隔一小段时间向 DnsServer 发送心跳 + 2. 检查 2., 3.i. 中得到的 zone、PeerRouteInfo 报告的 zone、本机 TOML 配置中的 zone 是否有变化,如果有变化,将变化的 Zone ID 添加进 delta +4. 每隔一小段时间向 DnsServer 发送心跳,如果 delta 非空,发送 delta、当前配置的全量快照、checksum(checksum + delta) ## DnsServer @@ -91,13 +89,11 @@ listeners = [ DnsServer 需要做到: -1. 提供两个 RPC 接口,以及与之对应的配置清理机制: - 1. 短期接口,该接口获得的配置更新频率较高,有效期与 DnsClient 的心跳间隔相同,比如:zone - 2. 长期接口,该接口获得的配置更新频率较低,有效期与 DnsClient 的(配置)有效期相同,比如:listeners, addresses -2. 接受心跳时检查是否有死亡的 Zone,需要清除 -3. 持续检查是否有过期(丢失心跳)的 DnsClient,需要把这些 DnsClient 提供的 listeners, addresses 和 zone 清除 (应该不需要专门清理 zone) +1. 提供一个 RPC 接口接受 DnsClient 的心跳 +2. 收到含有 delta 的心跳时,计算 checksum(local checksum + delta),如果相等用 delta 更新本地配置,如果不相等就全量替换本地配置 +3. 持续检查是否有过期(丢失心跳)的 DnsClient,需要把这些 DnsClient 提供的所有配置清除 4. 启动时自动添加 root zone,并把它的 forwarder 设置为系统 DNS -5. 使用短期接口更新 zone。不用合并同名 zone,直接用 Zone 结构体提供的 FallbackAuthority 按顺序插入 Catalog 就行,不过注意要先插入 InMemoryAuthority,这些都是 records,后插入 ForwardAuthority,这都是 forwarders +5. 使用 delta 更新 zone。不用合并同名 zone,直接用 Zone 结构体提供的 FallbackAuthority 按顺序插入 Catalog 就行,不过注意要先插入 InMemoryAuthority,这些都是 records,后插入 ForwardAuthority,这都是 forwarders 6. 更新 zone 的时候自动去掉 forwarder 中导致回环的那些,就是把 addresses 和 listeners 去掉(root zone 也需要这个逻辑) 7. 内部接口,控制 DnsServer 是否 bind 到某些 socket(也就是配置中的 listeners) 8. Listeners 绑定失败打印日志(失败一个打印一次然后就跳过),即便这时 addresses 为空也不要停机。(否则释放 socket 绑定后会有 instance 抢占 socket 试图启动 server,然后就死循环)