whitelist: Fix deadlock when handling client disconnection
Calling stream_t::destroy from the stream_t::on_read callback will block the thread in watcher_t::remove because the FD is currently "in callback". A similar issue was fixed in the lookip plugin with961409b668("lookip: Disconnect asynchronously to avoid dead-locking watcher unregistration"). Fixes:85ebf6abd4("whitelist: Add error handling to socket reads and fix a memory leak")
This commit is contained in:
committed by
Tobias Brunner
parent
8a6f9ba70e
commit
14cbe0bf24
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <daemon.h>
|
||||
#include <collections/linked_list.h>
|
||||
#include <processing/jobs/callback_job.h>
|
||||
|
||||
#include "whitelist_msg.h"
|
||||
|
||||
@@ -101,6 +102,40 @@ typedef struct {
|
||||
size_t read;
|
||||
} whitelist_conn_t;
|
||||
|
||||
/**
|
||||
* Information needed for async disconnect job.
|
||||
*/
|
||||
typedef struct {
|
||||
whitelist_conn_t *conn;
|
||||
stream_t *stream;
|
||||
} disconnect_data_t;
|
||||
|
||||
/**
|
||||
* Asynchronous callback to disconnect client
|
||||
*/
|
||||
CALLBACK(disconnect_async, job_requeue_t,
|
||||
disconnect_data_t *data)
|
||||
{
|
||||
data->stream->destroy(data->stream);
|
||||
free(data->conn);
|
||||
return JOB_REQUEUE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a connected client
|
||||
*/
|
||||
static void disconnect(whitelist_conn_t *conn, stream_t *stream)
|
||||
{
|
||||
disconnect_data_t *data;
|
||||
|
||||
INIT(data,
|
||||
.conn = conn,
|
||||
.stream = stream,
|
||||
);
|
||||
lib->processor->queue_job(lib->processor,
|
||||
(job_t*)callback_job_create(disconnect_async, data, free, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a received message
|
||||
*/
|
||||
@@ -127,8 +162,7 @@ CALLBACK(on_read, bool,
|
||||
{
|
||||
DBG1(DBG_CFG, "whitelist socket error: %s", strerror(errno));
|
||||
}
|
||||
stream->destroy(stream);
|
||||
free(conn);
|
||||
disconnect(conn, stream);
|
||||
return FALSE;
|
||||
}
|
||||
conn->read += len;
|
||||
|
||||
Reference in New Issue
Block a user