From 57c65763f4195f1c87af083ee3424939ad38dc03 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Sun, 18 Jun 2017 19:55:23 +0200 Subject: [PATCH] doveadm-server: http: Fixed crash occurring when disconnecting a client at server deinit. --- src/doveadm/client-connection-http.c | 30 +++++++++++++++++++++++-- src/doveadm/client-connection-private.h | 2 ++ src/doveadm/client-connection.c | 3 +++ src/doveadm/client-connection.h | 1 + 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/doveadm/client-connection-http.c b/src/doveadm/client-connection-http.c index 820dbf8541..d12a8aabfb 100644 --- a/src/doveadm/client-connection-http.c +++ b/src/doveadm/client-connection-http.c @@ -105,6 +105,7 @@ client_connection_create_http(int fd, bool ssl) pool = pool_alloconly_create("doveadm client", 1024*16); conn = p_new(pool, struct client_connection_http, 1); conn->client.pool = pool; + conn->client.http = TRUE; if (client_connection_init(&conn->client, fd) < 0) return NULL; @@ -115,10 +116,35 @@ client_connection_create_http(int fd, bool ssl) return &conn->client; } +void client_connection_destroy_http(struct client_connection *conn) +{ + struct client_connection_http *hconn = + (struct client_connection_http *)conn; + + if (hconn->http_client != NULL) { + /* We're not in the lib-http/server's connection destroy callback. */ + http_server_connection_close(&hconn->http_client, + "Server shutting down"); + } +} + static void -doveadm_http_server_connection_destroy(void *context, const char *reason ATTR_UNUSED) +doveadm_http_server_connection_destroy(void *context, + const char *reason ATTR_UNUSED) { - struct client_connection *conn = context; + struct client_connection_http *hconn = + (struct client_connection_http *)context; + struct client_connection *conn = &hconn->client; + + if (hconn->http_client == NULL) { + /* already destroying client directly */ + return; + } + + /* HTTP connection is destroyed already now */ + hconn->http_client = NULL; + + /* destroy the connection itself */ client_connection_destroy(&conn); } diff --git a/src/doveadm/client-connection-private.h b/src/doveadm/client-connection-private.h index 928158788e..fefadfc6b3 100644 --- a/src/doveadm/client-connection-private.h +++ b/src/doveadm/client-connection-private.h @@ -11,6 +11,8 @@ int client_connection_init(struct client_connection *conn, int fd); void client_connection_set_proctitle(struct client_connection *conn, const char *text); +void client_connection_destroy_http(struct client_connection *conn); + void doveadm_http_server_init(void); void doveadm_http_server_deinit(void); diff --git a/src/doveadm/client-connection.c b/src/doveadm/client-connection.c index 2e886835c2..d98c6564d3 100644 --- a/src/doveadm/client-connection.c +++ b/src/doveadm/client-connection.c @@ -563,6 +563,9 @@ void client_connection_destroy(struct client_connection **_conn) doveadm_print_deinit(); + if (conn->http) + client_connection_destroy_http(conn); + if (conn->ssl_iostream != NULL) ssl_iostream_destroy(&conn->ssl_iostream); diff --git a/src/doveadm/client-connection.h b/src/doveadm/client-connection.h index 1f2fc53b09..4dae6477f9 100644 --- a/src/doveadm/client-connection.h +++ b/src/doveadm/client-connection.h @@ -18,6 +18,7 @@ struct client_connection { bool handshaked:1; bool authenticated:1; + bool http:1; }; struct client_connection * -- 2.47.3