public ServicePointScheduler(ServicePoint servicePoint, int connectionLimit, int maxIdleTime)
        {
            ServicePoint         = servicePoint;
            this.connectionLimit = connectionLimit;
            this.maxIdleTime     = maxIdleTime;

            schedulerEvent  = new AsyncManualResetEvent(false);
            defaultGroup    = new ConnectionGroup(this, string.Empty);
            operations      = new LinkedList <(ConnectionGroup, WebOperation)> ();
            idleConnections = new LinkedList <(ConnectionGroup, WebConnection, Task)> ();
            idleSince       = DateTime.UtcNow;
        }
        private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate)
        {
            string          str   = ConnectionGroup.MakeQueryStr(connName);
            ConnectionGroup group = this.m_ConnectionGroupList[str] as ConnectionGroup;

            if ((group == null) && !dontCreate)
            {
                group = new ConnectionGroup(this, connName);
                this.m_ConnectionGroupList[str] = group;
            }
            return(group);
        }
 internal bool ReleaseConnectionGroup(string connName)
 {
     lock (this)
     {
         ConnectionGroup group = this.FindConnectionGroup(connName, true);
         if (group == null)
         {
             return(false);
         }
         group.DisableKeepAliveOnConnections();
         this.m_ConnectionGroupList.Remove(connName);
     }
     return(true);
 }
Beispiel #4
0
        private void SetConnectionLimit(int limit, bool fromUser)
        {
            lock (this) {
                // We'll only update the limit if the user hasn't previously
                // changed it or if this change is coming from the user.

                if (!m_UserChangedLimit || fromUser)
                {
                    // Save the value, and remember if it was changed by the
                    // user.

                    m_UserChangedLimit = fromUser;
                    m_ConnectionLimit  = limit;

                    // Now walk through the connection groups on this service
                    // point, and update all of them with the new value.
                    //

                    IDictionaryEnumerator CGEnumerator;

                    CGEnumerator = m_ConnectionGroupList.GetEnumerator();

                    while (CGEnumerator.MoveNext())
                    {
                        ConnectionGroup CurrentCG =
                            (ConnectionGroup)CGEnumerator.Value;

                        //
                        // If this change came in from the user, we want to
                        // propagate it down to the underlying connection
                        // groups no matter what. If it's from some internal state
                        // change, we want to propagate it via the internal
                        // mechanism, which only sets it if it hasn't been set by
                        // the user.

                        if (fromUser)
                        {
                            CurrentCG.ConnectionLimit = limit;
                        }
                        else
                        {
                            CurrentCG.InternalConnectionLimit = limit;
                        }
                    }
                }
            }
        }
Beispiel #5
0
        /// <devdoc>
        ///    <para>
        ///       Sets connections in this group to not be KeepAlive.
        ///       This is called to force cleanup of the ConnectionGroup by the
        ///       NTLM and Negotiate authentication modules.
        ///    </para>
        /// </devdoc>
        internal void ReleaseConnectionGroup(string connName)
        {
            //
            // look up the ConnectionGroup based on the name
            //
            ConnectionGroup connectionGroup = FindConnectionGroup(connName);

            //
            // force all connections on the ConnectionGroup to not be KeepAlive
            //
            connectionGroup.DisableKeepAliveOnConnections();
            //
            // remove ConnectionGroup from our Hashtable
            //
            lock (this) {
                m_ConnectionGroupList.Remove(connName);
            }
        }
 private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate)
 {
     string str = ConnectionGroup.MakeQueryStr(connName);
     ConnectionGroup group = this.m_ConnectionGroupList[str] as ConnectionGroup;
     if ((group == null) && !dontCreate)
     {
         group = new ConnectionGroup(this, connName);
         this.m_ConnectionGroupList[str] = group;
     }
     return group;
 }
        internal Connection(ConnectionGroup connectionGroup) : base(null) {
            //
            // add this Connection to the pool in the connection group,
            //  keep a weak reference to it
            //
            m_MaximumUnauthorizedUploadLength = SettingsSectionInternal.Section.MaximumUnauthorizedUploadLength;
            if(m_MaximumUnauthorizedUploadLength > 0){
                m_MaximumUnauthorizedUploadLength*=1024;
            }
            m_ResponseData = new CoreResponseData();
            m_ConnectionGroup = connectionGroup;
            m_ReadBuffer = new byte[4096];    // Using a fixed 4k read buffer.
            m_ReadState = ReadState.Start;
            m_WaitList = new List<WaitListItem>();
            m_WriteList = new ArrayList();
            m_AbortDelegate = new HttpAbortDelegate(AbortOrDisassociate);
            m_ConnectionUnlock = new UnlockConnectionDelegate(UnlockRequest);

            // for status line parsing
            m_StatusLineValues = new StatusLineValues();
            m_RecycleTimer = ConnectionGroup.ServicePoint.ConnectionLeaseTimerQueue.CreateTimer();
            // the following line must be the last line of the constructor
            ConnectionGroup.Associate(this);
            m_ReadDone = true;
            m_WriteDone = true;
            m_Error = WebExceptionStatus.Success;
        }
        /*++

            FindConnectionGroup       -

            Searches for the a Group object that actually holds the connections
              that we want to peak at.


            Input:
                    request                 - Request that's being submitted.
                    connName                - Connection Name if needed

            Returns:
                    ConnectionGroup

        --*/

        private ConnectionGroup FindConnectionGroup(string connName, bool dontCreate) {
            string lookupStr = ConnectionGroup.MakeQueryStr(connName);

            GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() lookupStr:[" + ValidationHelper.ToString(connName) + "]");

            ConnectionGroup entry = m_ConnectionGroupList[lookupStr] as ConnectionGroup;

            if (entry==null && !dontCreate) {
                entry = new ConnectionGroup(this, connName);
                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() adding ConnectionGroup lookupStr:[" + lookupStr + "]");

                m_ConnectionGroupList[lookupStr] = entry;
            }
            else {
                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() using existing ConnectionGroup");
            }
            GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() returning ConnectionGroup:" + ValidationHelper.ToString(entry) + (entry!=null ? " ConnLimit:" + entry.ConnectionLimit.ToString() : ""));
            return entry;
        }
 internal TimerThread.Timer CreateConnectionGroupTimer(ConnectionGroup connectionGroup) {
     return m_IdlingQueue.CreateTimer(m_IdleConnectionGroupTimeoutDelegate, connectionGroup);
 }
Beispiel #10
0
        internal Connection(ConnectionGroup connectionGroup) : base(null) {
            //
            // add this Connection to the pool in the connection group,
            //  keep a weak reference to it
            //
            m_MaximumUnauthorizedUploadLength = SettingsSectionInternal.Section.MaximumUnauthorizedUploadLength;
            if(m_MaximumUnauthorizedUploadLength > 0){
                m_MaximumUnauthorizedUploadLength*=1024;
            }
            m_ResponseData = new CoreResponseData();
            m_ConnectionGroup = connectionGroup;
            m_ReadBuffer = s_PinnableBufferCache.AllocateBuffer();
            m_ReadBufferFromPinnableCache = true;
            m_ReadState = ReadState.Start;
            m_WaitList = new List<WaitListItem>();
            m_WriteList = new ArrayList();
            m_AbortDelegate = new HttpAbortDelegate(AbortOrDisassociate);
            m_ConnectionUnlock = new UnlockConnectionDelegate(UnlockRequest);

            // for status line parsing
            m_StatusLineValues = new StatusLineValues();
            m_RecycleTimer = ConnectionGroup.ServicePoint.ConnectionLeaseTimerQueue.CreateTimer();
            // the following line must be the last line of the constructor
            ConnectionGroup.Associate(this);
            m_ReadDone = true;
            m_WriteDone = true;
            m_Error = WebExceptionStatus.Success;
            if (PinnableBufferCacheEventSource.Log.IsEnabled())
            {
                PinnableBufferCacheEventSource.Log.DebugMessage1("CTOR: In System.Net.Connection.Connnection", this.GetHashCode());
            }
        }
Beispiel #11
0
        // methods

        /*++

            FindConnectionGroup       -

            Searches for the a Group object that actually holds the connections
              that we want to peak at.


            Input:
                    request                 - Request that's being submitted.
                    connName                - Connection Name if needed

            Returns:
                    ConnectionGroup

        --*/

        internal ConnectionGroup FindConnectionGroup(string connName) {
            string lookupStr = ConnectionGroup.MakeQueryStr(connName);

            GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() lookupStr:[" + ValidationHelper.ToString(connName) + "]");

            ConnectionGroup entry = m_ConnectionGroupList[lookupStr] as ConnectionGroup;

            if (entry == null) {
                IPAddressInfo   RemoteInfo = GetCurrentIPAddressInfo();
                IPAddress       RemoteAddress = null;
                int             ConnLimit;

                if (RemoteInfo == null) {

                    GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[(null)] m_UserChangedLimit:" + m_UserChangedLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString());

                    //
                    // If we don't have any information about the remote IP address,
                    // limit ourself to one connection until the address is resolved.
                    //
                    ConnLimit = 1; // ServicePointManager.DefaultConnectionLimit;
                    //
                    // if this is a user given number, then
                    // make sure to propagte this value
                    //
                    if (m_UserChangedLimit) {
                        ConnLimit = m_ConnectionLimit;
                    }
                }
                else {

                    RemoteAddress = RemoteInfo.Address;

                    if (!RemoteInfo.IsLoopback) {
                        ConnLimit = m_ConnectionLimit;
                    }
                    else {
                        ConnLimit = LoopbackConnectionLimit;
                    }

                    GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[" + RemoteAddress.ToString() + "] ConnLimit:" + ConnLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString());
                }

                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() creating ConnectionGroup ConnLimit:" + ConnLimit.ToString());

                entry = new ConnectionGroup(this,
                                            RemoteAddress,
                                            ConnLimit,
                                            connName);

                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() adding ConnectionGroup lookupStr:[" + lookupStr + "]");

                m_ConnectionGroupList[lookupStr] = entry;
            }
            else {
                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() using existing ConnectionGroup");
            }

            GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() ConnectionGroup.ConnLimit:" + entry.ConnectionLimit.ToString());

            return entry;
        }
Beispiel #12
0
        public Connection(
            ConnectionGroup   connectionGroup,
            ServicePoint      servicePoint,
            IPAddress         remoteAddress,
            Version           version,
            bool              supportsPipeline ) {

            //
            // add this Connection to the pool in the connection group,
            //  keep a weak reference to it
            //

            m_ConnectionGroup = connectionGroup;
            m_WeakReference = new WeakReference(this);
            m_ConnectionGroup.Associate(m_WeakReference);

            m_Idle = true;
            m_Free = true;
            m_CanPipeline = supportsPipeline;
            m_Server = servicePoint;
            m_Version = version;
            m_ReadBuffer = new byte[m_ReadBufferSize];
            m_CurrentRequestIndex = 0;
            m_ReadState = ReadState.Start;
            m_WaitList = new ArrayList();
            m_WriteList = new ArrayList();
            m_ReadCallbackEvent = new ManualResetEvent(true);

            m_StartConnectionDelegate = new WaitOrTimerCallback(StartConnectionCallback);
            m_AbortDelegate = new HttpAbortDelegate(Abort);

            // for status line parsing
            m_StatusLineInts = new int[MaxStatusInts];
            InitializeParseStatueLine();
        }
Beispiel #13
0
        /*++
         *
         *  SetAddressList - Set the list of IP addresses for this service point.
         *
         *  This is a method called when the underlying code has resolved the
         *  destination to a list of IP addressess. We actually maintain some
         *  information about the viable IP addresses for this service point,
         *  like whether or not they're loopback, etc. So we walk through the
         *  list and set up an array of structures corresponding to the IP
         *  addresses.
         *
         *  Note that it's possible to have some IP addresses be loopbacked
         *  and some not. This can happen if a server name maps to multiple
         *  physical servers and we're one of those servers.
         *
         *  Input:
         *          addressList     - Array of resolved IP addresses.
         *
         *  Returns: Nothing.
         *
         * --*/
        private IPHostEntryInfo SetAddressList(IPHostEntry ipHostEntry)
        {
            GlobalLog.Print("SetAddressList(" + ipHostEntry.HostName + ")");
            //
            // Create an array of IPAddressInfo of the appropriate size, then
            // get a list of our local addresses. Walk through the input
            // address list. Copy each address in the address list into
            // our array, and if the address is a loopback address, mark it as
            // such.
            //
            IPAddress[]     addressList = ipHostEntry.AddressList;
            IPAddressInfo[] TempInfo    = new IPAddressInfo[addressList.Length];

            //
            // Walk through each member of the input list, copying it into our temp array.
            //
            int         i, k;
            IPHostEntry ipLocalHostEntry = null;

            try {
                ipLocalHostEntry = Dns.LocalHost;
            }
            catch (Exception exception) {
                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::SetAddressList() Dns.LocalHost threw exception:[" + ValidationHelper.ToString(exception) + "]");
            }
            for (i = 0; i < addressList.Length; i++)
            {
                TempInfo[i] = new IPAddressInfo(addressList[i]);

                // First, check to see if the current address is a  loopback
                // address.

                if (IPAddress.IsLoopback(TempInfo[i].Address))
                {
                    TempInfo[i].IsLoopback = true;
                    continue;
                }

                // See if the current IP address is a local address, and if
                // so mark it as such.
                if (ipLocalHostEntry != null)
                {
                    for (k = 0; k < ipLocalHostEntry.AddressList.Length; k++)
                    {
                        //
                        // IPv6 Changes: Use .Equals for this check !
                        //
                        if (TempInfo[i].Address.Equals(ipLocalHostEntry.AddressList[k]))
                        {
                            TempInfo[i].IsLoopback = true;
                            break;
                        }
                    }
                }
            }

            //
            // now look for connection group objects that don't have
            // an IP address associated with them. When it finds one, it updates
            // the IP address and tries to update the connection limit.
            //
            lock (this) {
                // Walk through the connection groups on this service
                // point, and update the ones we need to with an IP
                // address.
                //

                IDictionaryEnumerator CGEnumerator;

                CGEnumerator = m_ConnectionGroupList.GetEnumerator();

                while (CGEnumerator.MoveNext())
                {
                    ConnectionGroup CurrentCG = (ConnectionGroup)CGEnumerator.Value;

                    // If this connection group doesn't have an IP address
                    // assigned to it, give it one.

                    if (CurrentCG.RemoteIPAddress == null)
                    {
                        GlobalLog.Print("ServicePoint::UpdateConnectionGroupAddresses null CurrentCG.RemoteIPAddress");

                        // Update the address.

                        CurrentCG.RemoteIPAddress = TempInfo[0].Address;

                        // Now update the connection limit based on what we know.

                        CurrentCG.InternalConnectionLimit = TempInfo[0].IsLoopback ? LoopbackConnectionLimit : m_ConnectionLimit;

                        GlobalLog.Print("ServicePoint::UpdateConnectionGroupAddresses CurrentCG.InternalConnectionLimit:" + CurrentCG.InternalConnectionLimit.ToString());
                    }

                    GlobalLog.Print("ServicePoint::UpdateConnectionGroupAddresses CurrentCG.RemoteIPAddress:" + CurrentCG.RemoteIPAddress.ToString());
                }
            }

            IPHostEntryInfo ipAddressInfoList = new IPHostEntryInfo(TempInfo, ipHostEntry.HostName);

            return(ipAddressInfoList);
        }
Beispiel #14
0
        // methods

        /*++
         *
         *  FindConnectionGroup       -
         *
         *  Searches for the a Group object that actually holds the connections
         *    that we want to peak at.
         *
         *
         *  Input:
         *          request                 - Request that's being submitted.
         *          connName                - Connection Name if needed
         *
         *  Returns:
         *          ConnectionGroup
         *
         * --*/

        internal ConnectionGroup FindConnectionGroup(string connName)
        {
            string lookupStr = ConnectionGroup.MakeQueryStr(connName);

            GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() lookupStr:[" + ValidationHelper.ToString(connName) + "]");

            ConnectionGroup entry = m_ConnectionGroupList[lookupStr] as ConnectionGroup;

            if (entry == null)
            {
                IPAddressInfo RemoteInfo    = GetCurrentIPAddressInfo();
                IPAddress     RemoteAddress = null;
                int           ConnLimit;

                if (RemoteInfo == null)
                {
                    GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[(null)] m_UserChangedLimit:" + m_UserChangedLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString());

                    //
                    // If we don't have any information about the remote IP address,
                    // limit ourself to one connection until the address is resolved.
                    //
                    ConnLimit = 1; // ServicePointManager.DefaultConnectionLimit;
                    //
                    // if this is a user given number, then
                    // make sure to propagte this value
                    //
                    if (m_UserChangedLimit)
                    {
                        ConnLimit = m_ConnectionLimit;
                    }
                }
                else
                {
                    RemoteAddress = RemoteInfo.Address;

                    if (!RemoteInfo.IsLoopback)
                    {
                        ConnLimit = m_ConnectionLimit;
                    }
                    else
                    {
                        ConnLimit = LoopbackConnectionLimit;
                    }

                    GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() RemoteAddress:[" + RemoteAddress.ToString() + "] ConnLimit:" + ConnLimit.ToString() + " m_ConnectionLimit:" + m_ConnectionLimit.ToString());
                }

                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() creating ConnectionGroup ConnLimit:" + ConnLimit.ToString());

                entry = new ConnectionGroup(this,
                                            RemoteAddress,
                                            ConnLimit,
                                            connName);

                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() adding ConnectionGroup lookupStr:[" + lookupStr + "]");

                m_ConnectionGroupList[lookupStr] = entry;
            }
            else
            {
                GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() using existing ConnectionGroup");
            }

            GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::FindConnectionGroup() ConnectionGroup.ConnLimit:" + entry.ConnectionLimit.ToString());

            return(entry);
        }