X-Git-Url: http://git.megabrutal.com/?p=mgsmtp.git;a=blobdiff_plain;f=DNSResolve.pas;h=2ca6439012e325b974d8c3df13b71bd19d6298fa;hp=6e6acff0fdf1865903370d1df911fe0461f2fb53;hb=443339e2756df295317b7136b3262e368fdb9bfa;hpb=29de169741b074ce9158bce94f0b8db5088cdcf2 diff --git a/DNSResolve.pas b/DNSResolve.pas index 6e6acff..2ca6439 100644 --- a/DNSResolve.pas +++ b/DNSResolve.pas @@ -1,5 +1,5 @@ { - Copyright (C) 2010 MegaBrutal + Copyright (C) 2010-2018 MegaBrutal This unit is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -21,36 +21,75 @@ unit DNSResolve; interface -uses WinSock, Sockets; +uses WinSock, Sockets, ctypes; +type - function ResolveHost(HostName: ansistring): in_addr; - function ResolveIP(IP: in_addr): ansistring; + PAddrInfo = ^TAddrInfo; + TAddrInfo = record + ai_flags: cint; + ai_family: cint; + ai_socktype: cint; + ai_protocol: cint; + ai_addrlen: size_t; + ai_canonname: PChar; + ai_addr: PSockAddr; + ai_next: PAddrInfo; + end; + + TGAIResult = record + GAIError: integer; + AddrInfo: PAddrInfo; + end; + + + function getaddrinfo(NodeName, ServiceName: PChar; Hints: PAddrInfo; var AddrInfo: PAddrInfo): cint; stdcall; + external 'ws2_32.dll' name 'getaddrinfo'; + + procedure freeaddrinfo(AddrInfo: PAddrInfo); stdcall; + external 'ws2_32.dll' name 'freeaddrinfo'; + + function getnameinfo(SockAddr: PSockAddr; SockAddrLength: cuint32; NodeBuffer: PChar; NodeBufferSize: cuint32; + ServiceBuffer: PChar; ServiceBufferSize: cuint32; Flags: cint): cint; stdcall; + external 'ws2_32.dll' name 'getnameinfo'; + + function ResolveHost(HostName: ansistring): TGAIResult; + procedure FreeHost(var GAIResult: TGAIResult); + function ResolveIP(SockAddr: PSockAddr): ansistring; implementation -function ResolveHost(HostName: ansistring): in_addr; -var - HostEnt: PHostEnt; +function ResolveHost(HostName: ansistring): TGAIResult; +var hint: TAddrInfo; +begin + FillByte(hint, SizeOf(hint), 0); + with hint do begin + ai_family:= AF_INET; + ai_socktype:= SOCK_STREAM; + ai_protocol:= IPPROTO_TCP; + end; + ResolveHost.GAIError:= getaddrinfo(PChar(HostName), nil, @hint, ResolveHost.AddrInfo); +end; + +procedure FreeHost(var GAIResult: TGAIResult); begin - HostEnt:= gethostbyname(PChar(HostName)); - if HostEnt <> nil then - ResolveHost.s_addr:= PLongWord(HostEnt^.h_addr_list[0])^ - else - ResolveHost.s_addr:= 0; + if GAIResult.AddrInfo <> nil then begin + freeaddrinfo(GAIResult.AddrInfo); + GAIResult.AddrInfo:= nil; + end; end; -function ResolveIP(IP: in_addr): ansistring; +function ResolveIP(SockAddr: PSockAddr): ansistring; var - HostEnt: PHostEnt; + r: integer; + NodeBuffer: array[0..255] of char; begin - HostEnt:= gethostbyaddr(@IP, 4, AF_INET); - if HostEnt <> nil then - ResolveIP:= HostEnt^.h_name - else - ResolveIP:= NetAddrToStr(IP); + NodeBuffer[0]:= #0; + r:= getnameinfo(SockAddr, SizeOf(TSockAddr), @NodeBuffer, SizeOf(NodeBuffer), nil, 0, 0); + if r = 0 then ResolveIP:= PChar(@NodeBuffer) + else ResolveIP:= NetAddrToStr(SockAddr^.sin_addr); end;