]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
vici: Send all queued messages during shutdown
authorTobias Brunner <tobias@strongswan.org>
Tue, 20 Oct 2020 18:14:08 +0000 (20:14 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 30 Oct 2020 08:58:42 +0000 (09:58 +0100)
This ensures that e.g. ike/child-updown messages are sent that were
queued but couldn't be sent (even the job to enable to on_write() callback
requires a worker thread that's not around anymore during shutdown).

References #3602.

src/libcharon/plugins/vici/vici_socket.c

index 04a21227ab33306b4a37b4f4633a38f477fa47d9..e55020e6d2f17f47068781fd6ed44f425fbeb5f4 100644 (file)
@@ -310,7 +310,7 @@ static void disconnect(private_vici_socket_t *this, u_int id)
  * Write queued output data
  */
 static bool do_write(private_vici_socket_t *this, entry_t *entry,
-                                        stream_t *stream, char *errmsg, size_t errlen)
+                                        stream_t *stream, char *errmsg, size_t errlen, bool block)
 {
        msg_buf_t *out;
        ssize_t len;
@@ -321,7 +321,7 @@ static bool do_write(private_vici_socket_t *this, entry_t *entry,
                while (out->hdrlen < sizeof(out->hdr))
                {
                        len = stream->write(stream, out->hdr + out->hdrlen,
-                                                               sizeof(out->hdr) - out->hdrlen, FALSE);
+                                                               sizeof(out->hdr) - out->hdrlen, block);
                        if (len == 0)
                        {
                                return FALSE;
@@ -343,7 +343,7 @@ static bool do_write(private_vici_socket_t *this, entry_t *entry,
                while (out->buf.len > out->done)
                {
                        len = stream->write(stream, out->buf.ptr + out->done,
-                                                               out->buf.len - out->done, FALSE);
+                                                               out->buf.len - out->done, block);
                        if (len == 0)
                        {
                                snprintf(errmsg, errlen, "premature vici disconnect");
@@ -383,7 +383,7 @@ CALLBACK(on_write, bool,
        entry = find_entry(this, stream, 0, FALSE, TRUE);
        if (entry)
        {
-               ret = do_write(this, entry, stream, errmsg, sizeof(errmsg));
+               ret = do_write(this, entry, stream, errmsg, sizeof(errmsg), FALSE);
                if (ret)
                {
                        /* unregister if we have no more messages to send */
@@ -656,10 +656,30 @@ METHOD(vici_socket_t, send_, void,
        }
 }
 
+CALLBACK(flush_messages, void,
+       entry_t *entry, va_list args)
+{
+       private_vici_socket_t *this;
+       char errmsg[256] = "";
+       bool ret;
+
+       VA_ARGS_VGET(args, this);
+
+       /* no need for any locking as no other threads are running, the connections
+        * all get disconneted afterwards, so error handling is simple too */
+       ret = do_write(this, entry, entry->stream, errmsg, sizeof(errmsg), TRUE);
+
+       if (!ret && errmsg[0])
+       {
+               DBG1(DBG_CFG, errmsg);
+       }
+}
+
 METHOD(vici_socket_t, destroy, void,
        private_vici_socket_t *this)
 {
        DESTROY_IF(this->service);
+       this->connections->invoke_function(this->connections, flush_messages, this);
        this->connections->destroy_function(this->connections, destroy_entry);
        this->mutex->destroy(this->mutex);
        free(this);