private async Task SetupClient(TcpClient client) { lock (_pending) { _pending.Add(client); } _logger.LogVerbose(Properties.Resources.TcpNetworkListener_ConnectionLogString, client.Client.RemoteEndPoint); TcpClientDataAdapter da = new TcpClientDataAdapter(client); ClientConnectedEventArgs e = new ClientConnectedEventArgs(da); NetUtils.PopulateBagFromSocket(client.Client, e.Properties); try { await Task.Run(() => ClientConnected.Invoke(this, e)); } catch { client.Dispose(); } finally { lock (_pending) { _pending.Remove(client); } } }
/// <summary> /// Do connection /// </summary> /// <param name="timeout">Timeout for connection in seconds</param> /// <returns>The connected adapter</returns> /// <exception cref="TimeoutException">Thrown if imeout</exception> protected override IDataAdapter DoConnect(int timeout) { IDataAdapter ret = null; try { List <Socket> readSockets = new List <Socket>(); readSockets.Add(_listener.Server); List <Socket> errorSockets = new List <Socket>(); errorSockets.Add(_listener.Server); Socket.Select(readSockets, null, errorSockets, timeout < 0 ? timeout : timeout * 1000); if (readSockets.Count > 0) { ret = new TcpClientDataAdapter(_listener.AcceptTcpClient()); } else { throw new TimeoutException(); } } finally { _listener.Stop(); } return(ret); }
/// <summary> /// /// </summary> /// <param name="adapter"></param> /// <param name="meta"></param> /// <param name="globalMeta"></param> /// <param name="service"></param> /// <returns></returns> public override ProxyToken Accept(IDataAdapter adapter, MetaDictionary meta, MetaDictionary globalMeta, ProxyNetworkService service) { ProxyToken token = null; TcpClientDataAdapter tcpAdapter = adapter as TcpClientDataAdapter; if (_config.SslConfig.Enabled) { IDataAdapter client = null; INetworkLayer ssl = new SslNetworkLayer(_config.SslConfig); ssl.Negotiate(ref adapter, ref client, null, _logger, null, null, new PropertyBag("Root"), NetworkLayerBinding.Server); } DataAdapterToStream stm = new DataAdapterToStream(adapter); DataReader reader = new DataReader(stm); try { HttpRequestHeader header = HttpParser.ReadRequestHeader(reader, false, _logger); token = HandleOtherRequest(header, stm, tcpAdapter); } catch (HttpStreamParserException ex) { _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidRequest, ex.Message); // TODO: Put in some decent error codes ReturnResponse(null, 400, "Bad Request", "GET", HttpVersion.Version11, stm); } catch (EndOfStreamException) { token = null; } return(token); }
private Uri GetUri(string host, TcpClientDataAdapter tcpAdapter) { Uri ret = null; int port = _config.SslConfig.Enabled ? 443 : 80; // TODO: Should handle this case, perhaps just make it optional //if ((tcpAdapter != null) && (tcpAdapter.Socket.Client.LocalEndPoint is System.Net.IPEndPoint)) //{ // port = ((System.Net.IPEndPoint)tcpAdapter.Socket.Client.LocalEndPoint).Port; //} if (!String.IsNullOrWhiteSpace(host)) { try { if (!host.Contains(":")) { host = String.Format("{0}:{1}", host, port); } if (_config.SslConfig.Enabled) { ret = new Uri("https://" + host); } else { ret = new Uri("http://" + host); } } catch (UriFormatException) { } } return(ret); }
private IDataAdapter ConnectTcp(IpProxyToken token, Logger logger, PropertyBag properties) { IDataAdapter adapter = null; try { bool isIpv6 = IsTokenIpV6(token); TcpClient client = new TcpClient(isIpv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork); if (token.Hostname == null) { client.ConnectAsync(token.Address, token.Port).Wait(); } else { client.ConnectAsync(token.Hostname, token.Port).Wait(); } NetUtils.PopulateBagFromSocket(client.Client, properties); adapter = new TcpClientDataAdapter(client, IpProxyClient.GetDescription(token)); } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } return(adapter); }
/// <summary> /// Connect to the required service with the token /// </summary> /// <param name="token">The token recevied from proxy</param> /// <param name="globalMeta">The global meta</param> /// <param name="logger">The logger</param> /// <param name="meta">The meta</param> /// <param name="properties">Property bag to add any information to</param> /// <param name="credmgr">Credentials manager</param> /// <returns>The connected data adapter</returns> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties, CredentialsManagerService credmgr) { IDataAdapter ret = null; token.Status = NetStatusCodes.ConnectFailure; if ((token is IpProxyToken) && ((IpProxyToken)token).ClientType == IpProxyToken.IpClientType.Tcp) { TcpClient client = new TcpClient(); try { client.Connect(_hostname, _port); if (token is FullHttpProxyToken) { bool binary = false; if ((token.Layers != null) && (token.Layers.Length > 0)) { foreach (INetworkLayer layer in token.Layers) { // Find a binding layer if (layer.Binding == NetworkLayerBinding.Client || layer.Binding == NetworkLayerBinding.ClientAndServer || layer.Binding == NetworkLayerBinding.Default) { if (!(layer is HttpNetworkLayer)) { binary = true; } break; } } } if (!binary) { ret = new FullHttpProxyDataAdapter(client, (FullHttpProxyToken)token, IpProxyClient.GetDescription((IpProxyToken)token), logger); NetUtils.PopulateBagFromSocket(client.Client, properties); token.Status = NetStatusCodes.Success; } else { ConnectWithIpProxyToken(client.GetStream(), (IpProxyToken)token, logger); if (token.Status == NetStatusCodes.Success) { NetUtils.PopulateBagFromSocket(client.Client, properties); ret = new TcpClientDataAdapter(client, IpProxyClient.GetDescription((IpProxyToken)token)); } } } else { if (token is HttpProxyToken) { ConnectWithHttpProxyToken(client.GetStream(), (HttpProxyToken)token, logger); } else { ConnectWithIpProxyToken(client.GetStream(), (IpProxyToken)token, logger); } if (token.Status == NetStatusCodes.Success) { NetUtils.PopulateBagFromSocket(client.Client, properties); ret = new TcpClientDataAdapter(client, IpProxyClient.GetDescription((IpProxyToken)token)); } } } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } finally { if (ret == null) { client.Close(); } } } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.HttpProxyClient_InvalidProxyToken); } return(ret); }
/// <summary> /// Connection to the socks server /// </summary> /// <param name="token">The proxy token</param> /// <param name="logger">Logger</param> /// <param name="globalMeta">Global meta</param> /// <param name="meta">Meta</param> /// <param name="properties">Property bag to populate</param> /// <returns>A connected data adapter, or null if not available</returns> /// <exception cref="SocketException">Throw if cannot connect</exception> /// <exception cref="ArgumentException">Throw if invalid operation occurs</exception> /// <exception cref="EndOfStreamException">Throw if stream ends before reading all data</exception> public override IDataAdapter Connect(ProxyToken token, Logger logger, MetaDictionary meta, MetaDictionary globalMeta, PropertyBag properties) { IDataAdapter ret = null; if (token is IpProxyToken) { IpProxyToken iptoken = token as IpProxyToken; TcpClient client = new TcpClient(); try { client.ConnectAsync(_hostname, _port).Wait(); if (_version == SupportedVersion.Version4) { if (_sendHostName && !String.IsNullOrWhiteSpace(iptoken.Hostname)) { ConnectVersion4a(client.GetStream(), iptoken, logger); } else { ConnectVersion4(client.GetStream(), iptoken, logger); } } else { ConnectVersion5(client.GetStream(), iptoken, logger); } if (iptoken.Status == NetStatusCodes.Success) { NetUtils.PopulateBagFromSocket(client.Client, properties); ret = new TcpClientDataAdapter(client, IpProxyClient.GetDescription((IpProxyToken)token)); } } catch (SocketException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } catch (IOException ex) { logger.LogException(ex); token.Status = NetStatusCodes.ConnectFailure; } finally { if (ret == null) { client.Dispose(); } } } else { throw new ArgumentException(CANAPE.Net.Properties.Resources.SocksProxyClient_InvalidProxyToken3); } return(ret); }
private ProxyToken HandleOtherRequest(HttpRequestHeader header, DataAdapterToStream stm, TcpClientDataAdapter tcpAdapter) { string host = null; foreach (KeyDataPair <string> pair in header.Headers) { if (pair.Name.Equals("host", StringComparison.OrdinalIgnoreCase)) { host = pair.Value; } } Uri url = GetUri(host, tcpAdapter); if (url != null) { // Use generic token so filters don't get used IpProxyToken ret = new IpProxyToken(null, url.Host, url.Port, IpProxyToken.IpClientType.Tcp, false); if (_config.SslConfig.Enabled) { ret.Layers = new INetworkLayer[1]; ret.Layers[0] = new SslNetworkLayer(new SslNetworkLayerConfig(false, true) { Enabled = true }); } ret.State.Add("url", url); ret.State.Add("stm", stm); ret.State.Add("header", header); return(ret); } else { _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidUrl, header.Path); ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm); return(null); } }
private void AcceptCallback(IAsyncResult res) { GeneralUtils.SetThreadCulture(); if (res.IsCompleted) { try { TcpListener listener = ((TcpListener)res.AsyncState); TcpClient client = null; try { client = listener.EndAcceptTcpClient(res); client.NoDelay = _nodelay; } finally { // Restart it if (_isStarted) { listener.BeginAcceptTcpClient(AcceptCallback, listener); } } if (ClientConnected != null) { lock (_pending) { _pending.Add(client); } _logger.LogVerbose(CANAPE.Net.Properties.Resources.TcpNetworkListener_ConnectionLogString, client.Client.RemoteEndPoint); TcpClientDataAdapter da = new TcpClientDataAdapter(client); ClientConnectedEventArgs e = new ClientConnectedEventArgs(da); NetUtils.PopulateBagFromSocket(client.Client, e.Properties); ClientConnected.Invoke(this, e); lock (_pending) { _pending.Remove(client); } } else { // There was noone to accept the message, so just close client.Close(); } } catch (ObjectDisposedException) { // Don't do anything } catch (Exception ex) { _logger.LogException(ex); } } }