#ifndef lint
static char copyright[] =
-"$Id: failover.c,v 1.22 2000/08/24 18:41:42 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: failover.c,v 1.23 2000/08/31 04:41:10 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static dhcp_failover_state_t *failover_states;
static isc_result_t do_a_failover_option (omapi_object_t *,
dhcp_failover_link_t *);
+dhcp_failover_listener_t *failover_listeners;
void dhcp_failover_startup ()
{
dhcp_failover_state_t *state;
isc_result_t status;
+ dhcp_failover_listener_t *l;
for (state = failover_states; state; state = state -> next) {
dhcp_failover_state_transition (state, "startup");
- if (state -> i_am == secondary) {
- status = (dhcp_failover_listen
- ((omapi_object_t *)state));
- if (status != ISC_R_SUCCESS) {
- add_timeout (cur_time + 90,
- dhcp_failover_listener_restart,
- state,
- (tvref_t)omapi_object_reference,
- (tvunref_t)
- omapi_object_dereference);
- }
- } else {
- status = (dhcp_failover_link_initiate
- ((omapi_object_t *)state));
- if (status != ISC_R_SUCCESS) {
- add_timeout (cur_time + 90,
- dhcp_failover_reconnect, state,
- (tvref_t)
- dhcp_failover_state_reference,
- (tvunref_t)
- dhcp_failover_state_dereference);
- }
+
+ /* In case the peer is already running, immediately try
+ to establish a connection with it. */
+ status = (dhcp_failover_link_initiate
+ ((omapi_object_t *)state));
+ if (status != ISC_R_SUCCESS) {
+ add_timeout (cur_time + 90,
+ dhcp_failover_reconnect, state,
+ (tvref_t)
+ dhcp_failover_state_reference,
+ (tvunref_t)
+ dhcp_failover_state_dereference);
}
if (status != ISC_R_SUCCESS) {
log_error ("failover peer %s: %s", state -> name,
isc_result_totext (status));
}
+
+ status = (dhcp_failover_listen
+ ((omapi_object_t *)state));
+ if (status != ISC_R_SUCCESS) {
+ add_timeout (cur_time + 90,
+ dhcp_failover_listener_restart,
+ state,
+ (tvref_t)omapi_object_reference,
+ (tvunref_t)omapi_object_dereference);
+ }
}
}
status = dhcp_failover_link_allocate (&obj, MDL);
if (status != ISC_R_SUCCESS)
return status;
- option_cache_reference (&obj -> peer_address, state -> address, MDL);
- obj -> peer_port = state -> port;
+ option_cache_reference (&obj -> peer_address,
+ state -> partner.address, MDL);
+ obj -> peer_port = state -> partner.port;
dhcp_failover_state_reference (&obj -> state_object, state, MDL);
memset (&ds, 0, sizeof ds);
if (!evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
(struct option_state *)0,
(struct option_state *)0,
- &global_scope, state -> server_addr,
+ &global_scope, state -> me.address,
MDL)) {
memset (&local_addr, 0, sizeof local_addr);
local_addr.addrtype = AF_INET;
link = (dhcp_failover_link_t *)h;
if (!strcmp (name, "connect")) {
- /* If we're primary, send the connect message. */
+ if (link -> state_object -> i_am == primary) {
status = dhcp_failover_send_connect (h);
- if (status != ISC_R_SUCCESS)
- omapi_disconnect (h -> outer, 1);
+ if (status != ISC_R_SUCCESS) {
+ log_info ("dhcp_failover_send_connect: %s",
+ isc_result_totext (status));
+ omapi_disconnect (h -> outer, 1);
+ }
return status;
+ } else {
+ /* Allow the peer fifteen seconds to send us a
+ startup message. */
+ add_timeout (cur_time + 15,
+ dhcp_failover_link_startup_timeout,
+ link,
+ (tvref_t)dhcp_failover_link_reference,
+ (tvunref_t)dhcp_failover_link_dereference);
+ }
+ return ISC_R_SUCCESS;
}
if (!strcmp (name, "disconnect")) {
- if (link -> state_object) {
+ if (link -> state_object &&
+ link -> state_object -> link_to_peer == link) {
if (link -> state_object -> i_am == primary) {
add_timeout (cur_time + 5, dhcp_failover_reconnect,
link -> state_object,
link -> imsg = (failover_message_t *)0;
}
link -> state = dhcp_flink_disconnected;
+ log_info ("message length wait: no memory");
omapi_disconnect (c, 1);
/* XXX just blow away the protocol state now?
XXX or will disconnect blow it away? */
omapi_connection_get_uint32 (c, &link -> imsg -> xid);
link -> imsg_count += 4;
+#if defined (DEBUG_FAILOVER_MESSAGES)
+ log_info ("link: message %s payoff %d time %ld xid %ld",
+ dhcp_failover_message_name (link -> imsg -> type),
+ link -> imsg_payoff,
+ (unsigned long)link -> imsg -> time,
+ (unsigned long)link -> imsg -> xid);
+#endif
/* Skip over any portions of the message header that we
don't understand. */
if (link -> imsg_payoff - link -> imsg_count) {
dhcp_failover_send_connectack
((omapi_object_t *)link, state,
reason, errmsg);
+ log_info ("failover: disconnect: %s", errmsg);
omapi_disconnect (c, 0);
link -> state = dhcp_flink_disconnected;
return ISC_R_SUCCESS;
if (!link -> state_object)
dhcp_failover_state_reference
(&link -> state_object, state, MDL);
- option_cache_reference
- (&link -> peer_address, state -> address, MDL);
+ if (!link -> peer_address)
+ option_cache_reference
+ (&link -> peer_address,
+ state -> partner.address, MDL);
}
/* If we don't have a state object at this point, it's
some kind of bogus situation, so just drop the
connection. */
if (!link -> state_object) {
+ log_info ("failover: connect: no matching state.");
omapi_disconnect (c, 1);
link -> state = dhcp_flink_disconnected;
return ISC_R_INVALIDARG;
/* If it's an unknown code, skip over it. */
if (option_code > FTO_MAX) {
-#if defined (FAILOVER_PROTOCOL_DEBUG) && defined (FAILOVER_DEBUG_VERBOSE)
- log_debug (" option code %d len %d (not recognized)",
- option_code, option_len);
+#if defined (DEBUG_FAILOVER_MESSAGES)
+ log_debug (" option code %d (%s) len %d (not recognized)",
+ option_code,
+ dhcp_failover_option_name (option_code),
+ option_len);
#endif
omapi_connection_copyout ((unsigned char *)0, c, option_len);
link -> imsg_count += option_len;
log_error ("FAILOVER: digest not at end of message");
return ISC_R_PROTOCOLERROR;
}
-#if defined (FAILOVER_PROTOCOL_DEBUG) && defined (FAILOVER_DEBUG_VERBOSE)
+#if defined (DEBUG_FAILOVER_MESSAGES)
log_debug (" option %s len %d",
ft_options [option_code].name, option_len);
#endif
isc_result_t dhcp_failover_listen (omapi_object_t *h)
{
isc_result_t status;
- dhcp_failover_listener_t *obj;
+ dhcp_failover_listener_t *obj, *l;
omapi_value_t *value = (omapi_value_t *)0;
omapi_addr_t local_addr;
unsigned long port;
omapi_value_dereference (&value, MDL);
+ /* Are we already listening on this port and address? */
+ for (l = failover_listeners; l; l = l -> next) {
+ if (l -> address.port == local_addr.port &&
+ l -> address.addrtype == local_addr.addrtype &&
+ l -> address.addrlen == local_addr.addrlen &&
+ !memcmp (l -> address.address, local_addr.address,
+ local_addr.addrlen))
+ break;
+ }
+ /* Already listening. */
+ if (l)
+ return ISC_R_SUCCESS;
+
obj = (dhcp_failover_listener_t *)0;
status = dhcp_failover_listener_allocate (&obj, MDL);
if (status != ISC_R_SUCCESS)
return status;
- obj -> local_port = local_addr.port;
+ obj -> address = local_addr;
- status = omapi_listen_addr ((omapi_object_t *)obj, &local_addr, 1);
+ status = omapi_listen_addr ((omapi_object_t *)obj, &obj -> address, 1);
if (status != ISC_R_SUCCESS)
return status;
return status;
}
+ /* Put this listener on the list. */
+ dhcp_failover_listener_reference (&obj -> next,
+ failover_listeners, MDL);
+ dhcp_failover_listener_dereference (&failover_listeners, MDL);
+ dhcp_failover_listener_reference (&failover_listeners, obj, MDL);
+
return dhcp_failover_listener_dereference (&obj, MDL);
}
if (!c || c -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
+ /* See if we can find a failover_state object that
+ matches this connection. */
+ for (s = failover_states; s; s = s -> next) {
+ if (dhcp_failover_state_match
+ (s, (u_int8_t *)&c -> remote_addr.sin_addr,
+ sizeof c -> remote_addr.sin_addr))
+ state = s;
+ }
+ if (!state) {
+ log_info ("failover: listener: no matching state");
+ return omapi_disconnect ((omapi_object_t *)c, 1);
+ }
+
obj = (dhcp_failover_link_t *)0;
status = dhcp_failover_link_allocate (&obj, MDL);
if (status != ISC_R_SUCCESS)
if (status != ISC_R_SUCCESS) {
lose:
dhcp_failover_link_dereference (&obj, MDL);
+ log_info ("failover: listener: picayune failure.");
omapi_disconnect ((omapi_object_t *)c, 1);
return status;
}
if (status != ISC_R_SUCCESS)
goto lose;
+ status = dhcp_failover_state_reference (&obj -> state_object,
+ state, MDL);
+ if (status != ISC_R_SUCCESS)
+ goto lose;
+
+ omapi_signal_in ((omapi_object_t *)obj, "connect");
+
return dhcp_failover_link_dereference (&obj, MDL);
}
obj = (dhcp_failover_state_t *)0;
dhcp_failover_state_allocate (&obj, MDL);
- obj -> listen_port = port;
+ obj -> me.port = port;
status = omapi_listen ((omapi_object_t *)obj, port, 1);
if (status != ISC_R_SUCCESS) {
if (link -> imsg -> type == FTM_CONNECT) {
/* If we already have a link to the peer, it must be
dead, so drop it.
- XXX Is this the right thing to do? */
+ XXX Is this the right thing to do?
+ XXX Probably not - what if both peers start at
+ XXX the same time? */
if (state -> link_to_peer) {
- omapi_disconnect ((omapi_object_t *)
- state -> link_to_peer, 1);
- dhcp_failover_link_dereference
- (&state -> link_to_peer, MDL);
- dhcp_failover_state_transition (state,
- "disconnect");
+ dhcp_failover_send_connectack
+ ((omapi_object_t *)link, state,
+ FTR_DUP_CONNECTION,
+ "already connected");
+ omapi_disconnect (link -> outer, 1);
+ return ISC_R_SUCCESS;
}
+ if (!(link -> imsg -> options_present & FTB_MCLT)) {
+ dhcp_failover_send_connectack
+ ((omapi_object_t *)link, state,
+ FTR_INVALID_MCLT,
+ "no MCLT provided");
+ omapi_disconnect (link -> outer, 1);
+ return ISC_R_SUCCESS;
+ }
+
dhcp_failover_link_reference (&state -> link_to_peer,
link, MDL);
status = (dhcp_failover_send_connectack
if (status != ISC_R_SUCCESS) {
dhcp_failover_link_dereference
(&state -> link_to_peer, MDL);
+ log_info ("dhcp_failover_send_connectack: %s",
+ isc_result_totext (status));
omapi_disconnect (link -> outer, 1);
return ISC_R_SUCCESS;
}
- /* dhcp_failover_state_transition (state,
- "connect"); */
+ if (link -> imsg -> options_present & FTB_MAX_UNACKED)
+ state -> partner.max_flying_updates =
+ link -> imsg -> max_unacked;
+ if (link -> imsg -> options_present &
+ FTB_RECEIVE_TIMER)
+ state -> partner.max_response_delay =
+ link -> imsg -> receive_timer;
+ state -> mclt = link -> imsg -> mclt;
+ dhcp_failover_send_state (state);
+ cancel_timeout (dhcp_failover_link_startup_timeout,
+ link);
} else if (link -> imsg -> type == FTM_CONNECTACK) {
const char *errmsg;
int reason;
dhcp_failover_link_reference (&state -> link_to_peer,
link, MDL);
+ dhcp_failover_send_state (state);
+#if 0
dhcp_failover_state_transition (state, "connect");
+#endif
+ if (link -> imsg -> options_present & FTB_MAX_UNACKED)
+ state -> partner.max_flying_updates =
+ link -> imsg -> max_unacked;
+ if (link -> imsg -> options_present & FTB_RECEIVE_TIMER)
+ state -> partner.max_response_delay =
+ link -> imsg -> receive_timer;
add_timeout (cur_time +
- (int)state -> max_transmit_idle,
+ (int)state -> partner.max_response_delay / 3,
dhcp_failover_send_contact, state,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference);
add_timeout (cur_time +
- (int)state -> max_response_delay,
+ (int)state -> me.max_response_delay,
dhcp_failover_timeout, state,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference);
log_info ("pool response: %ld leases",
(unsigned long)
link -> imsg -> addresses_transferred);
- }
- if (state &&
- link -> imsg -> server_state !=
- state -> my_state)
+ } else if (link -> imsg -> type == FTM_STATE) {
dhcp_failover_peer_state_changed (state,
link -> imsg);
+ }
}
/* Add a timeout so that if the partner doesn't send another message
for the maximum transmit idle time plus a grace of one second,
we close the connection. */
- if (state -> my_state == normal)
+ if (state -> me.state == normal)
add_timeout (cur_time +
- (int)state -> max_response_delay,
+ (int)state -> me.max_response_delay,
dhcp_failover_timeout, state,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference);
/* XXX Check these state transitions against the spec! */
if (!strcmp (name, "disconnect")) {
if (state -> link_to_peer) {
+ log_info ("peer %s: disconnected", state -> name);
if (state -> link_to_peer -> state_object)
dhcp_failover_state_dereference
(&state -> link_to_peer -> state_object, MDL);
}
cancel_timeout (dhcp_failover_send_contact, state);
cancel_timeout (dhcp_failover_timeout, state);
+ cancel_timeout (dhcp_failover_startup_timeout, state);
- switch (state -> my_state) {
+ switch (state -> me.state == startup ?
+ state -> saved_state : state -> me.state) {
case resolution_interrupted:
case partner_down:
case communications_interrupted:
/* Already in the right state? */
+ if (state -> me.state == startup)
+ return (dhcp_failover_set_state
+ (state, state -> saved_state));
return ISC_R_SUCCESS;
case potential_conflict:
return dhcp_failover_set_state
(state, communications_interrupted);
- /* XXX ??? */
case unknown_state:
- default:
return dhcp_failover_set_state
(state, resolution_interrupted);
-
+ case startup:
+ break; /* can't happen. */
}
-#if 0 /* This is now handled in the partner state transition code. */
} else if (!strcmp (name, "connect")) {
- switch (state -> my_state) {
+ switch (state -> me.state) {
case communications_interrupted:
return dhcp_failover_set_state (state, normal);
- case partner_down:
- return dhcp_failover_set_state (state, recover);
-
case resolution_interrupted:
return dhcp_failover_set_state (state,
potential_conflict);
- /* We should never be in these states when we make
- a "connect" transition. */
- case recover:
+ case partner_down:
case potential_conflict:
case normal:
- return ISC_R_INVALIDARG;
-
- /* We should never be in the unknown_state or an
- unknown state either. */
+ case recover:
+ case shut_down:
+ case paused:
case unknown_state:
- default:
- return dhcp_failover_set_state (state,
- potential_conflict);
+ return dhcp_failover_send_state (state);
}
-#endif
} else if (!strcmp (name, "startup")) {
- state -> service_state = service_startup;
- state -> nrr = " (startup)";
- log_info ("peer %s service state: not responding for 15s",
- state -> name);
- add_timeout (cur_time + 15,
- dhcp_failover_startup_timeout,
- state,
- (tvref_t)omapi_object_reference,
- (tvunref_t)
- omapi_object_dereference);
+ dhcp_failover_set_state (state, startup);
+ return ISC_R_SUCCESS;
} else if (!strcmp (name, "connect-timeout")) {
- switch (state -> my_state) {
+ switch (state -> me.state) {
case communications_interrupted:
case partner_down:
case resolution_interrupted:
isc_result_t dhcp_failover_set_service_state (dhcp_failover_state_t *state)
{
- switch (state -> my_state) {
+ switch (state -> me.state) {
case unknown_state:
state -> service_state = not_responding;
state -> nrr = " (my state unknown)";
state -> service_state = not_responding;
state -> nrr = " (recover done)";
break;
+
+ case startup:
+ state -> service_state = service_startup;
+ state -> nrr = " (startup)";
+ break;
}
/* Some peer states can require us not to respond, even if our
state doesn't. */
/* XXX hm. I suspect this isn't true anymore. */
if (state -> service_state != not_responding) {
- switch (state -> partner_state) {
+ switch (state -> partner.state) {
case partner_down:
case recover:
state -> service_state = not_responding;
TIME saved_stos;
/* First make the transition out of the current state. */
- switch (state -> my_state) {
+ switch (state -> me.state) {
case normal:
/* Any updates that haven't been acked yet, we have to
resend, just in case. */
case partner_down:
case communications_interrupted:
case resolution_interrupted:
+ case startup:
default:
break;
}
/* Tentatively make the transition. */
- saved_state = state -> my_state;
- saved_stos = state -> my_stos;
- state -> my_stos = cur_time;
- state -> my_state = new_state;
+ saved_state = state -> me.state;
+ saved_stos = state -> me.stos;
+ state -> me.stos = cur_time;
+ state -> me.state = new_state;
if (!write_failover_state (state) || !commit_leases ()) {
/* XXX What to do? What to do? */
state -> name);
/* XXX for now, we don't make the state transition, but this is
XXX kind of a scary choice. */
- state -> my_state = saved_state;
- state -> my_stos = saved_stos;
+ state -> me.state = saved_state;
+ state -> me.stos = saved_stos;
return ISC_R_IOERROR;
}
log_info ("failover peer %s: I move from %s to %s",
state -> name, dhcp_failover_state_name_print (saved_state),
- dhcp_failover_state_name_print (state -> my_state));
+ dhcp_failover_state_name_print (state -> me.state));
switch (new_state)
{
potential-conflict, do we need to start over, or just continue
with the reconciliation process? This came up at one of the
teleconferences, so it's probably answered in the draft. */
- if (state -> max_flying_updates > state -> cur_unacked_updates &&
- state -> update_queue_head) {
+ if ((state -> partner.max_flying_updates >
+ state -> cur_unacked_updates) && state -> update_queue_head) {
dhcp_failover_send_updates (state);
}
dhcp_failover_state_pool_check (state);
dhcp_failover_send_update_request (state);
break;
+ case startup:
+ if (saved_state != startup)
+ state -> saved_state = saved_state;
+ add_timeout (cur_time + 15,
+ dhcp_failover_startup_timeout,
+ state,
+ (tvref_t)omapi_object_reference,
+ (tvunref_t)
+ omapi_object_dereference);
+ break;
+
default:
break;
}
+ if (new_state != startup && saved_state == startup)
+ cancel_timeout (dhcp_failover_startup_timeout, state);
+
dhcp_failover_set_service_state (state);
+ if (state -> link_to_peer)
+ dhcp_failover_send_state (state);
return ISC_R_SUCCESS;
}
isc_result_t dhcp_failover_peer_state_changed (dhcp_failover_state_t *state,
failover_message_t *msg)
{
- enum failover_state previous_state = state -> partner_state;
- enum failover_state new_state = msg -> server_state;
- int startupp = (msg -> server_flags & FTF_STARTUP) ? 1 : 0;
+ enum failover_state previous_state = state -> partner.state;
+ enum failover_state new_state;
+ int startupp;
- /* This isn't a state transition. */
- if (previous_state == new_state)
- return ISC_R_SUCCESS;
+ new_state = msg -> server_state;
+ startupp = (msg -> server_flags & FTF_STARTUP) ? 1 : 0;
- state -> partner_state = new_state;
+ state -> partner.state = new_state;
log_info ("failover peer %s: peer moves from %s to %s",
state -> name,
dhcp_failover_state_name_print (previous_state),
- dhcp_failover_state_name_print (state -> partner_state));
+ dhcp_failover_state_name_print (state -> partner.state));
if (!write_failover_state (state) || !commit_leases ()) {
/* This is bad, but it's not fatal. Of course, if we
/* Do any state transitions that are required as a result of the
peer's state transition. */
- switch (state -> my_state) {
+ switch (state -> me.state == startup ?
+ state -> saved_state : state -> me.state) {
+ case startup: /* can't happen. */
+ break;
+
case normal:
switch (new_state) {
case normal:
+ case communications_interrupted:
+ break;
+
case recover:
case potential_conflict:
case partner_down:
- case communications_interrupted:
case resolution_interrupted:
/* XXX this isn't really going to work, is it? */
/* XXX probably should just goto the switch
case unknown_state:
break;
}
+
+ /* If we didn't make a transition out of startup as a result of
+ the peer's state change, do it now as a result of the fact that
+ we got a state change from the peer. */
+ if (state -> me.state == startup && state -> saved_state != startup)
+ dhcp_failover_set_state (state, state -> saved_state);
/* For now, just set the service state based on the peer's state
if necessary. */
binding_state_t my_lease_state;
struct lease **lq;
- if (state -> my_state != normal || state -> i_am == secondary)
+ if (state -> me.state != normal || state -> i_am == secondary)
return 0;
for (s = shared_networks; s; s = s -> next) {
if (!pool -> failover_peer ||
pool -> failover_peer -> i_am == primary ||
- pool -> failover_peer -> my_state != normal)
+ pool -> failover_peer -> me.state != normal)
return 0;
if (pool -> failover_peer -> i_am == primary)
isc_result_t status;
/* Can't update peer if we're not talking to it! */
- if (state -> my_state != normal &&
- state -> my_state != recover &&
- state -> my_state != potential_conflict)
+ if (state -> me.state != normal &&
+ state -> me.state != recover &&
+ state -> me.state != potential_conflict)
return ISC_R_SUCCESS;
- while (state -> max_flying_updates > state -> cur_unacked_updates &&
- state -> update_queue_head) {
+ while ((state -> partner.max_flying_updates >
+ state -> cur_unacked_updates) && state -> update_queue_head) {
/* Grab the head of the update queue. */
lease_reference (&lp, state -> update_queue_head, MDL);
dhcp_failover_state_t *state = vs;
isc_result_t status;
- dhcp_failover_set_service_state (state);
+ dhcp_failover_state_transition (state, "disconnect");
+}
+
+void dhcp_failover_link_startup_timeout (void *vl)
+{
+ dhcp_failover_link_t *link = vl;
+ isc_result_t status;
+ omapi_object_t *p;
+
+ for (p = (omapi_object_t *)link; p -> inner; p = p -> inner)
+ ;
+ for (; p; p = p -> outer)
+ if (p -> type == omapi_type_connection)
+ break;
+ if (p) {
+ log_info ("failover: startup timeout");
+ omapi_disconnect (p, 1);
+ }
}
void dhcp_failover_listener_restart (void *vs)
name, s -> name, MDL);
return ISC_R_NOTFOUND;
} else if (!omapi_ds_strcmp (name, "partner-address")) {
- oc = s -> address;
+ oc = s -> partner.address;
getaddr:
memset (&ds, 0, sizeof ds);
if (!evaluate_option_cache (&ds, (struct packet *)0,
status = omapi_make_const_value (value,
name, ds.data, ds.len, MDL);
/* Disgusting kludge: */
- if (oc == s -> server_addr && !s -> server_identifier.len)
+ if (oc == s -> me.address && !s -> server_identifier.len)
data_string_copy (&s -> server_identifier, &ds, MDL);
data_string_forget (&ds, MDL);
return status;
} else if (!omapi_ds_strcmp (name, "local-address")) {
- oc = s -> server_addr;
+ oc = s -> me.address;
goto getaddr;
} else if (!omapi_ds_strcmp (name, "partner-port")) {
- return omapi_make_int_value (value, name, s -> port, MDL);
+ return omapi_make_int_value (value, name,
+ s -> partner.port, MDL);
} else if (!omapi_ds_strcmp (name, "local-port")) {
return omapi_make_int_value (value,
- name, s -> listen_port, MDL);
+ name, s -> me.port, MDL);
} else if (!omapi_ds_strcmp (name, "max-outstanding-updates")) {
return omapi_make_uint_value (value, name,
- s -> max_flying_updates, MDL);
+ s -> me.max_flying_updates,
+ MDL);
} else if (!omapi_ds_strcmp (name, "mclt")) {
return omapi_make_uint_value (value, name, s -> mclt, MDL);
} else if (!omapi_ds_strcmp (name, "load-balance-max-secs")) {
return ISC_R_NOTFOUND;
} else if (!omapi_ds_strcmp (name, "partner-state")) {
return omapi_make_uint_value (value, name,
- s -> partner_state, MDL);
+ s -> partner.state, MDL);
} else if (!omapi_ds_strcmp (name, "local-state")) {
return omapi_make_uint_value (value, name,
- s -> my_state, MDL);
+ s -> me.state, MDL);
} else if (!omapi_ds_strcmp (name, "partner-stos")) {
return omapi_make_int_value (value, name,
- s -> partner_stos, MDL);
+ s -> partner.stos, MDL);
} else if (!omapi_ds_strcmp (name, "local-stos")) {
return omapi_make_int_value (value, name,
- s -> my_stos, MDL);
+ s -> me.stos, MDL);
} else if (!omapi_ds_strcmp (name, "hierarchy")) {
return omapi_make_uint_value (value, name, s -> i_am, MDL);
} else if (!omapi_ds_strcmp (name, "last-packet-sent")) {
MDL);
} else if (!omapi_ds_strcmp (name, "skew")) {
return omapi_make_int_value (value, name, s -> skew, MDL);
- } else if (!omapi_ds_strcmp (name, "max-transmit-idle")) {
- return omapi_make_uint_value (value, name,
- s -> max_transmit_idle, MDL);
} else if (!omapi_ds_strcmp (name, "max-response-delay")) {
return omapi_make_uint_value (value, name,
- s -> max_response_delay, MDL);
+ s -> me.max_response_delay,
+ MDL);
} else if (!omapi_ds_strcmp (name, "cur-unacked-updates")) {
return omapi_make_int_value (value, name,
s -> cur_unacked_updates, MDL);
dhcp_failover_link_dereference (&s -> link_to_peer, MDL);
if (s -> name)
dfree (s -> name, MDL);
- if (s -> address)
- option_cache_dereference (&s -> address, MDL);
- if (s -> server_addr)
- option_cache_dereference (&s -> server_addr, MDL);
+ if (s -> partner.address)
+ option_cache_dereference (&s -> partner.address, MDL);
+ if (s -> me.address)
+ option_cache_dereference (&s -> me.address, MDL);
return ISC_R_SUCCESS;
}
status = omapi_connection_put_name (c, "partner-address");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof s -> address);
+ status = omapi_connection_put_uint32 (c, sizeof s -> partner.address);
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_copyin (c, (u_int8_t *)&s -> address,
- sizeof s -> address);
+ status = omapi_connection_copyin (c, (u_int8_t *)&s -> partner.address,
+ sizeof s -> partner.address);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, (u_int32_t)s -> port);
+ status = omapi_connection_put_uint32 (c, (u_int32_t)s -> partner.port);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_name (c, "local-address");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof s -> server_addr);
+ status = omapi_connection_put_uint32 (c, sizeof s -> me.address);
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_copyin (c, (u_int8_t *)&s -> server_addr,
- sizeof s -> server_addr);
+ status = omapi_connection_copyin (c, (u_int8_t *)&s -> me.address,
+ sizeof s -> me.address);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, (u_int32_t)s -> listen_port);
+ status = omapi_connection_put_uint32 (c, (u_int32_t)s -> me.port);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, s -> max_flying_updates);
+ status = omapi_connection_put_uint32 (c,
+ s -> me.max_flying_updates);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, s -> partner_state);
+ status = omapi_connection_put_uint32 (c, s -> partner.state);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, s -> my_state);
+ status = omapi_connection_put_uint32 (c, s -> me.state);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, (u_int32_t)s -> partner_stos);
+ status = omapi_connection_put_uint32 (c,
+ (u_int32_t)s -> partner.stos);
if (status != ISC_R_SUCCESS)
return status;
status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, (u_int32_t)s -> my_stos);
+ status = omapi_connection_put_uint32 (c, (u_int32_t)s -> me.stos);
if (status != ISC_R_SUCCESS)
return status;
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_name (c, "max-transmit-idle");
- if (status != ISC_R_SUCCESS)
- return status;
- status = omapi_connection_put_uint32 (c, sizeof (u_int32_t));
- if (status != ISC_R_SUCCESS)
- return status;
- status = (omapi_connection_put_uint32
- (c, (u_int32_t)s -> max_transmit_idle));
- if (status != ISC_R_SUCCESS)
- return status;
-
status = omapi_connection_put_name (c, "max-response-delay");
if (status != ISC_R_SUCCESS)
return status;
if (status != ISC_R_SUCCESS)
return status;
status = (omapi_connection_put_uint32
- (c, (u_int32_t)s -> max_response_delay));
+ (c, (u_int32_t)s -> me.max_response_delay));
if (status != ISC_R_SUCCESS)
return status;
(struct option_state *)0,
(struct option_state *)0,
&global_scope,
- state -> address, MDL)) {
+ state -> partner.address, MDL)) {
for (i = 0; i + addrlen - 1 < ds.len; i += addrlen) {
if (!memcmp (&ds.data [i],
addr, addrlen)) {
case recover:
return "recover";
+
+ case recover_done:
+ return "recover-done";
+
+ case shut_down:
+ return "shutdown";
+
+ case paused:
+ return "paused";
+
+ case startup:
+ return "startup";
+ }
+}
+
+const char *dhcp_failover_message_name (u_int8_t type)
+{
+ switch (type) {
+ case FTM_POOLREQ:
+ return "pool-request";
+
+ case FTM_POOLRESP:
+ return "pool-response";
+
+ case FTM_BNDUPD:
+ return "bind-update";
+
+ case FTM_BNDACK:
+ return "bind-ack";
+
+ case FTM_CONNECT:
+ return "connect";
+
+ case FTM_CONNECTACK:
+ return "connect-ack";
+
+ case FTM_UPDREQ:
+ return "update-request";
+
+ case FTM_UPDDONE:
+ return "update-done";
+
+ case FTM_UPDREQALL:
+ return "update-request-all";
+
+ case FTM_STATE:
+ return "state";
+
+ case FTM_CONTACT:
+ return "contact";
+
+ case FTM_DISCONNECT:
+ return "disconnect";
+
+ default:
+ return "<unknown message type>";
+ }
+}
+
+const char *dhcp_failover_option_name (u_int16_t type) {
+ switch (type) {
+ case FTO_BINDING_STATUS:
+ return "binding-status";
+
+ case FTO_ASSIGNED_IP_ADDRESS:
+ return "assigned-ip-address";
+
+ case FTO_SERVER_ADDR:
+ return "server-addr";
+
+ case FTO_ADDRESSES_TRANSFERRED:
+ return "addresses-transferred";
+
+ case FTO_CLIENT_IDENTIFIER:
+ return "client-identifier";
+
+ case FTO_CHADDR:
+ return "chaddr";
+
+ case FTO_DDNS:
+ return "ddns";
+
+ case FTO_REJECT_REASON:
+ return "reject-reason";
+
+ case FTO_MESSAGE:
+ return "message";
+
+ case FTO_MCLT:
+ return "mclt";
+
+ case FTO_VENDOR_CLASS:
+ return "vendor-class";
+
+ case FTO_LEASE_EXPIRY:
+ return "lease-expiry";
+
+ case FTO_POTENTIAL_EXPIRY:
+ return "potential-expiry";
+
+ case FTO_GRACE_EXPIRY:
+ return "grace-expiry";
+
+ case FTO_CLTT:
+ return "cltt";
+
+ case FTO_STOS:
+ return "stos";
+
+ case FTO_SERVER_STATE:
+ return "server-state";
+
+ case FTO_SERVER_FLAGS:
+ return "server-flags";
+
+ case FTO_VENDOR_OPTIONS:
+ return "vendor-options";
+
+ case FTO_MAX_UNACKED:
+ return "max-unacked";
+
+ case FTO_RECEIVE_TIMER:
+ return "receive-timer";
+
+ case FTO_HBA:
+ return "hba";
+
+ case FTO_MESSAGE_DIGEST:
+ return "message-digest";
+
+ case FTO_PROTOCOL_VERSION:
+ return "protocol-version";
+
+ case FTO_TLS_REQUEST:
+ return "tls-request";
+
+ case FTO_TLS_REPLY:
+ return "tls-reply";
+
+ case FTO_REQUEST_OPTIONS:
+ return "request-options";
+
+ case FTO_REPLY_OPTIONS:
+ return "reply-options";
+
+ default:
+ return "<unknown option>";
}
}
if (link -> state_object &&
link -> state_object -> link_to_peer == link)
add_timeout (cur_time +
- (int)link -> state_object -> max_transmit_idle,
+ (int)(link -> state_object ->
+ partner.max_response_delay) / 3,
dhcp_failover_send_contact, link -> state_object,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference);
err:
dfree (opbuf, MDL);
+ log_info ("dhcp_failover_put_message: something went wrong.");
omapi_disconnect (connection, 1);
return status;
}
if (!state || state -> type != dhcp_type_failover_state)
return;
- if (state -> my_state != normal)
+ if (state -> me.state != normal)
return;
link = state -> link_to_peer;
if (!link ||
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_CONTACT,
+ (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;
+}
+
+isc_result_t dhcp_failover_send_state (dhcp_failover_state_t *state)
+{
+ dhcp_failover_link_t *link;
+ isc_result_t status;
+
+#if defined (DEBUG_FAILOVER_MESSAGES)
+ char obuf [64];
+ unsigned obufix = 0;
+
+# define FMA obuf, &obufix, sizeof obuf
+ failover_print (FMA, "(state");
+#else
+# define FMA (char *)0, (unsigned *)0, 0
+#endif
+
+ if (!state || state -> type != dhcp_type_failover_state)
+ return ISC_R_INVALIDARG;
+ link = state -> link_to_peer;
+ if (!link ||
+ !link -> outer ||
+ link -> outer -> type != omapi_type_connection)
+ return ISC_R_INVALIDARG;
+
+ status = (dhcp_failover_put_message
+ (link, link -> outer,
+ FTM_STATE,
dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
+ (state -> me.state == startup
+ ? state -> saved_state
+ : state -> me.state)),
dhcp_failover_make_option
(FTO_SERVER_FLAGS, FMA,
(state -> service_state == service_startup
? FTF_STARTUP : 0)),
+ dhcp_failover_make_option (FTO_STOS, FMA, state -> me.stos),
(failover_option_t *)0));
#if defined (DEBUG_FAILOVER_MESSAGES)
log_debug ("%s", obuf);
}
#endif
- return;
+ return ISC_R_SUCCESS;
}
/* Send a connect message. */
if (!l -> outer || l -> outer -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
- if (state -> hba) {
- int i;
- for (i = 0; i < 32; i++)
- hba [i] = ~state -> hba [i];
- }
-
- status = (dhcp_failover_put_message
- (link, l -> outer,
- FTM_CONNECT,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
- dhcp_failover_make_option (FTO_SERVER_ADDR, FMA,
- state -> server_identifier.len,
- state -> server_identifier.data),
- dhcp_failover_make_option (FTO_MAX_UNACKED, FMA,
- state -> max_flying_updates),
- dhcp_failover_make_option (FTO_RECEIVE_TIMER, FMA,
- state -> max_response_delay),
- dhcp_failover_option_printf (FTO_VENDOR_CLASS, FMA,
- "isc-%s", DHCP_VERSION),
- dhcp_failover_make_option (FTO_PROTOCOL_VERSION, FMA,
- DHCP_FAILOVER_VERSION),
- dhcp_failover_make_option (FTO_TLS_REQUEST, FMA,
- 0, 0),
- dhcp_failover_make_option (FTO_MCLT, FMA,
- state -> mclt),
- (state -> hba
- ? dhcp_failover_make_option (FTO_HBA, FMA, 32, hba)
- : &skip_failover_option),
- (failover_option_t *)0));
-
+ status =
+ (dhcp_failover_put_message
+ (link, l -> outer,
+ FTM_CONNECT,
+ dhcp_failover_make_option (FTO_SERVER_ADDR, FMA,
+ state -> server_identifier.len,
+ state -> server_identifier.data),
+ dhcp_failover_make_option (FTO_MAX_UNACKED, FMA,
+ state -> me.max_flying_updates),
+ dhcp_failover_make_option (FTO_RECEIVE_TIMER, FMA,
+ state -> me.max_response_delay),
+ dhcp_failover_option_printf (FTO_VENDOR_CLASS, FMA,
+ "isc-%s", DHCP_VERSION),
+ dhcp_failover_make_option (FTO_PROTOCOL_VERSION, FMA,
+ DHCP_FAILOVER_VERSION),
+ dhcp_failover_make_option (FTO_TLS_REQUEST, FMA,
+ 0, 0),
+ dhcp_failover_make_option (FTO_MCLT, FMA,
+ state -> mclt),
+ (state -> hba
+ ? dhcp_failover_make_option (FTO_HBA, FMA, 32, state -> hba)
+ : &skip_failover_option),
+ (failover_option_t *)0));
+
#if defined (DEBUG_FAILOVER_MESSAGES)
if (status != ISC_R_SUCCESS)
failover_print (FMA, " (failed)");
if (!l -> outer || l -> outer -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
- status = (dhcp_failover_put_message
- (link, l -> outer,
- FTM_CONNECTACK,
- (state
- ? dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state)
- : &skip_failover_option),
- (state
- ? (dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)))
- : &skip_failover_option),
- (state
- ? (dhcp_failover_make_option
- (FTO_SERVER_ADDR, FMA,
- state -> server_identifier.len,
- state -> server_identifier.data))
- : &skip_failover_option),
- (state
- ? dhcp_failover_make_option (FTO_MAX_UNACKED, FMA,
- state -> max_flying_updates)
- : &skip_failover_option),
- (state
- ? dhcp_failover_make_option (FTO_RECEIVE_TIMER, FMA,
- state -> max_response_delay)
- : &skip_failover_option),
- dhcp_failover_option_printf (FTO_VENDOR_CLASS, FMA,
- "isc-%s", DHCP_VERSION),
- dhcp_failover_make_option (FTO_PROTOCOL_VERSION, FMA,
- DHCP_FAILOVER_VERSION),
- dhcp_failover_make_option (FTO_TLS_REQUEST, FMA,
- 0, 0),
- (reason
- ? dhcp_failover_make_option (FTO_REJECT_REASON,
- FMA, reason)
- : &skip_failover_option),
- (errmsg
- ? dhcp_failover_make_option (FTO_MESSAGE, FMA,
- strlen (errmsg), errmsg)
- : &skip_failover_option),
- (failover_option_t *)0));
+ status =
+ (dhcp_failover_put_message
+ (link, l -> outer,
+ FTM_CONNECTACK,
+ (state
+ ? (dhcp_failover_make_option
+ (FTO_SERVER_ADDR, FMA,
+ state -> server_identifier.len,
+ state -> server_identifier.data))
+ : &skip_failover_option),
+ (state
+ ? dhcp_failover_make_option (FTO_MAX_UNACKED, FMA,
+ state -> me.max_flying_updates)
+ : &skip_failover_option),
+ (state
+ ? dhcp_failover_make_option (FTO_RECEIVE_TIMER, FMA,
+ state -> me.max_response_delay)
+ : &skip_failover_option),
+ dhcp_failover_option_printf (FTO_VENDOR_CLASS, FMA,
+ "isc-%s", DHCP_VERSION),
+ dhcp_failover_make_option (FTO_PROTOCOL_VERSION, FMA,
+ DHCP_FAILOVER_VERSION),
+ dhcp_failover_make_option (FTO_TLS_REQUEST, FMA,
+ 0, 0),
+ (reason
+ ? dhcp_failover_make_option (FTO_REJECT_REASON,
+ FMA, reason)
+ : &skip_failover_option),
+ (errmsg
+ ? dhcp_failover_make_option (FTO_MESSAGE, FMA,
+ strlen (errmsg), errmsg)
+ : &skip_failover_option),
+ (failover_option_t *)0));
#if defined (DEBUG_FAILOVER_MESSAGES)
if (status != ISC_R_SUCCESS)
status = (dhcp_failover_put_message
(link, l -> outer,
FTM_DISCONNECT,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
dhcp_failover_make_option (FTO_REJECT_REASON,
FMA, reason),
(message
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_BNDUPD,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
dhcp_failover_make_option (FTO_ASSIGNED_IP_ADDRESS, FMA,
lease -> ip_addr.len,
lease -> ip_addr.iabuf),
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_BNDACK,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
dhcp_failover_make_option (FTO_ASSIGNED_IP_ADDRESS, FMA,
sizeof msg -> assigned_addr,
&msg -> assigned_addr),
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_POOLREQ,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
(failover_option_t *)0));
#if defined (DEBUG_FAILOVER_MESSAGES)
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_POOLREQ,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
dhcp_failover_make_option (FTO_ADDRESSES_TRANSFERRED, FMA,
leases),
(failover_option_t *)0));
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_UPDREQ,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
(failover_option_t *)0));
#if defined (DEBUG_FAILOVER_MESSAGES)
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_UPDREQALL,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
(failover_option_t *)0));
#if defined (DEBUG_FAILOVER_MESSAGES)
status = (dhcp_failover_put_message
(link, link -> outer,
FTM_UPDDONE,
- dhcp_failover_make_option (FTO_SERVER_STATE, FMA,
- state -> my_state),
- dhcp_failover_make_option
- (FTO_SERVER_FLAGS, FMA,
- (state -> service_state == service_startup
- ? FTF_STARTUP : 0)),
(failover_option_t *)0));
#if defined (DEBUG_FAILOVER_MESSAGES)
if (msg -> options_present & FTB_BINDING_STATUS) {
/* If we're in normal state, make sure the state transition
we got is valid. */
- if (state -> my_state == normal) {
+ if (state -> me.state == normal) {
new_binding_state = (binding_state_transition_check
(lease, state,
msg -> binding_status));
dhcp_failover_process_update_request (dhcp_failover_state_t *state,
failover_message_t *msg)
{
- /* Make sure we catch the peer state change *first*. */
- dhcp_failover_peer_state_changed (state, msg);
-
/* Generate a fresh update queue. */
dhcp_failover_generate_update_queue (state, 0);
dhcp_failover_process_update_request_all (dhcp_failover_state_t *state,
failover_message_t *msg)
{
- /* Make sure we catch the peer state change *first*. */
- dhcp_failover_peer_state_changed (state, msg);
-
/* Generate a fresh update queue that includes every lease. */
dhcp_failover_generate_update_queue (state, 1);
dhcp_failover_process_update_done (dhcp_failover_state_t *state,
failover_message_t *msg)
{
- /* Make sure we catch the peer state change *first*. */
- dhcp_failover_peer_state_changed (state, msg);
-
- switch (state -> my_state) {
+ switch (state -> me.state) {
case unknown_state:
case partner_down:
case normal:
break;
case recover:
- if (state -> my_stos + state -> mclt > cur_time)
- add_timeout ((int)(state -> my_stos + state -> mclt),
+ if (state -> me.stos + state -> mclt > cur_time)
+ add_timeout ((int)(state -> me.stos + state -> mclt),
dhcp_failover_recover_done,
state,
(tvref_t)omapi_object_reference,
if (peer -> i_am == primary)
return 1;
if (peer -> service_state == service_partner_down &&
- (lease -> tsfp < peer -> my_stos
- ? peer -> my_stos + peer -> mclt < cur_time
+ (lease -> tsfp < peer -> me.stos
+ ? peer -> me.stos + peer -> mclt < cur_time
: lease -> tsfp + peer -> mclt < cur_time))
return 1;
return 0;
case FTS_BOOTP:
case FTS_RESERVED:
if (peer -> service_state == service_partner_down &&
- (lease -> tsfp < peer -> my_stos
- ? peer -> my_stos + peer -> mclt < cur_time
+ (lease -> tsfp < peer -> me.stos
+ ? peer -> me.stos + peer -> mclt < cur_time
: lease -> tsfp + peer -> mclt < cur_time))
return 1;
return 0;
if (peer -> i_am == secondary)
return 1;
if (peer -> service_state == service_partner_down &&
- (lease -> tsfp < peer -> my_stos
- ? peer -> my_stos + peer -> mclt < cur_time
+ (lease -> tsfp < peer -> me.stos
+ ? peer -> me.stos + peer -> mclt < cur_time
: lease -> tsfp + peer -> mclt < cur_time))
return 1;
return 0;