X-Git-Url: http://git.megabrutal.com/?p=mgsmtp.git;a=blobdiff_plain;f=Network.pas;fp=Network.pas;h=d5b458da2d5919570e2805ae5416b63eac408752;hp=10a95f991d3898060489ecfdc31d252c242b81d7;hb=443339e2756df295317b7136b3262e368fdb9bfa;hpb=29de169741b074ce9158bce94f0b8db5088cdcf2 diff --git a/Network.pas b/Network.pas index 10a95f9..d5b458d 100644 --- a/Network.pas +++ b/Network.pas @@ -61,7 +61,7 @@ type FSocket: socket; FHostIP: TIPNamePair; FSockTimeOut: DWord; - sAddr: TSockAddr; + SockAddr: TSockAddr; public function Connect(const HostName: string; Port: word): boolean; procedure Disconnect; @@ -106,7 +106,7 @@ type FListenAddress: string; FListenPort: word; FListenSocket: socket; - sAddr: TSockAddr; + SockAddr: TSockAddr; protected procedure HandleClient(Connection: TTCPConnection); virtual; abstract; procedure Execute; override; @@ -133,7 +133,7 @@ end; constructor TTCPConnection.Create(const HostName: string; Port: word); { Connect to the given port on the given hostname. } begin - inherited Create; + Create; Connect(HostName, Port); end; @@ -142,7 +142,7 @@ constructor TTCPConnection.Create(Socket: socket; const Addr: TSockAddr); begin inherited Create; FSocket:= Socket; - sAddr:= Addr; + SockAddr:= Addr; FHostIP:= TIPNamePair.Create('', NetAddrToStr(Addr.sin_addr)); FConnected:= true; end; @@ -170,32 +170,35 @@ begin FListenPort:= Port; FFeatureRequest:= FeatureRequest; FreeOnTerminate:= false; + FillChar(SockAddr, SizeOf(SockAddr), 0); inherited Create(true); end; function TTCPConnection.Connect(const HostName: string; Port: word): boolean; { Resolves the given hostname, and tries to connect it on the given port. } +var GAIResult: TGAIResult; begin FSocket:= fpSocket(af_inet, sock_stream, 0); if (FSocket <> -1) then begin - with sAddr do begin - sin_family:= af_inet; - sin_port:= htons(Port); - { Resolve hostname to IP address. } - sin_addr:= ResolveHost(HostName); + GAIResult:= ResolveHost(HostName); + if GAIResult.GAIError = 0 then begin + SockAddr:= GAIResult.AddrInfo^.ai_addr^; + SockAddr.sin_port:= htons(Port); + + if SockAddr.sin_addr.s_addr <> 0 then + { Try to initiate connection. } + FConnected:= fpConnect(FSocket, @SockAddr, SizeOf(SockAddr)) <> -1; + + if FConnected then begin + FHostIP:= TIPNamePair.Create(HostName, NetAddrToStr(SockAddr.sin_addr)); + SetSockTimeOut(FSockTimeOut); + end + else + CloseSocket(FSocket); + + FreeHost(GAIResult); end; - - if sAddr.sin_addr.s_addr <> 0 then - { Try to initiate connection. } - FConnected:= fpConnect(FSocket, @sAddr, SizeOf(sAddr)) <> -1; - - if FConnected then begin - FHostIP:= TIPNamePair.Create(HostName, NetAddrToStr(sAddr.sin_addr)); - SetSockTimeOut(FSockTimeOut); - end - else - CloseSocket(FSocket); end; Result:= FConnected; end; @@ -214,15 +217,25 @@ procedure TTCPConnection.ReverseDNSLookup; var NHostIP: TIPNamePair; begin if FConnected then begin - NHostIP:= TIPNamePair.Create(ResolveIP(sAddr.sin_addr), FHostIP.IP); + NHostIP:= TIPNamePair.Create(ResolveIP(@SockAddr), FHostIP.IP); FHostIP.Free; FHostIP:= NHostIP; end; end; function TTCPConnection.VerifyFCrDNS: boolean; +var GAIResult: TGAIResult; ai: PAddrInfo; begin - Result:= NetAddrToStr(ResolveHost(HostIP.Name)) = HostIP.IP; + Result:= false; + GAIResult:= ResolveHost(HostIP.Name); + if GAIResult.GAIError = 0 then begin + ai:= GAIResult.AddrInfo; + { One of the addresses must match. } + while (ai <> nil) and not Result do begin + Result:= NetAddrToStr(ai^.ai_addr^.sin_addr) = HostIP.IP; + ai:= ai^.ai_next; + end; + end; end; procedure TTCPConnection.SetSockTimeOut(TimeOut: DWord); @@ -288,24 +301,29 @@ end; function TTCPListener.StartListen: boolean; +var GAIResult: TGAIResult; begin FListenSocket:= fpSocket(af_inet, sock_stream, 0); if FListenSocket <> -1 then begin - with sAddr do begin - sin_family:= af_inet; - sin_port:= htons(FListenPort); - sin_addr:= ResolveHost(FListenAddress); - end; - if fpBind(FListenSocket, @sAddr, sizeof(sAddr)) <> -1 then begin - { It seems the maximum connection value isn't enforced by the - Free Pascal library, so this 512 is a constant, dummy value. } - if fpListen(FListenSocket, 512) <> -1 then begin - Result:= true; - Start; + GAIResult:= ResolveHost(FListenAddress); + if GAIResult.GAIError = 0 then begin + SockAddr:= GAIResult.AddrInfo^.ai_addr^; + SockAddr.sin_port:= htons(FListenPort); + + if fpBind(FListenSocket, @SockAddr, SizeOf(SockAddr)) <> -1 then begin + { It seems the maximum connection value isn't enforced by the + Free Pascal library, so this 512 is a constant, dummy value. } + if fpListen(FListenSocket, 512) <> -1 then begin + Result:= true; + Start; + end + else Result:= false; end else Result:= false; + + FreeHost(GAIResult); end - else Result:= false; + else Result:= false; end else Result:= false; end; @@ -323,8 +341,8 @@ begin { Now, accept connections. } AcceptFailCount:= 0; while not Terminated do begin - Len:= SizeOf(sAddr); - ClientSocket:= fpAccept(FListenSocket, @sAddr, @Len); + Len:= SizeOf(SockAddr); + ClientSocket:= fpAccept(FListenSocket, @SockAddr, @Len); if ClientSocket <> -1 then begin AcceptFailCount:= 0; @@ -332,9 +350,9 @@ begin connection. } case FFeatureRequest of NET_TCP_BASIC: - TCPConnection:= TTCPConnection.Create(ClientSocket, sAddr); + TCPConnection:= TTCPConnection.Create(ClientSocket, SockAddr); NET_TCP_RFCSUPPORT: - TCPConnection:= TTCPRFCConnection.Create(ClientSocket, sAddr); + TCPConnection:= TTCPRFCConnection.Create(ClientSocket, SockAddr); end; { Then start a new thread with the connection handler. }