Add sock_queue_timeout config option to have queue timeout configurable.
Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
+/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
+#undef HAVE_LINUX_NET_TSTAMP_H
+
/* Define to 1 if you have the `tzset' function. */
#undef HAVE_TZSET
docdir
oldincludedir
includedir
-runstatedir
localstatedir
sharedstatedir
sysconfdir
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
- -runstatedir | --runstatedir | --runstatedi | --runstated \
- | --runstate | --runstat | --runsta | --runst | --runs \
- | --run | --ru | --r)
- ac_prev=runstatedir ;;
- -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
- | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
- | --run=* | --ru=* | --r=*)
- runstatedir=$ac_optarg ;;
-
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir runstatedir
+ libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
done
+# Check for Linux timestamping headers
+for ac_header in linux/net_tstamp.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "linux/net_tstamp.h" "ac_cv_header_linux_net_tstamp_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_linux_net_tstamp_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LINUX_NET_TSTAMP_H 1
+_ACEOF
+
+fi
+
+done
+
+
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default"
#endif
])
-# check for types.
+# Check for Linux timestamping headers
+AC_CHECK_HEADERS([linux/net_tstamp.h],,, [AC_INCLUDES_DEFAULT])
+
+# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
AC_CHECK_TYPE(int8_t, signed char)
AC_CHECK_TYPE(int16_t, short)
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
-
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+#include <linux/net_tstamp.h>
+#endif
/** number of queued TCP connections for listen() */
#define TCP_BACKLOG 256
return 1;
}
+/** set fd to receive software timestamps */
+static int
+set_recvtimestamp(int s)
+{
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+ int opt = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
+ if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMPNS, (void*)&opt, (socklen_t)sizeof(opt)) < 0) {
+ log_err("setsockopt(..., SO_TIMESTAMPNS, ...) failed: %s",
+ strerror(errno));
+ return 0;
+ }
+ return 1;
+#else
+ log_err("packets timestamping is not supported on this platform");
+ return 0;
+#endif
+}
+
/** set fd to receive source address packet info */
static int
set_recvpktinfo(int s, int family)
struct config_strlist* tls_additional_port, int https_port,
struct config_strlist* proxy_protocol_port,
int* reuseport, int transparent, int tcp_mss, int freebind,
- int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp)
+ int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp,
+ int sock_queue_timeout)
{
int s, noip6=0;
int is_https = if_is_https(ifname, port, https_port);
free(ub_sock);
return 0;
}
+ if (sock_queue_timeout && !set_recvtimestamp(s)) {
+ log_warn("socket timestamping is not available");
+ }
if(!port_insert(list, s, is_dnscrypt
?listen_type_udpancil_dnscrypt:listen_type_udpancil,
is_pp2, ub_sock)) {
}
return 0;
}
+ if (sock_queue_timeout && !set_recvtimestamp(s)) {
+ log_warn("socket timestamping is not available");
+ }
if(!port_insert(list, s, is_dnscrypt
?listen_type_udp_dnscrypt:listen_type_udp,
is_pp2, ub_sock)) {
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
- cfg->dnscrypt_port, cfg->ip_dscp)) {
+ cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
listening_ports_free(list);
return NULL;
}
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
- cfg->dnscrypt_port, cfg->ip_dscp)) {
+ cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
listening_ports_free(list);
return NULL;
}
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
- cfg->dnscrypt_port, cfg->ip_dscp)) {
+ cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
listening_ports_free(list);
return NULL;
}
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
- cfg->dnscrypt_port, cfg->ip_dscp)) {
+ cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
listening_ports_free(list);
return NULL;
}
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
- cfg->dnscrypt_port, cfg->ip_dscp)) {
+ cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
listening_ports_free(list);
return NULL;
}
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
- cfg->dnscrypt_port, cfg->ip_dscp)) {
+ cfg->dnscrypt_port, cfg->ip_dscp, cfg->sock_queue_timeout)) {
listening_ports_free(list);
return NULL;
}
cfg->tcp_auth_query_timeout = 3 * 1000; /* 3s in millisecs */
cfg->do_tcp_keepalive = 0;
cfg->tcp_keepalive_timeout = 120 * 1000; /* 120s in millisecs */
+ cfg->sock_queue_timeout = 0; /* do not check timeout */
cfg->ssl_service_key = NULL;
cfg->ssl_service_pem = NULL;
cfg->ssl_port = UNBOUND_DNS_OVER_TLS_PORT;
else S_NUMBER_NONZERO("tcp-reuse-timeout:", tcp_reuse_timeout)
else S_YNO("edns-tcp-keepalive:", do_tcp_keepalive)
else S_NUMBER_NONZERO("edns-tcp-keepalive-timeout:", tcp_keepalive_timeout)
+ else S_NUMBER_OR_ZERO("sock-queue-timeout:", sock_queue_timeout)
else S_YNO("ssl-upstream:", ssl_upstream)
else S_YNO("tls-upstream:", ssl_upstream)
else S_STR("ssl-service-key:", ssl_service_key)
else O_DEC(opt, "tcp-reuse-timeout", tcp_reuse_timeout)
else O_YNO(opt, "edns-tcp-keepalive", do_tcp_keepalive)
else O_DEC(opt, "edns-tcp-keepalive-timeout", tcp_keepalive_timeout)
+ else O_DEC(opt, "sock-queue-timeout", sock_queue_timeout)
else O_YNO(opt, "ssl-upstream", ssl_upstream)
else O_YNO(opt, "tls-upstream", ssl_upstream)
else O_STR(opt, "ssl-service-key", ssl_service_key)
int do_tcp_keepalive;
/** tcp keepalive timeout, in msec */
int tcp_keepalive_timeout;
+ /** timeout of packets sitting in the socket queue */
+ int sock_queue_timeout;
/** proxy protocol ports */
struct config_strlist* proxy_protocol_port;
tcp-auth-query-timeout{COLON} { YDVAR(1, VAR_TCP_AUTH_QUERY_TIMEOUT) }
edns-tcp-keepalive{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE) }
edns-tcp-keepalive-timeout{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE_TIMEOUT) }
+sock-queue-timeout{COLON} { YDVAR(1, VAR_SOCK_QUEUE_TIMEOUT) }
ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
tls-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
ssl-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) }
%token VAR_DO_IP4 VAR_DO_IP6 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_TIMEOUT
%token VAR_EDNS_TCP_KEEPALIVE VAR_EDNS_TCP_KEEPALIVE_TIMEOUT
+%token VAR_SOCK_QUEUE_TIMEOUT
%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
server_do_udp | server_do_tcp |
server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout |
server_tcp_keepalive | server_tcp_keepalive_timeout |
+ server_sock_queue_timeout |
server_interface | server_chroot | server_username |
server_directory | server_logfile | server_pidfile |
server_msg_cache_size | server_msg_cache_slabs |
free($2);
}
;
+server_sock_queue_timeout: VAR_SOCK_QUEUE_TIMEOUT STRING_ARG
+ {
+ OUTYY(("P(server_sock_queue_timeout:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else if (atoi($2) > 6553500)
+ cfg_parser->cfg->sock_queue_timeout = 6553500;
+ else if (atoi($2) < 1)
+ cfg_parser->cfg->sock_queue_timeout = 0;
+ else cfg_parser->cfg->sock_queue_timeout = atoi($2);
+ free($2);
+ }
+ ;
server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
{
OUTYY(("P(server_tcp_upstream:%s)\n", $2));
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
-
+#ifdef HAVE_LINUX_NET_TSTAMP_H
+#include <linux/net_tstamp.h>
+#endif
/* -------- Start of local definitions -------- */
/** if CMSG_ALIGN is not defined on this platform, a workaround */
#ifndef CMSG_ALIGN
sizeof(struct in_addr));
break;
#endif /* IP_PKTINFO or IP_RECVDSTADDR */
+#ifdef HAVE_LINUX_NET_TSTAMP_H
} else if( cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMPNS) {
ts = (struct timespec *)CMSG_DATA(cmsg);
} else if( cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMP) {
memmove(&rep.c->recv_tv, CMSG_DATA(cmsg), sizeof(struct timeval));
+#endif
}
}