From: Zheng Zhong <[email protected]>

Do a little cleanup when deleting a connection via "ipsec update"
command:
- delete all established CHILD_SAs
- unroute the connection
- delete IKE_SAs that have no more CHILD_SAs
- delete the connection
- make sure to refuse an undesired negotiation request from the peer,
  by deleting the connection before terminating it.

Signed-off-by: Zheng Zhong <[email protected]>
Acked-by: Christophe Gouault <[email protected]>
---
 src/starter/starter.c       |    8 +++++--
 src/starter/starterstroke.c |   49 +++++++++++++++++++++++++++++++++++++++++++
 src/starter/starterstroke.h |    2 ++
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/starter/starter.c b/src/starter/starter.c
index 71f33ae..aa740ba 100644
--- a/src/starter/starter.c
+++ b/src/starter/starter.c
@@ -713,11 +713,13 @@ int main (int argc, char **argv)
                                        {
                                                if (starter_charon_pid())
                                                {
+                                                       
starter_stroke_del_conn(conn);
+                                                       
starter_stroke_terminate_conn(conn);
+                                                       
starter_stroke_purge_ike();
                                                        if (conn->startup == 
STARTUP_ROUTE)
                                                        {
                                                                
starter_stroke_unroute_conn(conn);
                                                        }
-                                                       
starter_stroke_del_conn(conn);
                                                }
                                                conn->state = STATE_TO_ADD;
                                        }
@@ -774,11 +776,13 @@ int main (int argc, char **argv)
                                        {
                                                if (starter_charon_pid())
                                                {
+                                                       
starter_stroke_del_conn(conn);
+                                                       
starter_stroke_terminate_conn(conn);
+                                                       
starter_stroke_purge_ike();
                                                        if (conn->startup == 
STARTUP_ROUTE)
                                                        {
                                                                
starter_stroke_unroute_conn(conn);
                                                        }
-                                                       
starter_stroke_del_conn(conn);
                                                }
                                        }
                                }
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index 1e305db..e1b369b 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -16,6 +16,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 
 #include <credentials/auth_cfg.h>
 
@@ -47,6 +48,28 @@ static char* push_string(stroke_msg_t *msg, char *string)
        }
 }
 
+static char* push_format(stroke_msg_t *msg, const char *format, ...)
+{
+       unsigned long string_start = msg->length;
+       size_t room = sizeof(stroke_msg_t) - msg->length;
+       int written;
+       va_list ap;
+
+       va_start(ap, format);
+
+       written = vsnprintf((char*)msg + string_start, room, format, ap);
+
+       if (written >= room)
+       {
+               return NULL;
+       }
+       else
+       {
+               msg->length += written + 1;
+               return (char*)string_start;
+       }
+}
+
 static int send_stroke_msg (stroke_msg_t *msg)
 {
        stream_t *stream;
@@ -280,6 +303,32 @@ int starter_stroke_initiate_conn(starter_conn_t *conn)
        return send_stroke_msg(&msg);
 }
 
+/*
+ * Terminate all established CHILD_SAs of a connection
+ */
+int starter_stroke_terminate_conn(starter_conn_t *conn)
+{
+       stroke_msg_t msg;
+
+       msg.type = STR_TERMINATE;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.initiate.name = push_format(&msg, "%s{*}", connection_name(conn));
+       return send_stroke_msg(&msg);
+}
+
+/*
+ * Delete IKE_SAs without a CHILD_SA
+ */
+int starter_stroke_purge_ike(void)
+{
+       stroke_msg_t msg;
+
+       msg.type = STR_PURGE;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.purge.flags = PURGE_IKE;
+       return send_stroke_msg(&msg);
+}
+
 int starter_stroke_add_ca(starter_ca_t *ca)
 {
        stroke_msg_t msg;
diff --git a/src/starter/starterstroke.h b/src/starter/starterstroke.h
index 1264863..4d23b97 100644
--- a/src/starter/starterstroke.h
+++ b/src/starter/starterstroke.h
@@ -23,6 +23,8 @@ int starter_stroke_del_conn(starter_conn_t *conn);
 int starter_stroke_route_conn(starter_conn_t *conn);
 int starter_stroke_unroute_conn(starter_conn_t *conn);
 int starter_stroke_initiate_conn(starter_conn_t *conn);
+int starter_stroke_terminate_conn(starter_conn_t *conn);
+int starter_stroke_purge_ike(void);
 int starter_stroke_add_ca(starter_ca_t *ca);
 int starter_stroke_del_ca(starter_ca_t *ca);
 int starter_stroke_configure(starter_config_t *cfg);
-- 
1.7.10.4

_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev

Reply via email to