]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: http-client-connection - Create function for obtaining client settings...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 20 Feb 2019 21:19:03 +0000 (22:19 +0100)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 29 Mar 2019 08:46:21 +0000 (08:46 +0000)
This fixes and prevents segfaults occurring when settings are needed while the
connection is detached. In that case, the shared client context settings need
to be used rather than the client settings. Before, the attachment of a peer was
assumed for obtaining the settings when it actually could be absent in rare
cases, causing a NULL dereference.

src/lib-http/http-client-connection.c

index 7f3a05a05c3067c82898ae2db8d9c7169ddc82dc..f1b680ae2cb6df625a56fe1a531553d46b14891b 100644 (file)
 static void http_client_connection_ready(struct http_client_connection *conn);
 static void http_client_connection_input(struct connection *_conn);
 
+static inline const struct http_client_settings *
+http_client_connection_get_settings(struct http_client_connection *conn)
+{
+       if (conn->peer != NULL)
+               return &conn->peer->client->set;
+       return &conn->ppool->peer->cctx->set;
+}
+
 static inline void
 http_client_connection_ref_request(struct http_client_connection *conn,
        struct http_client_request *req)
@@ -119,7 +127,8 @@ static void
 http_client_connection_retry_requests(struct http_client_connection *conn,
        unsigned int status, const char *error)
 {
-       const struct http_client_settings *set = &conn->peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        struct http_client_request *req, **req_idx;
 
        if (!array_is_created(&conn->request_wait_list))
@@ -321,7 +330,8 @@ void http_client_connection_handle_output_error(
 
 int http_client_connection_check_ready(struct http_client_connection *conn)
 {
-       const struct http_client_settings *set = &conn->peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        int ret;
 
        if (conn->in_req_callback) {
@@ -415,9 +425,8 @@ http_client_connection_idle_timeout(struct http_client_connection *conn)
 
 void http_client_connection_lost_peer(struct http_client_connection *conn)
 {
-       struct http_client_peer *peer = conn->peer;
-       struct http_client *client = peer->client;
-       const struct http_client_settings *set = &client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        struct http_client_peer_pool *ppool = conn->ppool;
        struct http_client_peer_shared *pshared = ppool->peer;
        unsigned int timeout, count;
@@ -1354,7 +1363,8 @@ http_client_connection_ready(struct http_client_connection *conn)
        struct http_client_peer *peer = conn->peer;
        struct http_client_peer_pool *ppool = conn->ppool;
        struct http_client_peer_shared *pshared = ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
 
        e_debug(conn->event, "Ready for requests");
        i_assert(!conn->connect_succeeded);
@@ -1412,9 +1422,9 @@ static int
 http_client_connection_ssl_handshaked(const char **error_r, void *context)
 {
        struct http_client_connection *conn = context;
-       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_shared *pshared = conn->ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        const char *error, *host = pshared->addr.a.tcp.https_name;
 
        if (ssl_iostream_check_cert_validity(conn->ssl_iostream, host, &error) == 0)
@@ -1433,10 +1443,10 @@ static int
 http_client_connection_ssl_init(struct http_client_connection *conn,
                                const char **error_r)
 {
-       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_pool *ppool = conn->ppool;
        struct http_client_peer_shared *pshared = ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        struct ssl_iostream_settings ssl_set;
        struct ssl_iostream_context *ssl_ctx = ppool->ssl_ctx;
        const char *error;
@@ -1485,9 +1495,9 @@ http_client_connection_connected(struct connection *_conn, bool success)
 {
        struct http_client_connection *conn =
                (struct http_client_connection *)_conn;
-       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_shared *pshared = conn->ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        const char *error;
 
        if (!success) {