diff options
Diffstat (limited to 'server/failover.c')
-rw-r--r-- | server/failover.c | 249 |
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, |