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

时间:2016-11-17 01:03:06

标签: delphi dns indy10

我正在尝试使用硬编码的AName,在Delphi 10.1 update 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,但找不到有关如何正确执行此操作的文档。有人(雷米?)请解释一下如何做到这一点?

感谢。

1 个答案:

答案 0 :(得分:2)

TIdDNSResolver不会将TTextRecord用于qtDName响应记录。 TTextRecord仅用于qtTXTqtHINFO条记录(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 rev 5377):

  • 添加了一个新的TDNAMERecord类来解析DNAME数据。
  • 确保为TResultRecord.RecType属性分配了已知记录类型的值(即使它们未被解析)。
  • 为未知记录类型添加了新的TResultRecord.TypeCode属性,无法在TResultRecord.RecType属性中表示。

例如:

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;