I'm developing an P2P application which need enable a TCP Hole Punching.
For the Rendezvous Server I'm using a simple application (running in a public IP) with a TIdTCPServer
with SSL Enabled, this Application maintains the clients connections and returns the public endpoints (AContext.Binding.PeerIP and AContext.Binding.PeerPort) of the connected clients.
The Client (TIdTCPClient
) connections to the server have the property ReuseSocket set to rsTrue
.
This is how the clients are connected to the Rendezvous Server.
TCPClientMain.ConnectTimeout := 500;
TCPClientMain.Host := RendezvousServerIP;
TCPClientMain.Port := RendezvousServerPort;
TCPClientMain.UseNagle := false;
TCPClientMain.ReuseSocket := rsTrue;
OpenSSLHandlerMain.UseNagle := false;
OpenSSLHandlerMain.ReuseSocket := rsTrue;
TCPClientMain.IOHandler := OpenSSLHandlerMain;
TCPClientMain.Connect();
The issue happens when I try to create a new connection directly to the public end point of the Client A from B.
TCP Hole Punching code
var
LTCPClient : TIdTCPClient;
LOpenSSLHandle : TIdSSLIOHandlerSocketOpenSSL;
begin
//Init the SSL for the new connection
LOpenSSLHandle := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
LOpenSSLHandle.SSLOptions.Method := TIdSSLVersion.sslvTLSv1_2;
LOpenSSLHandle.SSLOptions.SSLVersions := [sslvTLSv1_2];
LOpenSSLHandle.UseNagle := False;
LTCPClient := TIdTCPClient.Create(nil);
LTCPClient.ConnectTimeout := 5000;
//Set the data of the public end point of the Client A
LTCPClient.Host := ARemoteIPAddress; //This is the public ip of the Client A
LTCPClient.Port := ARemotePort; //This is the port of the public endpoint of the client A
LTCPClient.ReuseSocket := rsTrue;
LTCPClient.IOHandler := LOpenSSLHandle;
LTCPClient.Connect(); //This raises a EIdSocketError exception
I'm getting Socket Error # 10061 Connection refused.
So, the question is how I can establish the new connection to the public endpoint of the Client without raise that exception?