[ros-diffs] [cgutman] 54912: [DHCPCSVC] - Fix ipconfig hang with ipconfig /renew and ipconfig /release - Fix duplicate protocol entries being added for the same adapter - Use WSAEventSelect and WaitForMultiple...

cgutman at svn.reactos.org cgutman at svn.reactos.org
Wed Jan 11 22:24:49 UTC 2012


Author: cgutman
Date: Wed Jan 11 22:24:49 2012
New Revision: 54912

URL: http://svn.reactos.org/svn/reactos?rev=54912&view=rev
Log:
[DHCPCSVC]
- Fix ipconfig hang with ipconfig /renew and ipconfig /release
- Fix duplicate protocol entries being added for the same adapter
- Use WSAEventSelect and WaitForMultipleObjects to manage waiting between timeouts, adapter state changes, and incoming packets

Modified:
    branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/adapter.c
    branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/api.c
    branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dispatch.c

Modified: branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/adapter.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/adapter.c?rev=54912&r1=54911&r2=54912&view=diff
==============================================================================
--- branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/adapter.c [iso-8859-1] (original)
+++ branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/adapter.c [iso-8859-1] Wed Jan 11 22:24:49 2012
@@ -1,6 +1,6 @@
 #include "rosdhcp.h"
 
-static SOCKET DhcpSocket = INVALID_SOCKET;
+SOCKET DhcpSocket = INVALID_SOCKET;
 static LIST_ENTRY AdapterList;
 static WSADATA wsd;
 
@@ -209,6 +209,7 @@
     PDHCP_ADAPTER Adapter = NULL;
     HANDLE AdapterStateChangedEvent = (HANDLE)Context;
     struct interface_info *ifi = NULL;
+    struct protocol *proto;
     int i, AdapterCount = 0, Broadcast;
 
     /* FIXME: Kill this thread when the service is stopped */
@@ -245,6 +246,10 @@
                     /* We're still active so we stay in the list */
                     ifi = &Adapter->DhclientInfo;
                 } else {
+                    proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
+                    if (proto)
+                        remove_protocol(proto);
+
                     /* We've lost our link so out we go */
                     RemoveEntryList(&Adapter->ListEntry);
                     free(Adapter);
@@ -330,7 +335,7 @@
                                      Adapter->DhclientInfo.rfdesc,
                                      got_one, &Adapter->DhclientInfo);
 
-	                state_init(&Adapter->DhclientInfo);
+                        state_init(&Adapter->DhclientInfo);
                     }
 
                     ApiLock();

Modified: branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/api.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/api.c?rev=54912&r1=54911&r2=54912&view=diff
==============================================================================
--- branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/api.c [iso-8859-1] (original)
+++ branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/api.c [iso-8859-1] Wed Jan 11 22:24:49 2012
@@ -14,6 +14,8 @@
 
 static CRITICAL_SECTION ApiCriticalSection;
 
+extern HANDLE AdapterStateChangedEvent;
+
 VOID ApiInit() {
     InitializeCriticalSection( &ApiCriticalSection );
 }
@@ -35,19 +37,28 @@
 DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     COMM_DHCP_REPLY Reply;
     PDHCP_ADAPTER Adapter;
-
-    ApiLock();
-
-    Adapter = AdapterFindIndex( Req->AdapterIndex );
-
-    Reply.Reply = Adapter ? 1 : 0;
-
-    if( Adapter ) {
+    struct protocol* proto;
+
+    ApiLock();
+
+    Adapter = AdapterFindIndex( Req->AdapterIndex );
+
+    Reply.Reply = Adapter ? 1 : 0;
+
+    if( Adapter ) {
+        proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
+        if (proto)
+            remove_protocol(proto);
+
         add_protocol( Adapter->DhclientInfo.name,
                       Adapter->DhclientInfo.rfdesc, got_one,
                       &Adapter->DhclientInfo );
-	Adapter->DhclientInfo.client->state = S_INIT;
-	state_reboot(&Adapter->DhclientInfo);
+
+        Adapter->DhclientInfo.client->state = S_INIT;
+        state_reboot(&Adapter->DhclientInfo);
+
+        if (AdapterStateChangedEvent != NULL)
+            SetEvent(AdapterStateChangedEvent);
     }
 
     ApiUnlock();
@@ -95,6 +106,12 @@
         proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
         if (proto)
            remove_protocol(proto);
+
+        Adapter->DhclientInfo.client->active = NULL;
+        Adapter->DhclientInfo.client->state = S_INIT;
+
+        if (AdapterStateChangedEvent != NULL)
+            SetEvent(AdapterStateChangedEvent);
     }
 
     ApiUnlock();
@@ -105,6 +122,7 @@
 DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     COMM_DHCP_REPLY Reply;
     PDHCP_ADAPTER Adapter;
+    struct protocol* proto;
 
     ApiLock();
 
@@ -118,11 +136,19 @@
 
     Reply.Reply = 1;
 
+    proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
+    if (proto)
+        remove_protocol(proto);
+
     add_protocol( Adapter->DhclientInfo.name,
                   Adapter->DhclientInfo.rfdesc, got_one,
                   &Adapter->DhclientInfo );
+
     Adapter->DhclientInfo.client->state = S_INIT;
     state_reboot(&Adapter->DhclientInfo);
+
+    if (AdapterStateChangedEvent != NULL)
+        SetEvent(AdapterStateChangedEvent);
 
     ApiUnlock();
 
@@ -154,6 +180,9 @@
                                &Adapter->NteContext,
                                &Adapter->NteInstance );
         Reply.Reply = NT_SUCCESS(Status);
+
+        if (AdapterStateChangedEvent != NULL)
+            SetEvent(AdapterStateChangedEvent);
     }
 
     ApiUnlock();

Modified: branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dispatch.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dispatch.c?rev=54912&r1=54911&r2=54912&view=diff
==============================================================================
--- branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dispatch.c [iso-8859-1] (original)
+++ branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dispatch.c [iso-8859-1] Wed Jan 11 22:24:49 2012
@@ -47,6 +47,8 @@
 //#include <ifaddrs.h>
 //#include <poll.h>
 
+extern SOCKET DhcpSocket;
+HANDLE AdapterStateChangedEvent = NULL;
 struct protocol *protocols = NULL;
 struct timeout *timeouts = NULL;
 static struct timeout *free_timeouts = NULL;
@@ -63,17 +65,19 @@
 void
 dispatch(void)
 {
-    int count, to_msec, err;
+    int count, to_msec;
     struct protocol *l;
-    fd_set fds;
     time_t howlong, cur_time;
-    struct timeval timeval;
-    HANDLE AdapterStateChangedEvent;
-
-    AdapterStateChangedEvent = StartAdapterDiscovery();
-    if (!AdapterStateChangedEvent)
+    HANDLE Events[2];
+    int EventCount = 1;
+
+    Events[0] = StartAdapterDiscovery();
+    if (!Events[0])
          return;
-
+    AdapterStateChangedEvent = Events[0];
+    
+    Events[1] = WSA_INVALID_EVENT;
+    
     ApiLock();
 
     do {
@@ -83,7 +87,8 @@
          */
         time(&cur_time);
 
-        if (timeouts) {
+        if (timeouts)
+        {
             struct timeout *t;
 
             if (timeouts->when <= cur_time) {
@@ -105,55 +110,75 @@
             if (howlong > INT_MAX / 1000)
                 howlong = INT_MAX / 1000;
             to_msec = howlong * 1000;
-
-            /* Set up the descriptors to be polled. */
-            FD_ZERO(&fds);
-
-            for (l = protocols; l; l = l->next)
-                 FD_SET(l->fd, &fds);
-
-            /* Wait for a packet or a timeout... XXX */
-            timeval.tv_sec = to_msec / 1000;
-            timeval.tv_usec = to_msec % 1000;
-
-            ApiUnlock();
-
-            count = select(0, &fds, NULL, NULL, &timeval);
-
-            ApiLock();
         }
         else
         {
-            ApiUnlock();
-            WaitForSingleObject(AdapterStateChangedEvent, INFINITE);
-            ApiLock();
-
+            to_msec = INFINITE;
+        }
+
+        if (Events[1] == WSA_INVALID_EVENT && DhcpSocket != INVALID_SOCKET)
+        {
+            Events[1] = WSACreateEvent();
+            if (Events[1] != WSA_INVALID_EVENT)
+            {
+                count = WSAEventSelect(DhcpSocket, Events[1], FD_READ | FD_CLOSE);
+                if (count != NO_ERROR)
+                {
+                    WSACloseEvent(Events[1]);
+                    Events[1] = WSA_INVALID_EVENT;
+                }
+                else
+                {
+                    EventCount = 2;
+                }
+            }
+        }
+        else if (Events[1] != WSA_INVALID_EVENT && DhcpSocket == INVALID_SOCKET)
+        {
+            WSACloseEvent(Events[1]);
+            Events[1] = WSA_INVALID_EVENT;
+
+            EventCount = 1;
+        }
+
+        ApiUnlock();
+        count = WaitForMultipleObjects(EventCount,
+                                       Events,
+                                       FALSE,
+                                       to_msec);
+        ApiLock();
+        if (count == WAIT_OBJECT_0)
+        {
+            /* Adapter state change */
             continue;
         }
-
-        DH_DbgPrint(MID_TRACE,("Select: %d\n", count));
-
-        /* Not likely to be transitory... */
-        if (count == SOCKET_ERROR) {
-            err = WSAGetLastError();
-            error("poll: %d", err);
-            break;
+        else if (count == WAIT_OBJECT_0 + 1)
+        {
+            /* Packet received */
+            
+            /* WSA events are manual reset events */
+            WSAResetEvent(Events[1]);
+        }
+        else
+        {
+            /* Timeout */
+            continue;
         }
 
         for (l = protocols; l; l = l->next) {
             struct interface_info *ip;
             ip = l->local;
-            if (FD_ISSET(l->fd, &fds)) {
-                if (ip && (l->handler != got_one ||
-                           !ip->dead)) {
-                    DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
-                    (*(l->handler))(l);
-                }
+            if (ip && (l->handler != got_one ||
+                        !ip->dead)) {
+                DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
+                (*(l->handler))(l);
             }
         }
     } while (1);
 
-    CloseHandle(AdapterStateChangedEvent);
+    AdapterStateChangedEvent = NULL;
+    CloseHandle(Events[0]);
+    WSACloseEvent(Events[1]);
 
     ApiUnlock();
 }




More information about the Ros-diffs mailing list