Ejemplo n.º 1
0
/**
 * DPD Timeout Function
 *
 * This function is called when a timeout DPD_EVENT occurs.  We set clear/trap
 * both the SA and the eroutes, depending on what the connection definition
 * tells us (either 'hold' or 'clear')
 *
 * @param st A state structure that is fully negotiated
 * @return void
 */
void dpd_timeout(struct state *st)
{
	struct connection *c = st->st_connection;
	int action = c->dpd_action;

	/** delete the state, which is probably in phase 2 */
	set_cur_connection(c);

	libreswan_log("DPD: No response from peer - declaring peer dead");

	switch (action) {
	case DPD_ACTION_HOLD:
		/** dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
		    leak traffic.  Also, being in %trap means new packets will
		    force an initiation of the conn again.  */
		libreswan_log("DPD: Putting connection into %%trap");
		if (c->kind == CK_INSTANCE) {
			DBG(DBG_DPD,
			    DBG_log(
				    "DPD: warning dpdaction=hold on instance futile - will be deleted"));
		}
		delete_states_by_connection(c, TRUE);
		break;

	case DPD_ACTION_CLEAR:
		/** dpdaction=clear - Wipe the SA & eroute - everything */

		libreswan_log("DPD: Clearing Connection");
		/*
		 * For CK_INSTANCE, delete_states_by_connection() will clear
		 * Note that delete_states_by_connection changes c->kind but we need
		 * to remember what it was to know if we still need to unroute after delete
		 */
		if (c->kind == CK_INSTANCE) {
			delete_states_by_connection(c, TRUE);
		} else {
			flush_pending_by_connection(c); /* remove any partial negotiations that are failing */
			delete_states_by_connection(c, TRUE);
			DBG(DBG_DPD,
			    DBG_log("DPD: unrouting connection (%s)",
				    enum_name(&connection_kind_names,
					      c->kind)));
			unroute_connection(c); /* --unroute */
		}
		break;

	case DPD_ACTION_RESTART:
		/* dpdaction=restart - immediately renegotiate connections to the same peer. */
		libreswan_log(
			"DPD: Restarting all connections that share this peer");
		restart_connections_by_peer(c);
		break;

	default:
		bad_case(action);
	}
	reset_cur_connection();
}
Ejemplo n.º 2
0
/**
 * DPD Timeout Function
 *
 * This function is called when a timeout DPD_EVENT occurs.  We set clear/trap
 * both the SA and the eroutes, depending on what the connection definition
 * tells us (either 'hold' or 'clear')
 *
 * @param st A state structure that is fully negotiated 
 * @return void
 */
void
dpd_timeout(struct state *st)
{
    int action;
    struct connection *c = st->st_connection;
    action = st->st_connection->dpd_action;
    
    /* probably wrong thing to assert here */
    passert(action == DPD_ACTION_HOLD
	    || action == DPD_ACTION_CLEAR
	    || action == DPD_ACTION_RESTART);
        
    /** delete the state, which is probably in phase 2 */
    set_cur_connection(c);

    log("DPD: No response from peer - declaring peer dead");

    switch(action) {
    case DPD_ACTION_HOLD:
	/** dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
	    leak traffic.  Also, being in %trap means new packets will
	    force an initiation of the conn again.  */
	log("DPD: Putting connection into %%trap");
	delete_states_by_connection(c);
	break;

    case DPD_ACTION_CLEAR:
        /** dpdaction=clear - Wipe the SA & eroute - everything */
    
        log("DPD: Clearing Connection");
	delete_states_by_connection(c);
	DBG(DBG_DPD, DBG_log("unrouting connection"));
        unroute_connection(c);        /* --unroute */
	break;

    case DPD_ACTION_RESTART:
	/** dpdaction=restart - immediate renegotiate the connection. */
        log("DPD: Restarting Connection");

	/* we replace the SA so that we do it in a rational place */
	delete_event(st);
	event_schedule(EVENT_SA_REPLACE, 0, st);
	break;
    }
    reset_cur_connection();
}
Ejemplo n.º 3
0
/**
 * DPD Timeout Function
 *
 * This function is called when a timeout DPD_EVENT occurs.  We set clear/trap
 * both the SA and the eroutes, depending on what the connection definition
 * tells us (either 'hold' or 'clear')
 *
 * @param st A state structure that is fully negotiated 
 * @return void
 */
void
dpd_timeout(struct state *st)
{
    int action;
    struct connection *c = st->st_connection;
    action = st->st_connection->dpd_action;
    
    /* probably wrong thing to assert here */
    passert(action == DPD_ACTION_HOLD
	    || action == DPD_ACTION_CLEAR
	    || action == DPD_ACTION_RESTART
	    || action == DPD_ACTION_RESTART_BY_PEER
	    );
        
    /** delete the state, which is probably in phase 2 */
    set_cur_connection(c);

    openswan_log("DPD: No response from peer - declaring peer dead");

    switch(action) {
    case DPD_ACTION_HOLD:
	/** dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
	    leak traffic.  Also, being in %trap means new packets will
	    force an initiation of the conn again.  */
	openswan_log("DPD: Putting connection into %%trap");
	delete_states_by_connection(c, TRUE);  
	break;

    case DPD_ACTION_CLEAR:
        /** dpdaction=clear - Wipe the SA & eroute - everything */
    
        openswan_log("DPD: Clearing Connection");
	delete_states_by_connection(c, TRUE);
	DBG(DBG_DPD, DBG_log("unrouting connection"));
        unroute_connection(c);        /* --unroute */
	break;

    case DPD_ACTION_RESTART:
	/** dpdaction=restart - immediate renegotiate the connection. */
        openswan_log("DPD: Restarting Connection");

	/*
	 * unlike the other kinds, we do not delete any states,
	 * but rather, we arrange to replace all SAs involved.
	 */
	rekey_p2states_by_connection(c);

	if (c->kind == CK_INSTANCE) {
		/* If this is a template (eg: right=%any) we won't be able to
		 * reinitiate, the peer has probably changed IP addresses,
		 * or isn't available anymore.  So remove the routes too */
	        unroute_connection(c);        /* --unroute */
	}

	/* we schedule the replace of the SA so that we do it
	 * in a rational place and do it at a negative future time,
	 * so it will occur before any of the phase 2 replacements.
	 */
	delete_event(st);
	delete_dpd_event(st);
	event_schedule(EVENT_SA_REPLACE, 0, st);

	case DPD_ACTION_RESTART_BY_PEER:
	/* dpdaction=restart_by_peer - immediately renegotiate connections to the same peer. */
	openswan_log("DPD: Restarting all connections that share this peer");
	restart_connections_by_peer(c);
	break;

	break;
    }
    reset_cur_connection();
}
Ejemplo n.º 4
0
static int
initiate_a_connection(struct connection *c
		      , void *arg)
{
    struct initiate_stuff *is = (struct initiate_stuff *)arg;
    int whackfd = is->whackfd;
    lset_t moredebug = is->moredebug;
    enum crypto_importance importance = is->importance;
    int success = 0;

    set_cur_connection(c);

    /* turn on any extra debugging asked for */
    c->extra_debugging |= moredebug;

    if (!oriented(*c))
    {
	loglog(RC_ORIENT, "We cannot identify ourselves with either end of this connection.");
    }
    else if (NEVER_NEGOTIATE(c->policy))
    {
	loglog(RC_INITSHUNT
	       , "cannot initiate an authby=never connection");
    }
    else if (c->kind != CK_PERMANENT)
    {
	if (isanyaddr(&c->spd.that.host_addr)) {
#ifdef DYNAMICDNS
	    if (c->dnshostname != NULL) {
		loglog(RC_NOPEERIP, "cannot initiate connection without resolved dynamic peer IP address, will keep retrying");
		success = 1;
		c->policy |= POLICY_UP;
	    } else
#endif
		loglog(RC_NOPEERIP, "cannot initiate connection without knowing peer IP address (kind=%s)"
		       , enum_show(&connection_kind_names, c->kind));
	} else
	    loglog(RC_WILDCARD, "cannot initiate connection with ID wildcards (kind=%s)"
		   , enum_show(&connection_kind_names, c->kind));
    }
    else
    {
	/* We will only request an IPsec SA if policy isn't empty
	 * (ignoring Main Mode items).
	 * This is a fudge, but not yet important.
	 * If we are to proceed asynchronously, whackfd will be NULL_FD.
	 */
	c->policy |= POLICY_UP;

	if(c->policy & (POLICY_ENCRYPT|POLICY_AUTHENTICATE)) {
	    struct alg_info_esp *alg = c->alg_info_esp;
	    struct db_sa *phase2_sa = kernel_alg_makedb(c->policy, alg, TRUE);

	    if(alg != NULL && phase2_sa == NULL) {
		whack_log(RC_NOALGO, "can not initiate: no acceptable kernel algorithms loaded");
		reset_cur_connection();
		close_any(is->whackfd);
		return 0;
	    }
	    free_sa(phase2_sa);
	}

	{
	    whackfd = dup(whackfd);
	    ipsecdoi_initiate(whackfd, c, c->policy, 1
			      , SOS_NOBODY, importance
                              , NULL_POLICY
			     );
	    success = 1;
	}
    }
    reset_cur_connection();

    return success;
}