Delphi / Indy 通过主机名查找解析 DNS 域

Delphi / Indy resolve DNS domain by host name lookup

我正在尝试使用硬编码的 AName,一些在 Delphi 10.1 更新 2 上使用 JNI 的代码,以及 TIdDNSResolver 来执行以下操作:

1) 从设备接口配置中获取设备 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 仅用于 qtTXTqtHINFO 记录(THINFORecord 派生自 TTextRecord)。

查看 TIdDNSResolver 的源代码,我发现 DNAME 实际上是一个 unhandled 响应类型(我不知道为什么),所以TIdDNSResolver 将最终使用 TResultRecord class 作为 DNAME 记录。因此,DNAME 记录数据根本不会被解析,r.RecType 也不会像您期望的那样 qtDName(从技术上讲,它实际上是未分配的,默认为 0,恰好是 qtA)。但是,原始答案数据至少会在 r.RData 中。

请注意,DNAME 查找可能会产生 CNAME 响应记录(以及其他)。 CNAME 记录在 QueryResult 中表示为 TNAMERecord 个对象,其中 r.RecType 将是 qtName.

我有 checked in a fix (SVN rev 5377):

  • 添加了一个新的 TDNAMERecord class 用于解析 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;