X-Git-Url: http://git.megabrutal.com/?p=mgsmtp.git;a=blobdiff_plain;f=Network.pas;h=d19aeeacbda844998fea48c0701f40c7cf56afeb;hp=cd13cb2ae4740ec5368c70686d381395fbd14660;hb=HEAD;hpb=a48c41148c3655c6c0de176060d739d3438e25f7 diff --git a/Network.pas b/Network.pas index cd13cb2..d19aeea 100644 --- a/Network.pas +++ b/Network.pas @@ -54,15 +54,16 @@ type TTCPConnection = class constructor Create; overload; constructor Create(const HostName: string; Port: word); overload; - constructor Create(Socket: socket; const Addr: TSockAddr); overload; + constructor Create(Socket: socket); overload; destructor Destroy; override; private FConnected: boolean; FSocket: socket; FHostIP: TIPNamePair; FSockTimeOut: DWord; - SockAddr: TSockAddr; + SrcSockAddr, DstSockAddr: TSockAddr; public + function SetBindAddress(const HostName: string): boolean; function Connect(const HostName: string; Port: word): boolean; procedure Disconnect; procedure ReverseDNSLookup; @@ -129,6 +130,8 @@ begin FConnected:= false; FSocket:= -1; FSockTimeOut:= DEF_SOCK_TIMEOUT; + FillChar(SrcSockAddr, SizeOf(SrcSockAddr), 0); + FillChar(DstSockAddr, SizeOf(DstSockAddr), 0); end; constructor TTCPConnection.Create(const HostName: string; Port: word); @@ -138,13 +141,17 @@ begin Connect(HostName, Port); end; -constructor TTCPConnection.Create(Socket: socket; const Addr: TSockAddr); +constructor TTCPConnection.Create(Socket: socket); { Use an already connected socket. } +var ssocklen, dsocklen: TSockLen; begin inherited Create; FSocket:= Socket; - SockAddr:= Addr; - FHostIP:= TIPNamePair.Create('', NetAddrToStr(Addr.sin_addr)); + ssocklen:= SizeOf(SrcSockAddr); + dsocklen:= SizeOf(DstSockAddr); + fpgetsockname(FSocket, @SrcSockAddr, @ssocklen); + fpgetpeername(FSocket, @DstSockAddr, @dsocklen); + FHostIP:= TIPNamePair.Create('', NetAddrToStr(DstSockAddr.sin_addr)); FConnected:= true; end; @@ -176,29 +183,44 @@ begin end; +function TTCPConnection.SetBindAddress(const HostName: string): boolean; +var GAIResult: TGAIResult; +begin + GAIResult:= ResolveHost(HostName); + if GAIResult.GAIError = 0 then begin + SrcSockAddr:= GAIResult.AddrInfo^.ai_addr^; + FreeHost(GAIResult); + Result:= true; + end + else + Result:= false; +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 - 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); + if (SrcSockAddr.sin_addr.s_addr = 0) or (fpBind(FSocket, @SrcSockAddr, SizeOf(SrcSockAddr)) = 0) then begin + GAIResult:= ResolveHost(HostName); + if GAIResult.GAIError = 0 then begin + DstSockAddr:= GAIResult.AddrInfo^.ai_addr^; + DstSockAddr.sin_port:= htons(Port); + + if DstSockAddr.sin_addr.s_addr <> 0 then + { Try to initiate connection. } + FConnected:= fpConnect(FSocket, @DstSockAddr, SizeOf(DstSockAddr)) <> -1; + + if FConnected then begin + FHostIP:= TIPNamePair.Create(HostName, NetAddrToStr(DstSockAddr.sin_addr)); + SetSockTimeOut(FSockTimeOut); + end + else + CloseSocket(FSocket); - FreeHost(GAIResult); + FreeHost(GAIResult); + end; end; end; Result:= FConnected; @@ -218,7 +240,7 @@ procedure TTCPConnection.ReverseDNSLookup; var NHostIP: TIPNamePair; begin if FConnected then begin - NHostIP:= TIPNamePair.Create(ResolveIP(@SockAddr), FHostIP.IP); + NHostIP:= TIPNamePair.Create(ResolveIP(@DstSockAddr), FHostIP.IP); FHostIP.Free; FHostIP:= NHostIP; end; @@ -356,9 +378,9 @@ begin connection. } case FFeatureRequest of NET_TCP_BASIC: - TCPConnection:= TTCPConnection.Create(ClientSocket, SockAddr); + TCPConnection:= TTCPConnection.Create(ClientSocket); NET_TCP_RFCSUPPORT: - TCPConnection:= TTCPRFCConnection.Create(ClientSocket, SockAddr); + TCPConnection:= TTCPRFCConnection.Create(ClientSocket); end; { Then start a new thread with the connection handler. }