summaryrefslogtreecommitdiff
path: root/server/failover.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/failover.c')
-rw-r--r--server/failover.c249
1 files changed, 140 insertions, 109 deletions
diff --git a/server/failover.c b/server/failover.c
index 4c221979..1da507b2 100644
--- a/server/failover.c
+++ b/server/failover.c
@@ -22,14 +22,16 @@
#ifndef lint
static char copyright[] =
-"$Id: failover.c,v 1.3 1999/11/14 00:42:57 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium. All rights reserved.\n";
+"$Id: failover.c,v 1.4 1999/11/20 18:36:31 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
+#include <omapip/omapip_p.h>
#if defined (FAILOVER_PROTOCOL)
static struct hash_table *failover_hash;
-static isc_result_t do_a_failover_option (omapi_connection_object_t *,
+static dhcp_failover_state_t *failover_states;
+static isc_result_t do_a_failover_option (omapi_object_t *,
dhcp_failover_link_t *);
void enter_failover_peer (peer)
@@ -70,15 +72,20 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h)
dhcp_failover_link_t *obj;
char *peer_name;
unsigned long port;
- omapi_typed_data_t *value = (omapi_typed_data_t *)0;
+ omapi_value_t *value = (omapi_value_t *)0;
status = omapi_get_value_str (h, (omapi_object_t *)0,
"remote-port", &value);
if (status != ISC_R_SUCCESS)
return status;
-
- status = omapi_get_int_value (&port, value);
- omapi_typed_data_dereference (&value, "dhcp_failover_link_initiate");
+ if (!value -> value) {
+ omapi_value_dereference (&value,
+ "dhcp_failover_link_initiate");
+ return ISC_R_INVALIDARG;
+ }
+
+ status = omapi_get_int_value (&port, value -> value);
+ omapi_value_dereference (&value, "dhcp_failover_link_initiate");
if (status != ISC_R_SUCCESS)
return status;
@@ -86,24 +93,26 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h)
"remote-peer", &value);
if (status != ISC_R_SUCCESS)
return status;
- if (value -> type != omapi_datatype_string &&
- value -> type != omapu_datatype_data) {
- omapi_typed_data_dereference (&value,
- "dhcp_failover_link_initiate");
+ if (!value -> value ||
+ (value -> value -> type != omapi_datatype_string &&
+ value -> value -> type != omapi_datatype_data)) {
+ omapi_value_dereference (&value,
+ "dhcp_failover_link_initiate");
return ISC_R_INVALIDARG;
}
/* Save the name. */
- peer_name = malloc (value -> u.buffer.len + 1);
+ peer_name = malloc (value -> value -> u.buffer.len + 1);
if (!peer_name) {
- omapi_typed_data_dereference (&value,
- "dhcp_failover_link_initiate");
+ omapi_value_dereference (&value,
+ "dhcp_failover_link_initiate");
return ISC_R_NOMEMORY;
}
- memcpy (peer_name, value -> u.buffer.data, value -> u.buffer.len);
- peer_name [value -> u.buffer.len] = 0;
- omapi_typed_data_dereference (&value, "dhcp_failover_link_initiate");
+ memcpy (peer_name, value -> value -> u.buffer.value,
+ value -> value -> u.buffer.len);
+ peer_name [value -> value -> u.buffer.len] = 0;
+ omapi_value_dereference (&value, "dhcp_failover_link_initiate");
obj = (dhcp_failover_link_t *)malloc (sizeof *obj);
if (!obj)
@@ -112,9 +121,9 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h)
obj -> refcnt = 1;
obj -> type = dhcp_type_failover_link;
obj -> peer_name = peer_name;
- obj -> port = port;
+ obj -> peer_port = port;
- status = omapi_connect ((omapi_object_t *)obj, server_name, port);
+ status = omapi_connect ((omapi_object_t *)obj, peer_name, port);
if (status != ISC_R_SUCCESS) {
omapi_object_dereference ((omapi_object_t **)&obj,
"dhcp_failover_link_initiate");
@@ -165,41 +174,50 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
/* Not a signal we recognize? */
if (strcmp (name, "ready")) {
- if (p -> inner && p -> inner -> type -> signal_handler)
- return (*(p -> inner -> type -> signal_handler)) (h,
+ if (h -> inner && h -> inner -> type -> signal_handler)
+ return (*(h -> inner -> type -> signal_handler)) (h,
name,
ap);
return ISC_R_NOTFOUND;
}
- if (!p -> outer || p -> outer -> type != omapi_type_connection)
+ if (!h -> outer || h -> outer -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
- c = p -> outer;
+ c = h -> outer;
/* We get here because we requested that we be woken up after
some number of bytes were read, and that number of bytes
has in fact been read. */
- switch (p -> state) {
+ switch (link -> state) {
case dhcp_flink_start:
- p -> state = dhcp_flink_message_length_wait;
+ link -> state = dhcp_flink_message_length_wait;
if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
break;
case dhcp_flink_message_length_wait:
- p -> state = dhcp_flink_message_wait;
- memset (link -> incoming_message, 0, sizeof (link -> imsg));
- /* Get the length: */
- omapi_connection_get_uint16 (c, &link -> imsg_len);
- link -> imsg_count = 0; /* Bytes read. */
-
- /* Maximum of 2048 bytes in any failover message. */
- if (link -> imsg_len > DHCP_FAILOVER_MAX_MESSAGE_SIZE) {
+ link -> state = dhcp_flink_message_wait;
+ link -> imsg = dmalloc (sizeof (failover_message_t),
+ "dhcp_failover_link_signal");
+ if (!link -> imsg) {
dhcp_flink_fail:
+ if (link -> imsg) {
+ dfree (link -> imsg,
+ "dhcp_failover_link_signal");
+ link -> imsg = (failover_message_t *)0;
+ }
link -> state = dhcp_flink_disconnected;
omapi_disconnect (c, 1);
/* XXX just blow away the protocol state now?
XXX or will disconnect blow it away? */
return ISC_R_UNEXPECTED;
}
+ memset (link -> imsg, 0, sizeof (link -> imsg));
+ /* Get the length: */
+ omapi_connection_get_uint16 (c, &link -> imsg_len);
+ link -> imsg_count = 0; /* Bytes read. */
+
+ /* Maximum of 2048 bytes in any failover message. */
+ if (link -> imsg_len > DHCP_FAILOVER_MAX_MESSAGE_SIZE)
+ goto dhcp_flink_fail;
if ((omapi_connection_require (c, link -> imsg_len)) !=
ISC_R_SUCCESS)
@@ -234,11 +252,11 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
/* Skip over any portions of the message header that we
don't understand. */
- if (link -> payoff - link -> imsg_count) {
+ if (link -> imsg_payoff - link -> imsg_count) {
omapi_connection_copyout ((unsigned char *)0, c,
- (link -> payoff -
+ (link -> imsg_payoff -
link -> imsg_count));
- link -> imsg_count = link -> payoff;
+ link -> imsg_count = link -> imsg_payoff;
}
/* Get transaction ID. */
@@ -264,14 +282,15 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
}
static isc_result_t do_a_failover_option (c, link)
- omapi_connection_object_t *c;
+ omapi_object_t *c;
dhcp_failover_link_t *link;
{
u_int16_t option_code;
u_int16_t option_len;
- char *op;
- int op_size;
- int op_count;
+ unsigned char *op;
+ unsigned op_size;
+ unsigned op_count;
+ int i;
if (link -> imsg_count + 2 > link -> imsg_len) {
log_error ("FAILOVER: message overflow at option code.");
@@ -299,7 +318,7 @@ static isc_result_t do_a_failover_option (c, link)
option_code, option_len);
#endif
omapi_connection_copyout ((unsigned char *)0, c, option_len);
- link -> imsg_count = += option_len;
+ link -> imsg_count += option_len;
return ISC_R_SUCCESS;
}
@@ -320,7 +339,7 @@ static isc_result_t do_a_failover_option (c, link)
}
/* Only accept an option once. */
- if (imsg -> options_present & ft_options [option_code].bit) {
+ if (link -> imsg -> options_present & ft_options [option_code].bit) {
log_error ("FAILOVER: duplicate option %s",
ft_options [option_code].name);
return ISC_R_PROTOCOLERROR;
@@ -335,7 +354,7 @@ static isc_result_t do_a_failover_option (c, link)
if (ft_options [option_code].bit &&
!(fto_allowed [option_code] & ft_options [option_code].bit)) {
omapi_connection_copyout ((unsigned char *)0, c, option_len);
- link -> imsg_count = += option_len;
+ link -> imsg_count += option_len;
return ISC_R_SUCCESS;
}
@@ -346,27 +365,28 @@ static isc_result_t do_a_failover_option (c, link)
we expect the space for them to be preallocated,
and we can just read the data in. */
- op = ((char *)&link -> imsg) + ft_options [option_code].offset;
+ op = ((unsigned char *)&link -> imsg) +
+ ft_options [option_code].offset;
op_size = ft_sizes [ft_options [option_code].type];
op_count = ft_options [option_code].num_present;
- if (option_length != op_size * op_count) {
+ if (option_len != op_size * op_count) {
log_error ("FAILOVER: option size (%d:%d), option %s",
- option_length,
+ option_len,
(ft_sizes [ft_options [option_code].type] *
ft_options [option_code].num_present),
ft_options [option_code].name);
return ISC_R_PROTOCOLERROR;
}
} else {
- struct failover_option *fo;
+ failover_option_t *fo;
/* FT_DDNS* are special - one or two bytes of status
followed by the client FQDN. */
if (ft_options [option_code].type == FT_DDNS1 ||
ft_options [option_code].type == FT_DDNS1) {
- struct failover_ddns *ddns =
- ((struct failover_ddns *)
+ ddns_fqdn_t *ddns =
+ ((ddns_fqdn_t *)
(((char *)&link -> imsg) +
ft_options [option_code].offset));
@@ -378,7 +398,7 @@ static isc_result_t do_a_failover_option (c, link)
if (op_count == 1)
ddns -> codes [1] = 0;
op_size = 1;
- op_count = option_length - op_count;
+ op_count = option_len - op_count;
ddns -> length = op_count;
ddns -> data = malloc (op_count);
@@ -393,7 +413,7 @@ static isc_result_t do_a_failover_option (c, link)
omapi_connection_copyout (ddns -> data, c, op_count);
goto out;
}
- } else {
+
/* A zero for num_present means that any number of
elements can appear, so we have to figure out how
many we got from the length of the option, and then
@@ -403,20 +423,20 @@ static isc_result_t do_a_failover_option (c, link)
/* Make sure that option data length is a multiple of the
size of the data type being sent. */
- if (op_size > 1 && option_length % op_size) {
- log_error ("FAILOVER: option_length %d not %s%d",
- option_length, "multiple of ", option_size);
+ if (op_size > 1 && option_len % op_size) {
+ log_error ("FAILOVER: option_len %d not %s%d",
+ option_len, "multiple of ", op_size);
return ISC_R_PROTOCOLERROR;
}
- op_count = option_length / op_size;
+ op_count = option_len / op_size;
- fo = ((struct failover_option *)
+ fo = ((failover_option_t *)
(((char *)&link -> imsg) +
ft_options [option_code].offset));
fo -> count = op_count;
- fo -> data = malloc (option_length);
+ fo -> data = malloc (option_len);
if (!fo -> data) {
log_error ("FAILOVER: no memory getting %s (%d)",
"option data", op_count);
@@ -438,12 +458,12 @@ static isc_result_t do_a_failover_option (c, link)
for (i = 0; i < op_count; i++) {
switch (ft_options [option_code].type) {
case FT_UINT32:
- omapi_connection_get_uint32 (c, op);
+ omapi_connection_get_uint32 (c, (u_int32_t *)op);
op += 4;
break;
case FT_UINT16:
- omapi_connection_get_uint16 (c, op);
+ omapi_connection_get_uint16 (c, (u_int16_t *)op);
op += 2;
break;
@@ -458,7 +478,7 @@ static isc_result_t do_a_failover_option (c, link)
}
out:
/* Remember that we got this option. */
- link -> options_present |= ft_options [option_code].bit;
+ link -> imsg -> options_present |= ft_options [option_code].bit;
return ISC_R_SUCCESS;
}
@@ -471,7 +491,7 @@ isc_result_t dhcp_failover_link_set_value (omapi_object_t *h,
return ISC_R_INVALIDARG;
/* Never valid to set these. */
- if (!omapi_ds_strcmp (name, "port") ||
+ if (!omapi_ds_strcmp (name, "link-port") ||
!omapi_ds_strcmp (name, "link-name") ||
!omapi_ds_strcmp (name, "link-state"))
return ISC_R_NOPERM;
@@ -493,8 +513,9 @@ isc_result_t dhcp_failover_link_get_value (omapi_object_t *h,
return ISC_R_INVALIDARG;
link = (dhcp_failover_link_t *)h;
- if (!omapi_ds_strcmp (name, "port")) {
- return omapi_make_int_value (value, name, link -> port,
+ if (!omapi_ds_strcmp (name, "link-port")) {
+ return omapi_make_int_value (value, name,
+ (int)link -> peer_port,
"dhcp_failover_link_get_value");
} else if (!omapi_ds_strcmp (name, "link-name")) {
return omapi_make_string_value
@@ -502,7 +523,7 @@ isc_result_t dhcp_failover_link_get_value (omapi_object_t *h,
"dhcp_failover_link_get_value");
} else if (!omapi_ds_strcmp (name, "link-state")) {
if (link -> state < 0 ||
- link -> state >= dhcp_failover_link_state_max)
+ link -> state >= dhcp_flink_state_max)
return omapi_make_string_value
(value, name, "invalid link state",
"dhcp_failover_link_get_value");
@@ -520,13 +541,14 @@ isc_result_t dhcp_failover_link_get_value (omapi_object_t *h,
isc_result_t dhcp_failover_link_destroy (omapi_object_t *h, const char *name)
{
- dhcp_failover_link_t *p;
+ dhcp_failover_link_t *link;
if (h -> type != dhcp_type_failover_link)
return ISC_R_INVALIDARG;
- p = (dhcp_failover_link_object_t *)h;
- if (p -> message)
- omapi_object_dereference ((omapi_object_t **)&p -> message,
- name);
+ link = (dhcp_failover_link_t *)h;
+ if (link -> imsg) {
+ dfree (link -> imsg, "dhcp_failover_link_destroy");
+ link -> imsg = (failover_message_t *)0;
+ }
return ISC_R_SUCCESS;
}
@@ -535,21 +557,22 @@ isc_result_t dhcp_failover_link_destroy (omapi_object_t *h, const char *name)
isc_result_t dhcp_failover_link_stuff_values (omapi_object_t *c,
omapi_object_t *id,
- omapi_object_t *p)
+ omapi_object_t *l)
{
dhcp_failover_link_t *link;
+ isc_result_t status;
- if (h -> type != omapi_type_protocol)
+ if (l -> type != dhcp_type_failover_link)
return ISC_R_INVALIDARG;
- link = (dhcp_failover_link_t *)h;
+ link = (dhcp_failover_link_t *)l;
- status = omapi_connection_put_name (c, "port");
+ status = omapi_connection_put_name (c, "link-port");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_put_uint32 (c, sizeof (int));
+ status = omapi_connection_put_uint32 (c, sizeof (int));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_put_uint32 (c, link -> port);
+ status = omapi_connection_put_uint32 (c, link -> peer_port);
if (status != ISC_R_SUCCESS)
return status;
@@ -564,7 +587,7 @@ isc_result_t dhcp_failover_link_stuff_values (omapi_object_t *c,
if (status != ISC_R_SUCCESS)
return status;
if (link -> state < 0 ||
- link -> state >= dhcp_failover_link_state_max)
+ link -> state >= dhcp_flink_state_max)
status = omapi_connection_put_string (c, "invalid link state");
else
status = (omapi_connection_put_string
@@ -572,19 +595,19 @@ isc_result_t dhcp_failover_link_stuff_values (omapi_object_t *c,
if (status != ISC_R_SUCCESS)
return status;
- if (p -> inner && p -> inner -> type -> stuff_values)
- return (*(p -> inner -> type -> stuff_values)) (c, id,
- p -> inner);
+ if (link -> inner && link -> inner -> type -> stuff_values)
+ return (*(link -> inner -> type -> stuff_values)) (c, id,
+ link -> inner);
return ISC_R_SUCCESS;
}
/* Set up a listener for the omapi protocol. The handle stored points to
a listener object, not a protocol object. */
-isc_result_t dhcp_failover_listen (omapi_object_t *h);
+isc_result_t dhcp_failover_listen (omapi_object_t *h)
{
isc_result_t status;
- dhcp_failover_listener_object_t *obj;
+ dhcp_failover_listener_t *obj;
unsigned long port;
omapi_value_t *value = (omapi_value_t *)0;
@@ -592,19 +615,23 @@ isc_result_t dhcp_failover_listen (omapi_object_t *h);
"local-port", &value);
if (status != ISC_R_SUCCESS)
return status;
+ if (!value -> value) {
+ omapi_value_dereference (&value, "dhcp_failover_listen");
+ return ISC_R_INVALIDARG;
+ }
- status = omapi_get_int_value (&port, value);
- omapi_typed_data_dereference (&value, "dhcp_failover_listen");
+ status = omapi_get_int_value (&port, value -> value);
+ omapi_value_dereference (&value, "dhcp_failover_listen");
if (status != ISC_R_SUCCESS)
return status;
- obj = (dhcp_failover_listener_object_t *)malloc (sizeof *obj);
+ obj = (dhcp_failover_listener_t *)malloc (sizeof *obj);
if (!obj)
return ISC_R_NOMEMORY;
memset (obj, 0, sizeof *obj);
obj -> refcnt = 1;
obj -> type = dhcp_type_failover_listener;
- obj -> port = port;
+ obj -> local_port = port;
status = omapi_listen ((omapi_object_t *)obj, port, 1);
omapi_object_dereference ((omapi_object_t **)&obj,
@@ -638,14 +665,14 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o,
{
isc_result_t status;
omapi_connection_object_t *c;
- omapi_protocol_object_t *obj;
- dhcp_failover_listener_object_t *p;
- dhcp_failover_state_object_t *state;
+ dhcp_failover_link_t *obj;
+ dhcp_failover_listener_t *p;
+ dhcp_failover_state_t *state;
char *peer_name;
if (!o || o -> type != dhcp_type_failover_listener)
return ISC_R_INVALIDARG;
- p = (dhcp_failover_listener_object_t *)o;
+ p = (dhcp_failover_listener_t *)o;
/* Not a signal we recognize? */
if (strcmp (name, "connect")) {
@@ -661,13 +688,13 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o,
/* See if we can find a secondary failover_state object that
matches this connection. */
- for (state = states; state; state = state -> next) {
+ for (state = failover_states; state; state = state -> next) {
struct hostent *he;
int hix;
struct in_addr ia;
if (inet_aton (state -> remote_peer, &ia)) {
- if (ia == c -> remote_addr.sin_addr)
+ if (ia.s_addr == c -> remote_addr.sin_addr.s_addr)
break;
} else {
he = gethostbyname (state -> remote_peer);
@@ -695,26 +722,26 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o,
return ISC_R_INVALIDARG;
}
- obj = (omapi_protocol_object_t *)malloc (sizeof *obj);
+ obj = (dhcp_failover_link_t *)malloc (sizeof *obj);
if (!obj)
return ISC_R_NOMEMORY;
memset (obj, 0, sizeof *obj);
obj -> refcnt = 1;
- obj -> type = omapi_type_protocol;
+ obj -> type = dhcp_type_failover_link;
peer_name = malloc (strlen (state -> remote_peer) + 1);
if (!peer_name)
return ISC_R_NOMEMORY;
strcpy (peer_name, state -> remote_peer);
obj -> peer_name = peer_name;
- obj -> port = ntohs (c -> remote_addr.sin_port);
+ obj -> peer_port = ntohs (c -> remote_addr.sin_port);
- status = omapi_object_reference (&obj -> outer, c,
+ status = omapi_object_reference (&obj -> outer, (omapi_object_t *)c,
"dhcp_failover_listener_signal");
if (status != ISC_R_SUCCESS) {
lose:
omapi_object_dereference ((omapi_object_t **)&obj,
"dhcp_failover_listener_signal");
- omapi_disconnect (c, 1);
+ omapi_disconnect ((omapi_object_t *)c, 1);
return status;
}
@@ -725,7 +752,7 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o,
/* Notify the master state machine of the arrival of a new
connection. */
- status = omapi_signal (state, "connect", obj);
+ status = omapi_signal_in ((omapi_object_t *)state, "connect", obj);
if (status != ISC_R_SUCCESS)
goto lose;
@@ -790,10 +817,10 @@ isc_result_t dhcp_failover_listener_stuff (omapi_object_t *c,
/* Set up master state machine for the failover protocol. */
-isc_result_t dhcp_failover_register (omapi_object_t *h);
+isc_result_t dhcp_failover_register (omapi_object_t *h)
{
isc_result_t status;
- dhcp_failover_state_object_t *obj;
+ dhcp_failover_state_t *obj;
unsigned long port;
omapi_value_t *value = (omapi_value_t *)0;
@@ -801,19 +828,23 @@ isc_result_t dhcp_failover_register (omapi_object_t *h);
"local-port", &value);
if (status != ISC_R_SUCCESS)
return status;
+ if (!value -> value) {
+ omapi_value_dereference (&value, "dhcp_failover_register");
+ return ISC_R_INVALIDARG;
+ }
- status = omapi_get_int_value (&port, value);
- omapi_typed_data_dereference (&value, "dhcp_failover_listen");
+ status = omapi_get_int_value (&port, value -> value);
+ omapi_value_dereference (&value, "dhcp_failover_listen");
if (status != ISC_R_SUCCESS)
return status;
- obj = (dhcp_failover_state_object_t *)malloc (sizeof *obj);
+ obj = (dhcp_failover_state_t *)malloc (sizeof *obj);
if (!obj)
return ISC_R_NOMEMORY;
memset (obj, 0, sizeof *obj);
obj -> refcnt = 1;
obj -> type = dhcp_type_failover_state;
- obj -> port = port;
+ obj -> listen_port = port;
status = omapi_listen ((omapi_object_t *)obj, port, 1);
omapi_object_dereference ((omapi_object_t **)&obj,
@@ -847,25 +878,25 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
isc_result_t status;
omapi_connection_object_t *c;
omapi_protocol_object_t *obj;
- dhcp_failover_state_object_t *p;
- dhcp_failover_state_object_t *state;
+ dhcp_failover_state_t *state;
char *peer_name;
if (!o || o -> type != dhcp_type_failover_state)
return ISC_R_INVALIDARG;
- p = (dhcp_failover_state_object_t *)o;
+ state = (dhcp_failover_state_t *)o;
/* Not a signal we recognize? */
if (strcmp (name, "connect") &&
strcmp (name, "disconnect") &&
strcmp (name, "message")) {
- if (p -> inner && p -> inner -> type -> signal_handler)
- return (*(p -> inner -> type -> signal_handler))
- (p -> inner, name, ap);
+ if (state -> inner && state -> inner -> type -> signal_handler)
+ return (*(state -> inner -> type -> signal_handler))
+ (state -> inner, name, ap);
return ISC_R_NOTFOUND;
}
-
+ /* Handle all the events we care about... */
+ return ISC_R_SUCCESS;
}
isc_result_t dhcp_failover_state_set_value (omapi_object_t *h,