⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 failover.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 status;	dhcp_failover_listener_t *obj, *l;	omapi_value_t *value = (omapi_value_t *)0;	omapi_addr_t local_addr;	unsigned long port;	status = omapi_get_value_str (h, (omapi_object_t *)0,				      "local-port", &value);	if (status != ISC_R_SUCCESS)		return status;	if (!value -> value) {		omapi_value_dereference (&value, MDL);		return ISC_R_INVALIDARG;	}		status = omapi_get_int_value (&port, value -> value);	omapi_value_dereference (&value, MDL);	if (status != ISC_R_SUCCESS)		return status;	local_addr.port = port;	status = omapi_get_value_str (h, (omapi_object_t *)0,				      "local-address", &value);	if (status != ISC_R_SUCCESS)		return status;	if (!value -> value) {	      nogood:		omapi_value_dereference (&value, MDL);		return ISC_R_INVALIDARG;	}		if (value -> value -> type != omapi_datatype_data ||	    value -> value -> u.buffer.len != sizeof (struct in_addr))		goto nogood;	memcpy (local_addr.address, value -> value -> u.buffer.value,		value -> value -> u.buffer.len);	local_addr.addrlen = value -> value -> u.buffer.len;	local_addr.addrtype = AF_INET;	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 -> address = local_addr;		status = omapi_listen_addr ((omapi_object_t *)obj, &obj -> address, 1);	if (status != ISC_R_SUCCESS)		return status;	status = omapi_object_reference (&h -> outer,					 (omapi_object_t *)obj, MDL);	if (status != ISC_R_SUCCESS) {		dhcp_failover_listener_dereference (&obj, MDL);		return status;	}	status = omapi_object_reference (&obj -> inner, h, MDL);	if (status != ISC_R_SUCCESS) {		dhcp_failover_listener_dereference (&obj, MDL);		return status;	}	/* Put this listener on the list. */	if (failover_listeners) {		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);}/* Signal handler for protocol listener - if we get a connect signal,   create a new protocol connection, otherwise pass the signal down. */isc_result_t dhcp_failover_listener_signal (omapi_object_t *o,					    const char *name, va_list ap){	isc_result_t status;	omapi_connection_object_t *c;	dhcp_failover_link_t *obj;	dhcp_failover_listener_t *p;	dhcp_failover_state_t *s, *state = (dhcp_failover_state_t *)0;	if (!o || o -> type != dhcp_type_failover_listener)		return ISC_R_INVALIDARG;	p = (dhcp_failover_listener_t *)o;	/* Not a signal we recognize? */	if (strcmp (name, "connect")) {		if (p -> inner && p -> inner -> type -> signal_handler)			return (*(p -> inner -> type -> signal_handler))				(p -> inner, name, ap);		return ISC_R_NOTFOUND;	}	c = va_arg (ap, omapi_connection_object_t *);	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;			break;		}	}			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)		return status;	obj -> peer_port = ntohs (c -> remote_addr.sin_port);	status = omapi_object_reference (&obj -> outer,					 (omapi_object_t *)c, MDL);	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;	}	status = omapi_object_reference (&c -> inner,					 (omapi_object_t *)obj, MDL);	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);}isc_result_t dhcp_failover_listener_set_value (omapi_object_t *h,						omapi_object_t *id,						omapi_data_string_t *name,						omapi_typed_data_t *value){	if (h -> type != dhcp_type_failover_listener)		return ISC_R_INVALIDARG;		if (h -> inner && h -> inner -> type -> set_value)		return (*(h -> inner -> type -> set_value))			(h -> inner, id, name, value);	return ISC_R_NOTFOUND;}isc_result_t dhcp_failover_listener_get_value (omapi_object_t *h,						omapi_object_t *id,						omapi_data_string_t *name,						omapi_value_t **value){	if (h -> type != dhcp_type_failover_listener)		return ISC_R_INVALIDARG;		if (h -> inner && h -> inner -> type -> get_value)		return (*(h -> inner -> type -> get_value))			(h -> inner, id, name, value);	return ISC_R_NOTFOUND;}isc_result_t dhcp_failover_listener_destroy (omapi_object_t *h,					      const char *file, int line){	dhcp_failover_listener_t *l;	if (h -> type != dhcp_type_failover_listener)		return ISC_R_INVALIDARG;	l = (dhcp_failover_listener_t *)h;	if (l -> next)		dhcp_failover_listener_dereference (&l -> next, file, line);	return ISC_R_SUCCESS;}/* Write all the published values associated with the object through the   specified connection. */isc_result_t dhcp_failover_listener_stuff (omapi_object_t *c,					   omapi_object_t *id,					   omapi_object_t *p){	int i;	if (p -> type != dhcp_type_failover_listener)		return ISC_R_INVALIDARG;	if (p -> inner && p -> inner -> type -> stuff_values)		return (*(p -> inner -> type -> stuff_values)) (c, id,								p -> inner);	return ISC_R_SUCCESS;}/* Set up master state machine for the failover protocol. */isc_result_t dhcp_failover_register (omapi_object_t *h){	isc_result_t status;	dhcp_failover_state_t *obj;	unsigned long port;	omapi_value_t *value = (omapi_value_t *)0;	status = omapi_get_value_str (h, (omapi_object_t *)0,				      "local-port", &value);	if (status != ISC_R_SUCCESS)		return status;	if (!value -> value) {		omapi_value_dereference (&value, MDL);		return ISC_R_INVALIDARG;	}		status = omapi_get_int_value (&port, value -> value);	omapi_value_dereference (&value, MDL);	if (status != ISC_R_SUCCESS)		return status;	obj = (dhcp_failover_state_t *)0;	dhcp_failover_state_allocate (&obj, MDL);	obj -> me.port = port;		status = omapi_listen ((omapi_object_t *)obj, port, 1);	if (status != ISC_R_SUCCESS) {		dhcp_failover_state_dereference (&obj, MDL);		return status;	}	status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj,					 MDL);	if (status != ISC_R_SUCCESS) {		dhcp_failover_state_dereference (&obj, MDL);		return status;	}	status = omapi_object_reference (&obj -> inner, h, MDL);	dhcp_failover_state_dereference (&obj, MDL);	return status;}/* Signal handler for protocol state machine. */isc_result_t dhcp_failover_state_signal (omapi_object_t *o,					 const char *name, va_list ap){	isc_result_t status;	omapi_connection_object_t *c;	omapi_protocol_object_t *obj;	dhcp_failover_state_t *state;	dhcp_failover_link_t *link;	char *peer_name;	if (!o || o -> type != dhcp_type_failover_state)		return ISC_R_INVALIDARG;	state = (dhcp_failover_state_t *)o;	/* Not a signal we recognize? */	if (strcmp (name, "disconnect") &&	    strcmp (name, "message")) {		if (state -> inner && state -> inner -> type -> signal_handler)			return (*(state -> inner -> type -> signal_handler))				(state -> inner, name, ap);		return ISC_R_NOTFOUND;	}	/* Handle connect signals by seeing what state we're in	   and potentially doing a state transition. */	if (!strcmp (name, "disconnect")) {		link = va_arg (ap, dhcp_failover_link_t *);		dhcp_failover_link_dereference (&state -> link_to_peer, MDL);		dhcp_failover_state_transition (state, "disconnect");		if (state -> i_am == primary) {#if defined (DEBUG_FAILOVER_TIMING)			log_info ("add_timeout +90 %s",				  "dhcp_failover_reconnect");#endif			add_timeout (cur_time + 90, dhcp_failover_reconnect,				     state,				     (tvref_t)dhcp_failover_state_reference,				     (tvunref_t)				     dhcp_failover_state_dereference);		}	} else if (!strcmp (name, "message")) {		link = va_arg (ap, dhcp_failover_link_t *);		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 Probably not - what if both peers start at			   XXX the same time? */			if (state -> link_to_peer) {				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				  ((omapi_object_t *)link, state, 0, 0));			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;			}			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;		    cancel_timeout (dhcp_failover_link_startup_timeout,				    link);		    if (link -> imsg -> reject_reason) {			log_error ("Failover CONNECT to %u.%u.%u.%u%s%s",				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [0],				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [1],				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [2],				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [3],				   " rejected: ",				   (dhcp_failover_reject_reason_print				    (link -> imsg -> reject_reason)));			/* XXX print message from peer if peer sent message. */			omapi_disconnect (link -> outer, 1);			return ISC_R_SUCCESS;		    }				      		    if (!dhcp_failover_state_match			(state,			 (u_int8_t *)&link -> imsg -> server_addr,			 sizeof link -> imsg -> server_addr)) {			errmsg = "unknown server";			reason = FTR_INVALID_PARTNER;		      badconnectack:			log_error ("Failover CONNECTACK from %u.%u.%u.%u: %s",				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [0],				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [1],				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [2],				   ((u_int8_t *)				    (&link -> imsg -> server_addr)) [3],				   errmsg);			dhcp_failover_send_disconnect ((omapi_object_t *)link,						       reason, errmsg);			omapi_disconnect (link -> outer, 0);			return ISC_R_SUCCESS;		    }		    if (state -> link_to_peer) {			errmsg = "already connected";			reason = FTR_DUP_CONNECTION;			goto badconnectack;		    }		    if ((cur_time > link -> imsg -> time &&			 cur_time - link -> imsg -> time > 60) ||			(cur_time < link -> imsg -> time &&			 link -> imsg -> time - cur_time > 60)) {			    errmsg = "time offset too large";			    reason = FTR_TIMEMISMATCH;			    goto badconnectack;		    }		    dhcp_failover_link_reference (&state -> link_to_peer,						  link, MDL);#if 0		    /* XXX This is probably the right thing to do, but		       XXX for release three, to make the smallest possible		       XXX change, we are doing this when the peer state		       XXX changes instead. */		    if (state -> me.state == startup)			    dhcp_failover_set_state (state,						     state -> saved_state);		    else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -