]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[#76] Added dhcp_timed_connect() function
authorThomas Markwalder <tmark@isc.org>
Mon, 10 Feb 2020 13:29:22 +0000 (08:29 -0500)
committerThomas Markwalder <tmark@isc.org>
Thu, 20 Jan 2022 21:31:28 +0000 (16:31 -0500)
dhcpctl/cltest2.c
    Added use of dhcp_timed_connect()

dhcpctl/dhcpctl.3
    Added entry for dhcp_timed_connect()

dhcpctl/dhcpctl.*
    dhcpctl_timed_connect() - new function
    dhcp_timed_wait_for_completion() - corrected commentary

dhcpctl/cltest2.c
dhcpctl/dhcpctl.3
dhcpctl/dhcpctl.c
dhcpctl/dhcpctl.h

index 26249a3e43ffe529d07f1cefa3ad6d6d6e945206..821441cde60f7763276cbdf90c37cfc01fc4413b 100644 (file)
@@ -68,6 +68,9 @@ void print_object(char *msg, dhcpctl_handle handle);
  * 5. Disconnect
  * 6. Reconnect
  * 7. Refresh the host object
+ * 8. Disconnect
+ * 9. Time connect
+ * 10. Time connect retry
  *
  * Note that this program tests dhcpctl_timed_wait_for_completion() by calling
  * it with extremely small timeouts.
@@ -143,7 +146,6 @@ int main (argc, argv)
             break;
     }
 
-
        /* Now we'll test disconnect */
        status = dhcpctl_disconnect(&connection, 0);
        fail_on_error(status, "can't disconnect");
@@ -161,6 +163,29 @@ int main (argc, argv)
 
     print_object("After reconnect/refresh", host);
 
+       /* Now we'll disconnect */
+       status = dhcpctl_disconnect(&connection, 0);
+       fail_on_error(status, "can't disconnect");
+
+    /* Try a timed connect */
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 1;
+       status = dhcpctl_timed_connect (&connection, ip_address, port, 0, &timeout);
+
+    /* Try again if we time out */
+    if (status == ISC_R_TIMEDOUT) {
+        printf ("Retry timed connect\n");
+        timeout.tv_sec = 10;
+           status = dhcpctl_timed_connect (&connection, ip_address, port, 0,
+                                        &timeout);
+    }
+
+    fail_on_error(status ,"can't reconnect");
+
+    /* Lastly we'll disconnect to clean up */
+       status = dhcpctl_disconnect(&connection, 0);
+    fail_on_error(status ,"can't disconnect");
+
        exit (0);
 }
 
index 9b2612095aba89eecde97e8247a274b4b18d7fb5..48fd728c7215382f238e38b1abab48a9592c308b 100644 (file)
 .\"
 .\"
 .Ft dhcpctl_status
+.Fo dhcpctl_timed_connect
+.Fa "dhcpctl_handle *cxn"
+.Fa "const char *host"
+.Fa "int port"
+.Fa "dhcpctl_handle auth"
+.Fa "dhcpctl_status *status"
+.Fc
+.\"
+.\"
+.\"
+.Ft dhcpctl_status
 .Fo dhcpctl_disconnect
 .Fa "dhcpctl_handle *cxn"
 .Fa "int force"
@@ -78,8 +89,8 @@
 .Ft dhcpctl_status
 .Fo dhcpctl_timed_wait_for_completion
 .Fa "dhcpctl_handle object"
-.Fa "struct timeval *timeout"
 .Fa "dhcpctl_status *status"
+.Fa "struct timeval *timeout"
 .Fc
 .\"
 .\"
@@ -251,7 +262,33 @@ OMAPI port). No authentication is used for the connection.
 .\"
 .\"
 .Pp
+.Fn dhcpctl_timed_connect
+opens a connection to the DHCP server at the given host and port. If an
+authenticator has been created for the connection, then it is given as the 4th
+argument. On a successful return the address pointed at by the first
+argument will have a new connection object assigned to it.
+How long the function waits for complete the connection is dictated by the value
+of the parameter, \fBtimeout\fR. If the value is null, it will wait indefinetly
+Otherwise it will wait for the amount of time specified by \fBtimeout\fR
+(tv_sec:tv_usec). Values of zero for both fields are valid but not recommended.
+An example is shown below:
+.Pp
+For example:
+.Bd -literal -offset indent
+struct timeval timeout;
+timeout.tv_sec = 5;   /* wait for 5 seconds */
+timeout.tv_usec = 0;
 
+s = dhcpctl_connect(&cxn, "127.0.0.1", 7911, NULL, &timeout);
+.Ed
+.Pp
+connects to the DHCP server on the localhost via port 7911 (the standard
+OMAPI port). No authentication is used for the connection.  It allows
+5 seconds for the connect to complete.
+.\"
+.\"
+.\"
+.Pp
 .Fn dhcpctl_disconnect
 closes the open connection specified by the first parameter, \fBcxn\fR.  Note
 that this call will free the connection object and \fBcxn\fR will be set to
@@ -295,19 +332,19 @@ to the server is lost.
 
 .Fn dhcpctl_timed_wait_for_completion
 flushes a pending message to the server and waits for the response.  How long
-the function waits for a response is dictated by the value of the second
+the function waits for a response is dictated by the value of the third
 parameter, \fBtimeout\fR. If the value is null, it will wait indefinetly or
 until the connection is lost. Otherwise it will wait for the amount of time
 specified by \fBtimeout\fR (tv_sec:tv_usec). Values of zero for both fields
 are valid but not recommended.  The result of the request as processed on the
-server is returned via the third parameter.  An example is shown below:
+server is returned via the second parameter.  An example is shown below:
 .Bd -literal -offset indent
 
 struct timeval timeout;
 timeout.tv_sec = 5;   /* wait for 5 seconds */
 timeout.tv_usec = 0;
 
-s = dhcpctl_wait_for_completion(cxn, &timeout, &wv);
+s = dhcpctl_wait_for_completion(cxn, &wv, &timeout);
 if (s != ISC_R_SUCCESS) {
        local_failure(s);
 } else if (wv != ISC_R_SUCCESS) {
index 845fa18c6f03131b47e5f3c126c1b81022fe97ab..924db321d5fe8f11ebe904b6c48aeb95a346db2a 100644 (file)
@@ -31,7 +31,6 @@
 #include "dhcpctl.h"
 #include <sys/time.h>
 
-
 /* #define DEBUG_DHCPCTL  1 */
 
 omapi_object_type_t *dhcpctl_callback_type;
@@ -144,6 +143,59 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
        return status;
 }
 
+/* dhcpctl_timed_connect
+
+   synchronous
+   returns nonzero status code if it didn't connect, zero otherwise
+   stores connection handle through connection, which can be used
+   for subsequent access to the specified server.
+   server_name is the name of the server, and port is the TCP
+   port on which it is listening.
+   authinfo is the handle to an object containing authentication
+   information.
+   How long the function waits for the connection to complete is
+   dictated by the value of the parameter, t. If the value is nul,
+   it will wait indefinetly. Otherwise it will wait for the amount
+   of time specified by t (tv_sec:tv_usec). Values of zero for both
+   fields are valid but not recommended. */
+dhcpctl_status dhcpctl_timed_connect (dhcpctl_handle *connection,
+                                     const char *server_name, int port,
+                                     dhcpctl_handle authinfo,
+                                     struct timeval *t)
+{
+       isc_result_t status;
+#ifdef DEBUG_DHCPCTL
+       log_debug("dhcpctl_timed_connect(%s:%d)", server_name, port);
+#endif
+       status = omapi_generic_new (connection, MDL);
+       if (status != ISC_R_SUCCESS) {
+               return status;
+       }
+
+       status = omapi_protocol_connect (*connection, server_name,
+                                        (unsigned)port, authinfo);
+
+       if (status == ISC_R_SUCCESS) {
+               return status;
+       }
+
+       if (status == DHCP_R_INCOMPLETE) {
+               isc_result_t wait_status = ISC_R_SUCCESS;
+
+               /* Wait for it to complete */
+               status = dhcpctl_timed_wait_for_completion(*connection,
+                                                          &wait_status, t);
+               if (status == ISC_R_SUCCESS) {
+                       status = wait_status;
+               }
+       }
+
+       if (status != ISC_R_SUCCESS) {
+               omapi_object_dereference (connection, MDL);
+       }
+       return status;
+}
+
 /* dhcpctl_wait_for_completion
 
    synchronous
@@ -174,15 +226,20 @@ dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
        return ISC_R_SUCCESS;
 }
 
-/* dhcpctl_wait_for_completion
+/* dhcpctl_timed_wait_for_completion
 
    synchronous
    returns zero if the callback completes, a nonzero status if
    there was some problem relating to the wait operation.   The
    status of the queued request will be stored through s, and
    will also be either zero for success or nonzero for some kind
-   of failure.    Never returns until completion or until the
-   connection to the server is lost.   This performs the same
+   of failure.  How long the function waits for a response is
+   dictated by the value of the parameter, t. If the value is nul,
+   it will wait indefinetly or until the connection is lost.
+   Otherwise it will wait for the amount of time specified by t
+  (tv_sec:tv_usec). Values of zero for both fields are valid
+   but not recommended.  The result of the request as processed on the
+   server is returned via the parameter, s.  This performs the same
    function as dhcpctl_set_callback and the subsequent callback,
    for programs that want to do inline execution instead of using
    callbacks. */
@@ -196,7 +253,8 @@ dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h,
 
 #ifdef DEBUG_DHCPCTL
         if (t) {
-                log_debug ("dhcpctl_timed_wait_for_completion(%u.%u secs.usecs)",
+               log_debug ("dhcpctl_timed_wait_for_completion"
+                          "(%u.%u secs.usecs)",
                            (unsigned int)(t->tv_sec),
                            (unsigned int)(t->tv_usec));
         } else {
@@ -212,10 +270,14 @@ dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h,
        }
 
        status = omapi_wait_for_completion (h, (t ? &adjusted_t : 0));
-       if (status != ISC_R_SUCCESS)
+       if (status != ISC_R_SUCCESS) {
                return status;
-       if (h -> type == dhcpctl_remote_type)
-               *s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
+       }
+
+       if (h->type == dhcpctl_remote_type) {
+               *s = ((dhcpctl_remote_object_t *)h)->waitstatus;
+       }
+
        return ISC_R_SUCCESS;
 }
 
@@ -309,7 +371,7 @@ dhcpctl_status dhcpctl_get_boolean (int *result,
        isc_result_t status;
        dhcpctl_data_string data = (dhcpctl_data_string)0;
        int rv;
-       
+
 #ifdef DEBUG_DHCPCTL
        log_debug("dhcpctl_get_boolean(%s)", value_name);
 #endif
@@ -703,8 +765,8 @@ dhcpctl_status dhcpctl_disconnect (dhcpctl_handle *connection,
 #ifdef DEBUG_DHCPCTL
        log_debug("dhcpctl_disconnect()");
 #endif
-       if (!connection || !((*connection)->outer) || 
-           !((*connection)->outer->type) || 
+       if (!connection || !((*connection)->outer) ||
+           !((*connection)->outer->type) ||
             ((*connection)->outer->type != omapi_type_protocol) ||
             !((*connection)->outer->outer)) {
                log_debug("dhcpctl_disconnect detected invalid arg");
index 083ccf1209422c3634953763cfdb27c8fd226188..a356699cbff46ea31a18349c091a95ad5cd0aa53 100644 (file)
@@ -62,6 +62,10 @@ extern omapi_object_type_t *dhcpctl_remote_type;
 dhcpctl_status dhcpctl_initialize (void);
 dhcpctl_status dhcpctl_connect (dhcpctl_handle *,
                                const char *, int, dhcpctl_handle);
+
+dhcpctl_status dhcpctl_timed_connect (dhcpctl_handle *, const char *,
+                                     int, dhcpctl_handle, struct timeval *);
+
 dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle, dhcpctl_status *);
 
 dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h,