]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
TLS: isc__nm_senddns() support
authorArtem Boldariev <artem@boldariev.com>
Wed, 7 Dec 2022 12:18:33 +0000 (14:18 +0200)
committerArtem Boldariev <artem@boldariev.com>
Tue, 20 Dec 2022 20:13:53 +0000 (22:13 +0200)
This commit adds support for isc_nm_senddns() to the generic TLS code.

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

index a57222c367597223b222e6306e938b4caac3bb66..f71d74fb5aeb0869c027a47460ec0900732489f8 100644 (file)
@@ -1444,6 +1444,14 @@ isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
  * Back-end implementation of isc_nm_send() for TLSDNS handles.
  */
 
+void
+isc__nm_tls_senddns(isc_nmhandle_t *handle, const isc_region_t *region,
+                   isc_nm_cb_t cb, void *cbarg);
+/*%<
+ * The same as 'isc__nm_tls_send()', but with data length sent
+ * ahead of data (two bytes (16 bit) in big-endian format).
+ */
+
 void
 isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
 /*%<
index 80bcca310dad86f820d1fec2f57198a8ff7a54f6..24caf453dae2e53b96b29c488b3622be2f5b6314 100644 (file)
@@ -1882,6 +1882,9 @@ isc__nm_senddns(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
        case isc_nm_tcpsocket:
                isc__nm_tcp_senddns(handle, region, cb, cbarg);
                break;
+       case isc_nm_tlssocket:
+               isc__nm_tls_senddns(handle, region, cb, cbarg);
+               break;
        default:
                UNREACHABLE();
        }
index 67298cf8eb779e56eb6e47540c64e6e4c5bb019c..8a337112552d2e87b569db6f54f6d3036eca5909 100644 (file)
@@ -542,10 +542,41 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
                        bool sent_shutdown =
                                ((SSL_get_shutdown(sock->tlsstream.tls) &
                                  SSL_SENT_SHUTDOWN) != 0);
-                       rv = SSL_write_ex(sock->tlsstream.tls,
-                                         send_data->uvbuf.base,
-                                         send_data->uvbuf.len, &len);
-                       if (rv != 1 || len != send_data->uvbuf.len) {
+                       bool write_failed = false;
+                       if (*(uint16_t *)send_data->tcplen != 0) {
+                               /*
+                                * There is a DNS message length to write - do
+                                * it.
+                                */
+                               rv = SSL_write_ex(
+                                       sock->tlsstream.tls, send_data->tcplen,
+                                       sizeof(send_data->tcplen), &len);
+                               if (rv != 1 || len != sizeof(send_data->tcplen))
+                               {
+                                       write_failed = true;
+                               } else {
+                                       /* Write data */
+                                       rv = SSL_write_ex(sock->tlsstream.tls,
+                                                         send_data->uvbuf.base,
+                                                         send_data->uvbuf.len,
+                                                         &len);
+                                       if (rv != 1 ||
+                                           len != send_data->uvbuf.len)
+                                       {
+                                               write_failed = true;
+                                       }
+                               }
+                       } else {
+                               /* Write data only */
+                               rv = SSL_write_ex(sock->tlsstream.tls,
+                                                 send_data->uvbuf.base,
+                                                 send_data->uvbuf.len, &len);
+                               if (rv != 1 || len != send_data->uvbuf.len) {
+                                       write_failed = true;
+                               }
+                       }
+
+                       if (write_failed) {
                                result = received_shutdown || sent_shutdown
                                                 ? ISC_R_CANCELED
                                                 : ISC_R_TLSERROR;
@@ -931,9 +962,9 @@ done:
        return;
 }
 
-void
-isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
-                isc_nm_cb_t cb, void *cbarg) {
+static void
+tls_send(isc_nmhandle_t *handle, const isc_region_t *region, isc_nm_cb_t cb,
+        void *cbarg, const bool dnsmsg) {
        isc__netievent_tlssend_t *ievent = NULL;
        isc__nm_uvreq_t *uvreq = NULL;
        isc_nmsocket_t *sock = NULL;
@@ -951,6 +982,9 @@ isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
        uvreq->cbarg = cbarg;
        uvreq->uvbuf.base = (char *)region->base;
        uvreq->uvbuf.len = region->length;
+       if (dnsmsg) {
+               *(uint16_t *)uvreq->tcplen = htons(region->length);
+       }
 
        /*
         * We need to create an event and pass it using async channel
@@ -959,6 +993,18 @@ isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
        isc__nm_enqueue_ievent(sock->worker, (isc__netievent_t *)ievent);
 }
 
+void
+isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
+                isc_nm_cb_t cb, void *cbarg) {
+       tls_send(handle, region, cb, cbarg, false);
+}
+
+void
+isc__nm_tls_senddns(isc_nmhandle_t *handle, const isc_region_t *region,
+                   isc_nm_cb_t cb, void *cbarg) {
+       tls_send(handle, region, cb, cbarg, true);
+}
+
 void
 isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
        isc_nmsocket_t *sock = NULL;