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;
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);
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;
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;
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;
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. }