/** * 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(); }
void recv_pcap_packet_gen(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) { struct msg_digest *md; u_int32_t *dlt; struct iphdr *ip; struct udphdr *udp; u_char *ike; const struct iface_port *ifp = &if1; int packet_len; err_t from_ugh; union { struct sockaddr sa; struct sockaddr_in sa_in4; struct sockaddr_in6 sa_in6; } from; md = alloc_md(); dlt = (u_int32_t *)bytes; if (*dlt != PF_INET) return; ip = (struct iphdr *)(dlt + 1); udp = (struct udphdr *)(dlt + ip->ihl + 1); ike = (u_char *)(udp + 1); from.sa_in4.sin_addr.s_addr = ip->saddr; from.sa_in4.sin_port = udp->source; md->iface = ifp; packet_len = h->len - (ike - bytes); happy(anyaddr(addrtypeof(&ifp->ip_addr), &md->sender)); from_ugh = initaddr((void *) &from.sa_in4.sin_addr, sizeof(from.sa_in4.sin_addr), AF_INET, &md->sender); setportof(from.sa_in4.sin_port, &md->sender); md->sender_port = ntohs(from.sa_in4.sin_port); cur_from = &md->sender; cur_from_port = md->sender_port; /* Clone actual message contents * and set up md->packet_pbs to describe it. */ init_pbs(&md->packet_pbs, clone_bytes(ike, packet_len, "message buffer in comm_handle()"), packet_len, "packet"); DBG_log("*received %d bytes from %s:%u on %s (port=%d)", (int) pbs_room(&md->packet_pbs), ip_str(&md->sender), (unsigned) md->sender_port, ifp->ip_dev->id_rname, ifp->port); DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs)); process_packet(&md); if (md != NULL) release_md(md); cur_state = NULL; reset_cur_connection(); cur_from = NULL; }
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; }