]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add PROXYv2 support to DNS over HTTP(S) transport
authorArtem Boldariev <artem@boldariev.com>
Wed, 10 May 2023 19:01:36 +0000 (22:01 +0300)
committerArtem Boldariev <artem@boldariev.com>
Wed, 6 Dec 2023 13:15:24 +0000 (15:15 +0200)
This commit extends DNS over HTTP(S) transport with PROXYv2 support.

bin/dig/dighost.c
bin/tests/test_client.c
bin/tests/test_server.c
lib/isc/include/isc/netmgr.h
lib/isc/netmgr/http.c
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/ns/interfacemgr.c
tests/isc/doh_test.c

index 5a7664cde3bea1cee532035fd052fbcbf715c7e2..e494189bb5b4371234f596c6781f5b310c1ab19c 100644 (file)
@@ -3045,7 +3045,7 @@ start_tcp(dig_query_t *query) {
                isc_nm_httpconnect(netmgr, &localaddr, &query->sockaddr, uri,
                                   !query->lookup->https_get, tcp_connected,
                                   connectquery, tlsctx, sess_cache,
-                                  local_timeout);
+                                  local_timeout, false, NULL);
 #endif
        } else {
                isc_nm_streamdnsconnect(netmgr, &localaddr, &query->sockaddr,
index f32fa6770e48469435639aa0f52555b8291c3bd4..e26b2e657ea9755b01900c82cd976468cbcc343c 100644 (file)
@@ -408,7 +408,7 @@ run(void) {
                }
                isc_nm_httpconnect(netmgr, &sockaddr_local, &sockaddr_remote,
                                   req_url, is_post, connect_cb, NULL, tls_ctx,
-                                  NULL, timeout);
+                                  NULL, timeout, false, NULL);
        } break;
 #endif
        default:
index 1a78534b37d852b89adb16b36a542af58efeeb2b..2dad8cf4f8bafa538753cf45d165115d03c21f8f 100644 (file)
@@ -275,7 +275,7 @@ run(void) {
                if (result == ISC_R_SUCCESS) {
                        result = isc_nm_listenhttp(netmgr, ISC_NM_LISTEN_ALL,
                                                   &sockaddr, 0, NULL, tls_ctx,
-                                                  eps, 0, &sock);
+                                                  eps, 0, false, &sock);
                }
                isc_nm_http_endpoints_detach(&eps);
        } break;
index 1bbdb522594a04c0b3451803ff56ab50affc4d27..8002884aea9edf49c94e28c3cfd0dd6990e259ca 100644 (file)
@@ -640,13 +640,14 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
                   const char *uri, bool POST, isc_nm_cb_t cb, void *cbarg,
                   isc_tlsctx_t                      *ctx,
                   isc_tlsctx_client_session_cache_t *client_sess_cache,
-                  unsigned int                       timeout);
+                  unsigned int timeout, bool proxy,
+                  isc_nm_proxyheader_info_t *proxy_info);
 
 isc_result_t
 isc_nm_listenhttp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
                  int backlog, isc_quota_t *quota, isc_tlsctx_t *ctx,
                  isc_nm_http_endpoints_t *eps, uint32_t max_concurrent_streams,
-                 isc_nmsocket_t **sockp);
+                 bool proxy, isc_nmsocket_t **sockp);
 
 isc_nm_http_endpoints_t *
 isc_nm_http_endpoints_new(isc_mem_t *mctx);
index f6a11d69d5f54c1265508c5a7fa6326479e2a5b6..aa106e06d9d2b1f18099f91fa8a3810268bff06f 100644 (file)
@@ -344,6 +344,13 @@ isc__nm_httpsession_detach(isc_nm_http_session_t **sessionp) {
                             sizeof(isc_nm_http_session_t));
 }
 
+isc_nmhandle_t *
+isc__nm_httpsession_handle(isc_nm_http_session_t *session) {
+       REQUIRE(VALID_HTTP2_SESSION(session));
+
+       return (session->handle);
+}
+
 static http_cstream_t *
 find_http_cstream(int32_t stream_id, isc_nm_http_session_t *session) {
        http_cstream_t *cstream = NULL;
@@ -1446,7 +1453,8 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
                   const char *uri, bool post, isc_nm_cb_t cb, void *cbarg,
                   isc_tlsctx_t *tlsctx,
                   isc_tlsctx_client_session_cache_t *client_sess_cache,
-                  unsigned int timeout) {
+                  unsigned int timeout, bool proxy,
+                  isc_nm_proxyheader_info_t *proxy_info) {
        isc_sockaddr_t local_interface;
        isc_nmsocket_t *sock = NULL;
        isc__networker_t *worker = NULL;
@@ -1510,8 +1518,12 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
 
        if (tlsctx != NULL) {
                isc_nm_tlsconnect(mgr, local, peer, transport_connect_cb, sock,
-                                 tlsctx, client_sess_cache, timeout, false,
+                                 tlsctx, client_sess_cache, timeout, proxy,
                                  NULL);
+       } else if (proxy) {
+               isc_nm_proxystreamconnect(mgr, local, peer,
+                                         transport_connect_cb, sock, timeout,
+                                         proxy_info);
        } else {
                isc_nm_tcpconnect(mgr, local, peer, transport_connect_cb, sock,
                                  timeout);
@@ -2461,7 +2473,7 @@ isc_result_t
 isc_nm_listenhttp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
                  int backlog, isc_quota_t *quota, isc_tlsctx_t *ctx,
                  isc_nm_http_endpoints_t *eps, uint32_t max_concurrent_streams,
-                 isc_nmsocket_t **sockp) {
+                 bool proxy, isc_nmsocket_t **sockp) {
        isc_nmsocket_t *sock = NULL;
        isc_result_t result;
        isc__networker_t *worker = NULL;
@@ -2486,7 +2498,11 @@ isc_nm_listenhttp(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
        if (ctx != NULL) {
                result = isc_nm_listentls(mgr, workers, iface,
                                          httplisten_acceptcb, sock, backlog,
-                                         quota, ctx, false, &sock->outer);
+                                         quota, ctx, proxy, &sock->outer);
+       } else if (proxy) {
+               result = isc_nm_listenproxystream(mgr, workers, iface,
+                                                 httplisten_acceptcb, sock,
+                                                 backlog, quota, &sock->outer);
        } else {
                result = isc_nm_listentcp(mgr, workers, iface,
                                          httplisten_acceptcb, sock, backlog,
@@ -3201,8 +3217,8 @@ isc__nm_http_cleanup_data(isc_nmsocket_t *sock) {
 
        if ((sock->type == isc_nm_httplistener ||
             sock->type == isc_nm_httpsocket ||
-            sock->type == isc_nm_tcpsocket ||
-            sock->type == isc_nm_tlssocket) &&
+            sock->type == isc_nm_tcpsocket || sock->type == isc_nm_tlssocket ||
+            sock->type == isc_nm_proxystreamsocket) &&
            sock->h2.session != NULL)
        {
                if (sock->h2.connect.uri != NULL) {
index 5011d0b20bb173066d16ee0e7494d821446f4952..34c4982c0e29334d06ad893331cddefbecc5b55a 100644 (file)
@@ -1088,6 +1088,9 @@ isc__nm_httpsession_attach(isc_nm_http_session_t *source,
 void
 isc__nm_httpsession_detach(isc_nm_http_session_t **sessionp);
 
+isc_nmhandle_t *
+isc__nm_httpsession_handle(isc_nm_http_session_t *session);
+
 void
 isc__nm_http_set_tlsctx(isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx);
 
index 97176c9336f3381971867b544203ea69d298cce6..0ac2529c886aa0da3bd5643e74aa4580349fc581 100644 (file)
@@ -2147,15 +2147,20 @@ get_proxy_handle(isc_nmhandle_t *handle) {
        switch (sock->type) {
        case isc_nm_proxystreamsocket:
                return (handle);
+#ifdef HAVE_LIBNGHTTP2
+       case isc_nm_httpsocket:
+               return (get_proxy_handle(
+                       isc__nm_httpsession_handle(sock->h2.session)));
+#endif /* HAVE_LIBNGHTTP2 */
        default:
                break;
        }
 
-       if (sock->outerhandle == NULL) {
-               return NULL;
+       if (sock->outerhandle != NULL) {
+               return (get_proxy_handle(sock->outerhandle));
        }
 
-       return (get_proxy_handle(sock->outerhandle));
+       return (NULL);
 }
 
 bool
index 6524702095eab09d2d6d06824c3240f3f2d7a406..3561acd21db022ae7d2eb3a3d5bda59a1d7c2e67 100644 (file)
@@ -581,10 +581,10 @@ ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps,
        if (result == ISC_R_SUCCESS) {
                quota = isc_mem_get(ifp->mgr->mctx, sizeof(*quota));
                isc_quota_init(quota, max_clients);
-               result = isc_nm_listenhttp(ifp->mgr->nm, ISC_NM_LISTEN_ALL,
-                                          &ifp->addr, ifp->mgr->backlog, quota,
-                                          sslctx, epset,
-                                          max_concurrent_streams, &sock);
+               result = isc_nm_listenhttp(
+                       ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr,
+                       ifp->mgr->backlog, quota, sslctx, epset,
+                       max_concurrent_streams, false, &sock);
        }
 
        isc_nm_http_endpoints_detach(&epset);
index 2a05429ba86df508fe69b46e0f3ff6c314887df1..6e46abe91795eb70de3d72cc7ef89be66ebd67c0 100644 (file)
@@ -103,6 +103,8 @@ static atomic_bool check_listener_quota = false;
 
 static isc_nm_http_endpoints_t *endpoints = NULL;
 
+static atomic_bool use_PROXY = false;
+
 static isc_nm_t **nm = NULL;
 
 /* Timeout for soft-timeout tests (0.05 seconds) */
@@ -184,7 +186,7 @@ connect_send_request(isc_nm_t *mgr, const char *uri, bool post,
 
        isc_nm_httpconnect(mgr, NULL, &tcp_listen_addr, uri, post,
                           connect_send_cb, data, ctx, client_sess_cache,
-                          timeout);
+                          timeout, atomic_load(&use_PROXY), NULL);
 }
 
 static int
@@ -472,7 +474,7 @@ ISC_LOOP_TEST_IMPL(mock_doh_uv_tcp_bind) {
        assert_int_equal(result, ISC_R_SUCCESS);
        result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
                                   &tcp_listen_addr, 0, NULL, NULL, endpoints,
-                                  0, &listen_sock);
+                                  0, false, &listen_sock);
        assert_int_not_equal(result, ISC_R_SUCCESS);
        assert_null(listen_sock);
 
@@ -504,7 +506,7 @@ doh_noop(void *arg ISC_ATTR_UNUSED) {
 
        result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
                                   &tcp_listen_addr, 0, NULL, NULL, endpoints,
-                                  0, &listen_sock);
+                                  0, atomic_load(&use_PROXY), &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
        isc_loop_teardown(mainloop, listen_sock_close, listen_sock);
 
@@ -547,7 +549,7 @@ doh_noresponse(void *arg ISC_ATTR_UNUSED) {
 
        result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
                                   &tcp_listen_addr, 0, NULL, NULL, endpoints,
-                                  0, &listen_sock);
+                                  0, atomic_load(&use_PROXY), &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
        isc_loop_teardown(mainloop, listen_sock_close, listen_sock);
 
@@ -639,7 +641,7 @@ doh_timeout_recovery(void *arg ISC_ATTR_UNUSED) {
 
        result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
                                   &tcp_listen_addr, 0, NULL, NULL, endpoints,
-                                  0, &listen_sock);
+                                  0, atomic_load(&use_PROXY), &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
        isc_loop_teardown(mainloop, listen_sock_close, listen_sock);
 
@@ -658,7 +660,8 @@ doh_timeout_recovery(void *arg ISC_ATTR_UNUSED) {
                        ISC_NM_HTTP_DEFAULT_PATH);
        isc_nm_httpconnect(connect_nm, NULL, &tcp_listen_addr, req_url,
                           atomic_load(&POST), timeout_request_cb, NULL, ctx,
-                          client_sess_cache, T_SOFT);
+                          client_sess_cache, T_SOFT, atomic_load(&use_PROXY),
+                          NULL);
 }
 
 static int
@@ -765,10 +768,10 @@ doh_recv_one(void *arg ISC_ATTR_UNUSED) {
                                           doh_receive_request_cb, NULL);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
-                                  &tcp_listen_addr, 0, quotap,
-                                  atomic_load(&use_TLS) ? server_tlsctx : NULL,
-                                  endpoints, 0, &listen_sock);
+       result = isc_nm_listenhttp(
+               listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap,
+               atomic_load(&use_TLS) ? server_tlsctx : NULL, endpoints, 0,
+               atomic_load(&use_PROXY), &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
 
        sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url,
@@ -892,10 +895,10 @@ doh_recv_two(void *arg ISC_ATTR_UNUSED) {
                                           doh_receive_request_cb, NULL);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
-                                  &tcp_listen_addr, 0, quotap,
-                                  atomic_load(&use_TLS) ? server_tlsctx : NULL,
-                                  endpoints, 0, &listen_sock);
+       result = isc_nm_listenhttp(
+               listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap,
+               atomic_load(&use_TLS) ? server_tlsctx : NULL, endpoints, 0,
+               atomic_load(&use_PROXY), &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
 
        sockaddr_to_url(&tcp_listen_addr, atomic_load(&use_TLS), req_url,
@@ -907,7 +910,8 @@ doh_recv_two(void *arg ISC_ATTR_UNUSED) {
 
        isc_nm_httpconnect(connect_nm, NULL, &tcp_listen_addr, req_url,
                           atomic_load(&POST), doh_connect_send_two_requests_cb,
-                          NULL, ctx, client_sess_cache, 5000);
+                          NULL, ctx, client_sess_cache, 5000,
+                          atomic_load(&use_PROXY), NULL);
 
        isc_loop_teardown(mainloop, listen_sock_close, listen_sock);
 }
@@ -992,10 +996,10 @@ doh_recv_send(void *arg ISC_ATTR_UNUSED) {
                                           doh_receive_request_cb, NULL);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
-                                  &tcp_listen_addr, 0, quotap,
-                                  atomic_load(&use_TLS) ? server_tlsctx : NULL,
-                                  endpoints, 0, &listen_sock);
+       result = isc_nm_listenhttp(
+               listen_nm, ISC_NM_LISTEN_ALL, &tcp_listen_addr, 0, quotap,
+               atomic_load(&use_TLS) ? server_tlsctx : NULL, endpoints, 0,
+               atomic_load(&use_PROXY), &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
 
        for (size_t i = 0; i < nthreads; i++) {
@@ -1108,7 +1112,8 @@ ISC_LOOP_TEST_IMPL(doh_bad_connect_uri) {
 
        result = isc_nm_listenhttp(listen_nm, ISC_NM_LISTEN_ALL,
                                   &tcp_listen_addr, 0, quotap, server_tlsctx,
-                                  endpoints, 0, &listen_sock);
+                                  endpoints, 0, atomic_load(&use_PROXY),
+                                  &listen_sock);
        assert_int_equal(result, ISC_R_SUCCESS);
 
        /*