1: /* failover.h
2:
3: Definitions for address trees... */
4:
5: /*
6: * Copyright (c) 2004,2005,2007,2009
7: * by Internet Systems Consortium, Inc. ("ISC")
8: * Copyright (c) 2000-2003 by Internet Software Consortium
9: *
10: * Permission to use, copy, modify, and distribute this software for any
11: * purpose with or without fee is hereby granted, provided that the above
12: * copyright notice and this permission notice appear in all copies.
13: *
14: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21: *
22: * Internet Systems Consortium, Inc.
23: * 950 Charter Street
24: * Redwood City, CA 94063
25: * <info@isc.org>
26: * https://www.isc.org/
27: *
28: * This software has been written for Internet Systems Consortium
29: * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
30: * To learn more about Internet Systems Consortium, see
31: * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
32: * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
33: * ``http://www.nominum.com''.
34: */
35:
36: #if defined (FAILOVER_PROTOCOL)
37: struct failover_option_info {
38: int code;
39: const char *name;
40: enum { FT_UINT8, FT_IPADDR, FT_UINT32, FT_BYTES, FT_TEXT_OR_BYTES,
41: FT_DDNS, FT_DDNS1, FT_UINT16, FT_TEXT,
42: FT_UNDEF, FT_DIGEST } type;
43: int num_present;
44: int offset;
45: u_int32_t bit;
46: };
47:
48: typedef struct {
49: unsigned count;
50: u_int8_t *data;
51: } failover_option_t;
52:
53: /* Failover configuration defaults. */
54: #ifndef DEFAULT_MAX_BALANCE_TIME
55: # define DEFAULT_MAX_BALANCE_TIME 3600
56: #endif
57:
58: #ifndef DEFAULT_MIN_BALANCE_TIME
59: # define DEFAULT_MIN_BALANCE_TIME 60
60: #endif
61:
62: #ifndef DEFAULT_MAX_LEASE_MISBALANCE
63: # define DEFAULT_MAX_LEASE_MISBALANCE 15
64: #endif
65:
66: #ifndef DEFAULT_MAX_LEASE_OWNERSHIP
67: # define DEFAULT_MAX_LEASE_OWNERSHIP 10
68: #endif
69:
70: #ifndef DEFAULT_MAX_FLYING_UPDATES
71: # define DEFAULT_MAX_FLYING_UPDATES 100
72: #endif
73:
74: #ifndef DEFAULT_MAX_RESPONSE_DELAY
75: # define DEFAULT_MAX_RESPONSE_DELAY 20
76: #endif
77:
78: #define FM_OFFSET(x) (long)(&(((failover_message_t *)0) -> x))
79:
80: /* All of the below definitions are mandated by draft-ietf-dhc-failover-12.
81: * The Sections referenced are Sections within that document of that
82: * version, and may be different in other documents of other versions.
83: */
84:
85: /* Failover message options from Section 12: */
86: #define FTO_ADDRESSES_TRANSFERRED 1
87: #define FTB_ADDRESSES_TRANSFERRED 0x00000002
88: #define FTO_ASSIGNED_IP_ADDRESS 2
89: #define FTB_ASSIGNED_IP_ADDRESS 0x00000004
90: #define FTO_BINDING_STATUS 3
91: #define FTB_BINDING_STATUS 0x00000008
92: #define FTO_CLIENT_IDENTIFIER 4
93: #define FTB_CLIENT_IDENTIFIER 0x00000010
94: #define FTO_CHADDR 5
95: #define FTB_CHADDR 0x00000020
96: #define FTO_CLTT 6
97: #define FTB_CLTT 0x00000040
98: #define FTO_REPLY_OPTIONS 7
99: #define FTB_REPLY_OPTIONS 0x00000080
100: #define FTO_REQUEST_OPTIONS 8
101: #define FTB_REQUEST_OPTIONS 0x00000100
102: #define FTO_DDNS 9
103: #define FTB_DDNS 0x00000200
104: #define FTO_DELAYED_SERVICE 10
105: #define FTB_DELAYED_SERVICE 0x00000400
106: #define FTO_HBA 11
107: #define FTB_HBA 0x00000800
108: #define FTO_IP_FLAGS 12
109: #define FTB_IP_FLAGS 0x00001000
110: #define FTO_LEASE_EXPIRY 13
111: #define FTB_LEASE_EXPIRY 0x00002000
112: #define FTO_MAX_UNACKED 14
113: #define FTB_MAX_UNACKED 0x00004000
114: #define FTO_MCLT 15
115: #define FTB_MCLT 0x00008000
116: #define FTO_MESSAGE 16
117: #define FTB_MESSAGE 0x00010000
118: #define FTO_MESSAGE_DIGEST 17
119: #define FTB_MESSAGE_DIGEST 0x00020000
120: #define FTO_POTENTIAL_EXPIRY 18
121: #define FTB_POTENTIAL_EXPIRY 0x00040000
122: #define FTO_RECEIVE_TIMER 19
123: #define FTB_RECEIVE_TIMER 0x00080000
124: #define FTO_PROTOCOL_VERSION 20
125: #define FTB_PROTOCOL_VERSION 0x00100000
126: #define FTO_REJECT_REASON 21
127: #define FTB_REJECT_REASON 0x00200000
128: #define FTO_RELATIONSHIP_NAME 22
129: #define FTB_RELATIONSHIP_NAME 0x00400000
130: #define FTO_SERVER_FLAGS 23
131: #define FTB_SERVER_FLAGS 0x00800000
132: #define FTO_SERVER_STATE 24
133: #define FTB_SERVER_STATE 0x01000000
134: #define FTO_STOS 25
135: #define FTB_STOS 0x02000000
136: #define FTO_TLS_REPLY 26
137: #define FTB_TLS_REPLY 0x04000000
138: #define FTO_TLS_REQUEST 27
139: #define FTB_TLS_REQUEST 0x08000000
140: #define FTO_VENDOR_CLASS 28
141: #define FTB_VENDOR_CLASS 0x10000000
142: #define FTO_VENDOR_OPTIONS 29
143: #define FTB_VENDOR_OPTIONS 0x20000000
144:
145: #define FTO_MAX FTO_VENDOR_OPTIONS
146:
147: /* Failover protocol message types from Section 6.1: */
148: #define FTM_POOLREQ 1
149: #define FTM_POOLRESP 2
150: #define FTM_BNDUPD 3
151: #define FTM_BNDACK 4
152: #define FTM_CONNECT 5
153: #define FTM_CONNECTACK 6
154: #define FTM_UPDREQALL 7
155: #define FTM_UPDDONE 8
156: #define FTM_UPDREQ 9
157: #define FTM_STATE 10
158: #define FTM_CONTACT 11
159: #define FTM_DISCONNECT 12
160:
161: /* Reject reasons from Section 12.21: */
162: #define FTR_ILLEGAL_IP_ADDR 1
163: #define FTR_FATAL_CONFLICT 2
164: #define FTR_MISSING_BINDINFO 3
165: #define FTR_TIMEMISMATCH 4
166: #define FTR_INVALID_MCLT 5
167: #define FTR_MISC_REJECT 6
168: #define FTR_DUP_CONNECTION 7
169: #define FTR_INVALID_PARTNER 8
170: #define FTR_TLS_UNSUPPORTED 9
171: #define FTR_TLS_UNCONFIGURED 10
172: #define FTR_TLS_REQUIRED 11
173: #define FTR_DIGEST_UNSUPPORTED 12
174: #define FTR_DIGEST_UNCONFIGURED 13
175: #define FTR_VERSION_MISMATCH 14
176: #define FTR_OUTDATED_BIND_INFO 15
177: #define FTR_LESS_CRIT_BIND_INFO 16
178: #define FTR_NO_TRAFFIC 17
179: #define FTR_HBA_CONFLICT 18
180: #define FTR_IP_NOT_RESERVED 19
181: #define FTR_IP_DIGEST_FAILURE 20
182: #define FTR_IP_MISSING_DIGEST 21
183: #define FTR_UNKNOWN 254
184:
185: /* Message size limitations defined in Section 6.1: */
186: #define DHCP_FAILOVER_MIN_MESSAGE_SIZE 12
187: #define DHCP_FAILOVER_MAX_MESSAGE_SIZE 2048
188:
189: /* Failover server flags from Section 12.23: */
190: #define FTF_SERVER_STARTUP 1
191:
192: /* DDNS flags from Section 12.9. These are really their names. */
193: #define FTF_DDNS_C 0x0001
194: #define FTF_DDNS_A 0x0002
195: #define FTF_DDNS_D 0x0004
196: #define FTF_DDNS_P 0x0008
197:
198: /* FTO_IP_FLAGS contents from Section 12.12: */
199: #define FTF_IP_FLAG_RESERVE 0x0001
200: #define FTF_IP_FLAG_BOOTP 0x0002
201:
202: /* FTO_MESSAGE_DIGEST Type Codes from Section 12.17: */
203: #define FTT_MESSAGE_DIGEST_HMAC_MD5 0x01
204:
205: typedef struct failover_message {
206: int refcnt;
207: struct failover_message *next;
208:
209: int options_present;
210:
211: u_int32_t time;
212: u_int32_t xid;
213: u_int8_t type;
214:
215: /* One-byte options. */
216: u_int8_t binding_status;
217: u_int8_t delayed_service;
218: u_int8_t protocol_version;
219: u_int8_t reject_reason;
220: u_int8_t server_flags;
221: u_int8_t server_state;
222: u_int8_t tls_reply;
223: u_int8_t tls_request;
224:
225: /* Two-byte options. */
226: u_int16_t ip_flags;
227:
228: /* Four-byte options. */
229: u_int32_t addresses_transferred;
230: u_int32_t assigned_addr;
231: u_int32_t cltt;
232: u_int32_t expiry;
233: u_int32_t max_unacked;
234: u_int32_t mclt;
235: u_int32_t potential_expiry;
236: u_int32_t receive_timer;
237: u_int32_t stos;
238:
239: /* Arbitrary field options. */
240: failover_option_t chaddr;
241: failover_option_t client_identifier;
242: failover_option_t hba;
243: failover_option_t message;
244: failover_option_t message_digest;
245: failover_option_t relationship_name;
246: failover_option_t reply_options;
247: failover_option_t request_options;
248: failover_option_t vendor_class;
249: failover_option_t vendor_options;
250:
251: /* Special contents options. */
252: ddns_fqdn_t ddns;
253: } failover_message_t;
254:
255: typedef struct {
256: OMAPI_OBJECT_PREAMBLE;
257: struct option_cache *peer_address;
258: unsigned peer_port;
259: int options_present;
260: enum dhcp_flink_state {
261: dhcp_flink_start,
262: dhcp_flink_message_length_wait,
263: dhcp_flink_message_wait,
264: dhcp_flink_disconnected,
265: dhcp_flink_state_max
266: } state;
267: failover_message_t *imsg;
268: struct _dhcp_failover_state *state_object;
269: u_int16_t imsg_len;
270: unsigned imsg_count;
271: u_int8_t imsg_payoff; /* Pay*load* offset. :') */
272: u_int32_t xid;
273: } dhcp_failover_link_t;
274:
275: typedef struct _dhcp_failover_listener {
276: OMAPI_OBJECT_PREAMBLE;
277: struct _dhcp_failover_listener *next;
278: omapi_addr_t address;
279: } dhcp_failover_listener_t;
280: #endif /* FAILOVER_PROTOCOL */
281:
282: /* A failover peer's running state. */
283: enum failover_state {
284: unknown_state = 0, /* XXX: Not a standard state. */
285: startup = 1,
286: normal = 2,
287: communications_interrupted = 3,
288: partner_down = 4,
289: potential_conflict = 5,
290: recover = 6,
291: paused = 7,
292: shut_down = 8,
293: recover_done = 9,
294: resolution_interrupted = 10,
295: conflict_done = 11,
296:
297: /* Draft revision 12 of the failover protocol documents a RECOVER-WAIT
298: * state, but does not enumerate its value in the section 12.24
299: * table. ISC DHCP 3.0.x used value 254 even though the state was
300: * not documented at all. For the time being, we will continue to use
301: * this value.
302: */
303: recover_wait = 254
304: };
305:
306: /* Service states are simplifications of failover states, particularly
307: useful because the startup state isn't actually implementable as a
308: separate failover state without maintaining a state stack. */
309:
310: enum service_state {
311: unknown_service_state,
312: cooperating,
313: not_cooperating,
314: service_partner_down,
315: not_responding,
316: service_startup
317: };
318:
319: #if defined (FAILOVER_PROTOCOL)
320: typedef struct _dhcp_failover_config {
321: struct option_cache *address;
322: int port;
323: u_int32_t max_flying_updates;
324: enum failover_state state;
325: TIME stos;
326: u_int32_t max_response_delay;
327: } dhcp_failover_config_t;
328:
329: typedef struct _dhcp_failover_state {
330: OMAPI_OBJECT_PREAMBLE;
331: struct _dhcp_failover_state *next;
332: char *name; /* Name of this failover instance. */
333: dhcp_failover_config_t me; /* My configuration. */
334: dhcp_failover_config_t partner; /* Partner's configuration. */
335: enum failover_state saved_state; /* Saved state during startup. */
336: struct data_string server_identifier; /* Server identifier (IP addr) */
337: u_int32_t mclt;
338:
339: u_int8_t *hba; /* Hash bucket array for load balancing. */
340: int load_balance_max_secs;
341:
342: u_int32_t max_lease_misbalance, max_lease_ownership;
343: u_int32_t max_balance, min_balance;
344: TIME last_balance, sched_balance;
345:
346: enum service_state service_state;
347: const char *nrr; /* Printable reason why we're in the
348: not_responding service state (empty
349: string if we are responding. */
350:
351: dhcp_failover_link_t *link_to_peer; /* Currently-established link
352: to peer. */
353:
354: enum {
355: primary, secondary
356: } i_am; /* We are primary or secondary in this relationship. */
357:
358: TIME last_packet_sent; /* Timestamp on last packet we sent. */
359: TIME last_timestamp_received; /* The last timestamp we sent that
360: has been returned by our partner. */
361: TIME skew; /* The skew between our clock and our partner's. */
362: struct lease *update_queue_head; /* List of leases we haven't sent
363: to peer. */
364: struct lease *update_queue_tail;
365:
366: struct lease *ack_queue_head; /* List of lease updates the peer
367: hasn't yet acked. */
368: struct lease *ack_queue_tail;
369:
370: struct lease *send_update_done; /* When we get a BNDACK for this
371: lease, send an UPDDONE message. */
372: int cur_unacked_updates; /* Number of updates we've sent
373: that have not yet been acked. */
374:
375: /* List of messages which we haven't
376: acked yet. */
377: failover_message_t *toack_queue_head;
378: failover_message_t *toack_queue_tail;
379: int pending_acks; /* Number of messages in the toack
380: queue. */
381: int pool_count; /* Number of pools referencing this
382: failover state object. */
383: int curUPD; /* If an UPDREQ* message is in motion,
384: this value indicates which one. */
385: u_int32_t updxid; /* XID of UPDREQ* message in action. */
386: } dhcp_failover_state_t;
387:
388: #define DHCP_FAILOVER_VERSION 1
389: #endif /* FAILOVER_PROTOCOL */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>