From: Ted Lemon Date: Wed, 5 Jan 2000 18:21:01 +0000 (+0000) Subject: Add lots more pieces of failover support. X-Git-Tag: V3-BETA-2-PATCH-1~463 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd53dc5a99982550eef936c3470294b8f87c1d6b;p=thirdparty%2Fdhcp.git Add lots more pieces of failover support. --- diff --git a/server/failover.c b/server/failover.c index 70e7e640c..7c09fba98 100644 --- a/server/failover.c +++ b/server/failover.c @@ -22,7 +22,7 @@ #ifndef lint static char copyright[] = -"$Id: failover.c,v 1.5 1999/11/23 22:25:07 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: failover.c,v 1.6 2000/01/05 18:21:01 mellon Exp $ Copyright (c) 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -36,19 +36,24 @@ static isc_result_t do_a_failover_option (omapi_object_t *, dhcp_failover_link_t *); void enter_failover_peer (peer) - struct failover_peer *peer; + dhcp_failover_state_t *peer; { - add_hash (failover_hash, peer -> name, 0, (unsigned char *)peer); } -struct failover_peer *find_failover_peer (name) +isc_result_t find_failover_peer (peer, name) + dhcp_failover_state_t **peer; char *name; { - struct failover_peer *peer; + dhcp_failover_state_t *p; - peer = ((struct failover_peer *) - hash_lookup (failover_hash, peer -> name, 0)); - return peer; + for (p = failover_states; p; p = p -> next) + if (!strcmp (name, p -> name)) + break; + if (p) + return omapi_object_reference ((omapi_object_t **)peer, + (omapi_object_t *)p, + "find_failover_peer"); + return ISC_R_NOTFOUND; } /* The failover protocol has three objects associated with it. For @@ -71,49 +76,23 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) { isc_result_t status; dhcp_failover_link_t *obj; - char *peer_name; unsigned long port; omapi_value_t *value = (omapi_value_t *)0; + dhcp_failover_state_t *state; + omapi_object_t *o; + int i; + struct data_string ds; - status = omapi_get_value_str (h, (omapi_object_t *)0, - "remote-port", &value); - if (status != ISC_R_SUCCESS) - return status; - if (!value -> value) { - omapi_value_dereference (&value, - "dhcp_failover_link_initiate"); - return ISC_R_INVALIDARG; + /* Find the failover state in the object chain. */ + for (o = h; o -> outer; o = o -> outer) + ; + for (; o; o = o -> inner) { + if (o -> type == dhcp_type_failover_state) + break; } - - status = omapi_get_int_value (&port, value -> value); - omapi_value_dereference (&value, "dhcp_failover_link_initiate"); - if (status != ISC_R_SUCCESS) - return status; - - status = omapi_get_value_str (h, (omapi_object_t *)0, - "remote-peer", &value); - if (status != ISC_R_SUCCESS) - return status; - if (!value -> value || - (value -> value -> type != omapi_datatype_string && - value -> value -> type != omapi_datatype_data)) { - omapi_value_dereference (&value, - "dhcp_failover_link_initiate"); + if (!o) return ISC_R_INVALIDARG; - } - - /* Save the name. */ - peer_name = malloc (value -> value -> u.buffer.len + 1); - if (!peer_name) { - omapi_value_dereference (&value, - "dhcp_failover_link_initiate"); - return ISC_R_NOMEMORY; - } - - 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"); + state = (dhcp_failover_state_t *)o; obj = (dhcp_failover_link_t *)malloc (sizeof *obj); if (!obj) @@ -121,37 +100,59 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) memset (obj, 0, sizeof *obj); obj -> refcnt = 1; obj -> type = dhcp_type_failover_link; - obj -> peer_name = peer_name; - obj -> peer_port = port; - - status = omapi_connect ((omapi_object_t *)obj, peer_name, port); - if (status != ISC_R_SUCCESS) { + option_cache_reference (&obj -> peer_address, state -> address, + "dhcp_failover_link_initiate"); + obj -> peer_port = state -> port; + + memset (&ds, 0, sizeof ds); + if (!evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0, + (struct option_state *)0, + (struct option_state *)0, + obj -> peer_address)) { + option_cache_dereference (&obj -> peer_address, + "dhcp_failover_link_initiate"); omapi_object_dereference ((omapi_object_t **)&obj, "dhcp_failover_link_initiate"); - return status; + return ISC_R_UNEXPECTED; } - status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, - "dhcp_failover_link_initiate"); + + /* Kludge around the fact that omapi_connect expects an ASCII string + representing the address to which to connect. */ + status = ISC_R_INVALIDARG; + for (i = 0; i + 4 <= ds.len; i += 4) { + char peer_name [40]; + sprintf (peer_name, "%d.%d.%d.%d", + ds.data [i], ds.data [i + 1], + ds.data [i + 2], ds.data [i + 3]); + status = omapi_connect ((omapi_object_t *)obj, + peer_name, port); + if (status == ISC_R_SUCCESS) + break; + } + data_string_forget (&ds, "dhcp_failover_link_initiate"); + + /* If we didn't connect to any of the addresses, give up. */ if (status != ISC_R_SUCCESS) { + lose: omapi_object_dereference ((omapi_object_t **)&obj, "dhcp_failover_link_initiate"); + option_cache_dereference (&obj -> peer_address, + "dhcp_failover_link_initiate"); return status; } + status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, + "dhcp_failover_link_initiate"); + if (status != ISC_R_SUCCESS) + goto lose; status = omapi_object_reference (&obj -> inner, h, "dhcp_failover_link_initiate"); - if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, - "dhcp_failover_link_initiate"); - return status; - } + if (status != ISC_R_SUCCESS) + goto lose; /* Send the introductory message. */ status = dhcp_failover_send_connect ((omapi_object_t *)obj); - if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, - "dhcp_failover_link_initiate"); - return status; - } + if (status != ISC_R_SUCCESS) + goto lose; omapi_object_dereference ((omapi_object_t **)&obj, "omapi_protocol_accept"); @@ -518,10 +519,6 @@ isc_result_t dhcp_failover_link_get_value (omapi_object_t *h, 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 - (value, name, link -> peer_name, - "dhcp_failover_link_get_value"); } else if (!omapi_ds_strcmp (name, "link-state")) { if (link -> state < 0 || link -> state >= dhcp_flink_state_max) @@ -577,13 +574,6 @@ isc_result_t dhcp_failover_link_stuff_values (omapi_object_t *c, if (status != ISC_R_SUCCESS) return status; - status = omapi_connection_put_name (c, "link-name"); - if (status != ISC_R_SUCCESS) - return status; - status = omapi_connection_put_string (c, link -> peer_name); - if (status != ISC_R_SUCCESS) - return status; - status = omapi_connection_put_name (c, "link-state"); if (status != ISC_R_SUCCESS) return status; @@ -669,7 +659,6 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o, 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; @@ -690,25 +679,20 @@ 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 = failover_states; state; state = state -> next) { - struct hostent *he; - int hix; - struct in_addr ia; - - if (inet_aton (state -> remote_peer, &ia)) { - if (ia.s_addr == c -> remote_addr.sin_addr.s_addr) - break; - } else { - he = gethostbyname (state -> remote_peer); - if (!he) - continue; - for (hix = 0; he -> h_addr_list [hix]; hix++) { - if (!memcmp (he -> h_addr_list [hix], - &c -> remote_addr.sin_addr, - sizeof c -> remote_addr.sin_addr)) + int i; + struct data_string ds; + + memset (&ds, 0, sizeof ds); + if (evaluate_option_cache (&ds, (struct packet *)0, + (struct lease *)0, + (struct option_state *)0, + (struct option_state *)0, + state -> address)) { + for (i = 0; i < ds.len; i += 4) { + if (!memcmp (&ds.data [i], + &c -> remote_addr, 4)) break; } - if (he -> h_addr_list [hix]) - break; } } @@ -729,11 +713,8 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o, memset (obj, 0, sizeof *obj); obj -> refcnt = 1; 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; + option_cache_reference (&obj -> peer_address, state -> address, + "dhcp_failover_listen_signal"); obj -> peer_port = ntohs (c -> remote_addr.sin_port); status = omapi_object_reference (&obj -> outer, (omapi_object_t *)c, @@ -979,13 +960,13 @@ isc_result_t dhcp_failover_state_lookup (omapi_object_t **sp, } } - /* Look the lease up by peer name. */ + /* Look the failover state up by peer name. */ status = omapi_get_value_str (ref, id, "peer_name", &tv); if (status == ISC_R_SUCCESS) { for (s = failover_states; s; s = s -> next) { - unsigned l = strlen (s -> remote_peer); + unsigned l = strlen (s -> name); if (l == tv -> value -> u.buffer.len || - !memcmp (s -> remote_peer, + !memcmp (s -> name, tv -> value -> u.buffer.value, l)) break; } @@ -1263,7 +1244,8 @@ isc_result_t dhcp_failover_put_message (dhcp_failover_link_t *link, the option portion of the message. */ va_start (list, msg_type); while ((option = va_arg (list, failover_option_t *))) { - size += option -> count; + if (option != &skip_failover_option) + size += option -> count; if (option == &null_failover_option) bad_option = 1; } @@ -1278,6 +1260,8 @@ isc_result_t dhcp_failover_put_message (dhcp_failover_link_t *link, va_start (list, msg_type); while ((option = va_arg (list, failover_option_t *))) { + if (option == &skip_failover_option) + continue; if (!bad_option && opbuf) memcpy (&opbuf [opix], option -> data, option -> count); @@ -1365,7 +1349,7 @@ isc_result_t dhcp_failover_send_connect (omapi_object_t *l) dhcp_failover_make_option (FTO_MAX_UNACKED, FMA, state -> max_flying_updates), dhcp_failover_make_option (FTO_RECEIVE_TIMER, FMA, - state -> partner_timeout), + state -> max_response_delay), dhcp_failover_make_option (FTO_VENDOR_CLASS, FMA, "isc-%s", DHCP_VERSION), dhcp_failover_make_option (FTO_PROTOCOL_VERSION, FMA, @@ -1389,6 +1373,75 @@ isc_result_t dhcp_failover_send_connect (omapi_object_t *l) return status; } +/* Send a Bind Update message. */ + +isc_result_t dhcp_failover_update_peer (struct lease *lease, int releasep) +{ + dhcp_failover_link_t *link; + dhcp_failover_state_t *state; + isc_result_t status; +#if defined (DEBUG_FAILOVER_MESSAGES) + char obuf [64]; + unsigned obufix = 0; + +# define FMA obuf, &obufix, sizeof obuf + failover_print (FMA, "(bndupd"); +#else +# define FMA (unsigned char *)0, (unsigned *)0, 0 +#endif + + if (!lease -> pool || + !lease -> pool -> failover_peer || + !lease -> pool -> failover_peer -> outer) + return ISC_R_INVALIDARG; + + state = lease -> pool -> failover_peer; + if (state -> outer -> type != dhcp_type_failover_link) + return ISC_R_INVALIDARG; + link = (dhcp_failover_link_t *)state -> outer; + + if (!link -> outer || link -> outer -> type != omapi_type_connection) + return ISC_R_INVALIDARG; + + status = (dhcp_failover_put_message + (link, link -> outer, + FTM_BNDUPD, + dhcp_failover_make_option (FTO_ASSIGNED_IP_ADDRESS, FMA, + lease -> ip_addr.iabuf), + dhcp_failover_make_option (FTO_BINDING_STATUS, FMA, + 0 /* ??? */), + lease -> uid_len + ? dhcp_failover_make_option (FTO_CLIENT_IDENTIFIER, FMA, + lease -> uid, + lease -> uid_len) + : &skip_failover_option, + dhcp_failover_make_option (FTO_CHADDR, FMA, + lease -> hardware_addr.hlen + 1, + lease -> hardware_addr.hbuf), + dhcp_failover_make_option (FTO_LEASE_EXPIRY, FMA, + lease -> ends), + dhcp_failover_make_option (FTO_POTENTIAL_EXPIRY, FMA, + lease -> tstp), + dhcp_failover_make_option (FTO_STOS, FMA, + lease -> starts), + dhcp_failover_make_option (FTO_CLTT, FMA, + lease -> cltt), + &skip_failover_option, /* XXX DDNS */ + &skip_failover_option, /* XXX request options */ + &skip_failover_option, /* XXX reply options */ + (failover_option_t *)0)); + +#if defined (DEBUG_FAILOVER_MESSAGES) + if (status != ISC_R_SUCCESS) + failover_print (FMA, " (failed)"); + failover_print (FMA, ")"); + if (obufix) { + log_debug ("%s", obuf); + } +#endif + return status; +} + #if defined (DEBUG_FAILOVER_MESSAGES) /* Print hunks of failover messages, doing line breaks as appropriate. Note that this assumes syslog is being used, rather than, e.g., the @@ -1414,4 +1467,7 @@ void failover_print (char *obuf, } #endif /* defined (DEBUG_FAILOVER_MESSAGES) */ +void update_partner (struct lease *lease) +{ +} #endif /* defined (FAILOVER_PROTOCOL) */