**+**\ [\ **no**\ ]\ **tcp**
Use the TCP protocol (default is UDP for standard query and TCP for AXFR/IXFR).
-**+**\ [\ **no**\ ]\ **fastopen**
- Use TCP Fast Open.
-
**+**\ [\ **no**\ ]\ **ignore**
Don't use TCP automatically if a truncated reply is received.
$ kdig @1.1.1.1 +https example.com.
$ kdig @193.17.47.1 +https=/doh example.com.
$ kdig @8.8.4.4 +https +https-get example.com.
- $ kdig @8.8.8.8 +https +tls-hostname=dns.google +fastopen example.com.
+ $ kdig @8.8.8.8 +https +tls-hostname=dns.google example.com.
6. More queries share one DoT connection::
return KNOT_EOK;
}
-int https_ctx_connect(https_ctx_t *ctx, int sockfd, bool fastopen,
- struct sockaddr_storage *addr)
+int https_ctx_connect(https_ctx_t *ctx, int sockfd, struct sockaddr_storage *addr)
{
if (ctx == NULL || addr == NULL) {
return KNOT_EINVAL;
}
// Create TLS connection
- int ret = tls_ctx_connect(ctx->tls, sockfd, fastopen, addr);
+ int ret = tls_ctx_connect(ctx->tls, sockfd, addr);
if (ret != KNOT_EOK) {
return ret;
}
*
* \param ctx HTTPS context.
* \param sockfd Socket descriptor.
- * \param fastopen Use TCP Fast Open indication.
* \param addr Socket address storage with address to server side.
*
* \retval KNOT_EOK When successfully connected.
* \retval KNOT_NET_ETIMEOUT When server respond takes too long.
* \retval KNOT_NET_ECONNECT When unnable to connect to the server.
*/
-int https_ctx_connect(https_ctx_t *ctx, int sockfd, bool fastopen,
- struct sockaddr_storage *addr);
+int https_ctx_connect(https_ctx_t *ctx, int sockfd, struct sockaddr_storage *addr);
/*!
* \brief Send buffer as DNS message over HTTPS.
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h> // OpenBSD
-#include <netinet/tcp.h> // TCP_FASTOPEN
#include <sys/socket.h>
#ifdef HAVE_SYS_UIO_H
const int iptype,
const int socktype,
const int wait,
- const net_flags_t flags,
const struct sockaddr *proxy_src,
const struct sockaddr *proxy_dst,
net_t *net)
net->wait = wait;
net->local = local;
net->remote = remote;
- net->flags = flags;
net->proxy.src = proxy_src;
net->proxy.dst = proxy_dst;
return KNOT_EOK;
}
-/*!
- * Connect with TCP Fast Open.
- */
-static int fastopen_connect(int sockfd, const struct addrinfo *srv)
-{
-#if defined( __FreeBSD__)
- const int enable = 1;
- return setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN, &enable, sizeof(enable));
-#elif defined(__APPLE__)
- // connection is performed lazily when first data are sent
- struct sa_endpoints ep = {0};
- ep.sae_dstaddr = srv->ai_addr;
- ep.sae_dstaddrlen = srv->ai_addrlen;
- int flags = CONNECT_DATA_IDEMPOTENT|CONNECT_RESUME_ON_READ_WRITE;
-
- return connectx(sockfd, &ep, SAE_ASSOCID_ANY, flags, NULL, 0, NULL, NULL);
-#elif defined(__linux__)
- // connect() will be called implicitly with sendto(), sendmsg()
- return 0;
-#else
- errno = ENOTSUP;
- return -1;
-#endif
-}
-
-/*!
- * Sends data with TCP Fast Open.
- */
-static int fastopen_send(int sockfd, const struct msghdr *msg, int timeout)
-{
-#if defined(__FreeBSD__) || defined(__APPLE__)
- return sendmsg(sockfd, msg, 0);
-#elif defined(__linux__)
- int ret = sendmsg(sockfd, msg, MSG_FASTOPEN);
- if (ret == -1 && errno == EINPROGRESS) {
- struct pollfd pfd = {
- .fd = sockfd,
- .events = POLLOUT,
- .revents = 0,
- };
- if (poll(&pfd, 1, 1000 * timeout) != 1) {
- errno = ETIMEDOUT;
- return -1;
- }
- ret = sendmsg(sockfd, msg, 0);
- }
- return ret;
-#else
- errno = ENOTSUP;
- return -1;
-#endif
-}
-
static char *net_get_remote(const net_t *net)
{
if (net->tls.params->sni != NULL) {
if (net->socktype == SOCK_STREAM) {
int cs = 1, err;
socklen_t err_len = sizeof(err);
- bool fastopen = net->flags & NET_FLAGS_FASTOPEN;
#ifdef TCP_NODELAY
(void)setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &cs, sizeof(cs));
#endif
// Establish a connection.
- if (net->tls.params == NULL || !fastopen) {
- if (fastopen) {
- ret = fastopen_connect(sockfd, net->srv);
- } else {
- ret = connect(sockfd, net->srv->ai_addr, net->srv->ai_addrlen);
- }
- if (ret != 0 && errno != EINPROGRESS) {
- WARN("can't connect to %s", net->remote_str);
- net_close(net);
- return KNOT_NET_ECONNECT;
- }
+ ret = connect(sockfd, net->srv->ai_addr, net->srv->ai_addrlen);
+ if (ret != 0 && errno != EINPROGRESS) {
+ WARN("can't connect to %s", net->remote_str);
+ net_close(net);
+ return KNOT_NET_ECONNECT;
+ }
- // Check for connection timeout.
- if (!fastopen && poll(&pfd, 1, 1000 * net->wait) != 1) {
- WARN("connection timeout for %s", net->remote_str);
- net_close(net);
- return KNOT_NET_ECONNECT;
- }
+ // Check for connection timeout.
+ if (poll(&pfd, 1, 1000 * net->wait) != 1) {
+ WARN("connection timeout for %s", net->remote_str);
+ net_close(net);
+ return KNOT_NET_ECONNECT;
+ }
- // Check if NB socket is writeable.
- cs = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &err_len);
- if (cs < 0 || err != 0) {
- WARN("can't connect to %s", net->remote_str);
- net_close(net);
- return KNOT_NET_ECONNECT;
- }
+ // Check if NB socket is writeable.
+ cs = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &err_len);
+ if (cs < 0 || err != 0) {
+ WARN("can't connect to %s", net->remote_str);
+ net_close(net);
+ return KNOT_NET_ECONNECT;
}
if (net->tls.params != NULL) {
if (remote && net->https.authority == NULL) {
net->https.authority = strdup(remote);
}
- ret = https_ctx_connect(&net->https, sockfd, fastopen,
+ ret = https_ctx_connect(&net->https, sockfd,
(struct sockaddr_storage *)net->srv->ai_addr);
} else
#endif //LIBNGHTTP2
net_close(net);
return ret;
}
- ret = tls_ctx_connect(&net->tls, sockfd, fastopen,
+ ret = tls_ctx_connect(&net->tls, sockfd,
(struct sockaddr_storage *)net->srv->ai_addr);
}
if (ret != KNOT_EOK) {
}
// Send data over TCP.
} else {
- bool fastopen = net->flags & NET_FLAGS_FASTOPEN;
-
char proxy_buf[PROXYV2_HEADER_MAXLEN];
uint16_t pktsize = htons(buf_len); // Leading packet length bytes.
struct iovec iov[3] = {
ssize_t total = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len;
- int ret = 0;
- if (fastopen) {
- ret = fastopen_send(net->sockfd, &msg, net->wait);
- } else {
- ret = sendmsg(net->sockfd, &msg, 0);
- }
+ int ret = sendmsg(net->sockfd, &msg, 0);
if (ret != total) {
WARN("can't send query to %s", net->remote_str);
return KNOT_NET_ESEND;
char *service;
} srv_info_t;
-typedef enum {
- NET_FLAGS_NONE = 0,
- NET_FLAGS_FASTOPEN = 1 << 0,
-} net_flags_t;
-
typedef struct {
/*! Socket descriptor. */
int sockfd;
int socktype;
/*! Timeout for all network operations. */
int wait;
- /*! Connection flags. */
- net_flags_t flags;
/*! Local interface parameters. */
const srv_info_t *local;
* \param iptype IP version.
* \param socktype Socket type.
* \param wait Network timeout interval.
- * \param flags Connection flags.
* \param proxy_src Proxy source address.
* \param proxy_dst Proxy destination address.
* \param net Network structure to initialize.
const int iptype,
const int socktype,
const int wait,
- const net_flags_t flags,
const struct sockaddr *proxy_src,
const struct sockaddr *proxy_dst,
net_t *net);
#include <gnutls/gnutls.h>
#include <gnutls/ocsp.h>
#include <gnutls/x509.h>
-#define GNUTLS_VERSION_FASTOPEN_READY 0x030503
-#if GNUTLS_VERSION_NUMBER >= GNUTLS_VERSION_FASTOPEN_READY
-#include <gnutls/socket.h>
-#endif
#include "utils/common/tls.h"
#include "utils/common/msg.h"
return KNOT_EOK;
}
-int tls_ctx_connect(tls_ctx_t *ctx, int sockfd, bool fastopen,
- struct sockaddr_storage *addr)
+int tls_ctx_connect(tls_ctx_t *ctx, int sockfd, struct sockaddr_storage *addr)
{
if (ctx == NULL) {
return KNOT_EINVAL;
int ret = 0;
gnutls_session_set_ptr(ctx->session, ctx);
- if (fastopen) {
-#if GNUTLS_VERSION_NUMBER >= GNUTLS_VERSION_FASTOPEN_READY
- gnutls_transport_set_fastopen(ctx->session, sockfd, (struct sockaddr *)addr,
- sockaddr_len(addr), 0);
-#else
- return KNOT_ENOTSUP;
-#endif
- } else {
- gnutls_transport_set_int(ctx->session, sockfd);
- }
+ gnutls_transport_set_int(ctx->session, sockfd);
gnutls_handshake_set_timeout(ctx->session, 1000 * ctx->wait);
unsigned int flags, int wait);
int tls_ctx_setup_remote_endpoint(tls_ctx_t *ctx, const gnutls_datum_t *alpn,
size_t alpn_size, const char *priority, const char *remote);
-int tls_ctx_connect(tls_ctx_t *ctx, int sockfd,
- bool fastopen, struct sockaddr_storage *addr);
+int tls_ctx_connect(tls_ctx_t *ctx, int sockfd, struct sockaddr_storage *addr);
int tls_ctx_send(tls_ctx_t *ctx, const uint8_t *buf, const size_t buf_len);
int tls_ctx_receive(tls_ctx_t *ctx, uint8_t *buf, const size_t buf_len);
// Get connection parameters.
int socktype = get_socktype(query->protocol, query->type_num);
- int flags = query->fastopen ? NET_FLAGS_FASTOPEN : NET_FLAGS_NONE;
// Loop over server list to process query.
WALK_LIST(server, query->servers) {
for (size_t i = 0; i <= query->retries; i++) {
// Initialize network structure for current server.
ret = net_init(query->local, remote, iptype, socktype,
- query->wait, flags,
+ query->wait,
(struct sockaddr *)&query->proxy.src,
(struct sockaddr *)&query->proxy.dst,
net);
// Get connection parameters.
int socktype = get_socktype(query->protocol, query->type_num);
- int flags = query->fastopen ? NET_FLAGS_FASTOPEN : NET_FLAGS_NONE;
// Use the first nameserver from the list.
srv_info_t *remote = HEAD(query->servers);
get_sockname(socktype));
// Initialize network structure.
- ret = net_init(query->local, remote, iptype, socktype, query->wait, flags,
+ ret = net_init(query->local, remote, iptype, socktype, query->wait,
(struct sockaddr *)&query->proxy.src,
(struct sockaddr *)&query->proxy.dst,
net);
return opt_ignore(arg, query);
}
-static int opt_fastopen(const char *arg, void *query)
-{
- query_t *q = query;
-
- q->fastopen = true;
-
- return opt_tcp(arg, query);
-}
-
-static int opt_nofastopen(const char *arg, void *query)
-{
- query_t *q = query;
-
- q->fastopen = false;
-
- return KNOT_EOK;
-}
-
static int opt_keepopen(const char *arg, void *query)
{
query_t *q = query;
{ "tcp", ARG_NONE, opt_tcp },
{ "notcp", ARG_NONE, opt_notcp },
- { "fastopen", ARG_NONE, opt_fastopen },
- { "nofastopen", ARG_NONE, opt_nofastopen },
-
{ "ignore", ARG_NONE, opt_ignore },
{ "noignore", ARG_NONE, opt_noignore },
query->operation = OPERATION_QUERY;
query->ip = IP_ALL;
query->protocol = PROTO_ALL;
- query->fastopen = false;
query->port = strdup("");
query->udp_size = -1;
query->retries = DEFAULT_RETRIES_DIG;
" +[no]ttl * Show TTL value.\n"
" +[no]crypto * Show binary parts of RRSIGs and DNSKEYs.\n"
" +[no]tcp Use TCP protocol.\n"
- " +[no]fastopen Use TCP Fast Open.\n"
" +[no]ignore Don't use TCP automatically if truncated.\n"
" +[no]keepopen Don't close the TCP connection to be reused.\n"
" +[no]tls Use TLS with Opportunistic privacy profile.\n"
ip_t ip;
/*!< Protocol type (TCP, UDP) to use. */
protocol_t protocol;
- /*!< Use TCP Fast Open. */
- bool fastopen;
/*!< Keep TCP connection open. */
bool keepopen;
/*!< Port/service to connect to. */
get_iptype(params->ip, params->server),
get_socktype(params->protocol, KNOT_RRTYPE_SOA),
params->wait,
- NET_FLAGS_NONE,
NULL,
NULL,
&net);