]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
TLS: add manual read timer control mode
authorArtem Boldariev <artem@boldariev.com>
Thu, 20 Oct 2022 12:40:51 +0000 (15:40 +0300)
committerArtem Boldariev <artem@boldariev.com>
Tue, 20 Dec 2022 19:24:44 +0000 (21:24 +0200)
This commit adds manual read timer control mode, similarly to TCP.
This way the read timer can be controlled manually using:

* isc__nmsocket_timer_start();
* isc__nmsocket_timer_stop();
* isc__nmsocket_timer_restart().

The change is required to make it possible to implement more
sophisticated read timer control policies in DNS transports, built on
top of TLS.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tlsstream.c

index 18833bfbde20deee9e415c0818cbd901696e2c21..274aec9a688c2f5fb568b265fd4d5dd9c0c8e609 100644 (file)
@@ -1570,6 +1570,9 @@ isc__nm_tls_cleartimeout(isc_nmhandle_t *handle);
 void
 isc__nmsocket_tls_reset(isc_nmsocket_t *sock);
 
+void
+isc__nmhandle_tls_set_manual_timer(isc_nmhandle_t *handle, const bool manual);
+
 const char *
 isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
 
index 350e3ba96390132325271a75762ac48b053b86f0..4c3c3107f367d6fdcae578b545711d9c4f11f44f 100644 (file)
@@ -2910,6 +2910,11 @@ isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual) {
        case isc_nm_tcpsocket:
                isc__nmhandle_tcp_set_manual_timer(handle, manual);
                return;
+#if HAVE_LIBNGHTTP2
+       case isc_nm_tlssocket:
+               isc__nmhandle_tls_set_manual_timer(handle, manual);
+               return;
+#endif /* HAVE_LIBNGHTTP2 */
        default:
                break;
        };
index 485c70410ae9256788f94ce19be27f14d0820abc..e99b03b4bb53051e4a67cc706226fb282ac72833 100644 (file)
@@ -458,6 +458,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                sock->tlsstream.state = TLS_HANDSHAKE;
                rv = tls_try_handshake(sock, NULL);
                INSIST(SSL_is_init_finished(sock->tlsstream.tls) == 0);
+               isc__nmsocket_timer_restart(sock);
        } else if (sock->tlsstream.state == TLS_CLOSED) {
                return;
        } else { /* initialised and doing I/O */
@@ -494,6 +495,11 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                                               1);
                                        INSIST(!atomic_load(&sock->client));
                                        finish = true;
+                               } else if (sock->tlsstream.state == TLS_IO &&
+                                          hs_result == ISC_R_SUCCESS &&
+                                          !sock->tlsstream.server)
+                               {
+                                       INSIST(atomic_load(&sock->client));
                                }
                        }
                } else if (send_data != NULL) {
@@ -523,6 +529,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                if (sock->tlsstream.state >= TLS_IO && sock->recv_cb != NULL &&
                    was_reading && sock->statichandle != NULL && !finish)
                {
+                       bool was_new_data = false;
                        uint8_t recv_buf[TLS_BUF_SIZE];
                        INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
                        while ((rv = SSL_read_ex(sock->tlsstream.tls, recv_buf,
@@ -532,6 +539,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                                region = (isc_region_t){ .base = &recv_buf[0],
                                                         .length = len };
 
+                               was_new_data = true;
                                INSIST(VALID_NMHANDLE(sock->statichandle));
                                sock->recv_cb(sock->statichandle, ISC_R_SUCCESS,
                                              &region, sock->recv_cbarg);
@@ -570,8 +578,29 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                                        break;
                                }
                        }
+
+                       if (was_new_data && !sock->manual_read_timer) {
+                               /*
+                                * Some data has been decrypted, it is the right
+                                * time to stop the read timer as it will be
+                                * restarted on the next read attempt.
+                                */
+                               isc__nmsocket_timer_stop(sock);
+                       }
                }
        }
+
+       /*
+        * Setting 'finish' to 'true' means that we are about to close the
+        * TLS stream (we intend to send TLS shutdown message to the
+        * remote side). After that no new data can be received, so we
+        * should stop the timer regardless of the
+        * 'sock->manual_read_timer' value.
+        */
+       if (finish) {
+               isc__nmsocket_timer_stop(sock);
+       }
+
        errno = 0;
        tls_status = SSL_get_error(sock->tlsstream.tls, rv);
        saved_errno = errno;
@@ -633,6 +662,9 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                INSIST(VALID_NMHANDLE(sock->outerhandle));
 
                isc_nm_read(sock->outerhandle, tls_readcb, sock);
+               if (!sock->manual_read_timer) {
+                       isc__nmsocket_timer_start(sock);
+               }
                return;
        default:
                result = tls_error_to_result(tls_status, sock->tlsstream.state,
@@ -764,6 +796,7 @@ tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        /* TODO: catch failure code, detach tlssock, and log the error */
 
+       isc__nmhandle_set_manual_timer(tlssock->outerhandle, true);
        tls_do_bio(tlssock, NULL, NULL, false);
        return (result);
 }
@@ -1081,6 +1114,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
         */
        handle->sock->tlsstream.tlssocket = tlssock;
 
+       isc__nmhandle_set_manual_timer(tlssock->outerhandle, true);
        tls_do_bio(tlssock, NULL, NULL, false);
        return;
 error:
@@ -1355,3 +1389,16 @@ tls_try_shutdown(isc_tls_t *tls, const bool force) {
                (void)SSL_shutdown(tls);
        }
 }
+
+void
+isc__nmhandle_tls_set_manual_timer(isc_nmhandle_t *handle, const bool manual) {
+       isc_nmsocket_t *sock;
+
+       REQUIRE(VALID_NMHANDLE(handle));
+       sock = handle->sock;
+       REQUIRE(VALID_NMSOCK(sock));
+       REQUIRE(sock->type == isc_nm_tlssocket);
+       REQUIRE(sock->tid == isc_tid());
+
+       sock->manual_read_timer = manual;
+}