]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/tls: in some cases rehandshake might be improperly handled, which may lead...
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 31 Dec 2018 13:30:44 +0000 (14:30 +0100)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Tue, 8 Jan 2019 09:15:23 +0000 (10:15 +0100)
daemon/io.c
daemon/tls.c
daemon/tls.h

index 7bb19b040a57bc9ffc35bd91809317b4a355435f..f183d3471e142436db504850cd7ce88d43d7d7a1 100644 (file)
@@ -235,7 +235,17 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
                /* buf->base points to start of the tls receive buffer.
                   Decode data free space in session wire buffer. */
                consumed = tls_process_input_data(s, (const uint8_t *)buf->base, nread);
-               if (consumed <= 0) {
+               if (consumed < 0) {
+                       if (kr_verbose_status) {
+                               struct sockaddr *peer = session_get_peer(s);
+                               char *peer_str = kr_straddr(peer);
+                               kr_log_verbose("[io] => connection to '%s': "
+                                              "error processing TLS data, close\n",
+                                              peer_str ? peer_str : "");
+                       }
+                       worker_end_tcp(s);
+                       return;
+               } else if (consumed == 0) {
                        return;
                }
                data = session_wirebuf_get_free_start(s);
index 02af3a1562d9a981ef11618059500c8db7877fb4..508bcf8546a4fc01ba0daa95f0824939c8ea66cf 100644 (file)
@@ -493,16 +493,21 @@ ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nr
                        kr_log_verbose("[%s] TLS rehandshake with %s has started\n",
                                       logstring,  kr_straddr(peer));
                        tls_set_hs_state(tls_p, TLS_HS_IN_PROGRESS);
+                       int err = kr_ok();
                        while (tls_p->handshake_state <= TLS_HS_IN_PROGRESS) {
-                               int err = tls_handshake(tls_p, tls_p->handshake_cb);
+                               err = tls_handshake(tls_p, tls_p->handshake_cb);
                                if (err == kr_error(EAGAIN)) {
                                        break;
                                } else if (err != kr_ok()) {
                                        return err;
                                }
                        }
-                       /* Wait for more data */
-                       break;
+                       if (err == kr_error(EAGAIN)) {
+                               /* pull function is out of data */
+                               break;
+                       }
+                       /* There are can be data available, check it. */
+                       continue;
                } else if (count < 0) {
                        kr_log_verbose("[%s] gnutls_record_recv failed: %s (%zd)\n",
                                     logstring, gnutls_strerror_name(count), count);
@@ -514,8 +519,21 @@ ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nr
                wire_buf += count;
                wire_buf_size -= count;
                submitted += count;
+               if (wire_buf_size == 0 && tls_p->consumed != tls_p->nread) {
+                       /* session buffer is full
+                        * whereas not all the data were consumed */
+                       return kr_error(ENOSPC);
+               }
+       }
+       /* Here all data must be consumed. */
+       if (tls_p->consumed != tls_p->nread) {
+               /* Something went wrong, better return error.
+                * This is most probably due to gnutls_record_recv() did not
+                * consume all available network data by calling kres_gnutls_pull().
+                * TODO assess the need for buffering of data amount.
+                */
+               return kr_error(ENOSPC);
        }
-       assert(tls_p->consumed == tls_p->nread);
        return submitted;
 }
 
index e57799c5c0e2ab30c68387d810e0c793e86b309d..2eb776c39bc1a2038d03e8c35a423aac8076c86f 100644 (file)
@@ -94,7 +94,7 @@ struct tls_common_ctx {
        const uint8_t *buf;
        ssize_t nread;
        ssize_t consumed;
-       uint8_t recv_buf[8192];
+       uint8_t recv_buf[16384];
        tls_handshake_cb handshake_cb;
        struct worker_ctx *worker;
        size_t write_queue_size;