]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- Fix DHCPRELEASE to do the right thing.
authorTed Lemon <source@isc.org>
Thu, 5 Apr 2001 20:42:11 +0000 (20:42 +0000)
committerTed Lemon <source@isc.org>
Thu, 5 Apr 2001 20:42:11 +0000 (20:42 +0000)
- If the interface goes away, stop trying to get an address on it.

client/dhclient.c

index 56b9386d69ecd96eb670c1fe31722a6a3d84f397..3500bc6f3c1df08e7e29017b4dbcac6f6379e99d 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static char ocopyright[] =
-"$Id: dhclient.c,v 1.125 2001/03/22 06:59:09 mellon Exp $ Copyright (c) 1995-2001 Internet Software Consortium.  All rights reserved.\n";
+"$Id: dhclient.c,v 1.126 2001/04/05 20:42:11 mellon Exp $ Copyright (c) 1995-2001 Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -135,6 +135,7 @@ int main (argc, argv, envp)
 
        dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
        dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
+       dhcp_interface_startup_hook = dhclient_interface_startup_hook;
 
        for (i = 1; i < argc; i++) {
                if (!strcmp (argv [i], "-r")) {
@@ -1681,7 +1682,6 @@ void send_release (cpp)
        destination.sin_len = sizeof destination;
 #endif
 
-
        /* Set the lease to end now, so that we don't accidentally
           reuse it if we restart before the old expiry time. */
        client -> active -> expiry =
@@ -2681,6 +2681,7 @@ void client_location_changed ()
 
                              case S_INIT:
                              case S_REBINDING:
+                             case S_STOPPED:
                                break;
                        }
                        client -> state = S_INIT;
@@ -2695,9 +2696,7 @@ void do_release(client)
        struct data_string ds;
        struct option_cache *oc;
 
-       /* make_request doesn't initialize xid because it normally comes
-          from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
-          so pick an xid now. */
+       /* Pick a random xid. */
        client -> xid = random ();
 
        /* is there even a lease to release? */
@@ -2742,13 +2741,19 @@ void do_release(client)
                script_go (client);
        }
 
-       /* remove the timeouts for this client */
-       cancel_timeout (0, client);
+       /* Cancel any timeouts. */
+       cancel_timeout (state_bound, client);
+       cancel_timeout (send_discover, client);
+       cancel_timeout (state_init, client);
+       cancel_timeout (send_request, client);
+       cancel_timeout (state_reboot, client);
+       client -> state = S_STOPPED;
 }
 
 int dhclient_interface_shutdown_hook (struct interface_info *interface)
 {
        do_release (interface -> client);
+
        return 1;
 }
 
@@ -2795,6 +2800,58 @@ int dhclient_interface_discovery_hook (struct interface_info *tmp)
        return 1;
 }
 
+isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
+{
+       struct interface_info *ip;
+       struct client_state *client;
+
+       /* This code needs some rethinking.   It doesn't test against
+          a signal name, and it just kind of bulls into doing something
+          that may or may not be appropriate. */
+
+       if (interfaces) {
+               interface_reference (&interface -> next, interfaces, MDL);
+               interface_dereference (&interfaces, MDL);
+       }
+       interface_reference (&interfaces, interface, MDL);
+
+       discover_interfaces (DISCOVER_UNCONFIGURED);
+
+       for (ip = interfaces; ip; ip = ip -> next) {
+               /* If interfaces were specified, don't configure
+                  interfaces that weren't specified! */
+               if (ip -> flags & INTERFACE_RUNNING ||
+                  (ip -> flags & (INTERFACE_REQUESTED |
+                                    INTERFACE_AUTOMATIC)) !=
+                    INTERFACE_REQUESTED)
+                       continue;
+               script_init (ip -> client,
+                            "PREINIT", (struct string_list *)0);
+               if (ip -> client -> alias)
+                       script_write_params (ip -> client, "alias_",
+                                            ip -> client -> alias);
+               script_go (ip -> client);
+       }
+       
+       discover_interfaces (interfaces_requested
+                            ? DISCOVER_REQUESTED
+                            : DISCOVER_RUNNING);
+
+       for (ip = interfaces; ip; ip = ip -> next) {
+               if (ip -> flags & INTERFACE_RUNNING)
+                       continue;
+               ip -> flags |= INTERFACE_RUNNING;
+               for (client = ip -> client; client; client = client -> next) {
+                       client -> state = S_INIT;
+                       /* Set up a timeout to start the initialization
+                          process. */
+                       add_timeout (cur_time + random () % 5,
+                                    state_reboot, client, 0, 0);
+               }
+       }
+       return ISC_R_SUCCESS;
+}
+
 /* The client should never receive a relay agent information option,
    so if it does, log it and discard it. */