Author: cgutman
Date: Fri Jan 13 10:03:38 2012
New Revision: 54933
URL:
http://svn.reactos.org/svn/reactos?rev=54933&view=rev
Log:
[DHCPCSVC]
- Fix an issue assigning a private address after the IpReleaseAddress API was used prior
to IpRenewAddress
- Move the IP refresh hack into dhcpcsvc so it now properly refresh IP information after
an adapter is disconnected and reconnected (wired and wireless)
- When a state change occurs (connecting to a different wireless network or unplugging and
plugging in the Ethernet cable), TCP/IP will flush routes and the neighbor cache then set
the IP address to 0.0.0.0. DHCP will detect that IP address (that part is the hack since
we do it via polling instead of events) then send a DHCP discover packet out via the new
network connection. No more ipconfig /renew to get a new DHCP lease after network changes.
It's all seamless now :D
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/dhclient.c
Modified: branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/adapter.c
URL:
http://svn.reactos.org/svn/reactos/branches/wlan-bringup/dll/win32/dhcpcsvc…
==============================================================================
--- 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] Fri Jan 13
10:03:38 2012
@@ -200,6 +200,84 @@
return 0;
}
+BOOL
+IsReconnectHackNeeded(PDHCP_ADAPTER Adapter, const MIB_IFROW* IfEntry)
+{
+ struct protocol *proto;
+ PIP_ADAPTER_INFO AdapterInfo, Orig;
+ DWORD Size, Ret;
+ char *ZeroAddress = "0.0.0.0";
+
+ proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
+
+ if (!proto)
+ return FALSE;
+
+ if (Adapter->DhclientInfo.client->state != S_BOUND)
+ return FALSE;
+
+ ApiUnlock();
+
+ Orig = AdapterInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
+ Size = sizeof(IP_ADAPTER_INFO);
+ if (!AdapterInfo)
+ {
+ ApiLock();
+ return FALSE;
+ }
+
+ Ret = GetAdaptersInfo(AdapterInfo, &Size);
+ if (Ret == ERROR_BUFFER_OVERFLOW)
+ {
+ HeapFree(GetProcessHeap(), 0, AdapterInfo);
+ AdapterInfo = HeapAlloc(GetProcessHeap(), 0, Size);
+ if (!AdapterInfo)
+ {
+ ApiLock();
+ return FALSE;
+ }
+
+ if (GetAdaptersInfo(AdapterInfo, &Size) != NO_ERROR)
+ {
+ ApiLock();
+ return FALSE;
+ }
+
+ Orig = AdapterInfo;
+ for (; AdapterInfo != NULL; AdapterInfo = AdapterInfo->Next)
+ {
+ if (AdapterInfo->Index == IfEntry->dwIndex)
+ break;
+ }
+
+ if (AdapterInfo == NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, Orig);
+ ApiLock();
+ return FALSE;
+ }
+ }
+ else if (Ret != NO_ERROR)
+ {
+ HeapFree(GetProcessHeap(), 0, Orig);
+ ApiLock();
+ return FALSE;
+ }
+
+ if (!strcmp(AdapterInfo->IpAddressList.IpAddress.String, ZeroAddress))
+ {
+ HeapFree(GetProcessHeap(), 0, Orig);
+ ApiLock();
+ return TRUE;
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, Orig);
+ ApiLock();
+ return FALSE;
+ }
+}
+
/*
* XXX Figure out the way to bind a specific adapter to a socket.
*/
@@ -241,12 +319,34 @@
if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr,
Table->table[i].dwPhysAddrLen)))
{
+ proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
+
/* This is an existing adapter */
if (InterfaceConnected(&Table->table[i])) {
/* We're still active so we stay in the list */
ifi = &Adapter->DhclientInfo;
+
+ /* This is a hack because IP helper API sucks */
+ if (IsReconnectHackNeeded(Adapter, &Table->table[i]))
+ {
+ /* This handles a disconnect/reconnect */
+
+ remove_protocol(proto);
+ Adapter->DhclientInfo.client->state = S_INIT;
+
+ /* These are already invalid since the media state change */
+ Adapter->RouterMib.dwForwardNextHop = 0;
+ Adapter->NteContext = 0;
+
+ add_protocol(Adapter->DhclientInfo.name,
+ Adapter->DhclientInfo.rfdesc,
+ got_one, &Adapter->DhclientInfo);
+ state_init(&Adapter->DhclientInfo);
+
+ SetEvent(AdapterStateChangedEvent);
+ }
+
} else {
- proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
if (proto)
remove_protocol(proto);
Modified: branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/api.c
URL:
http://svn.reactos.org/svn/reactos/branches/wlan-bringup/dll/win32/dhcpcsvc…
==============================================================================
--- 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] Fri Jan 13 10:03:38
2012
@@ -101,9 +101,15 @@
if( Adapter ) {
if (Adapter->NteContext)
+ {
DeleteIPAddress( Adapter->NteContext );
+ Adapter->NteContext = 0;
+ }
if (Adapter->RouterMib.dwForwardNextHop)
+ {
DeleteIpForwardEntry( &Adapter->RouterMib );
+ Adapter->RouterMib.dwForwardNextHop = 0;
+ }
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto)
@@ -171,9 +177,15 @@
if( Adapter ) {
if (Adapter->NteContext)
+ {
DeleteIPAddress( Adapter->NteContext );
+ Adapter->NteContext = 0;
+ }
if (Adapter->RouterMib.dwForwardNextHop)
+ {
DeleteIpForwardEntry( &Adapter->RouterMib );
+ Adapter->RouterMib.dwForwardNextHop = 0;
+ }
Adapter->DhclientState.state = S_STATIC;
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
Modified: branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dhclient.c
URL:
http://svn.reactos.org/svn/reactos/branches/wlan-bringup/dll/win32/dhcpcsvc…
==============================================================================
--- branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dhclient.c [iso-8859-1] (original)
+++ branches/wlan-bringup/dll/win32/dhcpcsvc/dhcp/dhclient.c [iso-8859-1] Fri Jan 13
10:03:38 2012
@@ -548,7 +548,10 @@
if( Adapter->NteContext )
+ {
DeleteIPAddress( Adapter->NteContext );
+ Adapter->NteContext = 0;
+ }
/* Set up our default router if we got one from the DHCP server */
if( new_lease->options[DHO_SUBNET_MASK].len ) {
@@ -1007,7 +1010,7 @@
we haven't found anything for this interface yet. */
if (interval > ip->client->config->timeout) {
state_panic(ip);
- return;
+ ip->client->first_sending = cur_time;
}
/* If we're selecting media, try the whole list before doing
@@ -1100,16 +1103,8 @@
{
struct interface_info *ip = ipp;
PDHCP_ADAPTER Adapter = AdapterFindInfo(ip);
- time_t cur_time;
-
- time(&cur_time);
note("No DHCPOFFERS received.");
-
- note("No working leases in persistent database - sleeping.\n");
- ip->client->state = S_INIT;
- add_timeout(cur_time + ip->client->config->retry_interval, state_init,
- ip);
if (!Adapter->NteContext)
{
@@ -1181,7 +1176,10 @@
discover a new address. */
if( Adapter )
+ {
DeleteIPAddress( Adapter->NteContext );
+ Adapter->NteContext = 0;
+ }
ip->client->state = S_INIT;
state_init(ip);