/// <summary> /// Ends the host connection phase and negotiates the proxied connection /// </summary> private void EndConnectToIPAddress(IAsyncResult res) { try { socket.EndConnect(res); if (destinationSsl) { socket.AuthenticateAsClient(destinationServer); } } catch (Exception sockex) { OnConnectionFailed("Can't connect to server: {0}", sockex); return; } if (parent.Connections.LocalInternalIP == null) { parent.Connections.LocalInternalIP = ((IPEndPoint)socket.LocalEndPoint).Address; } if (parent.ServerSettings.ProxySetting == ProxyType.None) { OnConnectionComplete(); return; } if (parent.ServerSettings.ProxySetting == ProxyType.Socks5) { Socks5AuthType auth = GetSocks5AuthMethod(); if (auth == Socks5AuthType.AuthMethodRejected) { socket.Close(); OnConnectionFailed("SOCKS5 authentication mechanism unsupported"); return; } else if (auth != Socks5AuthType.None) { if (SendSocks5Authentication() == false) { socket.Close(); OnConnectionFailed("SOCK5 authentication failed, bad username/password"); return; } } if (SendSocks5ConnectRequest() == false) { socket.Close(); OnConnectionFailed("SOCKS5 connect failed, proxy server failure"); return; } } // Done! OnConnectionComplete(); }