public static void NatConicityTest() { var info = new AddressInfoMessage[2]; var clients = new Client[2]; clients[0] = new Client(server_endpoints[0]); clients[0].ConnectToServer(); clients[1] = new Client(server_endpoints[1]); clients[1].ReuseEndPoint(clients[0].client.LocalEndPoint); clients[1].ConnectToServer(); info[0] = clients[0].GetMyAddressInfo(); info[1] = clients[1].GetMyAddressInfo(); System.Console.WriteLine($"AddressInfo 0: {info[0].ToPrettyString()}"); System.Console.WriteLine($"AddressInfo 1: {info[1].ToPrettyString()}"); bool isConic = info[0].PublicEndpoint.Equals(info[1].PublicEndpoint); System.Console.WriteLine($"Your nat is {(isConic ? "CONE" : "SIMMETRIC")}"); System.Console.WriteLine("If public ports and addresses are the same, then your NAT is cone."); System.Console.WriteLine("Clients will connect IF ONLY your NAT is CONE."); clients[0].client.Close(); clients[1].client.Close(); }
public Socket EstablishOutboundTcp(AddressInfoMessage info) { Socket private_client = CreateSocket(); Socket public_client = CreateSocket(); Socket listener = CreateSocket(); private_client.Bind(client.LocalEndPoint); public_client.Bind(client.LocalEndPoint); listener.Bind(client.LocalEndPoint); listener.Listen(1); Func <Task <Socket> >[] funcs = new Func <Task <Socket> >[] { () => Task.Run(() => { System.Console.WriteLine($"Sending connection request to {info.PrivateEndpoint.Convert()} from {private_client.LocalEndPoint}"); private_client.Connect(info.PrivateEndpoint.Convert()); return(private_client); }), () => Task.Run(() => { System.Console.WriteLine($"Sending connection request to {info.PublicEndpoint.Convert()} from {public_client.LocalEndPoint}"); public_client.Connect(info.PublicEndpoint.Convert()); return(public_client); }), () => Task.Run(() => listener.Accept()) }; Task <Socket>[] tasks = new Task <Socket>[] { funcs[0](), funcs[1](), funcs[2]() }; int num_errors = 0; const int max_errors = 10; while (true) { int index = Task.WaitAny(tasks); if (tasks[index].IsFaulted) { if (++num_errors >= max_errors) { return(null); } else { System.Console.WriteLine($"Task number {index} threw an error. Current number of errors: {num_errors}"); tasks[index] = funcs[index](); } } else { System.Console.WriteLine($"Task number {index} succeeded."); return(tasks[index].Result); } } }
public static string ToPrettyString(this AddressInfoMessage info) { return($"[{info.Id}] {info.PublicEndpoint.GetAddress()}:{info.PublicEndpoint.Port} | {info.PrivateEndpoint.GetAddress()}:{info.PrivateEndpoint.Port}"); }