public async ValueTask <ICap?> ConnectAsync(OmniAddress address, CancellationToken cancellationToken = default) { using (await _asyncLock.LockAsync()) { this.ThrowIfDisposingRequested(); var config = _tcpConnectOptions; if (config == null || !config.Enabled) { return(null); } if (!TryGetEndpoint(address, out var ipAddress, out ushort port)) { return(null); } var disposableList = new List <IDisposable>(); try { #if !DEBUG if (!IsGlobalIpAddress(ipAddress)) { return(null); } #endif if (config.ProxyOptions != null) { if (!TryGetEndpoint(config.ProxyOptions.Address, out var proxyAddress, out ushort proxyPort, true)) { return(null); } if (config.ProxyOptions.Type == TcpProxyType.Socks5Proxy) { var socket = await ConnectAsync(new IPEndPoint(proxyAddress, proxyPort)); if (socket == null) { return(null); } disposableList.Add(socket); var proxy = new Socks5ProxyClient(ipAddress.ToString(), port); await proxy.ConnectAsync(socket, cancellationToken); var cap = new SocketCap(socket); disposableList.Add(cap); return(cap); } else if (config.ProxyOptions.Type == TcpProxyType.HttpProxy) { var socket = await ConnectAsync(new IPEndPoint(proxyAddress, proxyPort)); if (socket == null) { return(null); } disposableList.Add(socket); var proxy = new HttpProxyClient(ipAddress.ToString(), port); await proxy.ConnectAsync(socket, cancellationToken); var cap = new SocketCap(socket); disposableList.Add(cap); return(cap); } } else { var socket = await ConnectAsync(new IPEndPoint(ipAddress, port)); if (socket == null) { return(null); } disposableList.Add(socket); var cap = new SocketCap(socket); disposableList.Add(cap); return(cap); } } catch (Exception e) { _logger.Error(e); foreach (var item in disposableList) { item.Dispose(); } } return(null); } }