stf_status dpd_init(struct state *st) { /** * Used to store the 1st state */ #ifdef HAVE_LABELED_IPSEC if (st->st_connection->loopback) { libreswan_log( "dpd is not required for ipsec connections over loopback"); return STF_OK; } #endif struct state *p1st; /* find the related Phase 1 state */ p1st = find_state_ikev1(st->st_icookie, st->st_rcookie, 0); if (p1st == NULL) { loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD"); /* * if the phase 1 state has gone away, it really should have * deleted all of its children. * Why would this happen? because a quick mode SA can take * some time to create (DNS lookups for instance), and the phase 1 * might have been taken down for some reason in the meantime. * We really can not do anything here --- attempting to invoke * the DPD action would be a good idea, but we really should * do that outside this function. */ return STF_FAIL; } /* if it was enabled, and we haven't turned it on already */ if (p1st->hidden_variables.st_dpd) { time_t n = now(); libreswan_log("Dead Peer Detection (RFC 3706): enabled"); if (st->st_dpd_event == NULL || (st->st_connection->dpd_delay + n) < st->st_dpd_event->ev_time) { if (st->st_dpd_event != NULL) delete_dpd_event(st); event_schedule(EVENT_DPD, st->st_connection->dpd_delay, st); } } else { libreswan_log( "Dead Peer Detection (RFC 3706): not enabled because peer did not advertise it"); } if (p1st != st) { /* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */ if (p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD) delete_dpd_event(p1st); } return STF_OK; }
stf_status dpd_init(struct state *st) { /** * Used to store the 1st state */ struct state *p1st; /* find the related Phase 1 state */ p1st = find_state_ikev1(st->st_icookie, st->st_rcookie, 0); if (p1st == NULL) { loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD"); /* * if the phase 1 state has gone away, it really should have * deleted all of its children. * Why would this happen? because a quick mode SA can take * some time to create (DNS lookups for instance), and the phase 1 * might have been taken down for some reason in the meantime. * We really cannot do anything here --- attempting to invoke * the DPD action would be a good idea, but we really should * do that outside this function. */ return STF_FAIL; } /* if it was enabled, and we haven't turned it on already */ if (p1st->hidden_variables.st_peer_supports_dpd) { DBG(DBG_DPD, DBG_log("Dead Peer Detection (RFC 3706): enabled")); if (st->st_dpd_event == NULL || ev_before(st->st_dpd_event, st->st_connection->dpd_delay)){ if (st->st_dpd_event != NULL) delete_dpd_event(st); event_schedule(EVENT_DPD, deltasecs(st->st_connection->dpd_delay), st); } } else { loglog(RC_LOG_SERIOUS, "Configured DPD (RFC 3706) support not enabled because remote peer did not advertise DPD support"); } if (p1st != st) { /* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */ if (p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD) delete_dpd_event(p1st); } return STF_OK; }
/* * Only schedule a new timeout if there isn't one currently, * or if it would be sooner than the current timeout. */ static void dpd_sched_timeout(struct state *p1st, monotime_t nw, deltatime_t timeout) { passert(deltasecs(timeout) > 0); if (p1st->st_dpd_event == NULL || monobefore(monotimesum(nw, timeout), p1st->st_dpd_event->ev_time)) { DBG(DBG_DPD, DBG_log("DPD: scheduling timeout to %ld", (long)deltasecs(timeout))); if (p1st->st_dpd_event != NULL) delete_dpd_event(p1st); event_schedule(EVENT_DPD_TIMEOUT, deltasecs(timeout), p1st); } }
/* * Only schedule a new timeout if there isn't one currently, * or if it would be sooner than the current timeout. */ static void dpd_sched_timeout(struct state *p1st, time_t tm, time_t timeout) { passert(timeout > 0); if (p1st->st_dpd_event == NULL || p1st->st_dpd_event->ev_time > tm + timeout) { DBG(DBG_DPD, DBG_log("DPD: scheduling timeout to %lu", (unsigned long)timeout)); if (p1st->st_dpd_event != NULL) delete_dpd_event(p1st); event_schedule(EVENT_DPD_TIMEOUT, timeout, p1st); } }
/** * DPD Out Initiator * * @param p2st A state struct that is already in phase2 * @return void */ static void dpd_outI(struct state *p1st, struct state *st, bool eroute_care, deltatime_t delay, deltatime_t timeout) { monotime_t nw; monotime_t last; deltatime_t nextdelay; u_int32_t seqno; DBG(DBG_DPD, DBG_log("DPD: processing for state #%lu (\"%s\")", st->st_serialno, st->st_connection->name)); /* If no DPD, then get out of here */ if (!st->hidden_variables.st_peer_supports_dpd) { DBG(DBG_DPD, DBG_log("DPD: peer does not support dpd")); return; } /* If there is no state, there can be no DPD */ if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)) { DBG(DBG_DPD, DBG_log("DPD: no phase1 state, so no DPD")); return; } /* find out when now is */ nw = mononow(); /* * pick least recent activity value, since with multiple phase 2s, * it may well be that one phase 2 is very active, while the other * for some reason, gets stomped upon by some network screw up. * * (this would only happen if the network was sensitive to different * SPI#, since for NAT-T, all traffic should be on the same UDP port. * At worst, this means that we send a bit more traffic then we need * to when there are multiple SAs and one is much less active. * * ??? the code actually picks the most recent. So much for comments. */ last = !monobefore(p1st->st_last_dpd, st->st_last_dpd) ? p1st->st_last_dpd : st->st_last_dpd; nextdelay = monotimediff(monotimesum(last, delay), nw); /* has there been enough activity of late? */ if (deltasecs(nextdelay) > 0) { /* Yes, just reschedule "phase 2" */ DBG(DBG_DPD, DBG_log("DPD: not yet time for dpd event: %ld < %ld", (long)nw.mono_secs, (long)(last.mono_secs + deltasecs(delay)))); event_schedule(EVENT_DPD, deltasecs(nextdelay), st); return; } /* now plan next check time */ /* ??? this test is nuts: it will always succeed! */ if (deltasecs(nextdelay) < 1) nextdelay = delay; /* * check the phase 2, if we are supposed to, * and return if it is active recently */ if (eroute_care && st->hidden_variables.st_nat_traversal == LEMPTY && !was_eroute_idle(st, delay)) { DBG(DBG_DPD, DBG_log("DPD: out event not sent, phase 2 active")); /* update phase 2 time stamp only */ st->st_last_dpd = nw; /* * Since there was activity, kill any EVENT_DPD_TIMEOUT that might * be waiting. This can happen when a R_U_THERE_ACK is lost, and * subsequently traffic started flowing over the SA again, and no * more DPD packets are sent to cancel the outstanding DPD timer. */ if (p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD_TIMEOUT) { DBG(DBG_DPD, DBG_log("DPD: deleting p1st DPD event")); delete_dpd_event(p1st); } event_schedule(EVENT_DPD, deltasecs(nextdelay), st); return; } if (st != p1st) { /* * reschedule next event, since we cannot do it from the activity * routine. */ event_schedule(EVENT_DPD, deltasecs(nextdelay), st); } if (p1st->st_dpd_seqno == 0) { /* Get a non-zero random value that has room to grow */ get_rnd_bytes((u_char *)&p1st->st_dpd_seqno, sizeof(p1st->st_dpd_seqno)); p1st->st_dpd_seqno &= 0x7fff; p1st->st_dpd_seqno++; } seqno = htonl(p1st->st_dpd_seqno); /* make sure that the timeout occurs. We do this before the send, * because the send may fail due to network issues, etc, and * the timeout has to occur anyway */ dpd_sched_timeout(p1st, nw, timeout); DBG(DBG_DPD, { ipstr_buf b; DBG_log("DPD: sending R_U_THERE %u to %s:%d (state #%lu)", p1st->st_dpd_seqno, ipstr(&p1st->st_remoteaddr, &b), p1st->st_remoteport, p1st->st_serialno); });
/* delete a state object */ void delete_state(struct state *st) { struct connection *const c = st->st_connection; struct state *old_cur_state = cur_state == st? NULL : cur_state; openswan_log("deleting state #%lu (%s)", st->st_serialno, enum_show(&state_names, st->st_state)); /* * for most IKEv2 things, we may have further things to do after marking the state deleted, * so we do not actually free it here at all, but back in the main loop when all the work is done. */ if(st->st_ikev2) { /* child sa*/ if(st->st_clonedfrom != 0) { DBG(DBG_CONTROL, DBG_log("received request to delete child state")); if(st->st_state == STATE_CHILDSA_DEL) { DBG(DBG_CONTROL, DBG_log("now deleting the child state")); } else { /* Only send request if child sa is established * otherwise continue with deletion */ if(IS_CHILD_SA_ESTABLISHED(st)) { DBG(DBG_CONTROL, DBG_log("sending Child SA delete equest")); send_delete(st); change_state(st, STATE_CHILDSA_DEL); /* actual deletion when we receive peer response*/ return; } } } else { DBG(DBG_CONTROL, DBG_log("considering request to delete IKE parent state")); /* parent sa */ if(st->st_state == STATE_IKESA_DEL) { DBG(DBG_CONTROL, DBG_log("now deleting the IKE (or parent) state")); } else { /* Another check to verify if a secured * INFORMATIONAL exchange can be sent or not */ if(st->st_skey_ei.ptr && st->st_skey_ai.ptr && st->st_skey_er.ptr && st->st_skey_ar.ptr) { DBG(DBG_CONTROL, DBG_log("sending IKE SA delete request")); send_delete(st); change_state(st, STATE_IKESA_DEL); /* actual deletion when we receive peer response*/ return; } } } } /* If DPD is enabled on this state object, clear any pending events */ if(st->st_dpd_event != NULL) delete_dpd_event(st); /* if there is a suspended state transition, disconnect us */ if (st->st_suspended_md != NULL) { passert(st->st_suspended_md->st == st); DBG(DBG_CONTROL, DBG_log("disconnecting state #%lu from md", st->st_serialno)); st->st_suspended_md->st = NULL; } /* tell the other side of any IPSEC SAs that are going down */ if (IS_IPSEC_SA_ESTABLISHED(st->st_state) || IS_ISAKMP_SA_ESTABLISHED(st->st_state)) send_delete(st); delete_event(st); /* delete any pending timer event */ /* Ditch anything pending on ISAKMP SA being established. * Note: this must be done before the unhash_state to prevent * flush_pending_by_state inadvertently and prematurely * deleting our connection. */ flush_pending_by_state(st); /* if there is anything in the cryptographic queue, then remove this * state from it. */ delete_cryptographic_continuation(st); /* effectively, this deletes any ISAKMP SA that this state represents */ unhash_state(st); /* tell kernel to delete any IPSEC SA * ??? we ought to tell peer to delete IPSEC SAs */ if (IS_IPSEC_SA_ESTABLISHED(st->st_state) || IS_CHILD_SA_ESTABLISHED(st)) delete_ipsec_sa(st, FALSE); else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state)) delete_ipsec_sa(st, TRUE); if (c->newest_ipsec_sa == st->st_serialno) c->newest_ipsec_sa = SOS_NOBODY; if (c->newest_isakmp_sa == st->st_serialno) c->newest_isakmp_sa = SOS_NOBODY; /* * fake a state change here while we are still associated with a * connection. Without this the state logging (when enabled) cannot * work out what happened. */ fake_state(st, STATE_UNDEFINED); st->st_connection = NULL; /* we might be about to free it */ cur_state = old_cur_state; /* without st_connection, st isn't complete */ connection_discard(c); change_state(st, STATE_UNDEFINED); release_whack(st); change_state(st, STATE_CHILDSA_DEL); }
/** * 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(); }
/** * DPD out Responder * * @param st A state structure (phase 1) * @param n A notification (isakmp_notification) * @param pbs A PB Stream * @return stf_status */ stf_status dpd_inR(struct state *p1st , struct isakmp_notification *const n , pb_stream *pbs) { time_t tm = now(); u_int32_t seqno; if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)) { loglog(RC_LOG_SERIOUS, "recevied R_U_THERE_ACK for unestablished ISKAMP SA"); return STF_FAIL; } if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2) { loglog(RC_LOG_SERIOUS, "R_U_THERE_ACK has invalid SPI length (%d)", n->isan_spisize); return STF_FAIL + PAYLOAD_MALFORMED; } if (memcmp(pbs->cur, p1st->st_icookie, COOKIE_SIZE) != 0) { /* RFC states we *SHOULD* check cookies, not MUST. So invalid cookies are technically valid, as per Geoffrey Huang */ loglog(RC_LOG_SERIOUS, "R_U_THERE_ACK has invalid icookie"); } pbs->cur += COOKIE_SIZE; if (memcmp(pbs->cur, p1st->st_rcookie, COOKIE_SIZE) != 0) { /* RFC states we *SHOULD* check cookies, not MUST. So invalid cookies are technically valid, as per Geoffrey Huang */ loglog(RC_LOG_SERIOUS, "R_U_THERE_ACK has invalid rcookie (tolerated)"); } pbs->cur += COOKIE_SIZE; if (pbs_left(pbs) != sizeof(seqno)) { loglog(RC_LOG_SERIOUS, "R_U_THERE_ACK has invalid data length (%d)", (int) pbs_left(pbs)); return STF_FAIL + PAYLOAD_MALFORMED; } seqno = ntohl(*(u_int32_t *)pbs->cur); DBG(DBG_DPD, DBG_log("R_U_THERE_ACK, seqno received: %u expected: %u (state=#%lu)", seqno, p1st->st_dpd_expectseqno, p1st->st_serialno)); if (!p1st->st_dpd_expectseqno && seqno != p1st->st_dpd_expectseqno) { loglog(RC_LOG_SERIOUS, "R_U_THERE_ACK has unexpected sequence number (expected: %u got: %u", seqno, p1st->st_dpd_expectseqno); p1st->st_dpd_expectseqno = 0; /* do not update time stamp, so we'll send a new one sooner */ } else { /* update the time stamp */ p1st->st_last_dpd = tm; } p1st->st_dpd_expectseqno = 0; /* * since there was activity, kill any EVENT_DPD_TIMEOUT that might * be waiting. */ if(p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD_TIMEOUT) { delete_dpd_event(p1st); } return STF_IGNORE; }
/** * DPD in Initiator, out Responder * * @param st A state structure (the phase 1 state) * @param n A notification (isakmp_notification) * @param pbs A PB Stream * @return stf_status */ stf_status dpd_inI_outR(struct state *p1st , struct isakmp_notification *const n , pb_stream *pbs) { time_t tm = now(); u_int32_t seqno; if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)) { loglog(RC_LOG_SERIOUS, "DPD Error: received R_U_THERE for unestablished ISKAMP SA"); return STF_IGNORE; } if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2) { loglog(RC_LOG_SERIOUS, "DPD Error: R_U_THERE has invalid SPI length (%d)", n->isan_spisize); return STF_FAIL + PAYLOAD_MALFORMED; } if (memcmp(pbs->cur, p1st->st_icookie, COOKIE_SIZE) != 0) { /* RFC states we *SHOULD* check cookies, not MUST. So invalid cookies are technically valid, as per Geoffrey Huang */ loglog(RC_LOG_SERIOUS, "DPD Warning: R_U_THERE has invalid icookie (broken Cisco?)"); } pbs->cur += COOKIE_SIZE; if (memcmp(pbs->cur, p1st->st_rcookie, COOKIE_SIZE) != 0) { loglog(RC_LOG_SERIOUS, "DPD Warning: R_U_THERE has invalid rcookie (broken Cisco?)"); } pbs->cur += COOKIE_SIZE; if (pbs_left(pbs) != sizeof(seqno)) { loglog(RC_LOG_SERIOUS, "DPD Error: R_U_THERE has invalid data length (%d)", (int) pbs_left(pbs)); return STF_FAIL + PAYLOAD_MALFORMED; } seqno = ntohl(*(u_int32_t *)pbs->cur); if (p1st->st_dpd_peerseqno && seqno <= p1st->st_dpd_peerseqno) { loglog(RC_LOG_SERIOUS, "DPD Info: received old or duplicate R_U_THERE"); return STF_IGNORE; } DBG(DBG_DPD, DBG_log("received R_U_THERE seq:%u time:%lu (state=#%lu name=\"%s\")" , seqno , (unsigned long)tm , p1st->st_serialno, p1st->st_connection->name)); p1st->st_dpd_peerseqno = seqno; if (send_isakmp_notification(p1st, R_U_THERE_ACK , pbs->cur, pbs_left(pbs)) != STF_IGNORE) { loglog(RC_LOG_SERIOUS, "DPD Info: could not send R_U_THERE_ACK"); return STF_IGNORE; } /* update the time stamp */ p1st->st_last_dpd = tm; /* * since there was activity, kill any EVENT_DPD_TIMEOUT that might * be waiting. */ if(p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD_TIMEOUT) { delete_dpd_event(p1st); } return STF_IGNORE; }
stf_status dpd_init(struct state *st) { /** * Used to store the 1st state */ struct state *p1st; #ifdef CONSOLE_DEBUG time_start = time(NULL); #endif /* find the related Phase 1 state */ p1st = find_state(st->st_icookie, st->st_rcookie, &st->st_connection->that.host_addr, 0); if (p1st == NULL) { loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD"); /* * if the phase 1 state has gone away, it really should have * deleted all of its children. * Why would this happen? because a quick mode SA can take * some time to create (DNS lookups for instance), and the phase 1 * might have been taken down for some reason in the meantime. * We really can not do anything here --- attempting to invoke * the DPD action would be a good idea, but we really should * do that outside this function. */ return STF_FAIL; } /* if it was enabled, and we haven't turned it on already */ if (p1st->hidden_variables.st_dpd) { time_t n = now(); log("Dead Peer Detection (RFC 3706): enabled"); /* If st is a phase 2 state, so turn its DPD on. This is needed, because * DPD support is negotiated during phase 1. */ if (p1st != st) st->hidden_variables.st_dpd = p1st->hidden_variables.st_dpd; if(st->st_dpd_event == NULL || (st->st_connection->dpd_idle_timeout + n) < st->st_dpd_event->ev_time) { delete_dpd_event(st); event_schedule(EVENT_DPD, st->st_connection->dpd_idle_timeout, st); } } else { log("Dead Peer Detection (RFC 3706): not enabled because peer did not advertise it"); } if(p1st != st) { /* st was not a phase 1 SA, so kill the DPD_EVENT on the phase 1 */ if(p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD) { delete_dpd_event(p1st); } } return STF_OK; }
/** * DPD Out Initiator * * @param p2st A state struct that is already in phase2 * @return void */ static void dpd_outI(struct state *p1st, struct state *st, bool eroute_care, time_t delay, time_t timeout) { time_t tm; time_t last; u_int32_t seqno; bool eroute_idle; time_t nextdelay; DBG(DBG_DPD, DBG_log("DPD: processing for state #%lu (\"%s\")", st->st_serialno, st->st_connection->name)); /* If no DPD, then get out of here */ if (!st->hidden_variables.st_dpd) return; /* If there is no state, there can be no DPD */ if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)) return; /* find out when now is */ tm = now(); /* * pick least recent activity value, since with multiple phase 2s, * it may well be that one phase 2 is very active, while the other * for some reason, gets stomped upon by some network screw up. * * (this would only happen if the network was sensitive to different * SPI#, since for NAT-T, all traffic should be on the same UDP port. * At worst, this means that we send a bit more traffic then we need * to when there are multiple SAs and one is much less active. * */ last = (p1st->st_last_dpd < st->st_last_dpd ? st->st_last_dpd : p1st->st_last_dpd ); nextdelay = last + delay - tm; /* has there been enough activity of late? */ if (nextdelay > 0) { /* Yes, just reschedule "phase 2" */ DBG(DBG_DPD, DBG_log("DPD: not yet time for dpd event: %lu < %lu", (unsigned long)tm, (unsigned long)(last + delay))); event_schedule(EVENT_DPD, nextdelay, st); return; } /* now plan next check time */ if (nextdelay < 1) nextdelay = delay; /* * check the phase 2, if we are supposed to, * and return if it is active recently */ if (eroute_care && !st->hidden_variables.st_nat_traversal) { eroute_idle = was_eroute_idle(st, delay); if (!eroute_idle) { DBG(DBG_DPD, DBG_log("DPD: out event not sent, phase 2 active")); /* update phase 2 time stamp only */ st->st_last_dpd = tm; /* * Since there was activity, kill any EVENT_DPD_TIMEOUT that might * be waiting. This can happen when a R_U_THERE_ACK is lost, and * subsequently traffic started flowing over the SA again, and no * more DPD packets are sent to cancel the outstanding DPD timer. */ if (p1st->st_dpd_event != NULL && p1st->st_dpd_event->ev_type == EVENT_DPD_TIMEOUT) delete_dpd_event(p1st); event_schedule(EVENT_DPD, nextdelay, st); return; } } if (st != p1st) { /* * reschedule next event, since we can not do it from the activity * routine. */ event_schedule(EVENT_DPD, nextdelay, st); } if (!p1st->st_dpd_seqno) { /* Get a non-zero random value that has room to grow */ get_rnd_bytes((u_char *)&p1st->st_dpd_seqno, sizeof(p1st->st_dpd_seqno)); p1st->st_dpd_seqno &= 0x7fff; p1st->st_dpd_seqno++; } seqno = htonl(p1st->st_dpd_seqno); /* make sure that the timeout occurs. We do this before the send, * because the send may fail due to network issues, etc, and * the timeout has to occur anyway */ dpd_sched_timeout(p1st, tm, timeout); DBG(DBG_DPD, DBG_log("DPD: sending R_U_THERE %u to %s:%d (state #%lu)", p1st->st_dpd_seqno, ip_str(&p1st->st_remoteaddr), p1st->st_remoteport, p1st->st_serialno)); if (send_isakmp_notification(p1st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE) { loglog(RC_LOG_SERIOUS, "DPD: could not send R_U_THERE"); return; } st->st_last_dpd = tm; p1st->st_last_dpd = tm; p1st->st_dpd_expectseqno = p1st->st_dpd_seqno++; }