| File: | programs/pluto/timer.c |
| Warning: | line 549, column 16 Access to field 'st_logger' results in a dereference of a null pointer (loaded from variable 'st') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* timer event handling | |||
| 2 | * | |||
| 3 | * Copyright (C) 1997 Angelos D. Keromytis. | |||
| 4 | * Copyright (C) 1998-2001 D. Hugh Redelmeier. | |||
| 5 | * Copyright (C) 2005-2008 Michael Richardson <mcr@xelerance.com> | |||
| 6 | * Copyright (C) 2008-2010 Paul Wouters <paul@xelerance.com> | |||
| 7 | * Copyright (C) 2009 David McCullough <david_mccullough@securecomputing.com> | |||
| 8 | * Copyright (C) 2012 Avesh Agarwal <avagarwa@redhat.com> | |||
| 9 | * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com> | |||
| 10 | * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com> | |||
| 11 | * Copyright (C) 2017 Antony Antony <antony@phenome.org> | |||
| 12 | * Copyright (C) 2017-2020 Andrew Cagney <cagney@gnu.org> | |||
| 13 | * | |||
| 14 | * This program is free software; you can redistribute it and/or modify it | |||
| 15 | * under the terms of the GNU General Public License as published by the | |||
| 16 | * Free Software Foundation; either version 2 of the License, or (at your | |||
| 17 | * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>. | |||
| 18 | * | |||
| 19 | * This program is distributed in the hope that it will be useful, but | |||
| 20 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |||
| 21 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
| 22 | * for more details. | |||
| 23 | */ | |||
| 24 | ||||
| 25 | #include <stdio.h> | |||
| 26 | #include <stdlib.h> | |||
| 27 | #include <sys/types.h> | |||
| 28 | #include <time.h> | |||
| 29 | #include <unistd.h> | |||
| 30 | #include <netinet/in.h> | |||
| 31 | #include <arpa/inet.h> | |||
| 32 | ||||
| 33 | #include <event2/event.h> | |||
| 34 | #include <event2/event_struct.h> | |||
| 35 | ||||
| 36 | #include "sysdep.h" | |||
| 37 | #include "constants.h" | |||
| 38 | #include "defs.h" | |||
| 39 | #include "id.h" | |||
| 40 | #include "x509.h" | |||
| 41 | #include "certs.h" | |||
| 42 | #include "connections.h" /* needs id.h */ | |||
| 43 | #include "state.h" | |||
| 44 | #include "packet.h" | |||
| 45 | #include "demux.h" /* needs packet.h */ | |||
| 46 | #include "ipsec_doi.h" /* needs demux.h and state.h */ | |||
| 47 | #include "kernel.h" /* needs connections.h */ | |||
| 48 | #include "server.h" | |||
| 49 | #include "log.h" | |||
| 50 | #include "rnd.h" | |||
| 51 | #include "timer.h" | |||
| 52 | #include "whack.h" | |||
| 53 | #include "ikev1_dpd.h" | |||
| 54 | #include "ikev2.h" | |||
| 55 | #include "ikev2_redirect.h" | |||
| 56 | #include "pending.h" /* for flush_pending_by_connection */ | |||
| 57 | #include "ikev1_xauth.h" | |||
| 58 | #ifdef USE_PAM_AUTH1 | |||
| 59 | #include "pam_auth.h" | |||
| 60 | #endif | |||
| 61 | #include "kernel.h" /* for kernel_ops */ | |||
| 62 | #include "nat_traversal.h" | |||
| 63 | #include "pluto_sd.h" | |||
| 64 | #include "ikev1_retry.h" | |||
| 65 | #include "ikev2_retry.h" | |||
| 66 | #include "fetch.h" /* for check_crls() */ | |||
| 67 | #include "pluto_stats.h" | |||
| 68 | #include "iface.h" | |||
| 69 | #include "ikev2_liveness.h" | |||
| 70 | #include "ikev2_mobike.h" | |||
| 71 | #include "ikev2_delete.h" /* for submit_v2_delete_exchange() */ | |||
| 72 | ||||
| 73 | struct state_event **state_event(struct state *st, enum event_type type) | |||
| 74 | { | |||
| 75 | /* | |||
| 76 | * Return a pointer to the event in the state object. | |||
| 77 | * | |||
| 78 | * XXX: why not just have an array and index it by KIND? | |||
| 79 | */ | |||
| 80 | switch (type) { | |||
| 81 | ||||
| 82 | case EVENT_v1_SEND_XAUTH: | |||
| 83 | return &st->st_v1_send_xauth_event; | |||
| 84 | ||||
| 85 | case EVENT_v2_LIVENESS: | |||
| 86 | return &st->st_v2_liveness_event; | |||
| 87 | ||||
| 88 | case EVENT_v2_ADDR_CHANGE: | |||
| 89 | return &st->st_v2_addr_change_event; | |||
| 90 | break; | |||
| 91 | ||||
| 92 | case EVENT_v2_REKEY: | |||
| 93 | return &st->st_v2_rekey_event; | |||
| 94 | break; | |||
| 95 | ||||
| 96 | case EVENT_v2_REAUTH: | |||
| 97 | return &st->st_v2_reauth_event; | |||
| 98 | break; | |||
| 99 | ||||
| 100 | case EVENT_DPD: | |||
| 101 | case EVENT_DPD_TIMEOUT: | |||
| 102 | return &st->st_dpd_event; | |||
| 103 | ||||
| 104 | case EVENT_RETRANSMIT: | |||
| 105 | return &st->st_retransmit_event; | |||
| 106 | ||||
| 107 | case EVENT_SA_DISCARD: | |||
| 108 | case EVENT_SA_REPLACE: | |||
| 109 | case EVENT_SA_EXPIRE: | |||
| 110 | case EVENT_v1_REPLACE_IF_USED: | |||
| 111 | case EVENT_CRYPTO_TIMEOUT: | |||
| 112 | case EVENT_PAM_TIMEOUT: | |||
| 113 | case EVENT_v2_REDIRECT: | |||
| 114 | /* | |||
| 115 | * Many of these don't make sense - however that's | |||
| 116 | * what happens when (the replaced) default: is used. | |||
| 117 | */ | |||
| 118 | return &st->st_event; | |||
| 119 | ||||
| 120 | case EVENT_RETAIN: | |||
| 121 | case EVENT_NULL: | |||
| 122 | return NULL((void*)0); | |||
| 123 | } | |||
| 124 | bad_case(type)libreswan_bad_case("type", (type), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 124, }; &here; })); | |||
| 125 | } | |||
| 126 | ||||
| 127 | /* | |||
| 128 | * This file has the event handling routines. Events are | |||
| 129 | * kept as a linked list of event structures. These structures | |||
| 130 | * have information like event type, expiration time and a pointer | |||
| 131 | * to event specific data (for example, to a state structure). | |||
| 132 | */ | |||
| 133 | ||||
| 134 | static void dispatch_event(struct state *st, enum event_type event_type, | |||
| 135 | deltatime_t event_delay); | |||
| 136 | static event_callback_routine timer_event_cb; | |||
| 137 | ||||
| 138 | static void timer_event_cb(evutil_socket_tint unused_fd UNUSED__attribute__ ((unused)), | |||
| 139 | const short unused_event UNUSED__attribute__ ((unused)), | |||
| 140 | void *arg) | |||
| 141 | { | |||
| 142 | /* | |||
| 143 | * Start billing before state is found. | |||
| 144 | */ | |||
| 145 | threadtime_t inception = threadtime_start(); | |||
| 146 | ||||
| 147 | /* | |||
| 148 | * Get rid of the old timer event before calling the timer | |||
| 149 | * event processor. | |||
| 150 | */ | |||
| 151 | struct state *st; | |||
| 152 | enum event_type event_type; | |||
| 153 | const char *event_name; | |||
| 154 | deltatime_t event_delay; | |||
| 155 | ||||
| 156 | { | |||
| 157 | struct state_event *ev = arg; | |||
| 158 | passert(ev != NULL)({ _Bool assertion__ = ev != ((void*)0); if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__ , .file = "programs/pluto/timer.c", .line = 158, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "ev != ((void*)0)"); } (void) 1; }); | |||
| 159 | event_type = ev->ev_type; | |||
| 160 | event_name = enum_name_short(&event_type_names, event_type); | |||
| 161 | event_delay = ev->ev_delay; | |||
| 162 | st = ev->ev_state; /* note: *st might be changed; XXX: why? */ | |||
| 163 | passert(st != NULL)({ _Bool assertion__ = st != ((void*)0); if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__ , .file = "programs/pluto/timer.c", .line = 163, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "st != ((void*)0)"); } (void) 1; }); | |||
| 164 | passert(event_name != NULL)({ _Bool assertion__ = event_name != ((void*)0); if (!assertion__ ) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 164, } ; &here; }); const struct logger *logger_ = &failsafe_logger ; llog_passert(logger_, here, "%s", "event_name != ((void*)0)" ); } (void) 1; }); | |||
| 165 | ||||
| 166 | dbg("%s: processing %s-event@%p for %s SA #%lu in state %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: processing %s-event@%p for %s SA #%lu in state %s" , __func__, event_name, ev, ((st)->st_clonedfrom == 0) ? "IKE" : "CHILD", st->st_serialno, st->st_state->short_name ); } } | |||
| 167 | __func__, event_name, ev,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: processing %s-event@%p for %s SA #%lu in state %s" , __func__, event_name, ev, ((st)->st_clonedfrom == 0) ? "IKE" : "CHILD", st->st_serialno, st->st_state->short_name ); } } | |||
| 168 | IS_IKE_SA(st) ? "IKE" : "CHILD",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: processing %s-event@%p for %s SA #%lu in state %s" , __func__, event_name, ev, ((st)->st_clonedfrom == 0) ? "IKE" : "CHILD", st->st_serialno, st->st_state->short_name ); } } | |||
| 169 | st->st_serialno, st->st_state->short_name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: processing %s-event@%p for %s SA #%lu in state %s" , __func__, event_name, ev, ((st)->st_clonedfrom == 0) ? "IKE" : "CHILD", st->st_serialno, st->st_state->short_name ); } }; | |||
| 170 | ||||
| 171 | struct state_event **evp = state_event(st, event_type); | |||
| 172 | if (evp == NULL((void*)0)) { | |||
| 173 | pexpect_failllog_pexpect(st->st_logger, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 173, }; &here; }), | |||
| 174 | "#%lu has no .st_event field for %s", | |||
| 175 | st->st_serialno, event_name); | |||
| 176 | return; | |||
| 177 | } | |||
| 178 | ||||
| 179 | if (*evp != ev) { | |||
| 180 | pexpect_failllog_pexpect(st->st_logger, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 180, }; &here; }), | |||
| 181 | "#%lu .st_event is %p but should be %s-pe@%p", | |||
| 182 | st->st_serialno, *evp, event_name, ev); | |||
| 183 | return; | |||
| 184 | } | |||
| 185 | ||||
| 186 | /* everything useful has been extracted */ | |||
| 187 | delete_pluto_event(evp); | |||
| 188 | arg = ev = *evp = NULL((void*)0); /* all gone */ | |||
| 189 | } | |||
| 190 | ||||
| 191 | statetime_t start = statetime_backdate(st, &inception); | |||
| 192 | dispatch_event(st, event_type, event_delay); | |||
| 193 | statetime_stop(&start, "%s() %s", __func__, event_name); | |||
| 194 | } | |||
| 195 | ||||
| 196 | static void dispatch_event(struct state *st, enum event_type event_type, | |||
| 197 | deltatime_t event_delay) | |||
| 198 | { | |||
| 199 | /* | |||
| 200 | * Check that st is as expected for the event type. | |||
| 201 | * | |||
| 202 | * For an event type associated with a state, remove the | |||
| 203 | * backpointer from the appropriate slot of the state object. | |||
| 204 | * | |||
| 205 | * We'll eventually either schedule a new event, or delete the | |||
| 206 | * state. | |||
| 207 | */ | |||
| 208 | switch (event_type) { | |||
| 209 | ||||
| 210 | case EVENT_v2_ADDR_CHANGE: | |||
| 211 | dbg("#%lu IKEv2 local address change", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu IKEv2 local address change", st->st_serialno ); } }; | |||
| 212 | ikev2_addr_change(st); | |||
| 213 | break; | |||
| 214 | ||||
| 215 | case EVENT_RETRANSMIT: | |||
| 216 | dbg("IKEv%d retransmit event", st->st_ike_version){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("IKEv%d retransmit event", st->st_connection ->ike_version); } }; | |||
| 217 | switch (st->st_ike_versionst_connection->ike_version) { | |||
| 218 | case IKEv2: | |||
| 219 | retransmit_v2_msg(st); | |||
| 220 | break; | |||
| 221 | #ifdef USE_IKEv11 | |||
| 222 | case IKEv1: | |||
| 223 | retransmit_v1_msg(st); | |||
| 224 | break; | |||
| 225 | #endif | |||
| 226 | default: | |||
| 227 | bad_case(st->st_ike_version)libreswan_bad_case("st->st_ike_version", (st->st_connection ->ike_version), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 227, } ; &here; })); | |||
| 228 | } | |||
| 229 | break; | |||
| 230 | ||||
| 231 | #ifdef USE_IKEv11 | |||
| 232 | case EVENT_v1_SEND_XAUTH: | |||
| 233 | dbg("XAUTH: event EVENT_v1_SEND_XAUTH #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XAUTH: event EVENT_v1_SEND_XAUTH #%lu %s", st ->st_serialno, st->st_state->name); } } | |||
| 234 | st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("XAUTH: event EVENT_v1_SEND_XAUTH #%lu %s", st ->st_serialno, st->st_state->name); } }; | |||
| 235 | xauth_send_request(st); | |||
| 236 | break; | |||
| 237 | #endif | |||
| 238 | ||||
| 239 | case EVENT_v2_LIVENESS: | |||
| 240 | liveness_check(st); | |||
| 241 | break; | |||
| 242 | ||||
| 243 | case EVENT_v2_REKEY: | |||
| 244 | pexpect(st->st_ike_version == IKEv2)({ _Bool assertion__ = st->st_connection->ike_version == IKEv2; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c" , .line = 244, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "st->st_connection->ike_version == IKEv2" ); } assertion__; }); | |||
| 245 | v2_event_sa_rekey(st); | |||
| 246 | break; | |||
| 247 | ||||
| 248 | case EVENT_v2_REAUTH: | |||
| 249 | pexpect(st->st_ike_version == IKEv2)({ _Bool assertion__ = st->st_connection->ike_version == IKEv2; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c" , .line = 249, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "st->st_connection->ike_version == IKEv2" ); } assertion__; }); | |||
| 250 | v2_event_sa_reauth(st); | |||
| 251 | break; | |||
| 252 | ||||
| 253 | case EVENT_SA_REPLACE: | |||
| 254 | case EVENT_v1_REPLACE_IF_USED: | |||
| 255 | switch (st->st_ike_versionst_connection->ike_version) { | |||
| 256 | case IKEv2: | |||
| 257 | pexpect(event_type == EVENT_SA_REPLACE)({ _Bool assertion__ = event_type == EVENT_SA_REPLACE; if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 257, } ; &here; }); const struct logger *logger_ = &failsafe_logger ; llog_pexpect(logger_, here_, "%s", "event_type == EVENT_SA_REPLACE" ); } assertion__; }); | |||
| 258 | v2_event_sa_replace(st); | |||
| 259 | break; | |||
| 260 | case IKEv1: | |||
| 261 | pexpect(event_type == EVENT_SA_REPLACE ||({ _Bool assertion__ = event_type == EVENT_SA_REPLACE || event_type == EVENT_v1_REPLACE_IF_USED; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 262, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect( logger_, here_, "%s", "event_type == EVENT_SA_REPLACE || event_type == EVENT_v1_REPLACE_IF_USED" ); } assertion__; }) | |||
| 262 | event_type == EVENT_v1_REPLACE_IF_USED)({ _Bool assertion__ = event_type == EVENT_SA_REPLACE || event_type == EVENT_v1_REPLACE_IF_USED; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 262, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect( logger_, here_, "%s", "event_type == EVENT_SA_REPLACE || event_type == EVENT_v1_REPLACE_IF_USED" ); } assertion__; }); | |||
| 263 | struct connection *c = st->st_connection; | |||
| 264 | const char *satype = IS_IKE_SA(st)((st)->st_clonedfrom == 0) ? "IKE" : "CHILD"; | |||
| 265 | ||||
| 266 | so_serial_t newer_sa = get_newer_sa_from_connection(st); | |||
| 267 | if (newer_sa != SOS_NOBODY0) { | |||
| 268 | /* not very interesting: no need to replace */ | |||
| 269 | dbg("not replacing stale %s SA %lu; #%lu will do",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not replacing stale %s SA %lu; #%lu will do", satype, st->st_serialno, newer_sa); } } | |||
| 270 | satype, st->st_serialno, newer_sa){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not replacing stale %s SA %lu; #%lu will do", satype, st->st_serialno, newer_sa); } }; | |||
| 271 | } else if (event_type == EVENT_v1_REPLACE_IF_USED && | |||
| 272 | !monobefore(mononow(), monotime_add(st->st_outbound_time, c->sa_rekey_margin))) { | |||
| 273 | /* | |||
| 274 | * we observed no recent use: no need to replace | |||
| 275 | * | |||
| 276 | * The sampling effects mean that st_outbound_time | |||
| 277 | * could be up to SHUNT_SCAN_INTERVAL more recent | |||
| 278 | * than actual traffic because the sampler looks at | |||
| 279 | * change over that interval. | |||
| 280 | * st_outbound_time could also not yet reflect traffic | |||
| 281 | * in the last SHUNT_SCAN_INTERVAL. | |||
| 282 | * We expect that SHUNT_SCAN_INTERVAL is smaller than | |||
| 283 | * c->sa_rekey_margin so that the effects of this will | |||
| 284 | * be unimportant. | |||
| 285 | * This is just an optimization: correctness is not | |||
| 286 | * at stake. | |||
| 287 | */ | |||
| 288 | dbg("not replacing stale %s SA: inactive for %jds",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not replacing stale %s SA: inactive for %jds" , satype, deltasecs(monotimediff(mononow(), st->st_outbound_time ))); } } | |||
| 289 | satype, deltasecs(monotimediff(mononow(), st->st_outbound_time))){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not replacing stale %s SA: inactive for %jds" , satype, deltasecs(monotimediff(mononow(), st->st_outbound_time ))); } }; | |||
| 290 | } else { | |||
| 291 | dbg("replacing stale %s SA",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("replacing stale %s SA", ((st)->st_clonedfrom == 0) ? "ISAKMP" : "IPsec"); } } | |||
| 292 | IS_IKE_SA(st) ? "ISAKMP" : "IPsec"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("replacing stale %s SA", ((st)->st_clonedfrom == 0) ? "ISAKMP" : "IPsec"); } }; | |||
| 293 | /* | |||
| 294 | * XXX: this call gets double billed - | |||
| 295 | * both to the state being deleted and | |||
| 296 | * to the new state being created. | |||
| 297 | */ | |||
| 298 | ipsecdoi_replace(st, 1); | |||
| 299 | } | |||
| 300 | ||||
| 301 | event_delete(EVENT_v2_LIVENESS, st); | |||
| 302 | event_delete(EVENT_DPD, st); | |||
| 303 | event_schedule(EVENT_SA_EXPIRE, st->st_replace_margin, st); | |||
| 304 | break; | |||
| 305 | default: | |||
| 306 | bad_case(st->st_ike_version)libreswan_bad_case("st->st_ike_version", (st->st_connection ->ike_version), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 306, } ; &here; })); | |||
| 307 | } | |||
| 308 | break; | |||
| 309 | ||||
| 310 | case EVENT_SA_EXPIRE: | |||
| 311 | { | |||
| 312 | struct connection *c = st->st_connection; | |||
| 313 | const char *satype = IS_IKE_SA(st)((st)->st_clonedfrom == 0) ? "IKE" : "CHILD"; | |||
| 314 | so_serial_t newer_sa = get_newer_sa_from_connection(st); | |||
| 315 | ||||
| 316 | if (newer_sa != SOS_NOBODY0) { | |||
| 317 | /* not very interesting: already superseded */ | |||
| 318 | dbg("%s SA expired (superseded by #%lu)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s SA expired (superseded by #%lu)", satype, newer_sa ); } } | |||
| 319 | satype, newer_sa){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s SA expired (superseded by #%lu)", satype, newer_sa ); } }; | |||
| 320 | } else if (!IS_IKE_SA_ESTABLISHED(st)((st)->st_state->kind == STATE_V2_ESTABLISHED_IKE_SA) && | |||
| 321 | !IS_V1_ISAKMP_SA_ESTABLISHED(st)((((lset_t)1 << ((st)->st_state->kind)) & ((( lset_t)1 << (STATE_MAIN_R3)) | ((lset_t)1 << (STATE_MAIN_I4 )) | ((lset_t)1 << (STATE_AGGR_I2)) | ((lset_t)1 << (STATE_AGGR_R2)) | ((lset_t)1 << (STATE_XAUTH_R0)) | ( (lset_t)1 << (STATE_XAUTH_R1)) | ((lset_t)1 << (STATE_MODE_CFG_R0 )) | ((lset_t)1 << (STATE_MODE_CFG_R1)) | ((lset_t)1 << (STATE_MODE_CFG_R2)) | ((lset_t)1 << (STATE_MODE_CFG_I1 )) | ((lset_t)1 << (STATE_XAUTH_I0)) | ((lset_t)1 << (STATE_XAUTH_I1)))) != ((lset_t)0))) { | |||
| 322 | /* not very interesting: failed IKE attempt */ | |||
| 323 | dbg("un-established partial Child SA timeout (SA expired)"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("un-established partial Child SA timeout (SA expired)" ); } }; | |||
| 324 | pstat_sa_failed(st, REASON_EXCHANGE_TIMEOUT); | |||
| 325 | } else { | |||
| 326 | log_state(RC_LOG, st, "%s SA expired (%s)", satype, | |||
| 327 | (c->policy & POLICY_DONT_REKEY((lset_t)1 << (POLICY_DONT_REKEY_IX))) ? "--dontrekey" : "LATEST!"); | |||
| 328 | } | |||
| 329 | ||||
| 330 | /* Delete this state object. It must be in the hash table. */ | |||
| 331 | switch (st->st_ike_versionst_connection->ike_version) { | |||
| 332 | case IKEv2: | |||
| 333 | { | |||
| 334 | struct ike_sa *ike = ike_sa(st, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 334, }; &here; })); | |||
| 335 | if (ike == NULL((void*)0)) { | |||
| 336 | /* | |||
| 337 | * XXX: SNAFU with IKE SA replacing | |||
| 338 | * itself (but not deleting its | |||
| 339 | * children?) simultaneous to a CHILD | |||
| 340 | * SA failing to establish and | |||
| 341 | * attempting to delete / replace | |||
| 342 | * itself? | |||
| 343 | * | |||
| 344 | * Because these things are | |||
| 345 | * not serialized it is hard | |||
| 346 | * to say. | |||
| 347 | */ | |||
| 348 | log_state(RC_LOG_SERIOUS, st, "Child SA lost its IKE SA #%lu", | |||
| 349 | st->st_clonedfrom); | |||
| 350 | delete_state(st); | |||
| 351 | st = NULL((void*)0); | |||
| 352 | } else if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { | |||
| 353 | /* IKEv2 parent, delete children too */ | |||
| 354 | dbg("IKEv2 SA expired, delete whole family"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("IKEv2 SA expired, delete whole family"); } }; | |||
| 355 | passert(&ike->sa == st)({ _Bool assertion__ = &ike->sa == st; if (!assertion__ ) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 355, } ; &here; }); const struct logger *logger_ = &failsafe_logger ; llog_passert(logger_, here, "%s", "&ike->sa == st"); } (void) 1; }); | |||
| 356 | delete_ike_family(ike, PROBABLY_SEND_DELETE); | |||
| 357 | /* note: no md->st to clear */ | |||
| 358 | st = NULL((void*)0); | |||
| 359 | } else if (IS_IKE_SA_ESTABLISHED(&ike->sa)((&ike->sa)->st_state->kind == STATE_V2_ESTABLISHED_IKE_SA )) { | |||
| 360 | /* note: no md->st to clear */ | |||
| 361 | submit_v2_delete_exchange(ike, pexpect_child_sa(st)); | |||
| 362 | st = NULL((void*)0); | |||
| 363 | } else { | |||
| 364 | delete_state(st); | |||
| 365 | st = NULL((void*)0); | |||
| 366 | } | |||
| 367 | break; | |||
| 368 | } | |||
| 369 | case IKEv1: | |||
| 370 | delete_state(st); | |||
| 371 | /* note: no md->st to clear */ | |||
| 372 | /* st = NULL; */ | |||
| 373 | break; | |||
| 374 | default: | |||
| 375 | bad_case(st->st_ike_version)libreswan_bad_case("st->st_ike_version", (st->st_connection ->ike_version), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 375, } ; &here; })); | |||
| 376 | } | |||
| 377 | break; | |||
| 378 | } | |||
| 379 | ||||
| 380 | case EVENT_SA_DISCARD: | |||
| 381 | /* | |||
| 382 | * The state failed to complete within a reasonable | |||
| 383 | * time, or the state failed but was left to live for | |||
| 384 | * a while so re-transmits could work, or the state is | |||
| 385 | * being garbage collected. Either way, time to | |||
| 386 | * delete it. | |||
| 387 | */ | |||
| 388 | if (deltatime_cmp(event_delay, >, deltatime_zero)(deltatime_sub_sign(event_delay, deltatime_zero) > 0)) { | |||
| 389 | /* Don't bother logging 0 delay */ | |||
| 390 | deltatime_buf dtb; | |||
| 391 | log_state(RC_LOG, st, "deleting incomplete state after %s seconds", | |||
| 392 | str_deltatime(event_delay, &dtb)); | |||
| 393 | } | |||
| 394 | /* | |||
| 395 | * If no other reason has been given then this is a | |||
| 396 | * timeout. | |||
| 397 | */ | |||
| 398 | pstat_sa_failed(st, REASON_EXCHANGE_TIMEOUT); | |||
| 399 | /* | |||
| 400 | * XXX: this is scary overkill - delete_state() likes | |||
| 401 | * to resurect things and/or send messages. What's | |||
| 402 | * needed is a lower-level discard_state() that just | |||
| 403 | * does its job. | |||
| 404 | * | |||
| 405 | * XXX: for IKEv2, it looks like delete_state() will | |||
| 406 | * stop spontaneously sending messages (and hopefully | |||
| 407 | * spontaneously deleting IKE families). | |||
| 408 | */ | |||
| 409 | delete_state(st); | |||
| 410 | break; | |||
| 411 | ||||
| 412 | case EVENT_v2_REDIRECT: | |||
| 413 | initiate_redirect(st); | |||
| 414 | break; | |||
| 415 | ||||
| 416 | #ifdef USE_IKEv11 | |||
| 417 | case EVENT_DPD: | |||
| 418 | dpd_event(st); | |||
| 419 | break; | |||
| 420 | ||||
| 421 | case EVENT_DPD_TIMEOUT: | |||
| 422 | dpd_timeout(st); | |||
| 423 | break; | |||
| 424 | ||||
| 425 | #ifdef USE_PAM_AUTH1 | |||
| 426 | case EVENT_PAM_TIMEOUT: | |||
| 427 | dbg("PAM thread timeout on state #%lu", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("PAM thread timeout on state #%lu", st->st_serialno ); } }; | |||
| 428 | pam_auth_abort(st, "timeout"); | |||
| 429 | /* | |||
| 430 | * Things get cleaned up when the PAM process exits. | |||
| 431 | * | |||
| 432 | * Should this schedule an event for the case when the | |||
| 433 | * child process (which is SIGKILLed) doesn't exit!?! | |||
| 434 | */ | |||
| 435 | break; | |||
| 436 | #endif | |||
| 437 | #endif | |||
| 438 | case EVENT_CRYPTO_TIMEOUT: | |||
| 439 | dbg("event crypto_failed on state #%lu, aborting",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("event crypto_failed on state #%lu, aborting", st->st_serialno); } } | |||
| 440 | st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("event crypto_failed on state #%lu, aborting", st->st_serialno); } }; | |||
| 441 | pstat_sa_failed(st, REASON_CRYPTO_TIMEOUT); | |||
| 442 | delete_state(st); | |||
| 443 | /* note: no md->st to clear */ | |||
| 444 | break; | |||
| 445 | ||||
| 446 | ||||
| 447 | default: | |||
| 448 | bad_case(event_type)libreswan_bad_case("event_type", (event_type), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c" , .line = 448, }; &here; })); | |||
| 449 | } | |||
| 450 | } | |||
| 451 | ||||
| 452 | /* | |||
| 453 | * Delete all of the lifetime events (if any). | |||
| 454 | * | |||
| 455 | * Most lifetime events (things that kill the state) try to share a | |||
| 456 | * single .st_event. However, there has been and likely will be | |||
| 457 | * exceptions (for instance the retransmit timer), and the code below | |||
| 458 | * is written to deal with it. | |||
| 459 | * | |||
| 460 | * XXX: | |||
| 461 | * | |||
| 462 | * The decision to have all the loosely lifetime related timers | |||
| 463 | * (retransmit, rekey, replace, ...) share a single .st_event field is | |||
| 464 | * ... unfortunate. The code has to constantly juggle the field | |||
| 465 | * deciding which event is next. Far easier to set and forget each | |||
| 466 | * independently. This is why the retransmit timer has been split | |||
| 467 | * off. | |||
| 468 | */ | |||
| 469 | void delete_event(struct state *st) | |||
| 470 | { | |||
| 471 | struct liveness { | |||
| 472 | const char *name; | |||
| 473 | struct state_event **event; | |||
| 474 | } events[] = { | |||
| 475 | { "st_event", &st->st_event, }, | |||
| 476 | }; | |||
| 477 | for (unsigned e = 0; e < elemsof(events)(sizeof(events) / sizeof(*(events))); e++) { | |||
| 478 | struct liveness *l = &events[e]; | |||
| 479 | if (*(l->event) == NULL((void*)0)) { | |||
| 480 | dbg("state #%lu has no .%s to delete", st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu has no .%s to delete", st->st_serialno , l->name); } } | |||
| 481 | l->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu has no .%s to delete", st->st_serialno , l->name); } }; | |||
| 482 | } else { | |||
| 483 | esb_buf b; | |||
| 484 | dbg("state #%lu deleting .%s %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu deleting .%s %s", st->st_serialno , l->name, enum_show(&event_type_names, (*l->event) ->ev_type, &b)); } } | |||
| 485 | st->st_serialno, l->name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu deleting .%s %s", st->st_serialno , l->name, enum_show(&event_type_names, (*l->event) ->ev_type, &b)); } } | |||
| 486 | enum_show(&event_type_names, (*l->event)->ev_type, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("state #%lu deleting .%s %s", st->st_serialno , l->name, enum_show(&event_type_names, (*l->event) ->ev_type, &b)); } }; | |||
| 487 | delete_pluto_event(l->event); | |||
| 488 | } | |||
| 489 | } | |||
| 490 | } | |||
| 491 | ||||
| 492 | /* | |||
| 493 | * This routine schedules a state event. | |||
| 494 | */ | |||
| 495 | void event_schedule(enum event_type type, deltatime_t delay, struct state *st) | |||
| 496 | { | |||
| 497 | passert(st != NULL)({ _Bool assertion__ = st != ((void*)0); if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__ , .file = "programs/pluto/timer.c", .line = 497, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "st != ((void*)0)"); } (void) 1; }); | |||
| 498 | /* | |||
| 499 | * Scheduling a month into the future is most likely a bug. | |||
| 500 | * pexpect() causes us to flag this in our test cases | |||
| 501 | */ | |||
| 502 | pexpect(deltasecs(delay) < secs_per_day * 31)({ _Bool assertion__ = deltasecs(delay) < secs_per_day * 31 ; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 502, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "deltasecs(delay) < secs_per_day * 31" ); } assertion__; }); | |||
| 503 | ||||
| 504 | const char *en = enum_name(&event_type_names, type); | |||
| 505 | ||||
| 506 | struct state_event **evp = state_event(st, type); | |||
| 507 | if (evp == NULL((void*)0)) { | |||
| 508 | pexpect_failllog_pexpect(st->st_logger, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 508, }; &here; }), | |||
| 509 | "#%lu has no .st_*event field for %s", | |||
| 510 | st->st_serialno, | |||
| 511 | enum_name(&event_type_names, type)); | |||
| 512 | return; | |||
| 513 | } | |||
| 514 | ||||
| 515 | if (*evp != NULL((void*)0)) { | |||
| 516 | /* help debugging by stumbling on */ | |||
| 517 | pexpect_failllog_pexpect(st->st_logger, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 517, }; &here; }), | |||
| 518 | "#%lu already has a scheduled %s; forcing replacement", | |||
| 519 | st->st_serialno, | |||
| 520 | enum_name(&event_type_names, type)); | |||
| 521 | delete_pluto_event(evp); | |||
| 522 | } | |||
| 523 | ||||
| 524 | struct state_event *ev = alloc_thing(struct state_event, en)((struct state_event*) alloc_bytes(sizeof(struct state_event) , (en))); | |||
| 525 | dbg("%s: newref %s-pe@%p", __func__, en, ev){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s: newref %s-pe@%p", __func__, en, ev); } }; | |||
| 526 | ev->ev_type = type; | |||
| 527 | ev->ev_name = en; | |||
| 528 | ev->ev_state = st; | |||
| 529 | ev->ev_epoch = mononow(); | |||
| 530 | ev->ev_delay = delay; | |||
| 531 | ev->ev_time = monotime_add(ev->ev_epoch, delay); | |||
| 532 | *evp = ev; | |||
| 533 | ||||
| 534 | deltatime_buf buf; | |||
| 535 | dbg("inserting event %s, timeout in %s seconds for #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("inserting event %s, timeout in %s seconds for #%lu" , en, str_deltatime(delay, &buf), ev->ev_state->st_serialno ); } } | |||
| 536 | en, str_deltatime(delay, &buf),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("inserting event %s, timeout in %s seconds for #%lu" , en, str_deltatime(delay, &buf), ev->ev_state->st_serialno ); } } | |||
| 537 | ev->ev_state->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("inserting event %s, timeout in %s seconds for #%lu" , en, str_deltatime(delay, &buf), ev->ev_state->st_serialno ); } }; | |||
| 538 | ||||
| 539 | fire_timer_photon_torpedo(&ev->ev, timer_event_cb, ev, delay); | |||
| 540 | } | |||
| 541 | ||||
| 542 | /* | |||
| 543 | * Delete a state backlinked event (if any); leave *evp == NULL. | |||
| 544 | */ | |||
| 545 | void event_delete(enum event_type type, struct state *st) | |||
| 546 | { | |||
| 547 | struct state_event **evp = state_event(st, type); | |||
| 548 | if (evp == NULL((void*)0)) { | |||
| 549 | pexpect_failllog_pexpect(st->st_logger, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 549, }; &here; }), | |||
| ||||
| 550 | "#%lu has no .st_event field for %s", | |||
| 551 | st->st_serialno, enum_name(&event_type_names, type)); | |||
| 552 | return; | |||
| 553 | } | |||
| 554 | if (*evp != NULL((void*)0)) { | |||
| 555 | dbg("#%lu requesting %s-pe@%p be deleted",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu requesting %s-pe@%p be deleted", st-> st_serialno, enum_name(&event_type_names, (*evp)->ev_type ), *evp); } } | |||
| 556 | st->st_serialno, enum_name(&event_type_names, (*evp)->ev_type), *evp){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu requesting %s-pe@%p be deleted", st-> st_serialno, enum_name(&event_type_names, (*evp)->ev_type ), *evp); } }; | |||
| 557 | pexpect(st == (*evp)->ev_state)({ _Bool assertion__ = st == (*evp)->ev_state; if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 557, } ; &here; }); const struct logger *logger_ = &failsafe_logger ; llog_pexpect(logger_, here_, "%s", "st == (*evp)->ev_state" ); } assertion__; }); | |||
| 558 | delete_pluto_event(evp); | |||
| 559 | pexpect((*evp) == NULL)({ _Bool assertion__ = (*evp) == ((void*)0); if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/timer.c", .line = 559, } ; &here; }); const struct logger *logger_ = &failsafe_logger ; llog_pexpect(logger_, here_, "%s", "(*evp) == ((void*)0)"); } assertion__; }); | |||
| 560 | }; | |||
| 561 | } | |||
| 562 | ||||
| 563 | void event_force(enum event_type type, struct state *st) | |||
| 564 | { | |||
| 565 | event_delete(type, st); | |||
| ||||
| 566 | deltatime_t delay = deltatime(0); | |||
| 567 | event_schedule(type, delay, st); | |||
| 568 | } | |||
| 569 | ||||
| 570 | void call_state_event_handler(struct logger *logger, struct state *st, | |||
| 571 | enum event_type event_type) | |||
| 572 | { | |||
| 573 | const char *event_name = enum_name_short(&event_type_names, event_type); | |||
| 574 | if (event_name == NULL((void*)0)) { | |||
| 575 | llog(RC_COMMENT, logger, "%d is not a valid event", event_type); | |||
| 576 | return; | |||
| 577 | } | |||
| 578 | ||||
| 579 | /* sanity checks */ | |||
| 580 | struct state_event **evp = state_event(st, event_type); | |||
| 581 | if (evp == NULL((void*)0)) { | |||
| 582 | llog(RC_COMMENT, logger, "%s is not a valid event", event_name); | |||
| 583 | return; | |||
| 584 | } | |||
| 585 | ||||
| 586 | /* | |||
| 587 | * Like timer_event_cb(), delete the old event before calling | |||
| 588 | * the event handler. | |||
| 589 | */ | |||
| 590 | deltatime_t event_delay = deltatime(1); | |||
| 591 | if (*evp == NULL((void*)0)) { | |||
| 592 | llog(RC_COMMENT, logger, | |||
| 593 | "no existing %s event to delete", event_name); | |||
| 594 | } else if ((*evp)->ev_type != event_type) { | |||
| 595 | llog(RC_COMMENT, logger, | |||
| 596 | "deleting existing %s event occupying the slot shared with %s", | |||
| 597 | enum_name(&event_type_names, (*evp)->ev_type), | |||
| 598 | event_name); | |||
| 599 | delete_pluto_event(evp); | |||
| 600 | } else { | |||
| 601 | llog(RC_COMMENT, logger, | |||
| 602 | "deleting existing %s event", | |||
| 603 | event_name); | |||
| 604 | event_delay = (*evp)->ev_delay; | |||
| 605 | delete_pluto_event(evp); | |||
| 606 | } | |||
| 607 | ||||
| 608 | llog(RC_COMMENT, logger, "calling %s event handler", event_name); | |||
| 609 | dispatch_event(st, event_type, event_delay); | |||
| 610 | } |