SRV 查找请求不返回 IP 地址

问题描述

我正在编写一个 XMPP 客户端。 RFC 表示我需要使用 SRV 查询连接到服务器(如 this one)。

当我使用 trust_dns_resolver 板条箱这样做时,查询似乎是空的。这是正常行为吗?

use trust_dns_resolver::Resolver;
use trust_dns_resolver::Name;
use std::str::FromStr;

fn main() {
    let resolver = Resolver::from_system_conf().unwrap();
    match resolver.srv_lookup(Name::from_str("_xmpp-client._tcp.xmpp.jp").unwrap()) {
        Ok(response) => {
            for ip in response.ip_iter() {
                println!("{}",ip.to_string());
            }
        },Err(e) => println!("{}",e),}
}

dig SRV _xmpp-client._tcp.xmpp.jp 命令行返回以下内容

; <<>> DiG 9.16.18 <<>> SRV _xmpp-client._tcp.xmpp.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY,status: NOERROR,id: 16710
;; flags: qr rd ra; QUERY: 1,ANSWER: 3,AUTHORITY: 0,ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; ednS: version: 0,flags:; udp: 1232
; COOKIE: 2605a5d828b394e22ffbec3e61010461a668fc990570d859 (good)
;; QUESTION SECTION:
;_xmpp-client._tcp.xmpp.jp. IN  SRV

;; ANSWER SECTION:
_xmpp-client._tcp.xmpp.jp. 23   IN  SRV 20 10 5222 sapporo.xmpp.jp.
_xmpp-client._tcp.xmpp.jp. 23   IN  SRV 30 10 5222 gw.lb.xmpp.jp.
_xmpp-client._tcp.xmpp.jp. 23   IN  SRV 10 10 5222 tokyo.xmpp.jp.

;; Query time: 13 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: mer. juil. 28 09:16:49 CEST 2021
;; MSG SIZE  rcvd: 183

我会有三个 IP 地址,对吗?

我想我误解了一些东西,但我不知道是什么。

解决方法

  • 如果 SRV 查找没有返回 IP 地址,也没关系。在我的例子中,查询只返回几个由域名和端口号组成的元组。获取它们后,我必须解析每个以获取其 IP 地址及其端口号。

  • trust_dns_proto 板条箱是处理 SRV 查找所必需的。所以我将它添加到 Cargo.toml 文件中,编译器停止哭泣......

然后我可以写下面的代码来提取端口号和域名:

use trust_dns_resolver::Resolver;
use trust_dns_resolver::Name;
use std::str::FromStr;
[...]
    let resolver = Resolver::from_system_conf().unwrap();
    match resolver.srv_lookup(Name::from_str("_xmpp-client._tcp.xmpp.jp.").unwrap()) { 
        Ok(response) => {
            for srv in response.iter() {
                println!("Port number:\t{}",srv.port());
                println!("Domain name:\t{}\n",srv.target().to_utf8());
                // have to resolve the domain name here
            }
            println!("{}",response.query().name());
        },Err(e) => println!("{}",e),}

感谢 Zeppi。他的解决方案远非完美,但它使我走上了寻找自己的正确轨道。

,

好的是正确的。您有 3 个 SRV 记录

一个 SRV 记录是相关的端口和域目标。

response.iter() 返回一个 trust_dns_proto::rr::rdata::srv。

使用 ip.port() 提取端口

和目标

let mut bytes = Vec::new();
let mut encoder: BinEncoder = BinEncoder::new(&mut bytes);
let is_canonical_names = encoder.is_canonical_names();

ip.target().emit_with_lowercase(encoder,is_canonical_names)?

接下来,xou 必须解析 target 以获得 ip Resolver::...