2021-01-25 17:44:39 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
2021-01-25 17:44:39 +02:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
|
|
|
*/
|
|
|
|
|
2021-04-06 20:57:45 +03:00
|
|
|
#include <errno.h>
|
2021-01-25 17:44:39 +02:00
|
|
|
#include <libgen.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
2023-03-23 22:42:21 +01:00
|
|
|
#include <isc/async.h>
|
2021-01-25 17:44:39 +02:00
|
|
|
#include <isc/atomic.h>
|
|
|
|
#include <isc/buffer.h>
|
|
|
|
#include <isc/condition.h>
|
|
|
|
#include <isc/log.h>
|
|
|
|
#include <isc/magic.h>
|
|
|
|
#include <isc/mem.h>
|
|
|
|
#include <isc/netmgr.h>
|
|
|
|
#include <isc/once.h>
|
|
|
|
#include <isc/quota.h>
|
|
|
|
#include <isc/random.h>
|
|
|
|
#include <isc/refcount.h>
|
|
|
|
#include <isc/region.h>
|
|
|
|
#include <isc/result.h>
|
|
|
|
#include <isc/sockaddr.h>
|
|
|
|
#include <isc/stdtime.h>
|
|
|
|
#include <isc/thread.h>
|
|
|
|
#include <isc/util.h>
|
2022-04-27 17:41:47 +02:00
|
|
|
#include <isc/uv.h>
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
#include "../openssl_shim.h"
|
2021-01-25 17:44:39 +02:00
|
|
|
#include "netmgr-int.h"
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
#define TLS_BUF_SIZE (UINT16_MAX)
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-12-29 20:03:26 +02:00
|
|
|
#define TLS_MAX_SEND_BUF_SIZE (UINT16_MAX + UINT16_MAX / 2)
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
#ifdef ISC_NETMGR_TRACE
|
|
|
|
ISC_ATTR_UNUSED static const char *
|
|
|
|
tls_status2str(int tls_status) {
|
|
|
|
switch (tls_status) {
|
|
|
|
case SSL_ERROR_NONE:
|
|
|
|
return ("SSL_ERROR_NONE");
|
|
|
|
case SSL_ERROR_ZERO_RETURN:
|
|
|
|
return ("SSL_ERROR_ZERO_RETURN");
|
|
|
|
case SSL_ERROR_WANT_WRITE:
|
|
|
|
return ("SSL_ERROR_WANT_WRITE");
|
|
|
|
case SSL_ERROR_WANT_READ:
|
|
|
|
return ("SSL_ERROR_WANT_READ");
|
|
|
|
case SSL_ERROR_SSL:
|
|
|
|
return ("SSL_ERROR_SSL");
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_ATTR_UNUSED static const char *
|
|
|
|
state2str(int state) {
|
|
|
|
switch (state) {
|
|
|
|
case TLS_INIT:
|
|
|
|
return ("TLS_INIT");
|
|
|
|
case TLS_HANDSHAKE:
|
|
|
|
return ("TLS_HANDSHAKE");
|
|
|
|
case TLS_IO:
|
|
|
|
return ("TLS_IO");
|
|
|
|
case TLS_CLOSED:
|
|
|
|
return ("TLS_CLOSED");
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* ISC_NETMGR_TRACE */
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
static isc_result_t
|
2022-01-13 14:35:24 +02:00
|
|
|
tls_error_to_result(const int tls_err, const int tls_state, isc_tls_t *tls) {
|
2021-01-25 17:44:39 +02:00
|
|
|
switch (tls_err) {
|
|
|
|
case SSL_ERROR_ZERO_RETURN:
|
|
|
|
return (ISC_R_EOF);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
case SSL_ERROR_SSL:
|
2022-01-13 14:35:24 +02:00
|
|
|
if (tls != NULL && tls_state < TLS_IO &&
|
|
|
|
SSL_get_verify_result(tls) != X509_V_OK)
|
|
|
|
{
|
|
|
|
return (ISC_R_TLSBADPEERCERT);
|
|
|
|
}
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
return (ISC_R_TLSERROR);
|
2021-01-25 17:44:39 +02:00
|
|
|
default:
|
|
|
|
return (ISC_R_UNEXPECTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
static void
|
|
|
|
tls_read_start(isc_nmsocket_t *restrict sock);
|
|
|
|
|
2022-10-27 20:13:06 +03:00
|
|
|
static void
|
|
|
|
tls_read_stop(isc_nmsocket_t *sock);
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
static void
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result);
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
|
|
|
isc__nm_uvreq_t *send_data, bool finish);
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
|
|
|
|
void *cbarg);
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
async_tls_do_bio(isc_nmsocket_t *sock);
|
|
|
|
|
2022-03-29 20:42:16 +03:00
|
|
|
static void
|
|
|
|
tls_init_listener_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *ctx);
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_cleanup_listener_tlsctx(isc_nmsocket_t *listener);
|
|
|
|
|
|
|
|
static isc_tlsctx_t *
|
|
|
|
tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid);
|
|
|
|
|
2022-04-22 15:59:11 +03:00
|
|
|
static void
|
|
|
|
tls_keep_client_tls_session(isc_nmsocket_t *sock);
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_try_shutdown(isc_tls_t *tls, const bool quite);
|
|
|
|
|
2022-08-25 22:37:26 +03:00
|
|
|
static void
|
|
|
|
tls_try_to_enable_tcp_nodelay(isc_nmsocket_t *tlssock);
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
/*
|
|
|
|
* The socket is closing, outerhandle has been detached, listener is
|
|
|
|
* inactive, or the netmgr is closing: any operation on it should abort
|
|
|
|
* with ISC_R_CANCELED.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
inactive(isc_nmsocket_t *sock) {
|
2023-03-24 13:37:19 +01:00
|
|
|
return (!isc__nmsocket_active(sock) || sock->closing ||
|
2021-01-25 17:44:39 +02:00
|
|
|
sock->outerhandle == NULL ||
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
!isc__nmsocket_active(sock->outerhandle->sock) ||
|
2023-03-24 13:37:19 +01:00
|
|
|
sock->outerhandle->sock->closing ||
|
2022-07-26 13:03:45 +02:00
|
|
|
isc__nm_closing(sock->worker));
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
static void
|
|
|
|
tls_call_connect_cb(isc_nmsocket_t *sock, isc_nmhandle_t *handle,
|
|
|
|
const isc_result_t result) {
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
INSIST(sock->connect_cb != NULL);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
sock->connect_cb(handle, result, sock->connect_cbarg);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
isc__nmsocket_clearcb(handle->sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_senddone(isc_nmhandle_t *handle, isc_result_t eresult, void *cbarg) {
|
|
|
|
isc_nmsocket_tls_send_req_t *send_req =
|
|
|
|
(isc_nmsocket_tls_send_req_t *)cbarg;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc_nmsocket_t *tlssock = NULL;
|
|
|
|
bool finish = send_req->finish;
|
2022-12-05 20:19:03 +02:00
|
|
|
isc_nm_cb_t send_cb = NULL;
|
|
|
|
void *send_cbarg = NULL;
|
|
|
|
isc_nmhandle_t *send_handle = NULL;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
REQUIRE(VALID_NMSOCK(send_req->tlssock));
|
|
|
|
|
|
|
|
tlssock = send_req->tlssock;
|
|
|
|
send_req->tlssock = NULL;
|
2022-12-05 20:19:03 +02:00
|
|
|
send_cb = send_req->cb;
|
2022-12-29 20:03:26 +02:00
|
|
|
send_req->cb = NULL;
|
2022-12-05 20:19:03 +02:00
|
|
|
send_cbarg = send_req->cbarg;
|
2022-12-29 20:03:26 +02:00
|
|
|
send_req->cbarg = NULL;
|
2022-12-05 20:19:03 +02:00
|
|
|
send_handle = send_req->handle;
|
|
|
|
send_req->handle = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-04-22 15:59:11 +03:00
|
|
|
if (finish) {
|
|
|
|
tls_try_shutdown(tlssock->tlsstream.tls, true);
|
|
|
|
}
|
|
|
|
|
2022-12-05 20:19:03 +02:00
|
|
|
/* Try to keep the object to be reused later - to avoid an allocation */
|
|
|
|
if (tlssock->tlsstream.send_req == NULL) {
|
|
|
|
tlssock->tlsstream.send_req = send_req;
|
2022-12-29 20:03:26 +02:00
|
|
|
/*
|
|
|
|
* We need to ensure that the buffer is not going to grow too
|
|
|
|
* large uncontrollably. We try to keep its size to be no more
|
|
|
|
* than TLS_MAX_SEND_BUF_SIZE. The constant should be larger
|
|
|
|
* than 64 KB for this to work efficiently when combined with
|
|
|
|
* DNS transports.
|
|
|
|
*/
|
|
|
|
if (isc_buffer_length(&send_req->data) > TLS_MAX_SEND_BUF_SIZE)
|
|
|
|
{
|
|
|
|
/* free the underlying buffer */
|
|
|
|
isc_buffer_clearmctx(&send_req->data);
|
|
|
|
isc_buffer_invalidate(&send_req->data);
|
|
|
|
isc_buffer_init(&send_req->data, send_req->smallbuf,
|
|
|
|
sizeof(send_req->smallbuf));
|
|
|
|
isc_buffer_setmctx(&send_req->data,
|
|
|
|
handle->sock->worker->mctx);
|
|
|
|
} else {
|
|
|
|
isc_buffer_clear(&send_req->data);
|
|
|
|
}
|
2022-12-05 20:19:03 +02:00
|
|
|
} else {
|
2022-12-29 20:03:26 +02:00
|
|
|
isc_buffer_clearmctx(&send_req->data);
|
|
|
|
isc_buffer_invalidate(&send_req->data);
|
2022-12-05 20:19:03 +02:00
|
|
|
isc_mem_put(handle->sock->worker->mctx, send_req,
|
|
|
|
sizeof(*send_req));
|
|
|
|
}
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tlssock->tlsstream.nsending--;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-12-05 20:19:03 +02:00
|
|
|
if (send_cb != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(tlssock->statichandle));
|
|
|
|
send_cb(send_handle, eresult, send_cbarg);
|
|
|
|
isc_nmhandle_detach(&send_handle);
|
|
|
|
/* The last handle has been just detached: close the underlying
|
|
|
|
* socket. */
|
|
|
|
if (tlssock->statichandle == NULL) {
|
|
|
|
finish = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
if (finish) {
|
|
|
|
/*
|
|
|
|
* If wrapping up, call tls_failed_read() - it will care of
|
|
|
|
* socket de-initialisation and calling the read callback, if
|
|
|
|
* necessary.
|
|
|
|
*/
|
2022-08-29 10:55:10 +02:00
|
|
|
tls_failed_read_cb(tlssock, ISC_R_EOF);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
} else if (eresult == ISC_R_SUCCESS) {
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_do_bio(tlssock, NULL, NULL, false);
|
|
|
|
} else if (eresult != ISC_R_SUCCESS &&
|
|
|
|
tlssock->tlsstream.state <= TLS_HANDSHAKE &&
|
|
|
|
!tlssock->tlsstream.server)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We are still waiting for the handshake to complete, but
|
|
|
|
* it isn't going to happen. Call the connect callback,
|
|
|
|
* passing the error code there.
|
|
|
|
*
|
|
|
|
* (Note: tls_failed_read_cb() calls the connect
|
|
|
|
* rather than the read callback in this case.
|
|
|
|
* XXX: clarify?)
|
|
|
|
*/
|
|
|
|
tls_failed_read_cb(tlssock, eresult);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
isc__nmsocket_detach(&tlssock);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
tls_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result) {
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
2021-04-21 10:28:26 -07:00
|
|
|
REQUIRE(result != ISC_R_SUCCESS);
|
2021-01-25 17:44:39 +02:00
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
/* This is TLS counterpart of isc__nm_failed_connect_cb() */
|
2021-01-25 17:44:39 +02:00
|
|
|
if (!sock->tlsstream.server &&
|
|
|
|
(sock->tlsstream.state == TLS_INIT ||
|
|
|
|
sock->tlsstream.state == TLS_HANDSHAKE) &&
|
|
|
|
sock->connect_cb != NULL)
|
|
|
|
{
|
2021-03-10 14:30:16 +02:00
|
|
|
isc_nmhandle_t *handle = NULL;
|
|
|
|
INSIST(sock->statichandle == NULL);
|
2021-05-26 08:15:34 +02:00
|
|
|
handle = isc__nmhandle_get(sock, &sock->peer, &sock->iface);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tls_call_connect_cb(sock, handle, result);
|
2021-03-10 14:30:16 +02:00
|
|
|
isc__nmsocket_clearcb(sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_nmhandle_detach(&handle);
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
goto destroy;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc__nmsocket_timer_stop(sock);
|
|
|
|
|
|
|
|
/* Nobody is reading from the socket yet */
|
|
|
|
if (sock->statichandle == NULL) {
|
|
|
|
goto destroy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is TLS counterpart of isc__nmsocket_readtimeout_cb() */
|
|
|
|
if (sock->client && result == ISC_R_TIMEDOUT) {
|
|
|
|
INSIST(sock->statichandle != NULL);
|
|
|
|
|
|
|
|
if (sock->recv_cb != NULL) {
|
|
|
|
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
|
|
|
isc__nm_readcb(sock, req, ISC_R_TIMEDOUT, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isc__nmsocket_timer_running(sock)) {
|
|
|
|
/* Timer was restarted, bail-out */
|
|
|
|
return;
|
2021-04-21 10:28:26 -07:00
|
|
|
}
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
|
|
|
|
isc__nmsocket_clearcb(sock);
|
|
|
|
|
|
|
|
goto destroy;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
/*
|
|
|
|
* We don't need to check for .nsending, as the callbacks will be
|
|
|
|
* cleared at the time the tls_senddone() tries to call it for the
|
|
|
|
* second time.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (sock->recv_cb != NULL) {
|
|
|
|
isc__nm_uvreq_t *req = isc__nm_get_read_req(sock, NULL);
|
|
|
|
isc__nmsocket_clearcb(sock);
|
|
|
|
isc__nm_readcb(sock, req, result, false);
|
2021-04-21 10:28:26 -07:00
|
|
|
}
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
|
|
|
|
destroy:
|
|
|
|
isc__nmsocket_prep_destroy(sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 10:55:10 +02:00
|
|
|
void
|
2022-11-23 14:03:23 +01:00
|
|
|
isc__nm_tls_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
bool async ISC_ATTR_UNUSED) {
|
2022-08-29 10:55:10 +02:00
|
|
|
if (!inactive(sock) && sock->tlsstream.state == TLS_IO) {
|
|
|
|
tls_do_bio(sock, NULL, NULL, true);
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
return;
|
2022-08-29 10:55:10 +02:00
|
|
|
}
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
|
|
|
|
tls_failed_read_cb(sock, result);
|
2022-08-29 10:55:10 +02:00
|
|
|
}
|
|
|
|
|
2023-03-23 22:52:47 +01:00
|
|
|
static void
|
|
|
|
tls_do_bio_cb(void *arg) {
|
|
|
|
isc_nmsocket_t *sock = arg;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
|
|
|
|
tls_do_bio(sock, NULL, NULL, false);
|
|
|
|
|
|
|
|
isc__nmsocket_detach(&sock);
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
static void
|
|
|
|
async_tls_do_bio(isc_nmsocket_t *sock) {
|
2023-03-23 22:52:47 +01:00
|
|
|
isc__nmsocket_attach(sock, &(isc_nmsocket_t *){ NULL });
|
|
|
|
isc_async_run(sock->worker->loop, tls_do_bio_cb, sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
static int
|
|
|
|
tls_send_outgoing(isc_nmsocket_t *sock, bool finish, isc_nmhandle_t *tlshandle,
|
|
|
|
isc_nm_cb_t cb, void *cbarg) {
|
|
|
|
isc_nmsocket_tls_send_req_t *send_req = NULL;
|
|
|
|
int pending;
|
|
|
|
int rv;
|
2021-03-10 14:30:16 +02:00
|
|
|
size_t len = 0;
|
2022-12-29 20:03:26 +02:00
|
|
|
bool new_send_req = false;
|
|
|
|
isc_region_t used_region = { 0 };
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
|
|
|
if (inactive(sock)) {
|
|
|
|
if (cb != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(tlshandle));
|
|
|
|
cb(tlshandle, ISC_R_CANCELED, cbarg);
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2022-04-22 15:59:11 +03:00
|
|
|
if (finish) {
|
|
|
|
tls_try_shutdown(sock->tlsstream.tls, false);
|
|
|
|
tls_keep_client_tls_session(sock);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
pending = BIO_pending(sock->tlsstream.bio_out);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
if (pending <= 0) {
|
|
|
|
return (pending);
|
|
|
|
}
|
|
|
|
|
2022-12-05 20:19:03 +02:00
|
|
|
/* Try to reuse previously allocated object */
|
|
|
|
if (sock->tlsstream.send_req != NULL) {
|
|
|
|
send_req = sock->tlsstream.send_req;
|
2022-12-29 20:03:26 +02:00
|
|
|
send_req->finish = finish;
|
2022-12-05 20:19:03 +02:00
|
|
|
sock->tlsstream.send_req = NULL;
|
|
|
|
} else {
|
|
|
|
send_req = isc_mem_get(sock->worker->mctx, sizeof(*send_req));
|
2022-12-29 20:03:26 +02:00
|
|
|
*send_req = (isc_nmsocket_tls_send_req_t){ .finish = finish };
|
|
|
|
new_send_req = true;
|
2022-12-05 20:19:03 +02:00
|
|
|
}
|
|
|
|
|
2022-12-29 20:03:26 +02:00
|
|
|
if (new_send_req) {
|
|
|
|
isc_buffer_init(&send_req->data, &send_req->smallbuf,
|
|
|
|
sizeof(send_req->smallbuf));
|
|
|
|
isc_buffer_setmctx(&send_req->data, sock->worker->mctx);
|
2021-08-02 17:15:13 +03:00
|
|
|
}
|
2022-12-29 20:03:26 +02:00
|
|
|
INSIST(isc_buffer_remaininglength(&send_req->data) == 0);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
|
|
|
isc__nmsocket_attach(sock, &send_req->tlssock);
|
|
|
|
if (cb != NULL) {
|
|
|
|
send_req->cb = cb;
|
|
|
|
send_req->cbarg = cbarg;
|
|
|
|
isc_nmhandle_attach(tlshandle, &send_req->handle);
|
|
|
|
}
|
|
|
|
|
2022-12-29 20:03:26 +02:00
|
|
|
RUNTIME_CHECK(isc_buffer_reserve(&send_req->data, pending) ==
|
|
|
|
ISC_R_SUCCESS);
|
|
|
|
isc_buffer_add(&send_req->data, pending);
|
|
|
|
rv = BIO_read_ex(sock->tlsstream.bio_out,
|
|
|
|
isc_buffer_base(&send_req->data), pending, &len);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
/* There's something pending, read must succeed */
|
2022-12-29 20:03:26 +02:00
|
|
|
RUNTIME_CHECK(rv == 1 && len == (size_t)pending);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
|
|
|
|
sock->tlsstream.nsending++;
|
2022-12-29 20:03:26 +02:00
|
|
|
isc_buffer_remainingregion(&send_req->data, &used_region);
|
|
|
|
isc_nm_send(sock->outerhandle, &used_region, tls_senddone, send_req);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
|
|
|
return (pending);
|
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
static int
|
|
|
|
tls_process_outgoing(isc_nmsocket_t *sock, bool finish,
|
|
|
|
isc__nm_uvreq_t *send_data) {
|
|
|
|
int pending;
|
|
|
|
|
2022-04-22 15:59:11 +03:00
|
|
|
bool received_shutdown = ((SSL_get_shutdown(sock->tlsstream.tls) &
|
|
|
|
SSL_RECEIVED_SHUTDOWN) != 0);
|
|
|
|
bool sent_shutdown = ((SSL_get_shutdown(sock->tlsstream.tls) &
|
|
|
|
SSL_SENT_SHUTDOWN) != 0);
|
|
|
|
|
|
|
|
if (received_shutdown && !sent_shutdown) {
|
|
|
|
finish = true;
|
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
/* Data from TLS to network */
|
|
|
|
if (send_data != NULL) {
|
|
|
|
pending = tls_send_outgoing(sock, finish, send_data->handle,
|
|
|
|
send_data->cb.send,
|
|
|
|
send_data->cbarg);
|
|
|
|
} else {
|
|
|
|
pending = tls_send_outgoing(sock, finish, NULL, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2022-07-02 03:31:35 +03:00
|
|
|
tls_try_handshake(isc_nmsocket_t *sock, isc_result_t *presult) {
|
2021-03-10 14:30:16 +02:00
|
|
|
REQUIRE(sock->tlsstream.state == TLS_HANDSHAKE);
|
|
|
|
|
|
|
|
if (SSL_is_init_finished(sock->tlsstream.tls) == 1) {
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2023-03-24 15:32:02 +01:00
|
|
|
int rv = SSL_do_handshake(sock->tlsstream.tls);
|
2021-03-10 14:30:16 +02:00
|
|
|
if (rv == 1) {
|
2023-03-24 15:32:02 +01:00
|
|
|
isc_nmhandle_t *tlshandle = NULL;
|
2022-01-13 14:35:24 +02:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2023-03-24 15:32:02 +01:00
|
|
|
|
|
|
|
REQUIRE(sock->statichandle == NULL);
|
2021-03-10 14:30:16 +02:00
|
|
|
INSIST(SSL_is_init_finished(sock->tlsstream.tls) == 1);
|
2023-03-24 15:32:02 +01:00
|
|
|
|
2022-04-22 15:59:11 +03:00
|
|
|
isc__nmsocket_log_tls_session_reuse(sock, sock->tlsstream.tls);
|
2021-05-26 08:15:34 +02:00
|
|
|
tlshandle = isc__nmhandle_get(sock, &sock->peer, &sock->iface);
|
2022-10-27 20:13:06 +03:00
|
|
|
tls_read_stop(sock);
|
2023-03-24 15:32:02 +01:00
|
|
|
|
|
|
|
if (isc__nm_closing(sock->worker)) {
|
|
|
|
result = ISC_R_SHUTTINGDOWN;
|
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
if (sock->tlsstream.server) {
|
2022-12-01 22:42:54 +02:00
|
|
|
/*
|
2023-03-24 15:32:02 +01:00
|
|
|
* The listening sockets are now closed from outer
|
|
|
|
* to inner order, which means that this function
|
|
|
|
* will never be called when the outer socket has
|
|
|
|
* stopped listening.
|
2022-12-01 22:42:54 +02:00
|
|
|
*
|
|
|
|
* Also see 'isc__nmsocket_stop()' - the function used
|
|
|
|
* to shut down the listening TLS socket - for more
|
|
|
|
* details.
|
|
|
|
*/
|
2023-03-24 15:32:02 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
result = sock->accept_cb(tlshandle, result,
|
|
|
|
sock->accept_cbarg);
|
2022-08-24 14:59:50 +02:00
|
|
|
}
|
2021-03-10 14:30:16 +02:00
|
|
|
} else {
|
2022-01-13 14:35:24 +02:00
|
|
|
tls_call_connect_cb(sock, tlshandle, result);
|
2021-03-10 14:30:16 +02:00
|
|
|
}
|
|
|
|
isc_nmhandle_detach(&tlshandle);
|
|
|
|
sock->tlsstream.state = TLS_IO;
|
2022-07-02 03:31:35 +03:00
|
|
|
|
|
|
|
if (presult != NULL) {
|
|
|
|
*presult = result;
|
|
|
|
}
|
2021-03-10 14:30:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return (rv);
|
|
|
|
}
|
|
|
|
|
2022-06-24 15:20:13 +03:00
|
|
|
static bool
|
|
|
|
tls_try_to_close_unused_socket(isc_nmsocket_t *sock) {
|
|
|
|
if (sock->tlsstream.state > TLS_HANDSHAKE &&
|
|
|
|
sock->statichandle == NULL && sock->tlsstream.nsending == 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* It seems that no action on the socket has been
|
|
|
|
* scheduled on some point after the handshake, let's
|
|
|
|
* close the connection.
|
|
|
|
*/
|
|
|
|
isc__nmsocket_prep_destroy(sock);
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
static void
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data,
|
|
|
|
isc__nm_uvreq_t *send_data, bool finish) {
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2021-03-10 14:30:16 +02:00
|
|
|
int pending, tls_status = SSL_ERROR_NONE;
|
|
|
|
int rv = 0;
|
|
|
|
size_t len = 0;
|
2021-04-06 20:57:45 +03:00
|
|
|
int saved_errno = 0;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(sock->tid == isc_tid());
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-10-04 21:03:23 +03:00
|
|
|
/*
|
|
|
|
* Clear the TLS error queue so that SSL_get_error() and SSL I/O
|
|
|
|
* routine calls will not get affected by prior error statuses.
|
|
|
|
*
|
|
|
|
* See here:
|
|
|
|
* https://www.openssl.org/docs/man3.0/man3/SSL_get_error.html
|
|
|
|
*
|
|
|
|
* In particular, it mentions the following:
|
|
|
|
*
|
|
|
|
* The current thread's error queue must be empty before the
|
|
|
|
* TLS/SSL I/O operation is attempted, or SSL_get_error() will not
|
|
|
|
* work reliably.
|
|
|
|
*
|
|
|
|
* As we use the result of SSL_get_error() to decide on I/O
|
|
|
|
* operations, we need to ensure that it works reliably by
|
|
|
|
* cleaning the error queue.
|
|
|
|
*
|
|
|
|
* The sum of details: https://stackoverflow.com/a/37980911
|
|
|
|
*/
|
|
|
|
ERR_clear_error();
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
if (sock->tlsstream.state == TLS_INIT) {
|
2021-03-10 14:30:16 +02:00
|
|
|
INSIST(received_data == NULL && send_data == NULL);
|
|
|
|
if (sock->tlsstream.server) {
|
|
|
|
SSL_set_accept_state(sock->tlsstream.tls);
|
|
|
|
} else {
|
|
|
|
SSL_set_connect_state(sock->tlsstream.tls);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
sock->tlsstream.state = TLS_HANDSHAKE;
|
2022-07-02 03:31:35 +03:00
|
|
|
rv = tls_try_handshake(sock, NULL);
|
2021-03-10 14:30:16 +02:00
|
|
|
INSIST(SSL_is_init_finished(sock->tlsstream.tls) == 0);
|
2022-10-20 15:40:51 +03:00
|
|
|
isc__nmsocket_timer_restart(sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
} else if (sock->tlsstream.state == TLS_CLOSED) {
|
|
|
|
return;
|
2021-03-10 14:30:16 +02:00
|
|
|
} else { /* initialised and doing I/O */
|
|
|
|
if (received_data != NULL) {
|
|
|
|
INSIST(send_data == NULL);
|
|
|
|
rv = BIO_write_ex(sock->tlsstream.bio_in,
|
|
|
|
received_data->base,
|
|
|
|
received_data->length, &len);
|
|
|
|
if (rv <= 0 || len != received_data->length) {
|
|
|
|
result = ISC_R_TLSERROR;
|
2023-01-17 13:58:10 -08:00
|
|
|
#if ISC_NETMGR_TRACE
|
2021-04-06 20:57:45 +03:00
|
|
|
saved_errno = errno;
|
2021-11-24 14:09:31 +02:00
|
|
|
#endif
|
2021-03-10 14:30:16 +02:00
|
|
|
goto error;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
/*
|
|
|
|
* Only after doing the IO we can check whether SSL
|
|
|
|
* handshake is done.
|
|
|
|
*/
|
|
|
|
if (sock->tlsstream.state == TLS_HANDSHAKE) {
|
2022-07-02 03:31:35 +03:00
|
|
|
isc_result_t hs_result = ISC_R_UNSET;
|
|
|
|
rv = tls_try_handshake(sock, &hs_result);
|
|
|
|
if (sock->tlsstream.state == TLS_IO &&
|
2022-11-02 19:33:14 +01:00
|
|
|
hs_result != ISC_R_SUCCESS)
|
|
|
|
{
|
2022-07-02 03:31:35 +03:00
|
|
|
/*
|
2023-03-30 18:17:11 +03:00
|
|
|
* The accept/connect callback has been
|
|
|
|
* called unsuccessfully. Let's try to
|
|
|
|
* shut down the TLS connection
|
|
|
|
* gracefully.
|
2022-07-02 03:31:35 +03:00
|
|
|
*/
|
|
|
|
INSIST(SSL_is_init_finished(
|
|
|
|
sock->tlsstream.tls) ==
|
|
|
|
1);
|
|
|
|
finish = true;
|
|
|
|
}
|
2021-03-10 14:30:16 +02:00
|
|
|
}
|
|
|
|
} else if (send_data != NULL) {
|
|
|
|
INSIST(received_data == NULL);
|
|
|
|
INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
|
2021-04-06 23:44:37 +03:00
|
|
|
bool received_shutdown =
|
2021-03-10 14:30:16 +02:00
|
|
|
((SSL_get_shutdown(sock->tlsstream.tls) &
|
|
|
|
SSL_RECEIVED_SHUTDOWN) != 0);
|
2021-04-14 19:02:50 +03:00
|
|
|
bool sent_shutdown =
|
|
|
|
((SSL_get_shutdown(sock->tlsstream.tls) &
|
|
|
|
SSL_SENT_SHUTDOWN) != 0);
|
2022-12-07 14:18:33 +02:00
|
|
|
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) {
|
2021-05-12 14:39:24 +03:00
|
|
|
result = received_shutdown || sent_shutdown
|
|
|
|
? ISC_R_CANCELED
|
|
|
|
: ISC_R_TLSERROR;
|
2021-03-10 14:30:16 +02:00
|
|
|
send_data->cb.send(send_data->handle, result,
|
|
|
|
send_data->cbarg);
|
|
|
|
send_data = NULL;
|
2022-03-22 20:24:46 +02:00
|
|
|
return;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
/* Decrypt and pass data from network to client */
|
|
|
|
if (sock->tlsstream.state >= TLS_IO && sock->recv_cb != NULL &&
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
sock->statichandle != NULL && sock->reading && !finish)
|
2021-03-10 14:30:16 +02:00
|
|
|
{
|
2022-10-20 15:40:51 +03:00
|
|
|
bool was_new_data = false;
|
2021-03-10 14:30:16 +02:00
|
|
|
uint8_t recv_buf[TLS_BUF_SIZE];
|
|
|
|
INSIST(sock->tlsstream.state > TLS_HANDSHAKE);
|
|
|
|
while ((rv = SSL_read_ex(sock->tlsstream.tls, recv_buf,
|
|
|
|
TLS_BUF_SIZE, &len)) == 1)
|
|
|
|
{
|
|
|
|
isc_region_t region;
|
|
|
|
region = (isc_region_t){ .base = &recv_buf[0],
|
|
|
|
.length = len };
|
|
|
|
|
2022-10-20 15:40:51 +03:00
|
|
|
was_new_data = true;
|
2021-04-13 18:45:10 +03:00
|
|
|
INSIST(VALID_NMHANDLE(sock->statichandle));
|
2021-03-10 14:30:16 +02:00
|
|
|
sock->recv_cb(sock->statichandle, ISC_R_SUCCESS,
|
|
|
|
®ion, sock->recv_cbarg);
|
2021-04-13 18:45:10 +03:00
|
|
|
/* The handle could have been detached in
|
|
|
|
* sock->recv_cb, making the sock->statichandle
|
|
|
|
* nullified (it happens in netmgr.c). If it is
|
|
|
|
* the case, then it means that we are not
|
|
|
|
* interested in keeping the connection alive
|
2022-07-02 03:31:35 +03:00
|
|
|
* anymore. Let's shut down the SSL session,
|
|
|
|
* send what we have in the SSL buffers,
|
|
|
|
* and close the connection.
|
2021-04-13 18:45:10 +03:00
|
|
|
*/
|
|
|
|
if (sock->statichandle == NULL) {
|
|
|
|
finish = true;
|
|
|
|
break;
|
2022-11-22 15:11:57 +02:00
|
|
|
} else if (sock->recv_cb == NULL) {
|
|
|
|
/*
|
|
|
|
* The 'sock->recv_cb' might have been
|
|
|
|
* nullified during the call to
|
|
|
|
* 'sock->recv_cb'. That could happen,
|
|
|
|
* e.g. by an indirect call to
|
|
|
|
* 'isc_nmhandle_close()' from within
|
|
|
|
* the callback when wrapping up.
|
|
|
|
*
|
|
|
|
* In this case, let's close the TLS
|
|
|
|
* connection.
|
|
|
|
*/
|
|
|
|
finish = true;
|
|
|
|
break;
|
2022-08-29 10:55:10 +02:00
|
|
|
} else if (!sock->reading) {
|
2022-07-29 19:33:25 +03:00
|
|
|
/*
|
|
|
|
* Reading has been paused from withing
|
|
|
|
* the context of read callback - stop
|
|
|
|
* processing incoming data.
|
|
|
|
*/
|
|
|
|
break;
|
2021-04-13 18:45:10 +03:00
|
|
|
}
|
2021-03-10 14:30:16 +02:00
|
|
|
}
|
2022-10-20 15:40:51 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
}
|
2022-10-20 15:40:51 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2022-07-14 23:33:26 +03:00
|
|
|
errno = 0;
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_status = SSL_get_error(sock->tlsstream.tls, rv);
|
2021-04-06 20:57:45 +03:00
|
|
|
saved_errno = errno;
|
|
|
|
|
|
|
|
/* See "BUGS" section at:
|
|
|
|
* https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
|
|
|
|
*
|
|
|
|
* It is mentioned there that when TLS status equals
|
|
|
|
* SSL_ERROR_SYSCALL AND errno == 0 it means that underlying
|
|
|
|
* transport layer returned EOF prematurely. However, we are
|
|
|
|
* managing the transport ourselves, so we should just resume
|
|
|
|
* reading from the TCP socket.
|
|
|
|
*
|
|
|
|
* It seems that this case has been handled properly on modern
|
|
|
|
* versions of OpenSSL. That being said, the situation goes in
|
|
|
|
* line with the manual: it is briefly mentioned there that
|
|
|
|
* SSL_ERROR_SYSCALL might be returned not only in a case of
|
|
|
|
* low-level errors (like system call failures).
|
|
|
|
*/
|
|
|
|
if (tls_status == SSL_ERROR_SYSCALL && saved_errno == 0 &&
|
|
|
|
received_data == NULL && send_data == NULL && finish == false)
|
|
|
|
{
|
|
|
|
tls_status = SSL_ERROR_WANT_READ;
|
|
|
|
}
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
pending = tls_process_outgoing(sock, finish, send_data);
|
2022-10-04 21:03:23 +03:00
|
|
|
if (pending > 0 && tls_status != SSL_ERROR_SSL) {
|
2021-01-25 17:44:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
switch (tls_status) {
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
case SSL_ERROR_NONE:
|
2021-03-10 14:30:16 +02:00
|
|
|
case SSL_ERROR_ZERO_RETURN:
|
2022-06-24 15:20:13 +03:00
|
|
|
(void)tls_try_to_close_unused_socket(sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
return;
|
|
|
|
case SSL_ERROR_WANT_WRITE:
|
|
|
|
if (sock->tlsstream.nsending == 0) {
|
|
|
|
/*
|
|
|
|
* Launch tls_do_bio asynchronously. If we're sending
|
|
|
|
* already the send callback will call it.
|
|
|
|
*/
|
|
|
|
async_tls_do_bio(sock);
|
|
|
|
}
|
2021-03-10 14:30:16 +02:00
|
|
|
return;
|
2021-01-25 17:44:39 +02:00
|
|
|
case SSL_ERROR_WANT_READ:
|
2022-07-29 19:33:25 +03:00
|
|
|
if (tls_try_to_close_unused_socket(sock) ||
|
2022-11-02 19:33:14 +01:00
|
|
|
sock->outerhandle == NULL)
|
|
|
|
{
|
2022-07-02 03:31:35 +03:00
|
|
|
return;
|
2022-10-27 20:13:06 +03:00
|
|
|
} else if (sock->reading == false &&
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
sock->tlsstream.state == TLS_HANDSHAKE)
|
2022-10-27 20:13:06 +03:00
|
|
|
{
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
/*
|
|
|
|
* We need to read data when doing handshake even if
|
|
|
|
* 'sock->reading == false'. It will be stopped when
|
|
|
|
* handshake is completed.
|
|
|
|
*/
|
|
|
|
tls_read_start(sock);
|
|
|
|
return;
|
|
|
|
} else if (sock->reading == false) {
|
2022-10-27 20:13:06 +03:00
|
|
|
return;
|
2022-07-02 03:31:35 +03:00
|
|
|
}
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
tls_read_start(sock);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
return;
|
2021-01-25 17:44:39 +02:00
|
|
|
default:
|
2022-01-13 14:35:24 +02:00
|
|
|
result = tls_error_to_result(tls_status, sock->tlsstream.state,
|
|
|
|
sock->tlsstream.tls);
|
2021-03-10 14:30:16 +02:00
|
|
|
break;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
error:
|
2023-01-17 13:58:10 -08:00
|
|
|
#if ISC_NETMGR_TRACE
|
2022-12-07 09:45:34 +01:00
|
|
|
isc__nmsocket_log(sock, ISC_LOG_NOTICE,
|
|
|
|
"SSL error in BIO: %d %s (errno: %d). Arguments: "
|
|
|
|
"received_data: %p, "
|
|
|
|
"send_data: %p, finish: %s",
|
|
|
|
tls_status, isc_result_totext(result), saved_errno,
|
|
|
|
received_data, send_data, finish ? "true" : "false");
|
2021-11-24 14:09:31 +02:00
|
|
|
#endif
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_failed_read_cb(sock, result);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
|
|
|
|
void *cbarg) {
|
|
|
|
isc_nmsocket_t *tlssock = (isc_nmsocket_t *)cbarg;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMSOCK(tlssock));
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(tlssock->tid == isc_tid());
|
2021-02-28 19:33:16 +02:00
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_failed_read_cb(tlssock, result);
|
2021-01-25 17:44:39 +02:00
|
|
|
return;
|
2022-07-26 13:03:45 +02:00
|
|
|
} else if (isc__nmsocket_closing(handle->sock)) {
|
|
|
|
tls_failed_read_cb(tlssock, ISC_R_CANCELED);
|
|
|
|
return;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
2021-04-21 10:28:26 -07:00
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
REQUIRE(handle == tlssock->outerhandle);
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_do_bio(tlssock, region, NULL, false);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
initialize_tls(isc_nmsocket_t *sock, bool server) {
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(sock->tid == isc_tid());
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
sock->tlsstream.bio_in = BIO_new(BIO_s_mem());
|
|
|
|
if (sock->tlsstream.bio_in == NULL) {
|
|
|
|
isc_tls_free(&sock->tlsstream.tls);
|
|
|
|
return (ISC_R_TLSERROR);
|
|
|
|
}
|
|
|
|
sock->tlsstream.bio_out = BIO_new(BIO_s_mem());
|
|
|
|
if (sock->tlsstream.bio_out == NULL) {
|
|
|
|
BIO_free_all(sock->tlsstream.bio_in);
|
|
|
|
sock->tlsstream.bio_in = NULL;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc_tls_free(&sock->tlsstream.tls);
|
2021-01-25 17:44:39 +02:00
|
|
|
return (ISC_R_TLSERROR);
|
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
if (BIO_set_mem_eof_return(sock->tlsstream.bio_in, EOF) != 1 ||
|
|
|
|
BIO_set_mem_eof_return(sock->tlsstream.bio_out, EOF) != 1)
|
|
|
|
{
|
|
|
|
goto error;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
2021-03-10 14:30:16 +02:00
|
|
|
|
|
|
|
SSL_set_bio(sock->tlsstream.tls, sock->tlsstream.bio_in,
|
|
|
|
sock->tlsstream.bio_out);
|
|
|
|
sock->tlsstream.server = server;
|
2021-01-25 17:44:39 +02:00
|
|
|
sock->tlsstream.nsending = 0;
|
2021-04-23 17:30:59 +03:00
|
|
|
sock->tlsstream.state = TLS_INIT;
|
2021-01-25 17:44:39 +02:00
|
|
|
return (ISC_R_SUCCESS);
|
2021-03-10 14:30:16 +02:00
|
|
|
error:
|
|
|
|
isc_tls_free(&sock->tlsstream.tls);
|
|
|
|
sock->tlsstream.bio_out = sock->tlsstream.bio_in = NULL;
|
|
|
|
return (ISC_R_TLSERROR);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2022-08-25 22:37:26 +03:00
|
|
|
static void
|
|
|
|
tls_try_to_enable_tcp_nodelay(isc_nmsocket_t *tlssock) {
|
|
|
|
/*
|
|
|
|
* Try to enable TCP_NODELAY for TLS connections by default to speed up
|
|
|
|
* the handshakes, just like other software (e.g. NGINX) does.
|
|
|
|
*/
|
|
|
|
isc_result_t result = isc_nmhandle_set_tcp_nodelay(tlssock->outerhandle,
|
|
|
|
true);
|
|
|
|
tlssock->tlsstream.tcp_nodelay_value = (result == ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
static isc_result_t
|
|
|
|
tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|
|
|
isc_nmsocket_t *tlslistensock = (isc_nmsocket_t *)cbarg;
|
|
|
|
isc_nmsocket_t *tlssock = NULL;
|
2022-03-29 20:42:16 +03:00
|
|
|
isc_tlsctx_t *tlsctx = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
/* If accept() was unsuccessful we can't do anything */
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(VALID_NMSOCK(tlslistensock));
|
|
|
|
REQUIRE(tlslistensock->type == isc_nm_tlslistener);
|
|
|
|
|
2022-11-30 22:58:13 +02:00
|
|
|
if (isc__nm_closing(handle->sock->worker)) {
|
|
|
|
return (ISC_R_SHUTTINGDOWN);
|
|
|
|
} else if (isc__nmsocket_closing(handle->sock)) {
|
2022-10-14 20:45:40 +03:00
|
|
|
return (ISC_R_CANCELED);
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
/*
|
|
|
|
* We need to create a 'wrapper' tlssocket for this connection.
|
|
|
|
*/
|
2022-07-26 13:03:45 +02:00
|
|
|
tlssock = isc_mem_get(handle->sock->worker->mctx, sizeof(*tlssock));
|
|
|
|
isc__nmsocket_init(tlssock, handle->sock->worker, isc_nm_tlssocket,
|
2023-01-03 08:27:54 +01:00
|
|
|
&handle->sock->iface, NULL);
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
/* We need to initialize SSL now to reference SSL_CTX properly */
|
2022-07-26 13:03:45 +02:00
|
|
|
tlsctx = tls_get_listener_tlsctx(tlslistensock, isc_tid());
|
2022-03-29 20:42:16 +03:00
|
|
|
RUNTIME_CHECK(tlsctx != NULL);
|
|
|
|
isc_tlsctx_attach(tlsctx, &tlssock->tlsstream.ctx);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tlssock->tlsstream.tls = isc_tls_create(tlssock->tlsstream.ctx);
|
|
|
|
if (tlssock->tlsstream.tls == NULL) {
|
2023-03-24 13:37:19 +01:00
|
|
|
tlssock->closed = true;
|
2022-03-29 20:42:16 +03:00
|
|
|
isc_tlsctx_free(&tlssock->tlsstream.ctx);
|
2021-01-25 17:44:39 +02:00
|
|
|
isc__nmsocket_detach(&tlssock);
|
|
|
|
return (ISC_R_TLSERROR);
|
|
|
|
}
|
|
|
|
|
2023-03-24 15:32:02 +01:00
|
|
|
tlssock->accept_cb = tlslistensock->accept_cb;
|
|
|
|
tlssock->accept_cbarg = tlslistensock->accept_cbarg;
|
|
|
|
isc__nmsocket_attach(handle->sock, &tlssock->listener);
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_nmhandle_attach(handle, &tlssock->outerhandle);
|
|
|
|
tlssock->peer = handle->sock->peer;
|
2022-07-26 13:03:45 +02:00
|
|
|
tlssock->read_timeout =
|
2023-03-24 13:37:19 +01:00
|
|
|
atomic_load_relaxed(&handle->sock->worker->netmgr->init);
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-03-22 20:24:46 +02:00
|
|
|
/*
|
|
|
|
* Hold a reference to tlssock in the TCP socket: it will
|
|
|
|
* detached in isc__nm_tls_cleanup_data().
|
|
|
|
*/
|
|
|
|
handle->sock->tlsstream.tlssocket = tlssock;
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
result = initialize_tls(tlssock, true);
|
|
|
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
|
|
|
/* TODO: catch failure code, detach tlssock, and log the error */
|
|
|
|
|
2022-08-25 22:37:26 +03:00
|
|
|
tls_try_to_enable_tcp_nodelay(tlssock);
|
|
|
|
|
2022-10-20 15:40:51 +03:00
|
|
|
isc__nmhandle_set_manual_timer(tlssock->outerhandle, true);
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_do_bio(tlssock, NULL, NULL, false);
|
2021-01-25 17:44:39 +02:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2022-03-25 16:44:21 +01:00
|
|
|
isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
|
2022-03-23 13:57:15 +01:00
|
|
|
isc_nm_accept_cb_t accept_cb, void *accept_cbarg, int backlog,
|
2023-05-04 23:06:23 +03:00
|
|
|
isc_quota_t *quota, SSL_CTX *sslctx, bool proxy,
|
|
|
|
isc_nmsocket_t **sockp) {
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_result_t result;
|
2021-05-26 08:15:34 +02:00
|
|
|
isc_nmsocket_t *tlssock = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_nmsocket_t *tsock = NULL;
|
2023-11-21 14:33:07 +11:00
|
|
|
isc__networker_t *worker = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
REQUIRE(VALID_NM(mgr));
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(isc_tid() == 0);
|
|
|
|
|
2023-11-21 14:33:07 +11:00
|
|
|
worker = &mgr->workers[isc_tid()];
|
|
|
|
|
2022-07-26 13:03:45 +02:00
|
|
|
if (isc__nm_closing(worker)) {
|
2022-06-27 14:27:49 +03:00
|
|
|
return (ISC_R_SHUTTINGDOWN);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-07-26 13:03:45 +02:00
|
|
|
if (workers == 0) {
|
|
|
|
workers = mgr->nloops;
|
|
|
|
}
|
|
|
|
REQUIRE(workers <= mgr->nloops);
|
|
|
|
|
|
|
|
tlssock = isc_mem_get(worker->mctx, sizeof(*tlssock));
|
2021-05-26 08:15:34 +02:00
|
|
|
|
2023-01-03 08:27:54 +01:00
|
|
|
isc__nmsocket_init(tlssock, worker, isc_nm_tlslistener, iface, NULL);
|
2021-01-25 17:44:39 +02:00
|
|
|
tlssock->accept_cb = accept_cb;
|
|
|
|
tlssock->accept_cbarg = accept_cbarg;
|
2022-03-29 20:42:16 +03:00
|
|
|
tls_init_listener_tlsctx(tlssock, sslctx);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tlssock->tlsstream.tls = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* tlssock will be a TLS 'wrapper' around an unencrypted stream.
|
|
|
|
* We set tlssock->outer to a socket listening for a TCP connection.
|
|
|
|
*/
|
2023-05-04 23:06:23 +03:00
|
|
|
if (proxy) {
|
|
|
|
result = isc_nm_listenproxystream(
|
|
|
|
mgr, workers, iface, tlslisten_acceptcb, tlssock,
|
2023-05-18 21:52:23 +03:00
|
|
|
backlog, quota, NULL, &tlssock->outer);
|
2023-05-04 23:06:23 +03:00
|
|
|
} else {
|
|
|
|
result = isc_nm_listentcp(mgr, workers, iface,
|
|
|
|
tlslisten_acceptcb, tlssock, backlog,
|
|
|
|
quota, &tlssock->outer);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2023-03-24 13:37:19 +01:00
|
|
|
tlssock->closed = true;
|
2021-01-25 17:44:39 +02:00
|
|
|
isc__nmsocket_detach(&tlssock);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2023-01-31 13:30:12 -08:00
|
|
|
/* copy the actual port we're listening on into sock->iface */
|
|
|
|
if (isc_sockaddr_getport(iface) == 0) {
|
|
|
|
tlssock->iface = tlssock->outer->iface;
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
/* wait for listen result */
|
|
|
|
isc__nmsocket_attach(tlssock->outer, &tsock);
|
|
|
|
tlssock->result = result;
|
2023-03-28 17:03:56 +02:00
|
|
|
tlssock->active = true;
|
2021-01-25 17:44:39 +02:00
|
|
|
INSIST(tlssock->outer->tlsstream.tlslistener == NULL);
|
|
|
|
isc__nmsocket_attach(tlssock, &tlssock->outer->tlsstream.tlslistener);
|
|
|
|
isc__nmsocket_detach(&tsock);
|
2021-05-05 11:51:39 +02:00
|
|
|
INSIST(result != ISC_R_UNSET);
|
2022-10-14 20:45:40 +03:00
|
|
|
tlssock->nchildren = tlssock->outer->nchildren;
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
*sockp = tlssock;
|
|
|
|
}
|
|
|
|
|
2020-12-07 14:19:10 +02:00
|
|
|
return (result);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2023-03-23 22:46:58 +01:00
|
|
|
static void
|
|
|
|
tls_send_direct(void *arg) {
|
|
|
|
isc__nm_uvreq_t *req = arg;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_UVREQ(req));
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2023-03-23 22:46:58 +01:00
|
|
|
isc_nmsocket_t *sock = req->sock;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2023-03-23 22:46:58 +01:00
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->tid == isc_tid());
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
if (inactive(sock)) {
|
|
|
|
req->cb.send(req->handle, ISC_R_CANCELED, req->cbarg);
|
2021-03-10 14:30:16 +02:00
|
|
|
goto done;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2021-03-10 14:30:16 +02:00
|
|
|
tls_do_bio(sock, NULL, req, false);
|
|
|
|
done:
|
2023-03-24 12:11:44 +01:00
|
|
|
isc__nm_uvreq_put(&req);
|
2021-01-25 17:44:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-12-07 14:18:33 +02:00
|
|
|
static void
|
|
|
|
tls_send(isc_nmhandle_t *handle, const isc_region_t *region, isc_nm_cb_t cb,
|
|
|
|
void *cbarg, const bool dnsmsg) {
|
2021-01-25 17:44:39 +02:00
|
|
|
isc__nm_uvreq_t *uvreq = NULL;
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
2020-10-31 20:42:18 +01:00
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
|
|
|
|
REQUIRE(sock->type == isc_nm_tlssocket);
|
|
|
|
|
2023-03-24 12:11:44 +01:00
|
|
|
uvreq = isc__nm_uvreq_get(sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_nmhandle_attach(handle, &uvreq->handle);
|
|
|
|
uvreq->cb.send = cb;
|
|
|
|
uvreq->cbarg = cbarg;
|
2021-08-02 14:43:54 +03:00
|
|
|
uvreq->uvbuf.base = (char *)region->base;
|
2021-01-25 17:44:39 +02:00
|
|
|
uvreq->uvbuf.len = region->length;
|
2022-12-07 14:18:33 +02:00
|
|
|
if (dnsmsg) {
|
|
|
|
*(uint16_t *)uvreq->tcplen = htons(region->length);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2023-04-11 12:37:21 +02:00
|
|
|
isc_job_run(sock->worker->loop, &uvreq->job, tls_send_direct, uvreq);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2022-12-07 14:18:33 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
void
|
|
|
|
isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
sock = handle->sock;
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->statichandle == handle);
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(sock->tid == isc_tid());
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
if (inactive(sock)) {
|
2022-10-27 21:16:36 +03:00
|
|
|
cb(handle, ISC_R_CANCELED, NULL, cbarg);
|
2021-01-25 17:44:39 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sock->recv_cb = cb;
|
|
|
|
sock->recv_cbarg = cbarg;
|
2022-10-27 20:13:06 +03:00
|
|
|
sock->reading = true;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-10-27 20:13:06 +03:00
|
|
|
async_tls_do_bio(sock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
tls_read_start(isc_nmsocket_t *restrict sock) {
|
|
|
|
if (sock->tlsstream.reading) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sock->tlsstream.reading = true;
|
|
|
|
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
|
|
|
|
isc_nm_read(sock->outerhandle, tls_readcb, sock);
|
|
|
|
if (!sock->manual_read_timer) {
|
|
|
|
isc__nmsocket_timer_start(sock);
|
|
|
|
}
|
|
|
|
}
|
2022-08-29 10:55:10 +02:00
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
static void
|
|
|
|
tls_read_stop(isc_nmsocket_t *sock) {
|
|
|
|
sock->tlsstream.reading = false;
|
2022-10-27 20:13:06 +03:00
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
isc_nm_read_stop(sock->outerhandle);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-08-29 10:55:10 +02:00
|
|
|
isc__nm_tls_read_stop(isc_nmhandle_t *handle) {
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
handle->sock->reading = false;
|
|
|
|
|
2022-10-27 20:13:06 +03:00
|
|
|
tls_read_stop(handle->sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
void
|
|
|
|
isc__nm_tls_close(isc_nmsocket_t *sock) {
|
2021-01-25 17:44:39 +02:00
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
REQUIRE(sock->type == isc_nm_tlssocket);
|
|
|
|
REQUIRE(!sock->closing);
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(sock->tid == isc_tid());
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
REQUIRE(!sock->closed);
|
|
|
|
REQUIRE(!sock->closing);
|
|
|
|
|
|
|
|
sock->closing = true;
|
|
|
|
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
/*
|
|
|
|
* At this point we're certain that there are no
|
|
|
|
* external references, we can close everything.
|
|
|
|
*/
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
tls_read_stop(sock);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
if (sock->outerhandle != NULL) {
|
2022-08-29 10:55:10 +02:00
|
|
|
isc_nm_read_stop(sock->outerhandle);
|
|
|
|
isc_nmhandle_close(sock->outerhandle);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc_nmhandle_detach(&sock->outerhandle);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
if (sock->listener != NULL) {
|
|
|
|
isc__nmsocket_detach(&sock->listener);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
|
2022-03-22 20:24:46 +02:00
|
|
|
/* Further cleanup performed in isc__nm_tls_cleanup_data() */
|
2023-03-24 13:37:19 +01:00
|
|
|
sock->closed = true;
|
2023-03-28 17:03:56 +02:00
|
|
|
sock->active = false;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
sock->tlsstream.state = TLS_CLOSED;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
isc__nm_tls_stoplistening(isc_nmsocket_t *sock) {
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->type == isc_nm_tlslistener);
|
2022-08-24 14:59:50 +02:00
|
|
|
REQUIRE(sock->tlsstream.tls == NULL);
|
|
|
|
REQUIRE(sock->tlsstream.ctx == NULL);
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2022-10-14 20:45:40 +03:00
|
|
|
isc__nmsocket_stop(sock);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2021-04-23 17:30:59 +03:00
|
|
|
static void
|
|
|
|
tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg);
|
|
|
|
|
2021-03-31 18:32:32 +02:00
|
|
|
void
|
2021-05-26 08:15:34 +02:00
|
|
|
isc_nm_tlsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
isc_nm_cb_t connect_cb, void *connect_cbarg,
|
|
|
|
isc_tlsctx_t *ctx,
|
2022-04-22 15:59:11 +03:00
|
|
|
isc_tlsctx_client_session_cache_t *client_sess_cache,
|
2023-05-04 23:06:23 +03:00
|
|
|
unsigned int timeout, bool proxy,
|
|
|
|
isc_nm_proxyheader_info_t *proxy_info) {
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
isc_nmsocket_t *sock = NULL;
|
2023-11-21 14:33:07 +11:00
|
|
|
isc__networker_t *worker = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
REQUIRE(VALID_NM(mgr));
|
|
|
|
|
2023-11-21 14:33:07 +11:00
|
|
|
worker = &mgr->workers[isc_tid()];
|
|
|
|
|
2022-07-26 13:03:45 +02:00
|
|
|
if (isc__nm_closing(worker)) {
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
connect_cb(NULL, ISC_R_SHUTTINGDOWN, connect_cbarg);
|
2022-06-27 14:27:49 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
sock = isc_mem_get(worker->mctx, sizeof(*sock));
|
|
|
|
isc__nmsocket_init(sock, worker, isc_nm_tlssocket, local, NULL);
|
|
|
|
sock->connect_cb = connect_cb;
|
|
|
|
sock->connect_cbarg = connect_cbarg;
|
|
|
|
sock->connect_timeout = timeout;
|
|
|
|
isc_tlsctx_attach(ctx, &sock->tlsstream.ctx);
|
|
|
|
sock->client = true;
|
2022-04-22 15:59:11 +03:00
|
|
|
if (client_sess_cache != NULL) {
|
|
|
|
INSIST(isc_tlsctx_client_session_cache_getctx(
|
|
|
|
client_sess_cache) == ctx);
|
|
|
|
isc_tlsctx_client_session_cache_attach(
|
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra. Fix the
logic in the way:
1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
the handle, the read callback will be called with ISC_R_CANCELED to
cancel active reading from the socket/handle.
2. When isc_nm_read() has been called and isc_nm_read_stop() has been
called on the on the handle, the read callback will be called with
ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
is being shut down.
3. The .reading and .recv_read flags are little bit tricky. The
.reading flag indicates if the outer layer is reading the data (that
would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
the .recv_read flag indicates whether somebody is interested in the
data read from the socket.
Usually, you would expect that the .reading should be false when
.recv_read is false, but it gets even more tricky with TLSStream as
the TLS protocol might need to read from the socket even when sending
data.
Fix the usage of the .recv_read and .reading flags in the TLSStream
to their true meaning - which mostly consist of using .recv_read
everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
with the .reading flag.
4. The TLS failed read helper has been modified to resemble the TCP code
as much as possible, clearing and re-setting the .recv_read flag in
the TCP timeout code has been fixed and .recv_read is now cleared
when isc_nm_read_stop() has been called on the streaming socket.
5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
isc_httpd units have been greatly simplified due to the improved design.
6. More unit tests for TCP and TLS testing the shutdown conditions have
been added.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-13 17:27:50 +02:00
|
|
|
client_sess_cache, &sock->tlsstream.client_sess_cache);
|
2022-04-22 15:59:11 +03:00
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
|
2023-05-04 23:06:23 +03:00
|
|
|
if (proxy) {
|
|
|
|
isc_nm_proxystreamconnect(mgr, local, peer, tcp_connected, sock,
|
2023-05-18 21:52:23 +03:00
|
|
|
sock->connect_timeout, NULL, NULL,
|
|
|
|
proxy_info);
|
2023-05-04 23:06:23 +03:00
|
|
|
} else {
|
|
|
|
isc_nm_tcpconnect(mgr, local, peer, tcp_connected, sock,
|
|
|
|
sock->connect_timeout);
|
|
|
|
}
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_nmsocket_t *tlssock = (isc_nmsocket_t *)cbarg;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc_nmhandle_t *tlshandle = NULL;
|
2022-07-26 13:03:45 +02:00
|
|
|
isc__networker_t *worker = NULL;
|
2021-01-25 17:44:39 +02:00
|
|
|
|
|
|
|
REQUIRE(VALID_NMSOCK(tlssock));
|
|
|
|
|
2022-07-26 13:03:45 +02:00
|
|
|
worker = tlssock->worker;
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
goto error;
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
|
2022-06-24 15:49:15 +03:00
|
|
|
INSIST(VALID_NMHANDLE(handle));
|
|
|
|
|
2021-06-07 17:46:08 +03:00
|
|
|
tlssock->iface = handle->sock->iface;
|
|
|
|
tlssock->peer = handle->sock->peer;
|
2022-07-26 13:03:45 +02:00
|
|
|
if (isc__nm_closing(worker)) {
|
2021-07-26 13:14:41 +02:00
|
|
|
result = ISC_R_SHUTTINGDOWN;
|
2021-03-31 18:32:32 +02:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
/*
|
|
|
|
* We need to initialize SSL now to reference SSL_CTX properly.
|
|
|
|
*/
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tlssock->tlsstream.tls = isc_tls_create(tlssock->tlsstream.ctx);
|
|
|
|
if (tlssock->tlsstream.tls == NULL) {
|
2021-01-25 17:44:39 +02:00
|
|
|
result = ISC_R_TLSERROR;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2021-04-23 17:30:59 +03:00
|
|
|
result = initialize_tls(tlssock, false);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
tlssock->peer = isc_nmhandle_peeraddr(handle);
|
|
|
|
isc_nmhandle_attach(handle, &tlssock->outerhandle);
|
2023-03-28 17:03:56 +02:00
|
|
|
tlssock->active = true;
|
2021-03-10 14:30:16 +02:00
|
|
|
|
2022-04-22 15:59:11 +03:00
|
|
|
if (tlssock->tlsstream.client_sess_cache != NULL) {
|
|
|
|
isc_tlsctx_client_session_cache_reuse_sockaddr(
|
|
|
|
tlssock->tlsstream.client_sess_cache, &tlssock->peer,
|
|
|
|
tlssock->tlsstream.tls);
|
|
|
|
}
|
|
|
|
|
2022-03-22 20:24:46 +02:00
|
|
|
/*
|
|
|
|
* Hold a reference to tlssock in the TCP socket: it will
|
|
|
|
* detached in isc__nm_tls_cleanup_data().
|
|
|
|
*/
|
|
|
|
handle->sock->tlsstream.tlssocket = tlssock;
|
|
|
|
|
2022-08-25 22:37:26 +03:00
|
|
|
tls_try_to_enable_tcp_nodelay(tlssock);
|
|
|
|
|
2022-10-20 15:40:51 +03:00
|
|
|
isc__nmhandle_set_manual_timer(tlssock->outerhandle, true);
|
2021-04-23 17:30:59 +03:00
|
|
|
tls_do_bio(tlssock, NULL, NULL, false);
|
2021-01-25 17:44:39 +02:00
|
|
|
return;
|
|
|
|
error:
|
|
|
|
tlshandle = isc__nmhandle_get(tlssock, NULL, NULL);
|
2023-03-24 13:37:19 +01:00
|
|
|
tlssock->closed = true;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
tls_call_connect_cb(tlssock, tlshandle, result);
|
2021-01-25 17:44:39 +02:00
|
|
|
isc_nmhandle_detach(&tlshandle);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc__nmsocket_detach(&tlssock);
|
|
|
|
}
|
|
|
|
|
2021-01-25 17:44:39 +02:00
|
|
|
void
|
|
|
|
isc__nm_tls_cleanup_data(isc_nmsocket_t *sock) {
|
2023-05-04 23:06:23 +03:00
|
|
|
if ((sock->type == isc_nm_tcplistener ||
|
|
|
|
sock->type == isc_nm_proxystreamlistener) &&
|
2022-11-02 19:33:14 +01:00
|
|
|
sock->tlsstream.tlslistener != NULL)
|
|
|
|
{
|
2021-01-25 17:44:39 +02:00
|
|
|
isc__nmsocket_detach(&sock->tlsstream.tlslistener);
|
2022-03-22 20:24:46 +02:00
|
|
|
} else if (sock->type == isc_nm_tlslistener) {
|
|
|
|
tls_cleanup_listener_tlsctx(sock);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
} else if (sock->type == isc_nm_tlssocket) {
|
|
|
|
if (sock->tlsstream.tls != NULL) {
|
2022-04-22 15:59:11 +03:00
|
|
|
/*
|
2022-07-02 03:31:35 +03:00
|
|
|
* Let's shut down the TLS session properly so that
|
|
|
|
* the session will remain resumable, if required.
|
2022-04-22 15:59:11 +03:00
|
|
|
*/
|
|
|
|
tls_try_shutdown(sock->tlsstream.tls, true);
|
|
|
|
tls_keep_client_tls_session(sock);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
isc_tls_free(&sock->tlsstream.tls);
|
|
|
|
/* These are destroyed when we free SSL */
|
2021-03-10 14:30:16 +02:00
|
|
|
sock->tlsstream.bio_out = NULL;
|
|
|
|
sock->tlsstream.bio_in = NULL;
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
}
|
2022-04-22 15:59:11 +03:00
|
|
|
if (sock->tlsstream.ctx != NULL) {
|
|
|
|
isc_tlsctx_free(&sock->tlsstream.ctx);
|
|
|
|
}
|
|
|
|
if (sock->tlsstream.client_sess_cache != NULL) {
|
2023-03-24 13:37:19 +01:00
|
|
|
INSIST(sock->client);
|
2022-04-22 15:59:11 +03:00
|
|
|
isc_tlsctx_client_session_cache_detach(
|
|
|
|
&sock->tlsstream.client_sess_cache);
|
|
|
|
}
|
2022-12-05 20:19:03 +02:00
|
|
|
|
|
|
|
if (sock->tlsstream.send_req != NULL) {
|
2022-12-29 20:03:26 +02:00
|
|
|
isc_buffer_clearmctx(&sock->tlsstream.send_req->data);
|
|
|
|
isc_buffer_invalidate(&sock->tlsstream.send_req->data);
|
2022-12-05 20:19:03 +02:00
|
|
|
isc_mem_put(sock->worker->mctx,
|
|
|
|
sock->tlsstream.send_req,
|
|
|
|
sizeof(*sock->tlsstream.send_req));
|
|
|
|
}
|
2023-05-04 23:06:23 +03:00
|
|
|
} else if ((sock->type == isc_nm_tcpsocket ||
|
|
|
|
sock->type == isc_nm_proxystreamsocket) &&
|
2022-11-02 19:33:14 +01:00
|
|
|
sock->tlsstream.tlssocket != NULL)
|
|
|
|
{
|
2022-03-22 20:24:46 +02:00
|
|
|
/*
|
|
|
|
* The TLS socket can't be destroyed until its underlying TCP
|
|
|
|
* socket is, to avoid possible use-after-free errors.
|
|
|
|
*/
|
|
|
|
isc__nmsocket_detach(&sock->tlsstream.tlssocket);
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-16 09:03:02 +01:00
|
|
|
void
|
|
|
|
isc__nm_tls_cleartimeout(isc_nmhandle_t *handle) {
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
isc_nmhandle_cleartimeout(sock->outerhandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
refactor outgoing HTTP connection support
- style, cleanup, and removal of unnecessary code.
- combined isc_nm_http_add_endpoint() and isc_nm_http_add_doh_endpoint()
into one function, renamed isc_http_endpoint().
- moved isc_nm_http_connect_send_request() into doh_test.c as a helper
function; remove it from the public API.
- renamed isc_http2 and isc_nm_http2 types and functions to just isc_http
and isc_nm_http, for consistency with other existing names.
- shortened a number of long names.
- the caller is now responsible for determining the peer address.
in isc_nm_httpconnect(); this eliminates the need to parse the URI
and the dependency on an external resolver.
- the caller is also now responsible for creating the SSL client context,
for consistency with isc_nm_tlsdnsconnect().
- added setter functions for HTTP/2 ALPN. instead of setting up ALPN in
isc_tlsctx_createclient(), we now have a function
isc_tlsctx_enable_http2client_alpn() that can be run from
isc_nm_httpconnect().
- refactored isc_nm_httprequest() into separate read and send functions.
isc_nm_send() or isc_nm_read() is called on an http socket, it will
be stored until a corresponding isc_nm_read() or _send() arrives; when
we have both halves of the pair the HTTP request will be initiated.
- isc_nm_httprequest() is renamed isc__nm_http_request() for use as an
internal helper function by the DoH unit test. (eventually doh_test
should be rewritten to use read and send, and this function should
be removed.)
- added implementations of isc__nm_tls_settimeout() and
isc__nm_http_settimeout().
- increased NGHTTP2 header block length for client connections to 128K.
- use isc_mem_t for internal memory allocations inside nghttp2, to
help track memory leaks.
- send "Cache-Control" header in requests and responses. (note:
currently we try to bypass HTTP caching proxies, but ideally we should
interact with them: https://tools.ietf.org/html/rfc8484#section-5.1)
2021-02-03 16:59:49 -08:00
|
|
|
void
|
|
|
|
isc__nm_tls_settimeout(isc_nmhandle_t *handle, uint32_t timeout) {
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
isc_nmhandle_settimeout(sock->outerhandle, timeout);
|
2021-01-25 17:44:39 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-14 21:12:37 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
isc__nmhandle_tls_keepalive(isc_nmhandle_t *handle, bool value) {
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
|
|
|
|
isc_nmhandle_keepalive(sock->outerhandle, value);
|
|
|
|
}
|
|
|
|
}
|
2022-01-13 14:35:24 +02:00
|
|
|
|
2022-06-23 20:18:58 +03:00
|
|
|
void
|
|
|
|
isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle,
|
|
|
|
uint64_t write_timeout) {
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
|
|
|
|
isc_nmhandle_setwritetimeout(sock->outerhandle, write_timeout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-26 17:07:19 +03:00
|
|
|
void
|
|
|
|
isc__nmsocket_tls_reset(isc_nmsocket_t *sock) {
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
REQUIRE(VALID_NMSOCK(sock->outerhandle->sock));
|
|
|
|
isc__nmsocket_reset(sock->outerhandle->sock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-26 17:36:32 +03:00
|
|
|
bool
|
|
|
|
isc__nmsocket_tls_timer_running(isc_nmsocket_t *sock) {
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
REQUIRE(VALID_NMSOCK(sock->outerhandle->sock));
|
|
|
|
return (isc__nmsocket_timer_running(sock->outerhandle->sock));
|
|
|
|
}
|
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
2022-07-27 16:26:55 +03:00
|
|
|
void
|
|
|
|
isc__nmsocket_tls_timer_restart(isc_nmsocket_t *sock) {
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
REQUIRE(VALID_NMSOCK(sock->outerhandle->sock));
|
|
|
|
isc__nmsocket_timer_restart(sock->outerhandle->sock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
isc__nmsocket_tls_timer_stop(isc_nmsocket_t *sock) {
|
|
|
|
REQUIRE(VALID_NMSOCK(sock));
|
|
|
|
REQUIRE(sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
REQUIRE(VALID_NMSOCK(sock->outerhandle->sock));
|
|
|
|
isc__nmsocket_timer_stop(sock->outerhandle->sock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-13 14:35:24 +02:00
|
|
|
const char *
|
|
|
|
isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle) {
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
if (sock->tlsstream.tls == NULL) {
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (isc_tls_verify_peer_result_string(sock->tlsstream.tls));
|
|
|
|
}
|
2022-03-29 20:42:16 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
tls_init_listener_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *ctx) {
|
2022-03-31 13:47:48 +03:00
|
|
|
size_t nworkers;
|
2022-03-29 20:42:16 +03:00
|
|
|
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(VALID_NMSOCK(listener));
|
2022-03-29 20:42:16 +03:00
|
|
|
REQUIRE(ctx != NULL);
|
|
|
|
|
2022-07-26 13:03:45 +02:00
|
|
|
nworkers =
|
|
|
|
(size_t)isc_loopmgr_nloops(listener->worker->netmgr->loopmgr);
|
2022-03-31 13:47:48 +03:00
|
|
|
INSIST(nworkers > 0);
|
|
|
|
|
2023-08-23 08:56:31 +02:00
|
|
|
listener->tlsstream.listener_tls_ctx = isc_mem_cget(
|
|
|
|
listener->worker->mctx, nworkers, sizeof(isc_tlsctx_t *));
|
2022-03-31 13:47:48 +03:00
|
|
|
listener->tlsstream.n_listener_tls_ctx = nworkers;
|
2022-03-29 20:42:16 +03:00
|
|
|
for (size_t i = 0; i < nworkers; i++) {
|
|
|
|
listener->tlsstream.listener_tls_ctx[i] = NULL;
|
|
|
|
isc_tlsctx_attach(ctx,
|
|
|
|
&listener->tlsstream.listener_tls_ctx[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_cleanup_listener_tlsctx(isc_nmsocket_t *listener) {
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(VALID_NMSOCK(listener));
|
2022-03-29 20:42:16 +03:00
|
|
|
|
|
|
|
if (listener->tlsstream.listener_tls_ctx == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-31 13:47:48 +03:00
|
|
|
for (size_t i = 0; i < listener->tlsstream.n_listener_tls_ctx; i++) {
|
2022-03-29 20:42:16 +03:00
|
|
|
isc_tlsctx_free(&listener->tlsstream.listener_tls_ctx[i]);
|
|
|
|
}
|
2023-08-23 08:56:31 +02:00
|
|
|
isc_mem_cput(
|
|
|
|
listener->worker->mctx, listener->tlsstream.listener_tls_ctx,
|
|
|
|
listener->tlsstream.n_listener_tls_ctx, sizeof(isc_tlsctx_t *));
|
2022-03-31 13:47:48 +03:00
|
|
|
listener->tlsstream.n_listener_tls_ctx = 0;
|
2022-03-29 20:42:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_tlsctx_t *
|
|
|
|
tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid) {
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(VALID_NMSOCK(listener));
|
2022-03-29 20:42:16 +03:00
|
|
|
REQUIRE(tid >= 0);
|
|
|
|
|
|
|
|
if (listener->tlsstream.listener_tls_ctx == NULL) {
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (listener->tlsstream.listener_tls_ctx[tid]);
|
|
|
|
}
|
2022-03-31 13:47:48 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
isc__nm_async_tls_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx,
|
|
|
|
const int tid) {
|
|
|
|
REQUIRE(tid >= 0);
|
|
|
|
|
|
|
|
isc_tlsctx_free(&listener->tlsstream.listener_tls_ctx[tid]);
|
|
|
|
isc_tlsctx_attach(tlsctx, &listener->tlsstream.listener_tls_ctx[tid]);
|
|
|
|
}
|
2022-04-22 15:59:11 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
tls_keep_client_tls_session(isc_nmsocket_t *sock) {
|
|
|
|
/*
|
|
|
|
* Ensure that the isc_tls_t is being accessed from
|
|
|
|
* within the worker thread the socket is bound to.
|
|
|
|
*/
|
2022-07-26 13:03:45 +02:00
|
|
|
REQUIRE(sock->tid == isc_tid());
|
2022-04-22 15:59:11 +03:00
|
|
|
if (sock->tlsstream.client_sess_cache != NULL &&
|
|
|
|
sock->tlsstream.client_session_saved == false)
|
|
|
|
{
|
2023-03-24 13:37:19 +01:00
|
|
|
INSIST(sock->client);
|
2022-04-22 15:59:11 +03:00
|
|
|
isc_tlsctx_client_session_cache_keep_sockaddr(
|
|
|
|
sock->tlsstream.client_sess_cache, &sock->peer,
|
|
|
|
sock->tlsstream.tls);
|
|
|
|
sock->tlsstream.client_session_saved = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
tls_try_shutdown(isc_tls_t *tls, const bool force) {
|
|
|
|
if (force) {
|
|
|
|
(void)SSL_set_shutdown(tls, SSL_SENT_SHUTDOWN);
|
|
|
|
} else if ((SSL_get_shutdown(tls) & SSL_SENT_SHUTDOWN) == 0) {
|
|
|
|
(void)SSL_shutdown(tls);
|
|
|
|
}
|
|
|
|
}
|
2022-10-20 15:40:51 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2022-08-03 14:46:33 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
isc__nmhandle_tls_get_selected_alpn(isc_nmhandle_t *handle,
|
|
|
|
const unsigned char **alpn,
|
|
|
|
unsigned int *alpnlen) {
|
|
|
|
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());
|
|
|
|
|
|
|
|
isc_tls_get_selected_alpn(sock->tlsstream.tls, alpn, alpnlen);
|
|
|
|
}
|
2022-08-25 22:37:26 +03:00
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
isc__nmhandle_tls_set_tcp_nodelay(isc_nmhandle_t *handle, const bool value) {
|
|
|
|
isc_nmsocket_t *sock = NULL;
|
|
|
|
isc_result_t result = ISC_R_FAILURE;
|
|
|
|
|
|
|
|
REQUIRE(VALID_NMHANDLE(handle));
|
|
|
|
REQUIRE(VALID_NMSOCK(handle->sock));
|
|
|
|
REQUIRE(handle->sock->type == isc_nm_tlssocket);
|
|
|
|
|
|
|
|
sock = handle->sock;
|
|
|
|
if (sock->outerhandle != NULL) {
|
|
|
|
INSIST(VALID_NMHANDLE(sock->outerhandle));
|
|
|
|
|
|
|
|
if (value == sock->tlsstream.tcp_nodelay_value) {
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
} else {
|
|
|
|
result = isc_nmhandle_set_tcp_nodelay(sock->outerhandle,
|
|
|
|
value);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
sock->tlsstream.tcp_nodelay_value = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|