mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-01 23:05:29 +00:00
[#76] Added dhcp_timed_connect() function
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
This commit is contained in:
@@ -68,6 +68,9 @@ void print_object(char *msg, dhcpctl_handle handle);
|
|||||||
* 5. Disconnect
|
* 5. Disconnect
|
||||||
* 6. Reconnect
|
* 6. Reconnect
|
||||||
* 7. Refresh the host object
|
* 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
|
* Note that this program tests dhcpctl_timed_wait_for_completion() by calling
|
||||||
* it with extremely small timeouts.
|
* it with extremely small timeouts.
|
||||||
@@ -143,7 +146,6 @@ int main (argc, argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Now we'll test disconnect */
|
/* Now we'll test disconnect */
|
||||||
status = dhcpctl_disconnect(&connection, 0);
|
status = dhcpctl_disconnect(&connection, 0);
|
||||||
fail_on_error(status, "can't disconnect");
|
fail_on_error(status, "can't disconnect");
|
||||||
@@ -161,6 +163,29 @@ int main (argc, argv)
|
|||||||
|
|
||||||
print_object("After reconnect/refresh", host);
|
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);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -60,6 +60,17 @@
|
|||||||
.\"
|
.\"
|
||||||
.\"
|
.\"
|
||||||
.Ft dhcpctl_status
|
.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
|
.Fo dhcpctl_disconnect
|
||||||
.Fa "dhcpctl_handle *cxn"
|
.Fa "dhcpctl_handle *cxn"
|
||||||
.Fa "int force"
|
.Fa "int force"
|
||||||
@@ -78,8 +89,8 @@
|
|||||||
.Ft dhcpctl_status
|
.Ft dhcpctl_status
|
||||||
.Fo dhcpctl_timed_wait_for_completion
|
.Fo dhcpctl_timed_wait_for_completion
|
||||||
.Fa "dhcpctl_handle object"
|
.Fa "dhcpctl_handle object"
|
||||||
.Fa "struct timeval *timeout"
|
|
||||||
.Fa "dhcpctl_status *status"
|
.Fa "dhcpctl_status *status"
|
||||||
|
.Fa "struct timeval *timeout"
|
||||||
.Fc
|
.Fc
|
||||||
.\"
|
.\"
|
||||||
.\"
|
.\"
|
||||||
@@ -251,7 +262,33 @@ OMAPI port). No authentication is used for the connection.
|
|||||||
.\"
|
.\"
|
||||||
.\"
|
.\"
|
||||||
.Pp
|
.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
|
.Fn dhcpctl_disconnect
|
||||||
closes the open connection specified by the first parameter, \fBcxn\fR. Note
|
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
|
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
|
.Fn dhcpctl_timed_wait_for_completion
|
||||||
flushes a pending message to the server and waits for the response. How long
|
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
|
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
|
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
|
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
|
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
|
.Bd -literal -offset indent
|
||||||
|
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = 5; /* wait for 5 seconds */
|
timeout.tv_sec = 5; /* wait for 5 seconds */
|
||||||
timeout.tv_usec = 0;
|
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) {
|
if (s != ISC_R_SUCCESS) {
|
||||||
local_failure(s);
|
local_failure(s);
|
||||||
} else if (wv != ISC_R_SUCCESS) {
|
} else if (wv != ISC_R_SUCCESS) {
|
||||||
|
@@ -31,7 +31,6 @@
|
|||||||
#include "dhcpctl.h"
|
#include "dhcpctl.h"
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
||||||
/* #define DEBUG_DHCPCTL 1 */
|
/* #define DEBUG_DHCPCTL 1 */
|
||||||
|
|
||||||
omapi_object_type_t *dhcpctl_callback_type;
|
omapi_object_type_t *dhcpctl_callback_type;
|
||||||
@@ -144,6 +143,59 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
|
|||||||
return status;
|
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
|
/* dhcpctl_wait_for_completion
|
||||||
|
|
||||||
synchronous
|
synchronous
|
||||||
@@ -174,15 +226,20 @@ dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
|
|||||||
return ISC_R_SUCCESS;
|
return ISC_R_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dhcpctl_wait_for_completion
|
/* dhcpctl_timed_wait_for_completion
|
||||||
|
|
||||||
synchronous
|
synchronous
|
||||||
returns zero if the callback completes, a nonzero status if
|
returns zero if the callback completes, a nonzero status if
|
||||||
there was some problem relating to the wait operation. The
|
there was some problem relating to the wait operation. The
|
||||||
status of the queued request will be stored through s, and
|
status of the queued request will be stored through s, and
|
||||||
will also be either zero for success or nonzero for some kind
|
will also be either zero for success or nonzero for some kind
|
||||||
of failure. Never returns until completion or until the
|
of failure. How long the function waits for a response is
|
||||||
connection to the server is lost. This performs the same
|
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,
|
function as dhcpctl_set_callback and the subsequent callback,
|
||||||
for programs that want to do inline execution instead of using
|
for programs that want to do inline execution instead of using
|
||||||
callbacks. */
|
callbacks. */
|
||||||
@@ -196,7 +253,8 @@ dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h,
|
|||||||
|
|
||||||
#ifdef DEBUG_DHCPCTL
|
#ifdef DEBUG_DHCPCTL
|
||||||
if (t) {
|
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_sec),
|
||||||
(unsigned int)(t->tv_usec));
|
(unsigned int)(t->tv_usec));
|
||||||
} else {
|
} 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));
|
status = omapi_wait_for_completion (h, (t ? &adjusted_t : 0));
|
||||||
if (status != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS) {
|
||||||
return status;
|
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;
|
return ISC_R_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +371,7 @@ dhcpctl_status dhcpctl_get_boolean (int *result,
|
|||||||
isc_result_t status;
|
isc_result_t status;
|
||||||
dhcpctl_data_string data = (dhcpctl_data_string)0;
|
dhcpctl_data_string data = (dhcpctl_data_string)0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
#ifdef DEBUG_DHCPCTL
|
#ifdef DEBUG_DHCPCTL
|
||||||
log_debug("dhcpctl_get_boolean(%s)", value_name);
|
log_debug("dhcpctl_get_boolean(%s)", value_name);
|
||||||
#endif
|
#endif
|
||||||
@@ -703,8 +765,8 @@ dhcpctl_status dhcpctl_disconnect (dhcpctl_handle *connection,
|
|||||||
#ifdef DEBUG_DHCPCTL
|
#ifdef DEBUG_DHCPCTL
|
||||||
log_debug("dhcpctl_disconnect()");
|
log_debug("dhcpctl_disconnect()");
|
||||||
#endif
|
#endif
|
||||||
if (!connection || !((*connection)->outer) ||
|
if (!connection || !((*connection)->outer) ||
|
||||||
!((*connection)->outer->type) ||
|
!((*connection)->outer->type) ||
|
||||||
((*connection)->outer->type != omapi_type_protocol) ||
|
((*connection)->outer->type != omapi_type_protocol) ||
|
||||||
!((*connection)->outer->outer)) {
|
!((*connection)->outer->outer)) {
|
||||||
log_debug("dhcpctl_disconnect detected invalid arg");
|
log_debug("dhcpctl_disconnect detected invalid arg");
|
||||||
|
@@ -62,6 +62,10 @@ extern omapi_object_type_t *dhcpctl_remote_type;
|
|||||||
dhcpctl_status dhcpctl_initialize (void);
|
dhcpctl_status dhcpctl_initialize (void);
|
||||||
dhcpctl_status dhcpctl_connect (dhcpctl_handle *,
|
dhcpctl_status dhcpctl_connect (dhcpctl_handle *,
|
||||||
const char *, int, 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_wait_for_completion (dhcpctl_handle, dhcpctl_status *);
|
||||||
|
|
||||||
dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h,
|
dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h,
|
||||||
|
Reference in New Issue
Block a user