isc_result_t
isc_nm_listenproxystream(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
- int backlog, isc_quota_t *quota,
+ int backlog, isc_quota_t *quota, isc_tlsctx_t *tlsctx,
isc_nmsocket_t **sockp);
/*%<
* Start listening for data preceded by a PROXYv2 header over the
- * TCP on interface 'iface', using net manager 'mgr'.
+ * TCP or TLS on interface 'iface', using net manager 'mgr'.
*
* On success, 'sockp' will be updated to contain a new listening TCP
* socket.
*
* If 'quota' is not NULL, then the socket is attached to the specified
* quota. This allows us to enforce TCP client quota limits.
+ *
+ * If 'tlsctx' is not NULL, then listen for TLS connections. In that
+ * case PROXYv2 headers are expected to be sent encrypted right after
+ * the TLS handshake.
*/
void
isc_nm_proxystreamconnect(isc_nm_t *mgr, isc_sockaddr_t *local,
isc_sockaddr_t *peer, isc_nm_cb_t cb, void *cbarg,
- unsigned int timeout,
- isc_nm_proxyheader_info_t *proxy_info);
+ unsigned int timeout, isc_tlsctx_t *tlsctx,
+ isc_tlsctx_client_session_cache_t *client_sess_cache,
+ isc_nm_proxyheader_info_t *proxy_info);
/*%<
* Create a TCP socket using netmgr 'mgr', bind it to the address
* 'local', and connect it to the address 'peer'. Right after the
isc_result_t
isc_nm_listenproxystream(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface,
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
- int backlog, isc_quota_t *quota,
+ int backlog, isc_quota_t *quota, isc_tlsctx_t *tlsctx,
isc_nmsocket_t **sockp) {
isc_result_t result;
isc_nmsocket_t *listener = NULL;
listener->accept_cb = accept_cb;
listener->accept_cbarg = accept_cbarg;
- result = isc_nm_listentcp(mgr, workers, iface, proxystream_accept_cb,
- listener, backlog, quota, &listener->outer);
+ if (tlsctx == NULL) {
+ result = isc_nm_listentcp(mgr, workers, iface,
+ proxystream_accept_cb, listener,
+ backlog, quota, &listener->outer);
+ } else {
+ result = isc_nm_listentls(
+ mgr, workers, iface, proxystream_accept_cb, listener,
+ backlog, quota, tlsctx, false, &listener->outer);
+ }
if (result != ISC_R_SUCCESS) {
listener->closed = true;
void
isc_nm_proxystreamconnect(isc_nm_t *mgr, isc_sockaddr_t *local,
isc_sockaddr_t *peer, isc_nm_cb_t cb, void *cbarg,
- unsigned int timeout,
+ unsigned int timeout, isc_tlsctx_t *tlsctx,
+ isc_tlsctx_client_session_cache_t *client_sess_cache,
isc_nm_proxyheader_info_t *proxy_info) {
isc_result_t result = ISC_R_FAILURE;
isc_nmsocket_t *nsock = NULL;
&proxy_info->proxy_info.tlv_data);
}
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_nm_tcpconnect(mgr, local, peer, proxystream_connect_cb, nsock,
- nsock->connect_timeout);
+
+ if (tlsctx == NULL) {
+ isc_nm_tcpconnect(mgr, local, peer, proxystream_connect_cb,
+ nsock, nsock->connect_timeout);
+ } else {
+ isc_nm_tlsconnect(mgr, local, peer, proxystream_connect_cb,
+ nsock, tlsctx, client_sess_cache,
+ nsock->connect_timeout, false, NULL);
+ }
}
static void
isc__nm_proxystream_cleanup_data(isc_nmsocket_t *sock) {
switch (sock->type) {
case isc_nm_tcpsocket:
+ case isc_nm_tlssocket:
if (sock->proxy.sock != NULL) {
isc__nmsocket_detach(&sock->proxy.sock);
}
isc_nm_cb_t cb, void *cbarg) {
proxystream_send(handle, region, cb, cbarg, true);
}
+
+void
+isc__nm_proxystream_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx) {
+ REQUIRE(VALID_NMSOCK(listener));
+ REQUIRE(listener->type == isc_nm_proxystreamlistener);
+
+ if (listener->outer != NULL) {
+ INSIST(VALID_NMSOCK(listener->outer));
+ isc_nmsocket_set_tlsctx(listener->outer, tlsctx);
+ }
+}
+
+bool
+isc__nm_proxystream_has_encryption(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_proxystreamsocket);
+
+ sock = handle->sock;
+ if (sock->outerhandle != NULL) {
+ INSIST(VALID_NMHANDLE(sock->outerhandle));
+ return (isc_nm_has_encryption(sock->outerhandle));
+ }
+
+ return (false);
+}
+
+const char *
+isc__nm_proxystream_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_proxystreamsocket);
+
+ sock = handle->sock;
+ if (sock->outerhandle != NULL) {
+ INSIST(VALID_NMHANDLE(sock->outerhandle));
+ return (isc_nm_verify_tls_peer_result_string(
+ sock->outerhandle));
+ }
+
+ return (NULL);
+}
+
+void
+isc__nmhandle_proxystream_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_proxystreamsocket);
+ REQUIRE(sock->tid == isc_tid());
+
+ isc__nmhandle_get_selected_alpn(sock->outerhandle, alpn, alpnlen);
+}