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

📄 failover.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif			    dhcp_failover_send_state (state);		    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;#if defined (DEBUG_FAILOVER_TIMING)		    log_info ("add_timeout +%d %s",			      (int)state -> partner.max_response_delay / 3,			      "dhcp_failover_send_contact");#endif		    add_timeout (cur_time +				 (int)state -> partner.max_response_delay / 3,				 dhcp_failover_send_contact, state,				 (tvref_t)dhcp_failover_state_reference,				 (tvunref_t)dhcp_failover_state_dereference);#if defined (DEBUG_FAILOVER_TIMING)		    log_info ("add_timeout +%d %s",			      (int)state -> me.max_response_delay,			      "dhcp_failover_timeout");#endif		    add_timeout (cur_time +				 (int)state -> me.max_response_delay,				 dhcp_failover_timeout, state,				 (tvref_t)dhcp_failover_state_reference,				 (tvunref_t)dhcp_failover_state_dereference);		} else if (link -> imsg -> type == FTM_DISCONNECT) {		    if (link -> imsg -> reject_reason) {			log_error ("Failover DISCONNECT from %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],				   ": ",				   (dhcp_failover_reject_reason_print				    (link -> imsg -> reject_reason)));		    }		    omapi_disconnect (link -> outer, 1);		} else if (link -> imsg -> type == FTM_BNDUPD) {			dhcp_failover_process_bind_update (state,							   link -> imsg);		} else if (link -> imsg -> type == FTM_BNDACK) {			dhcp_failover_process_bind_ack (state, link -> imsg);		} else if (link -> imsg -> type == FTM_UPDREQ) {			dhcp_failover_process_update_request (state,							      link -> imsg);		} else if (link -> imsg -> type == FTM_UPDREQALL) {			dhcp_failover_process_update_request_all				(state, link -> imsg);		} else if (link -> imsg -> type == FTM_UPDDONE) {			dhcp_failover_process_update_done (state,							   link -> imsg);		} else if (link -> imsg -> type == FTM_POOLREQ) {			dhcp_failover_pool_rebalance (state);		} else if (link -> imsg -> type == FTM_POOLRESP) {			log_info ("pool response: %ld leases",				  (unsigned long)				  link -> imsg -> addresses_transferred);		} 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 -> link_to_peer &&		    state -> link_to_peer == link &&		    state -> link_to_peer -> state != dhcp_flink_disconnected)		{#if defined (DEBUG_FAILOVER_TIMING)		    log_info ("add_timeout +%d %s",			      (int)state -> me.max_response_delay,			      "dhcp_failover_timeout");#endif		    add_timeout (cur_time +				 (int)state -> me.max_response_delay,				 dhcp_failover_timeout, state,				 (tvref_t)dhcp_failover_state_reference,				 (tvunref_t)dhcp_failover_state_dereference);		}	}	/* Handle all the events we care about... */	return ISC_R_SUCCESS;}isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *state,					     const char *name){	isc_result_t status;	/* 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);		    dhcp_failover_link_dereference (&state -> link_to_peer,						    MDL);		}		cancel_timeout (dhcp_failover_send_contact, state);		cancel_timeout (dhcp_failover_timeout, state);		cancel_timeout (dhcp_failover_startup_timeout, state);		switch (state -> me.state == startup ?			state -> saved_state : state -> me.state) {		      case resolution_interrupted:		      case partner_down:		      case communications_interrupted:		      case recover:			/* 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, resolution_interrupted);						      case normal:			return dhcp_failover_set_state				(state, communications_interrupted);		      case unknown_state:			return dhcp_failover_set_state				(state, resolution_interrupted);		      case startup:			break;	/* can't happen. */		}	} else if (!strcmp (name, "connect")) {		switch (state -> me.state) {		      case communications_interrupted:			status = dhcp_failover_set_state (state, normal);			dhcp_failover_send_updates (state);			return status;		      case resolution_interrupted:			return dhcp_failover_set_state (state,							potential_conflict);		      case partner_down:		      case potential_conflict:		      case normal:		      case recover:		      case shut_down:		      case paused:		      case unknown_state:		      case recover_done:		      case startup:		      case recover_wait:			return dhcp_failover_send_state (state);		}	} else if (!strcmp (name, "startup")) {		dhcp_failover_set_state (state, startup);		return ISC_R_SUCCESS;	} else if (!strcmp (name, "connect-timeout")) {		switch (state -> me.state) {		      case communications_interrupted:		      case partner_down:		      case resolution_interrupted:			return ISC_R_SUCCESS;		      case normal:		      case recover:			return dhcp_failover_set_state				(state, communications_interrupted);		      case potential_conflict:			return dhcp_failover_set_state				(state, resolution_interrupted);		      case unknown_state:			return dhcp_failover_set_state				(state, communications_interrupted);		      default:			return dhcp_failover_set_state				(state, resolution_interrupted);		}	}	return ISC_R_INVALIDARG;}isc_result_t dhcp_failover_set_service_state (dhcp_failover_state_t *state){	switch (state -> me.state) {	      case unknown_state:		state -> service_state = not_responding;		state -> nrr = " (my state unknown)";		break;	      case partner_down:		state -> service_state = service_partner_down;		state -> nrr = "";		break;	      case normal:		state -> service_state = cooperating;		state -> nrr = "";		break;	      case communications_interrupted:		state -> service_state = not_cooperating;		state -> nrr = "";		break;	      case resolution_interrupted:	      case potential_conflict:		state -> service_state = not_responding;		state -> nrr = " (resolving conflicts)";		break;	      case recover:		state -> service_state = not_responding;		state -> nrr = " (recovering)";		break;	      case shut_down:		state -> service_state = not_responding;		state -> nrr = " (shut down)";		break;	      case paused:		state -> service_state = not_responding;		state -> nrr = " (paused)";		break;	      case recover_wait:		state -> service_state = not_responding;		state -> nrr = " (recover wait)";		break;	      case recover_done:		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) {		      case partner_down:			state -> service_state = not_responding;			state -> nrr = " (recovering)";			break;		      case potential_conflict:			state -> service_state = not_responding;			state -> nrr = " (resolving conflicts)";			break;			/* Other peer states don't affect our behaviour. */		      default:			break;		}	}	return ISC_R_SUCCESS;}isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,				      enum failover_state new_state){    enum failover_state saved_state;    TIME saved_stos;    struct pool *p;    struct shared_network *s;    struct lease *l;    /* First make the transition out of the current state. */    switch (state -> me.state) {      case normal:	/* Any updates that haven't been acked yet, we have to	   resend, just in case. */	if (state -> ack_queue_tail) {	    struct lease *lp;			    /* Zap the flags. */	    for (lp = state -> ack_queue_head; lp; lp = lp -> next_pending)		    lp -> flags = ((lp -> flags & ~ON_ACK_QUEUE) |				   ON_UPDATE_QUEUE);			    /* Now hook the ack queue to the beginning of the update	       queue. */	    if (state -> update_queue_head) {		lease_reference (&state -> ack_queue_tail -> next_pending,				 state -> update_queue_head, MDL);		lease_dereference (&state -> update_queue_head, MDL);	    }	    lease_reference (&state -> update_queue_head,			     state -> ack_queue_head, MDL);	    if (!state -> update_queue_tail) {#if defined (POINTER_DEBUG)		if (state -> ack_queue_tail -> next_pending) {		    log_error ("next pending on ack queue tail.");		    abort ();		}#endif		lease_reference (&state -> update_queue_tail,				 state -> ack_queue_tail, MDL);	    }	    lease_dereference (&state -> ack_queue_tail, MDL);	    lease_dereference (&state -> ack_queue_head, MDL);	    state -> cur_unacked_updates = 0;	}	cancel_timeout (dhcp_failover_keepalive, state);	break;	      case recover:      case recover_wait:      case recover_done:      case potential_conflict:      case partner_down:      case communications_interrupted:      case resolution_interrupted:      case startup:      default:	break;    }    /* Tentatively make the transition. */    saved_state = state -> me.state;    saved_stos = state -> me.stos;    /* Keep the old stos if we're going into recover_wait or if we're       coming into or out of startup. */    if (new_state != recover_wait && new_state != startup &&	saved_state != startup)	    state -> me.stos = cur_time;    /* If we're in shutdown, peer is in partner_down, and we're moving       to recover, we can skip waiting for MCLT to expire.    This happens       when a server is moved administratively into shutdown prior to       actually shutting down.   Of course, if there are any updates       pending we can't actually do this. */    if (new_state == recover && saved_state == shut_down &&	state -> partner.state == partner_down &&	!state -> update_queue_head && !state -> ack_queue_head)	    state -> me.stos = cur_time - state -> mclt;    state -> me.state = new_state;    if (new_state == startup && saved_state != startup)	state -> saved_state = saved_state;    /* If we can't record the new state, we can't make a state transition. */    if (!write_failover_state (state) || !commit_leases ()) {	    log_error ("Unable to record current failover state for %s",		       state -> name);	    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 -> me.state));        /* If we were in startup and we just left it, cancel the timeout. */    if (new_state != startup && saved_state == startup)	cancel_timeout (dhcp_failover_startup_timeout, state);    /* Set our service state. */    dhcp_failover_set_service_state (state);    /* Tell the peer about it. */    if (state -> link_to_peer)	    dhcp_failover_send_state (state);    switch (new_state) {	  case normal:	    if (state -> partner.state == normal)		    dhcp_failover_state_pool_check (state);	    break;	    	  case potential_conflict:	    if (state -> i_am == primary)		    dhcp_failover_send_update_request (state);	    break;	    	  case startup:#if defined (DEBUG_FAILOVER_TIMING)	    log_info ("add_timeout +15 %s",		      "dhcp_failover_startup_timeout");#endif	    add_timeout (cur_time + 15,			 dhcp_failover_startup_timeout,			 state,			 (tvref_t)omapi_object_reference,			 (tvunref_t)			 omapi_object_dereference);	    break;	    	    /* If we come back in recover_wait and there's still waiting	       to do, set a timeout. */	  case recover_wait:	    if (state -> me.stos + state -> mclt > cur_time) {#if defined (DEBUG_FAILOVER_TIMING)		    log_info ("add_timeout +%d %s",			      (int)(cur_time -				    state -> me.stos + state -> mclt),			      "dhcp_failover_startup_timeout");#endif		    add_timeout ((int)(state -> me.stos + state -> mclt),				 dhcp_failover_recover_done,				 state,				 (tvref_t)omapi_object_reference,				 (tvunref_t)				 omapi_object_dereference);	    } else		    dhcp_failover_recover_done (state);	    break;	    	  case recover:	    if (state -> link_to_peer)		    dhcp_failover_send_update_request_all (state);	    break;	  case partner_down:	    /* For every expired lease, set a timeout for it to become free. */

⌨️ 快捷键说明

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