我正在尝试使用硬编码的 AName、在 Delphi 10.1 update 2 上使用 JNI 的一些代码以及 TIdDNSResolver 来执行以下操作:
1) 从设备接口(interface)配置中获取设备 DNS 服务器(有效!)
2) 在 DNS 服务器上进行查找以检索该服务器的域名(失败!)
3) 将 DNS 域附加到硬编码的 AName(尚未存在)
4) 使用 FQDN AName 查找服务器 IP 地址(尚不存在)
到目前为止,在 Delphi 中使用 JNI 函数我可以获得 DNS 服务器的 IP 地址。当我尝试查找域名时,我失败了。这是我的代码:
dns.Host := s;
dns.WaitingTime := 2048;
dns.QueryType := [qtDName];
dns.Resolve('hard_coded_server_name');
for i := 0 to Pred(dns.QueryResult.Count) do
begin
r := dns.QueryResult[i];
case r.RecType of
qtDName: begin
txt := TTextRecord(r);
Memo1.Lines.AddStrings(txt.Text);
end;
end;
end;
我确定我错误地使用了 TResultRecord,但找不到有关如何正确执行此操作的文档。有人(雷米?)请解释一下如何做到这一点吗?
谢谢。
最佳答案
TIdDNSResolver
不将 TTextRecord
用于 qtDName
响应记录。 TTextRecord
仅用于 qtTXT
和 qtHINFO
记录(THINFORecord
派生自 TTextRecord
) .
查看TIdDNSResolver
的源代码,我发现DNAME
实际上是一个未处理响应类型(我不知道为什么),因此,TIdDNSResolver
最终将按原样使用 TResultRecord
类来处理 DNAME
记录。因此,DNAME
记录数据根本不会被解析,并且 r.RecType
不会像您期望的那样 qtDName
(从技术上讲) ,它实际上是未分配的,默认为 0,恰好是 qtA)。但是,原始答案数据至少位于 r.RData
中。
请注意,DNAME
查找可能会产生 CNAME
响应记录(以及其他记录)。 CNAME
记录在 QueryResult
中表示为 TNAMERecord
对象,其中 r.RecType
将为 qtName
.
我有checked in a fix (SVN 修订版 5377):
- 添加了新的
TDNAMERecord
类,用于解析DNAME
数据。 - 确保为
TResultRecord.RecType
属性分配已知记录类型的值(即使它们未被解析)。 - 为无法在
TResultRecord.RecType
属性中表达的未知记录类型添加了新的TResultRecord.TypeCode
属性。
例如:
dns.Host := s;
dns.WaitingTime := 2048;
dns.QueryType := [qtDName];
dns.Resolve('hard_coded_server_name');
for i := 0 to Pred(dns.QueryResult.Count) do
begin
r := dns.QueryResult[i];
case r.RecType of
qtName: begin
Memo1.Lines.Add('CNAME: ' + TNAMERecord(r).HostName);
end;
qtDName: begin
Memo1.Lines.Add('DNAME: ' + TDNAMERecord(r).HostName);
end;
// other types as needed ...
else
Memo1.Lines.Add(IntToStr(r.TypeCode) + ': ' + ToHex(r.RData));
end;
end;
关于Delphi/Indy 通过主机名查找解析 DNS 域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40645064/