如何在delphi中使用indy查找dns记录

时间:2016-09-22 23:22:20

标签: dns indy

如何在Delphi中使用Indy查找DNS记录?例如,SRV条记录,SPF条记录,TEXT条记录等

我知道我们可以直接从Windows使用nslookup,但我想用Indy或任何其他Delphi组件来做这件事。

我尝试搜索Google,我发现了类似的内容:

function ReverseDNSLookup(IPAddress: String; DNSServer: String =
SDefaultDNS; Timeout: Integer = 30; Retries: Integer = 3) : string;
var
  AIdDNSResolver: TIdDNSResolver;
  RetryCount: Integer;
begin
  Result := '';
  IPAddress := ReverseIP(IPAddress);

  AIdDNSResolver := TIdDNSResolver.Create(nil);
  try
    AIdDNSResolver.QueryResult.Clear;
    AIdDNSResolver.WaitingTime := Timeout;
    AIdDNSResolver.QueryType := [qtPTR];
    AIdDNSResolver.Host := DNSServer;

    RetryCount := Retries;
    repeat
      try
        dec(RetryCount);

        AIdDNSResolver.Resolve(IPAddress);

        Break;
      except
        on e: Exception do
        begin
          if RetryCount <= 0 then
          begin
    //            if SameText(e.Message, RSCodeQueryName) then
    //              Result := FALSE
    //            else
                  raise Exception.Create(e.Message);
            Break;
          end;
        end;
      end;
    until false;

    if AIdDNSResolver.QueryResult.Count > 0 then
      Result := AIdDNSResolver.QueryResult.DomainName;
  finally
    FreeAndNil(AIdDNSResolver);
  end;
end;

但它只是查找IP地址。我想要SRVTEXT条记录,也许还有SPF条记录。

1 个答案:

答案 0 :(得分:1)

TIdDNSResolver正是您要找的。您显示的示例仅使用TIdDNSResolver支持的一小部分。您只需设置TIdDNSResolver.QueryType属性以指定要查询的记录的类型,然后循环访问TIdDNSResolver.QueryResult集合以访问各个记录。 TIdDNSResolver支持SRVTXT条记录,例如:

var
  DNS: TIdDNSResolver;
  I: Integer;
  Record: TResultRecord;
  Txt: TTextRecord;
  Srv: TSRVRecord;
begin
  DNS := TIdDNSResolver.Create(nil);
  try
    DNS.WaitingTime := Timeout;
    DNS.QueryType := [qtTXT, qtService];
    DNS.Host := 'some.dns.server';

    DNS.Resolve('some.hostname');

    for I := 0 to DNS.QueryResult.Count -1 do
    begin
      Record := DNS.QueryResult[I];
      case Record.RecType of
      begin
        qtTXT: begin
          Txt := TTextRecord(Record);
          // use Txt.Text as needed...
        end;
        qtService: begin
          Srv := TSRVRecord(Record);
          // use Srv.OriginalName, Srv.Service, Srv.Protocol, etc as needed...
        end;
      else
        // something else...
      end;
    end;
  finally
    DNS.Free;
  end;
end;

TIdDNSResolver 支持2006年RFC 4408中定义的SPF记录类型(代码99):

  

本文档定义了一个类型为SPF的新DNS RR,代码为99.此类型的格式与TXT RR [RFC1035]相同。对于任何一种类型,记录的字符内容都编码为[US-ASCII]。

     

人们认识到,当前的做法(使用TXT记录)并不是最佳的,但它是必要的,因为有许多常用的DNS服务器和解析器实现无法处理新的RR类型。双记录类型方案提供了使用为此目的保留的RR类型的更好解决方案的前向路径。

该记录类型后来于2014年被RFC 7208淘汰:

  

SPF记录必须仅作为DNS TXT(类型16)资源记录(RR)[RFC1035]发布。记录的字符内容编码为[US-ASCII]。 SPF的实验阶段支持使用替代DNS RR类型,但已停止使用。

     

2003年,当SPF首次开发时,分配新DNS RR类型的要求比现在要严格得多。此外,在DNS服务器和配置系统中未广泛部署支持轻松部署新的DNS RR类型。因此,SPF的开发人员发现使用TXT RR类型进行SPF记录更容易,更实用。

     

在对[RFC4408]的审查中,SPFbis工作组得出结论,其双RR类型转换模型存在根本缺陷,因为它不包含实施者需要服务并需要检查的常见RR类型。许多替代方案被认为可以解决这个问题,但最终工作组得出结论认为,在可预见的未来很可能大规模迁移到SPF RR类型,解决这一互操作性问题的最佳解决方案是放弃对SPF RR类型的支持。 SPF版本1.有关详细信息,请参阅[RFC6686]的附录A.

     

十年前SPF初步部署的情况是独一无二的。如果未开发的SPF更新未重用现有的SPF记录,则可以使用SPF RR类型。 SPF对结构化数据使用TXT RR类型绝不应被视为未来协议设计者的先例。有关使用新DNS RR类型时的设计注意事项的进一步讨论,请参见[RFC5507]。