/** * 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(); }
/** * 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(); }
/** * 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(); }
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; }