mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00: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)
This commit is contained in:
committed by
Artem Boldariev
parent
9c8b7a5c45
commit
88752b1121
@@ -34,6 +34,7 @@
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include "uv-compat.h"
|
||||
@@ -156,8 +157,6 @@ isc__nm_dump_active(isc_nm_t *nm);
|
||||
#define isc__nmsocket_prep_destroy(sock) isc___nmsocket_prep_destroy(sock)
|
||||
#endif
|
||||
|
||||
typedef struct isc_nm_http2_session isc_nm_http2_session_t;
|
||||
|
||||
/*
|
||||
* Single network event loop worker.
|
||||
*/
|
||||
@@ -195,6 +194,7 @@ typedef struct isc__networker {
|
||||
atomic_load(&(t)->references) > 0)
|
||||
|
||||
typedef void (*isc__nm_closecb)(isc_nmhandle_t *);
|
||||
typedef struct isc_nm_http_session isc_nm_http_session_t;
|
||||
|
||||
struct isc_nmhandle {
|
||||
int magic;
|
||||
@@ -210,7 +210,7 @@ struct isc_nmhandle {
|
||||
isc_nmsocket_t *sock;
|
||||
size_t ah_pos; /* Position in the socket's 'active handles' array */
|
||||
|
||||
isc_nm_http2_session_t *httpsession;
|
||||
isc_nm_http_session_t *httpsession;
|
||||
|
||||
isc_sockaddr_t peer;
|
||||
isc_sockaddr_t local;
|
||||
@@ -302,20 +302,18 @@ typedef enum isc__netievent_type {
|
||||
|
||||
typedef union {
|
||||
isc_nm_recv_cb_t recv;
|
||||
isc_nm_http_cb_t http;
|
||||
isc_nm_cb_t send;
|
||||
isc_nm_cb_t connect;
|
||||
isc_nm_accept_cb_t accept;
|
||||
} isc__nm_cb_t;
|
||||
|
||||
typedef struct isc_nm_http2_server_handler isc_nm_http2_server_handler_t;
|
||||
|
||||
struct isc_nm_http2_server_handler {
|
||||
typedef struct isc_nm_httphandler isc_nm_httphandler_t;
|
||||
struct isc_nm_httphandler {
|
||||
char *path;
|
||||
isc_nm_http_cb_t cb;
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
size_t extrahandlesize;
|
||||
LINK(isc_nm_http2_server_handler_t) link;
|
||||
LINK(isc_nm_httphandler_t) link;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -674,7 +672,7 @@ typedef enum isc_nmsocket_type {
|
||||
isc_nm_tlsdnslistener,
|
||||
isc_nm_tlsdnssocket,
|
||||
isc_nm_httplistener,
|
||||
isc_nm_httpstream
|
||||
isc_nm_httpsocket
|
||||
} isc_nmsocket_type;
|
||||
|
||||
/*%
|
||||
@@ -704,25 +702,29 @@ enum {
|
||||
typedef struct isc_nmsocket_tls_send_req {
|
||||
isc_nmsocket_t *tlssock;
|
||||
isc_region_t data;
|
||||
isc_nm_cb_t cb;
|
||||
void *cbarg;
|
||||
isc_nmhandle_t *handle;
|
||||
bool finish;
|
||||
} isc_nmsocket_tls_send_req_t;
|
||||
|
||||
typedef enum isc_doh_request_type {
|
||||
typedef enum isc_http_request_type {
|
||||
ISC_HTTP_REQ_GET,
|
||||
ISC_HTTP_REQ_POST,
|
||||
ISC_HTTP_REQ_UNSUPPORTED
|
||||
} isc_http2_request_type_t;
|
||||
} isc_http_request_type_t;
|
||||
|
||||
typedef enum isc_http2_scheme_type {
|
||||
typedef enum isc_http_scheme_type {
|
||||
ISC_HTTP_SCHEME_HTTP,
|
||||
ISC_HTTP_SCHEME_HTTP_SECURE,
|
||||
ISC_HTTP_SCHEME_UNSUPPORTED
|
||||
} isc_http2_scheme_type_t;
|
||||
} isc_http_scheme_type_t;
|
||||
|
||||
typedef struct isc_nm_http_doh_cbarg {
|
||||
typedef struct isc_nm_httpcbarg {
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
LINK(struct isc_nm_http_doh_cbarg) link;
|
||||
} isc_nm_http_doh_cbarg_t;
|
||||
LINK(struct isc_nm_httpcbarg) link;
|
||||
} isc_nm_httpcbarg_t;
|
||||
|
||||
typedef struct isc_nmsocket_h2 {
|
||||
isc_nmsocket_t *psock; /* owner of the structure */
|
||||
@@ -730,38 +732,43 @@ typedef struct isc_nmsocket_h2 {
|
||||
char *query_data;
|
||||
size_t query_data_len;
|
||||
bool query_too_large;
|
||||
isc_nm_http2_server_handler_t *handler;
|
||||
isc_nm_httphandler_t *handler;
|
||||
|
||||
uint8_t *buf;
|
||||
size_t bufsize;
|
||||
size_t bufpos;
|
||||
|
||||
int32_t stream_id;
|
||||
isc_nm_http2_session_t *session;
|
||||
isc_nm_http_session_t *session;
|
||||
|
||||
isc_nmsocket_t *httpserver;
|
||||
|
||||
isc_http2_request_type_t request_type;
|
||||
isc_http2_scheme_type_t request_scheme;
|
||||
isc_http_request_type_t request_type;
|
||||
isc_http_scheme_type_t request_scheme;
|
||||
|
||||
size_t content_length;
|
||||
char clenbuf[128];
|
||||
|
||||
bool content_type_verified;
|
||||
bool accept_type_verified;
|
||||
|
||||
isc_nm_http_cb_t handler_cb;
|
||||
void *handler_cbarg;
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
LINK(struct isc_nmsocket_h2) link;
|
||||
|
||||
ISC_LIST(isc_nm_http2_server_handler_t) handlers;
|
||||
ISC_LIST(isc_nm_http_doh_cbarg_t) handlers_cbargs;
|
||||
isc_rwlock_t handlers_lock;
|
||||
ISC_LIST(isc_nm_httphandler_t) handlers;
|
||||
ISC_LIST(isc_nm_httpcbarg_t) handler_cbargs;
|
||||
isc_rwlock_t lock;
|
||||
|
||||
char response_content_length_str[128];
|
||||
|
||||
struct isc_nmsocket_h2_connect_data {
|
||||
struct {
|
||||
char *uri;
|
||||
bool post;
|
||||
isc_tlsctx_t *tlsctx;
|
||||
isc_nmiface_t local_interface;
|
||||
void *cstream;
|
||||
} connect;
|
||||
} isc_nmsocket_h2_t;
|
||||
|
||||
struct isc_nmsocket {
|
||||
/*% Unlocked, RO */
|
||||
int magic;
|
||||
@@ -778,8 +785,8 @@ struct isc_nmsocket {
|
||||
|
||||
/*% TLS stuff */
|
||||
struct tls {
|
||||
SSL *ssl;
|
||||
SSL_CTX *ctx;
|
||||
isc_tls_t *tls;
|
||||
isc_tlsctx_t *ctx;
|
||||
BIO *app_rbio;
|
||||
BIO *app_wbio;
|
||||
BIO *ssl_rbio;
|
||||
@@ -802,21 +809,22 @@ struct isc_nmsocket {
|
||||
struct tlsstream {
|
||||
bool server;
|
||||
BIO *app_bio;
|
||||
SSL *ssl;
|
||||
SSL_CTX *ctx;
|
||||
isc_tls_t *tls;
|
||||
isc_tlsctx_t *ctx;
|
||||
BIO *ssl_bio;
|
||||
isc_nmsocket_t *tlslistener;
|
||||
isc_nmiface_t server_iface;
|
||||
isc_nmiface_t local_iface;
|
||||
bool connect_from_networker;
|
||||
atomic_bool result_updated;
|
||||
enum {
|
||||
TLS_INIT,
|
||||
TLS_HANDSHAKE,
|
||||
TLS_IO,
|
||||
TLS_ERROR,
|
||||
TLS_CLOSING,
|
||||
TLS_CLOSED
|
||||
} state;
|
||||
} state; /*%< The order of these is significant */
|
||||
size_t nsending;
|
||||
/* List of active send requests. */
|
||||
ISC_LIST(isc__nm_uvreq_t) sends;
|
||||
} tlsstream;
|
||||
|
||||
isc_nmsocket_h2_t h2;
|
||||
@@ -1149,11 +1157,15 @@ isc__nmsocket_clearcb(isc_nmsocket_t *sock);
|
||||
void
|
||||
isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult);
|
||||
|
||||
void
|
||||
isc__nm_connectcb_force_async(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
|
||||
isc_result_t eresult);
|
||||
|
||||
void
|
||||
isc__nm_async_connectcb(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
/*%<
|
||||
* Issue a connect callback on the socket, used to call the callback
|
||||
|
||||
*/
|
||||
|
||||
void
|
||||
@@ -1518,19 +1530,42 @@ isc__nm_tls_cleanup_data(isc_nmsocket_t *sock);
|
||||
void
|
||||
isc__nm_tls_stoplistening(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_tls_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
|
||||
/*%<
|
||||
* Set the read timeout and reset the timer for the socket
|
||||
* associated with 'handle', and the TCP socket it wraps
|
||||
* around.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_http_stoplistening(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_http_clear_handlers(isc_nmsocket_t *sock);
|
||||
isc__nm_http_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
|
||||
/*%<
|
||||
* Set the read timeout and reset the timer for the socket
|
||||
* associated with 'handle', and the TLS/TCP socket it wraps
|
||||
* around.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_http_clear_session(isc_nmsocket_t *sock);
|
||||
isc__nm_http_initsocket(isc_nmsocket_t *sock);
|
||||
|
||||
void
|
||||
isc__nm_http_cleanup_data(isc_nmsocket_t *sock);
|
||||
|
||||
isc_result_t
|
||||
isc__nm_http_request(isc_nmhandle_t *handle, isc_region_t *region,
|
||||
isc_nm_recv_cb_t reply_cb, void *cbarg);
|
||||
|
||||
void
|
||||
isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
||||
isc_nm_cb_t cb, void *cbarg);
|
||||
|
||||
void
|
||||
isc__nm_http_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
|
||||
|
||||
void
|
||||
isc__nm_http_close(isc_nmsocket_t *sock);
|
||||
|
||||
@@ -1544,8 +1579,8 @@ void
|
||||
isc__nm_async_httpclose(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
|
||||
bool
|
||||
isc__nm_parse_doh_query_string(const char *query_string, const char **start,
|
||||
size_t *len);
|
||||
isc__nm_parse_httpquery(const char *query_string, const char **start,
|
||||
size_t *len);
|
||||
|
||||
char *
|
||||
isc__nm_base64url_to_base64(isc_mem_t *mem, const char *base64url,
|
||||
@@ -1555,6 +1590,12 @@ char *
|
||||
isc__nm_base64_to_base64url(isc_mem_t *mem, const char *base64,
|
||||
const size_t base64_len, size_t *res_len);
|
||||
|
||||
void
|
||||
isc__nm_httpsession_attach(isc_nm_http_session_t *source,
|
||||
isc_nm_http_session_t **targetp);
|
||||
void
|
||||
isc__nm_httpsession_detach(isc_nm_http_session_t **sessionp);
|
||||
|
||||
#define isc__nm_uverr2result(x) \
|
||||
isc___nm_uverr2result(x, true, __FILE__, __LINE__, __func__)
|
||||
isc_result_t
|
||||
|
Reference in New Issue
Block a user