getaddrinfoW为任何主机名返回11001,但如果IP输入

时间:2017-10-10 03:08:40

标签: delphi dns ping getaddrinfo nslookup

我使用Delphi XE5而不是Indy,一个客户正在使用

套接字错误#11001
找不到主人。

我机器上的同一个电话正常工作

用于SMTP和FTP
如果我输入IP或主机名

,Ping和nslookup都可以在该计算机上运行

我创建了一个复制问题的单元

unit Unit3;

interface
uses winsock2, TypInfo;

const
  AI_PASSIVE                = $00000001;   // Socket address will be used in bind() call
  AI_CANONNAME              = $00000002;   // Return canonical name in first ai_canonname
  AI_NUMERICHOST            = $00000004;   // Nodename must be a numeric address string
  AI_NUMERICSERV            = $00000008;  // Servicename must be a numeric port number
  AI_ALL                    = $00000100;  // Query both IP6 and IP4 with AI_V4MAPPED
  AI_ADDRCONFIG             = $00000400;  // Resolution only if global address configured
  AI_V4MAPPED               = $00000800;  // On v6 failure, query v4 and convert to V4MAPPED format (Vista or later)
  AI_NON_AUTHORITATIVE      = $00004000;  // LUP_NON_AUTHORITATIVE  (Vista or later)
  AI_SECURE                 = $00008000;  // LUP_SECURE  (Vista or later and applies only to NS_EMAIL namespace.)
  AI_RETURN_PREFERRED_NAMES = $00010000;  // LUP_RETURN_PREFERRED_NAMES (Vista or later and applies only to NS_EMAIL namespace.)
  AI_FQDN                   = $00020000;  // Return the FQDN in ai_canonname  (Windows 7 or later)
  AI_FILESERVER             = $00040000;  // Resolving fileserver name resolution (Windows 7 or later)
  AI_DISABLE_IDN_ENCODING   = $00080000;  // Disable Internationalized Domain Names handling

type
  TAIFlag = (idf_Passive, idf_CanonName, idf_NumericHost, idf_NumericServ, idf_All, idf_AddrConfig,
    idf_V4Mapped, idf_NonAuthoritative, idf_Secure, idf_ReturnPreferredNames, idf_FQDN, idf_FileServer,
    idf_DisableIDNEncoding);
  TAIFlags = set Of TAIFlag;

  TAFFamily = ( aff_UNSPEC, aff_INET, aff_NETBIOS, aff_INET6, aff_IRDA, aff_BTH);

  TAIPROTOCAL = ( aip_IP, aip_TCP, aip_UDP, aip_RM_Or_PGM );

  function GetTAIFlagsValue(aTAIFlags : TAIFlags) : integer;
  function GetTAFFamilyValue(aTAFFamily : TAFFamily) : integer;
  function GetTAIPROTOCALValue(aTAIPROTOCAL : TAIPROTOCAL) : integer;

type
  ULONG_PTR = NativeUInt;
  SIZE_T = ULONG_PTR;

  TIN6_ADDR = record
    s6_bytes: array[0..15] of u_char;
    {
    case Integer of
      0: (s6_bytes: array[0..15] of u_char);
      1: (s6_words: array[0..7] of u_short);   }
  end;

  sockaddr_in6 = record
    sin6_family: Smallint;
    sin6_port: u_short;
    sin6_flowinfo: u_long;
    sin6_addr : TIN6_ADDR;
    sin6_scope_id: u_long;
  end;
  TSockAddrIn6 = sockaddr_in6;
  PSockAddrIn6 = ^sockaddr_in6;

  PAddrInfoW = ^ADDRINFOW;
  ADDRINFOW = record
    ai_flags        : Integer;      // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
    ai_family       : Integer;      // PF_xxx
    ai_socktype     : Integer;      // SOCK_xxx
    ai_protocol     : Integer;      // 0 or IPPROTO_xxx for IPv4 and IPv6
    ai_addrlen      : size_t;        // Length of ai_addr
    ai_canonname    : PWideChar;    // Canonical name for nodename
    ai_addr         : PSockAddrIn;    // Binary address
    ai_next         : PAddrInfoW;   // Next structure in linked list
  end;
  TAddrInfoW = ADDRINFOW;
  LPADDRINFOW = PAddrInfoW;



  function GetAddrInfoW(const nodename: PWideChar; const servname : PWideChar; const hints: PAddrInfoW; var res: PaddrinfoW): Integer; stdcall; external 'ws2_32.dll';// name 'getaddrinfo';
  procedure FreeAddrInfoW(ai: PAddrInfoW); stdcall; external 'ws2_32.dll';// name 'freeaddrinfo';

function DoIT(aHostName : String; aTAIFlags : TAIFlags = []; aTAFFamily : TAFFamily = aff_UNSPEC;aTAIPROTOCAL : TAIPROTOCAL = aip_IP) : String;

implementation
uses sysutils, windows;

function GetTAIPROTOCALValue(aTAIPROTOCAL : TAIPROTOCAL) : integer;
begin
  result := IPPROTO_IP;
  case aTAIPROTOCAL of
    aip_IP        : Result := IPPROTO_IP;
    aip_TCP       : Result := IPPROTO_TCP;
    aip_UDP       : Result := IPPROTO_UDP;
    aip_RM_Or_PGM : Result := IPPROTO_PGM;
    else
      raise Exception.Create('GetTAIPROTOCALValue unknown value ('+ inttostr( ord( aTAIPROTOCAL ) ) +')');
  end;
end;

function GetTAFFamilyValue(aTAFFamily : TAFFamily) : integer;
begin
  result := 0;
  case aTAFFamily of
    aff_UNSPEC : Result := AF_UNSPEC;
    aff_INET   : Result := AF_INET;
    aff_NETBIOS: Result := AF_NETBIOS;
    aff_INET6  : Result := AF_INET6;
    aff_IRDA   : Result := AF_IRDA;
    aff_BTH    : Result := AF_BTH;
  else
    raise Exception.Create('Unknown Value('+ inttostr( Ord( aTAFFamily )) +') fn[ GetTAFFamilyValue] ');
  end;
end;

function GetTAIFlagsValue(aTAIFlags : TAIFlags) : integer;
begin
  result := 0;
  if idf_Passive in aTAIFlags then begin
    result := result + AI_PASSIVE;
  end;
  if idf_CanonName in aTAIFlags then begin
    result := result + AI_CANONNAME;
  end;
  if idf_NumericHost in aTAIFlags then begin
    result := result + AI_NUMERICHOST;
  end;
  if idf_NumericServ in aTAIFlags then begin
    result := result + AI_NUMERICSERV;
  end;
  if idf_All in aTAIFlags then begin
    result := result + AI_ALL;
  end;
  if idf_AddrConfig in aTAIFlags then begin
    result := result + AI_ADDRCONFIG;
  end;
  if idf_V4Mapped in aTAIFlags then begin
    result := result + AI_V4MAPPED;
  end;
  if idf_NonAuthoritative in aTAIFlags then begin
    result := result + AI_NON_AUTHORITATIVE;
  end;
  if idf_Secure in aTAIFlags then begin
    result := result + AI_SECURE;
  end;
  if idf_ReturnPreferredNames in aTAIFlags then begin
    result := result + AI_RETURN_PREFERRED_NAMES;
  end;
  if idf_FQDN in aTAIFlags then begin
    result := result + AI_FQDN;
  end;
  if idf_FileServer in aTAIFlags then begin
    result := result + AI_FILESERVER;
  end;
  if idf_DisableIDNEncoding in aTAIFlags then begin
    result := result + AI_DISABLE_IDN_ENCODING;
  end;
end;

function DoIT(aHostName : String; aTAIFlags : TAIFlags = []; aTAFFamily : TAFFamily = aff_UNSPEC;
  aTAIPROTOCAL : TAIPROTOCAL = aip_IP) : String;

var
  myWsaData : WSAData;
  Sock: TSocket;
  myResult : Integer;
  myReturnVal : Integer;
  myDWRetVal : Word;
  i : integer;
  MyAddrInfo_Result: PAddrInfoW;
  MyAddrInfo_Hint  : TAddrInfoW;
  DestIP: Integer;
  sTmp : String;
begin
  result := 'Starting Xunit3.DoIt';
  try

    myResult := WSAStartup($0202, myWsaData);
    result := result + sLineBreak + 'WSAStartup result = ' + inttostr(myResult);
    if myResult <> 0 then begin
      result := result + sLineBreak + 'Exiting due to WSAStartup error';
      exit;
    end;
    try
      result := result + sLineBreak + 'Setting up vars';
      MyAddrInfo_Result := nil;
      ZeroMemory(@MyAddrInfo_Hint, SizeOf(MyAddrInfo_Hint));

      MyAddrInfo_Hint.ai_flags    := GetTAIFlagsValue( aTAIFlags ) ;
      MyAddrInfo_Hint.ai_family   := GetTAFFamilyValue( aTAFFamily );
      MyAddrInfo_Hint.ai_socktype := SOCK_STREAM;
      MyAddrInfo_Hint.ai_protocol := GetTAIPROTOCALValue(aTAIPROTOCAL);

      result := result + sLineBreak + 'ai_family = ' + GetEnumName(Typeinfo(TAFFamily), ord(aTAFFamily));
      result := result + sLineBreak + 'ai_protocol = ' + GetEnumName(Typeinfo(TAIPROTOCAL), ord(aTAIPROTOCAL));

      result := result + sLineBreak + 'Calling getaddrinfo "'+ PWideChar(aHostName) +'"';
      myResult := getaddrinfoW (
        PWideChar(aHostName)
       , nil
       , @MyAddrInfo_Hint
       , MyAddrInfo_Result);
      result := result + sLineBreak + 'getaddrinfo result = ' + inttostr(myResult);
      if myResult = 0 then begin
        if MyAddrInfo_Result^.ai_canonname > '' then
          result := result + sLineBreak + 'getaddrinfo canonname = "' + MyAddrInfo_Result^.ai_canonname + '"';

        result := result + sLineBreak + 'sin_family = "' + inttostr( MyAddrInfo_Result.ai_addr.sin_family) + '"';
        if MyAddrInfo_Result.ai_addr.sin_family = AF_INET6 then begin
          sTmp := inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[0])) +    //Yes this is bad but im just dumping out something
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[1])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[2])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[3])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[4])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[5])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[6])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[7])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[8])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[9])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[10])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[11])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[12])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[13])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[14])) +
                  inttostr(ord(PSockAddrIn6(MyAddrInfo_Result).sin6_addr.s6_bytes[15]));
          result := result + sLineBreak + 'IP6-Bytes = "' + sTmp + '"';

          result := result + sLineBreak + 'IP = "' + ':( not yet coded' + '"';
        end else begin
          result := result + sLineBreak + 'IP = "' + StrPas(inet_ntoa(MyAddrInfo_Result.ai_addr.sin_addr)) + '"';
        end;

      end;
    finally
      result := result + sLineBreak + 'running WSACleanup';
      WSACleanup();
    end;
  Except
    on E:Exception do begin
      e.Message := 'fn[unit3.DoIT;]' + sLineBreak + e.Message;
      result := result + 'ERROR: ' + e.Message;
    end;
  end;

end;

end.

如果我在我的机器上调用该功能

ShowMessage( DoIT( 'google.com' ) )

它有效,我得到172.217.25.174

在他们的机器上我得到了错误 但如果我像

那样运行它
ShowMessage( DoIT( '172.217.25.174' ) )

它可以工作,在他们的机器上运行这些调用

C:\>ping google.com

Pinging google.com [216.58.199.78] with 32 bytes of data:
Reply from 216.58.199.78: bytes=32 time=23ms TTL=56
Reply from 216.58.199.78: bytes=32 time=21ms TTL=56
Reply from 216.58.199.78: bytes=32 time=21ms TTL=56
Reply from 216.58.199.78: bytes=32 time=21ms TTL=56

Ping statistics for 216.58.199.78:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 21ms, Maximum = 23ms, Average = 21ms

nslookup确实有一些奇怪的事情“非权威性答案”和“服务器:未知”但我对DNS知之甚少并不知道这是否是一个问题

C:\>nslookup google.com
Server:  UnKnown
Address:  192.168.1.2

Non-authoritative answer:
Name:    google.com
Addresses:  2404:6800:4006:804::200e
            216.58.196.142

这是ipconfig

C:\>ipconfig -all

Windows IP Configuration

   Host Name . . . . . . . . . . . . : xxx-xx
   Primary Dns Suffix  . . . . . . . : xxxxxx.local
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : xxxxxx.local

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Microsoft Hyper-V Network Adapter
   Physical Address. . . . . . . . . : 00-15-5D-00-46-01
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::a490:bb74:caa4:b1b1%3(Preferred)
   IPv4 Address. . . . . . . . . . . : 192.168.1.3(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.1.1
   DHCPv6 IAID . . . . . . . . . . . : 50337117
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-21-4B-66-60-00-15-5D-00-46-01
   DNS Servers . . . . . . . . . . . : 192.168.1.2
   NetBIOS over Tcpip. . . . . . . . : Enabled

Tunnel adapter isatap.{32C9B8E2-B420-411A-A88B-1AB178A8EF0B}:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Microsoft ISATAP Adapter #3
   Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes

我可以做任何事情让代码在上面工作吗? 如果这是一个DNS问题,我告诉他们的硬件人员看什么 可以通过解析IP地址阻止GetAddrInfoW调用吗?

更新   在同一网络上的另一台机器上运行DOIT()调用工作正常

0 个答案:

没有答案