summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortobhe <tobhe@openbsd.org>2020-04-13 19:10:32 +0000
committertobhe <tobhe@openbsd.org>2020-04-13 19:10:32 +0000
commitea5b94870eabe08c0a8e723ddfcf88ba93a4b57d (patch)
tree615fd40be6ca913053498c820ad4d570f8fece4d
parentAdd helpers for the simple case of parse string and add to command queue. (diff)
downloadwireguard-openbsd-ea5b94870eabe08c0a8e723ddfcf88ba93a4b57d.tar.xz
wireguard-openbsd-ea5b94870eabe08c0a8e723ddfcf88ba93a4b57d.zip
Try to send a DELETE message if the SA is reset with 'ikectl reset id'.
This way the peer can delete its SAs and eventually reestablish the connection without having to wait for a timeout. ok markus@
-rw-r--r--sbin/iked/config.c10
-rw-r--r--sbin/iked/iked.h3
-rw-r--r--sbin/iked/ikev2.c17
3 files changed, 25 insertions, 5 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c
index 250eaece5e6..6fdd4f8e55d 100644
--- a/sbin/iked/config.c
+++ b/sbin/iked/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.56 2020/04/09 19:55:19 tobhe Exp $ */
+/* $OpenBSD: config.c,v 1.57 2020/04/13 19:10:32 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -527,8 +527,12 @@ config_getreset(struct iked *env, struct imsg *imsg)
for (sa = RB_MIN(iked_sas, &env->sc_sas);
sa != NULL; sa = nextsa) {
nextsa = RB_NEXT(iked_sas, &env->sc_sas, sa);
- RB_REMOVE(iked_sas, &env->sc_sas, sa);
- config_free_sa(env, sa);
+ /* for RESET_SA we try send a DELETE */
+ if (mode == RESET_ALL ||
+ ikev2_ike_sa_delete(env, sa) != 0) {
+ RB_REMOVE(iked_sas, &env->sc_sas, sa);
+ config_free_sa(env, sa);
+ }
}
}
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 3053e6f4574..609913dda7c 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.144 2020/04/11 20:14:11 tobhe Exp $ */
+/* $OpenBSD: iked.h,v 1.145 2020/04/13 19:10:32 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -879,6 +879,7 @@ int ikev2_childsa_delete(struct iked *, struct iked_sa *,
void ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
void ikev2_ike_sa_timeout(struct iked *env, void *);
void ikev2_ike_sa_setreason(struct iked_sa *, char *);
+int ikev2_ike_sa_delete(struct iked *, struct iked_sa *);
struct ibuf *
ikev2_prfplus(struct iked_hash *, struct ibuf *, struct ibuf *,
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 8d79248186d..956563c5b83 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.214 2020/04/11 20:14:11 tobhe Exp $ */
+/* $OpenBSD: ikev2.c,v 1.215 2020/04/13 19:10:32 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -411,6 +411,21 @@ ikev2_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
return (0);
}
+/* try to delete established SA if no other exchange is active */
+int
+ikev2_ike_sa_delete(struct iked *env, struct iked_sa *sa)
+{
+ if (sa->sa_state != IKEV2_STATE_ESTABLISHED)
+ return (-1);
+ if (sa->sa_stateflags & (IKED_REQ_CHILDSA|IKED_REQ_INF))
+ return (-1);
+ ikev2_disable_timer(env, sa);
+ ikev2_ike_sa_setreason(sa, "reset sa control message");
+ ikev2_ikesa_delete(env, sa, 1);
+ timer_add(env, &sa->sa_timer, 0);
+ return (0);
+}
+
void
ikev2_ctl_reset_id(struct iked *env, struct imsg *imsg, unsigned int type)
{