From: Tobias Brunner Date: Tue, 20 Oct 2020 18:14:08 +0000 (+0200) Subject: vici: Send all queued messages during shutdown X-Git-Tag: 5.9.1rc1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef636316d2344a7260d88c2ea232e452b872e3cb;p=thirdparty%2Fstrongswan.git vici: Send all queued messages during shutdown 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. --- diff --git a/src/libcharon/plugins/vici/vici_socket.c b/src/libcharon/plugins/vici/vici_socket.c index 04a21227ab..e55020e6d2 100644 --- a/src/libcharon/plugins/vici/vici_socket.c +++ b/src/libcharon/plugins/vici/vici_socket.c @@ -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);