1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
/*
* timer event handling
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2001 D. Hugh Redelmeier.
* Copyright (C) 2005-2008 Michael Richardson <mcr@xelerance.com>
* Copyright (C) 2008-2010 Paul Wouters <paul@xelerance.com>
* Copyright (C) 2009 David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2012 Avesh Agarwal <avagarwa@redhat.com>
* Copyright (C) 2012-2015 Paul Wouters <pwouters@redhat.com>
* Copyright (C) 2013 Matt Rogers <mrogers@redhat.com>
* Copyright (C) 2017 Antony Antony <antony@phenome.org>
* Copyright (C) 2017-2019 Andrew Cagney <cagney@gnu.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "defs.h"
#include "state.h"
#include "ikev2_retransmit.h"
#include "passert.h"
#include "connections.h"
#include "log.h"
#include "pluto_stats.h"
#include "ikev2_send.h"
#include "pending.h"
#include "ikev2_replace.h"
#include "ikev2.h" /* for ikev2_retry_establishing_ike_sa() */
#include "routing.h"
#include "revival.h"
#include "terminate.h"
/*
* XXX: it is the IKE SA that is responsible for all retransmits.
*/
void event_v2_retransmit(struct state *ike_sa, monotime_t now UNUSED)
{
passert(ike_sa != NULL);
struct ike_sa *ike = pexpect_ike_sa(ike_sa);
if (ike == NULL) {
return;
}
/*
* Handle IKE SAs crossing-streams.
*
* Note: can't assume the connection's Child SA as been
* established as peer's established IKE SA can connswitch the
* Child leaving this negotiation in limbo.
*
* terminate_ike_family() gets to handle this.
*
* Note: a larger serialno does not mean superseded. Crossed
* streams could mean the lower serial established later and
* is the "newest". Hence the equality check (and not >).
*/
struct connection *c = ike->sa.st_connection;
if (!IS_IKE_SA_ESTABLISHED(&ike->sa) && c->established_ike_sa != SOS_NOBODY) {
/*
* The connection is established, yet this IKE SA is
* not. Presumably this means that the peer also
* initiated and established an IKE SA leaving this
* IKE SA in limbo.
*
* Note: since it isn't established it can't be the
* connection's established IKE SA.
*
* Note: this may also leave the Child SA for the
* connection in limbo. Hopefully revival code will
* pick that up.
*/
PEXPECT(ike->sa.logger, c->established_ike_sa != ike->sa.st_serialno);
llog(RC_LOG, ike->sa.logger,
"dropping negotiation as superseeded by established IKE SA #%lu",
c->established_ike_sa);
terminate_ike_family(&ike, REASON_SUPERSEDED_BY_NEW_SA, HERE);
return;
}
enum retransmit_action retransmit_action = retransmit(&ike->sa);
switch (retransmit_action) {
case RETRANSMIT_YES:
send_recorded_v2_message(ike, "EVENT_RETRANSMIT",
ike->sa.st_v2_msgid_windows.initiator.outgoing_fragments);
return;
case RETRANSMIT_NO:
return;
case RETRANSMIT_TIMEOUT:
case TIMEOUT_ON_RETRANSMIT:
/*
* Tell the connection so it can revive/retry if
* needed and then delete the state.
*/
terminate_ike_family(&ike, REASON_TOO_MANY_RETRANSMITS, HERE);
return;
}
bad_case(retransmit_action);
}
|