private void ProcessClient(TcpClientInfo clientInfo) { if (!_listening) { return; //the proxy was stopped } //queue the client _clientQueue.Enqueue(clientInfo); PruneConnections(null); }
/// <summary> /// Prunes the collections list and initializes new connections /// </summary> private void PruneConnections(object state) { try { if (!_listening) { return; } Queue <IProxyConnection> connectionsToStart = new Queue <IProxyConnection>(); lock (_lockConnections) { IProxyConnection conn; int counter = 0; //first clear dead connections while (counter < _connections.Count) { conn = _connections.Dequeue(); if (conn.Closed && _connections.Count >= _connectionLimit) { //call connection stop just in case we have a lingering thread //this should set the _stop flag to true and end any async operations conn.Stop(); } else //if the connection is not closed put it back at the end of the queue { _connections.Enqueue(conn); counter++; //update the counter to show this connection was processed } } //if the number is still high clear connections that are not busy //find connections that idle and drop them starting with the oldest in the list counter = 0; while (_connections.Count >= _connectionLimit && counter < _connections.Count) { conn = _connections.Dequeue(); if (!conn.IsBusy) { conn.Stop(); HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Max clients exceeded. Idle connection was dropped"); } else { //put the connection back to the end of the queue _connections.Enqueue(conn); counter++; } } //lastly if the number is still high forcefully kill the oldest connections until we get below the limit //this should be a rare situation and something may be wrong with the connection, a very slow client while (_connections.Count >= _connectionLimit) { conn = _connections.Dequeue(); conn.Stop(); HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Max clients exceeded. Older connections were dropped"); } //now that we ensured there's room dequeue any pending connections and start them while (_connections.Count < _connectionLimit && _clientQueue.Count > 0) { TcpClientInfo clientInfo = _clientQueue.Dequeue(); if (clientInfo.Client.Connected) { // Create the new connection conn = GetConnection(clientInfo); // Add the connection to list of connections _connections.Enqueue(conn); //adding the connection to a separate collection in order to //start it outside the lock connectionsToStart.Enqueue(conn); } } } //end critical section //start connections while (connectionsToStart.Count > 0 && _listening) { IProxyConnection conn = connectionsToStart.Dequeue(); conn.Start(); } } catch (Exception ex) { SdkSettings.Instance.Logger.Log(TraceLevel.Error, "BaseProxy.PruneConnections: Caught exception: {0}", ex.ToString()); } }
/// <summary> /// Gets the proxy connection to be used /// </summary> /// <param name="clientInfo"></param> /// <returns></returns> protected abstract IProxyConnection GetConnection(TcpClientInfo clientInfo);
/// <summary> /// Gets the http proxy connection /// </summary> /// <param name="clientInfo"></param> /// <returns></returns> protected override IProxyConnection GetConnection(TrafficViewerSDK.Http.TcpClientInfo clientInfo) { return(new DriveByAttackProxyConnection(clientInfo.Client, clientInfo.IsSecure, NetworkSettings, this, TrafficDataStore)); }
/// <summary> /// Gets the proxy connection to be used when a request comes in /// </summary> /// <param name="clientInfo">Information about the tcp client</param> /// <returns></returns> protected override IProxyConnection GetConnection(TcpClientInfo clientInfo) { return(new ManualExploreProxyConnection(clientInfo.Client, clientInfo.IsSecure, _trafficDataStore, Resources.ManualExploreRequestDescription, NetworkSettings)); }
/// <summary> /// Gets the connection /// </summary> /// <param name="clientInfo"></param> /// <returns></returns> protected override IProxyConnection GetConnection(TcpClientInfo clientInfo) { return(new CommandProxyConnection(this, clientInfo.Client)); }