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.
This commit is contained in:
@@ -310,7 +310,7 @@ static void disconnect(private_vici_socket_t *this, u_int id)
|
|||||||
* Write queued output data
|
* Write queued output data
|
||||||
*/
|
*/
|
||||||
static bool do_write(private_vici_socket_t *this, entry_t *entry,
|
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;
|
msg_buf_t *out;
|
||||||
ssize_t len;
|
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))
|
while (out->hdrlen < sizeof(out->hdr))
|
||||||
{
|
{
|
||||||
len = stream->write(stream, out->hdr + out->hdrlen,
|
len = stream->write(stream, out->hdr + out->hdrlen,
|
||||||
sizeof(out->hdr) - out->hdrlen, FALSE);
|
sizeof(out->hdr) - out->hdrlen, block);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -343,7 +343,7 @@ static bool do_write(private_vici_socket_t *this, entry_t *entry,
|
|||||||
while (out->buf.len > out->done)
|
while (out->buf.len > out->done)
|
||||||
{
|
{
|
||||||
len = stream->write(stream, out->buf.ptr + 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)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
snprintf(errmsg, errlen, "premature vici disconnect");
|
snprintf(errmsg, errlen, "premature vici disconnect");
|
||||||
@@ -383,7 +383,7 @@ CALLBACK(on_write, bool,
|
|||||||
entry = find_entry(this, stream, 0, FALSE, TRUE);
|
entry = find_entry(this, stream, 0, FALSE, TRUE);
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
ret = do_write(this, entry, stream, errmsg, sizeof(errmsg));
|
ret = do_write(this, entry, stream, errmsg, sizeof(errmsg), FALSE);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
/* unregister if we have no more messages to send */
|
/* 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,
|
METHOD(vici_socket_t, destroy, void,
|
||||||
private_vici_socket_t *this)
|
private_vici_socket_t *this)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->service);
|
DESTROY_IF(this->service);
|
||||||
|
this->connections->invoke_function(this->connections, flush_messages, this);
|
||||||
this->connections->destroy_function(this->connections, destroy_entry);
|
this->connections->destroy_function(this->connections, destroy_entry);
|
||||||
this->mutex->destroy(this->mutex);
|
this->mutex->destroy(this->mutex);
|
||||||
free(this);
|
free(this);
|
||||||
|
|||||||
Reference in New Issue
Block a user