summaryrefslogtreecommitdiff
path: root/server/failover.c
diff options
context:
space:
mode:
authorShawn Routhier <sar@isc.org>2012-10-11 14:30:24 -0700
committerShawn Routhier <sar@isc.org>2012-10-11 14:30:24 -0700
commitdbd65517691c76acab15ab0059ec56d70ff72597 (patch)
treee8f9571cfddbee2aaf52fa022f857bb6e2f8042b /server/failover.c
parent30e4232753ce1eaaa526f8797ab07307752f42b1 (diff)
downloadisc-dhcp-dbd65517691c76acab15ab0059ec56d70ff72597.tar.gz
[master]
[ISC-Bugs #26108] Add a compile time option, enable-secs-byteorder, to deal with clients that do the byte ordering on the secs field incorrectly. This field should be in network byte order but some clients get it wrong. When this option is enabled the server will examine the secs field and if it looks wrong (high byte non zero and low byte zero) swap the bytes. The default is disabled. This option is only useful when doing load balancing within failover.
Diffstat (limited to 'server/failover.c')
-rw-r--r--server/failover.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/server/failover.c b/server/failover.c
index 5a6d37fc..56b07aa9 100644
--- a/server/failover.c
+++ b/server/failover.c
@@ -5840,38 +5840,52 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state)
struct data_string ds;
unsigned char hbaix;
int hm;
+ u_int16_t ec;
- if (state -> load_balance_max_secs < ntohs (packet -> raw -> secs)) {
- return 1;
+ ec = ntohs(packet->raw->secs);
+
+#if defined(SECS_BYTEORDER)
+ /*
+ * If desired check to see if the secs field may have been byte
+ * swapped. We assume it has if the high order byte isn't cleared
+ * while the low order byte is cleared. In this case we swap the
+ * bytes and continue processing.
+ */
+ if ((ec > 255) && ((ec & 0xff) == 0)) {
+ ec = (ec >> 8) | (ec << 8);
+ }
+#endif
+
+ if (state->load_balance_max_secs < ec) {
+ return (1);
}
/* If we don't have a hash bucket array, we can't tell if this
one's ours, so we assume it's not. */
- if (!state -> hba)
- return 0;
+ if (!state->hba)
+ return (0);
- oc = lookup_option (&dhcp_universe, packet -> options,
- DHO_DHCP_CLIENT_IDENTIFIER);
- memset (&ds, 0, sizeof ds);
+ oc = lookup_option(&dhcp_universe, packet->options,
+ DHO_DHCP_CLIENT_IDENTIFIER);
+ memset(&ds, 0, sizeof ds);
if (oc &&
- evaluate_option_cache (&ds, packet, (struct lease *)0,
- (struct client_state *)0,
- packet -> options, (struct option_state *)0,
- &global_scope, oc, MDL)) {
- hbaix = loadb_p_hash (ds.data, ds.len);
+ evaluate_option_cache(&ds, packet, NULL, NULL,
+ packet->options, NULL,
+ &global_scope, oc, MDL)) {
+ hbaix = loadb_p_hash(ds.data, ds.len);
data_string_forget(&ds, MDL);
} else {
- hbaix = loadb_p_hash (packet -> raw -> chaddr,
- packet -> raw -> hlen);
+ hbaix = loadb_p_hash(packet->raw->chaddr,
+ packet->raw->hlen);
}
hm = state->hba[(hbaix >> 3) & 0x1F] & (1 << (hbaix & 0x07));
- if (state -> i_am == primary)
- return hm;
+ if (state->i_am == primary)
+ return (hm);
else
- return !hm;
+ return (!hm);
}
/* The inverse of load_balance_mine ("load balance theirs"). We can't