Beispiel #1
0
        public ARP()
        {
            DebugPrint("Initializing ARP module\n");
            arpTable                = new ArpTable(this);
            pendingRequests         = new Queue();
            pendingRequestsFreelist = new Queue();

            //start the array list with 256 elements to
            for (int i = 0; i < DefaultMaxPendingArpRequests; i++)
            {
                PendingArpRequest pendingArpRequest =
                    new PendingArpRequest();
                pendingRequestsFreelist.Enqueue(pendingArpRequest);
            }
            arpHandle = new AutoResetEvent(false);

            Thread arpThread = new Thread(this);

            DebugStub.Assert(arpThread != null);
            arpThread.Start();
        }
Beispiel #2
0
        private AutoResetEvent AddPendingRequest(IPv4 address,
                                                 TimeSpan timeout,
                                                 EthernetAddress localMac,
                                                 Bytes header,
                                                 Bytes buffer,
                                                 IAdapter adapter
                                                 )
        {
            PendingArpRequest pendingRequest = (PendingArpRequest)pendingRequestsFreelist.Dequeue();

            VTable.Assert(pendingRequest != null);
            pendingRequest.address  = address;
            pendingRequest.active   = true;
            pendingRequest.localMac = localMac;
            pendingRequest.adapter  = adapter;
            VectorQueueByte txBuffer = pendingRequest.txContainer.Acquire();

            txBuffer.AddTail(header);
            txBuffer.AddTail(buffer);
            pendingRequest.txContainer.Release(txBuffer);

            using (pendingRequestsLock.Lock()) {
                pendingRequests.Enqueue(pendingRequest);
            }

            SchedulerTime expiration = SchedulerTime.Now;

            expiration = expiration.Add(timeout);
            pendingRequest.requestExpiration = expiration;

            //poke the wait thread
            if (pendingRequests.Count == 1)
            {
                arpHandle.Set();
            }
            return(pendingRequest.requestEvent);
        }
Beispiel #3
0
        private void ARPManageThread()
        {
            DebugPrint("ARP managment thread spinning up\n");
            //the pending requests list is ordered by deadline...
            //finding a requests when we rceive a reply is in the worst case O(n)...
            //Hopefully we won't have many oustanding requests, and the first request out
            //will often return first...

            //track two different timeouts here...ARP requests and ARP table aging.
            SchedulerTime ageTableTimeout;
            SchedulerTime now;
            SchedulerTime nextTimer;


            ageTableTimeout = SchedulerTime.Now;
            ageTableTimeout = ageTableTimeout.AddMinutes(5);
            while (true)
            {
                now = SchedulerTime.Now;
                if (now > ageTableTimeout)
                {
                    arpTable.AgeTable();
                    ageTableTimeout = SchedulerTime.Now;
                    ageTableTimeout = ageTableTimeout.AddMinutes(5);
                }
                using (pendingRequestsLock.Lock()) {
                    nextTimer = SchedulerTime.MaxValue;
                    bool done = false;
                    while (!done)
                    {
                        if (pendingRequests.Count == 0)
                        {
                            done = true;
                            continue;
                        }
                        PendingArpRequest pendingArpRequest = (PendingArpRequest)pendingRequests.Peek();
                        if (pendingArpRequest == null)
                        {
                            done = true;
                            continue;
                        }
                        if (pendingArpRequest.requestExpiration > now)
                        {
                            nextTimer = pendingArpRequest.requestExpiration;
                            done      = true;
                            continue;
                        }
                        else
                        {
                            pendingArpRequest = (PendingArpRequest)pendingRequests.Dequeue();
                            if (pendingArpRequest.active == true)
                            {
                                //We need error propagation here...
                                pendingArpRequest.active = false;
                                DebugStub.Assert(false);
                            }
                            pendingRequestsFreelist.Enqueue(pendingArpRequest);
                        }
                    }
                }
                if (ageTableTimeout < nextTimer)
                {
                    DebugPrint("setting nextTimer ageTableTimeout\n");
                    nextTimer = ageTableTimeout;
                }
                bool rc;
                rc = arpHandle.WaitOne(nextTimer);
            }
        }