]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
config: add sock_queue_timeout configuration
authorVadim Fedorenko <vadfed@meta.com>
Thu, 13 Apr 2023 14:49:32 +0000 (07:49 -0700)
committerVadim Fedorenko <vadfed@meta.com>
Wed, 26 Apr 2023 10:27:19 +0000 (03:27 -0700)
Add sock_queue_timeout config option to have queue timeout configurable.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
config.h.in
configure
configure.ac
services/listen_dnsport.c
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/netevent.c

index 6f7a062afd8dc78fb66b4924701de622a2805c95..e7a44bf60a94bb5c8e0d899a3fc63c4e1feeada4 100644 (file)
 /* 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
 
index f7abb5289ea902037151179fab31d1f5cb2beebc..491228b54d8d2dd15ca87d2cdea2624b7da5566f 100755 (executable)
--- a/configure
+++ b/configure
@@ -813,7 +813,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -965,7 +964,6 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1218,15 +1216,6 @@ do
   | -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=* \
@@ -1364,7 +1353,7 @@ fi
 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.
@@ -1517,7 +1506,6 @@ Fine tuning of the installation directories:
   --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"
index 73fef5f87c77a876a2cffe426a7ca63fe7b039a2..fa5ca10188a4faf5300515e03bd7524e566b7148 100644 (file)
@@ -454,7 +454,10 @@ AC_CHECK_HEADERS([netioapi.h],,, [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)
index 484529034056cc23e05cbef1151e42f67fe288fc..2163a949ddbbea292174d399b0a07d19adf33136 100644 (file)
@@ -79,7 +79,9 @@
 #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
 
@@ -1114,6 +1116,24 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype,
        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)
@@ -1223,7 +1243,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
        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);
@@ -1269,6 +1290,9 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                        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)) {
@@ -1295,6 +1319,9 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                        }
                        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)) {
@@ -1809,7 +1836,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                                                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;
                                        }
@@ -1826,7 +1853,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                                                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;
                                        }
@@ -1845,7 +1872,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                                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;
                        }
@@ -1861,7 +1888,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                                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;
                        }
@@ -1879,7 +1906,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                                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;
                        }
@@ -1895,7 +1922,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
                                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;
                        }
index 8e4d925e90229c7c3f7ae237e937c6d29d2fd0fb..a04c8cf091f886623d4e091421994ba3590116c5 100644 (file)
@@ -116,6 +116,7 @@ config_create(void)
        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;
@@ -543,6 +544,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
        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)
@@ -1066,6 +1068,7 @@ config_get_option(struct config_file* cfg, const char* opt,
        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)
index 1590dc4602f3911853c65fbe30c7ecb879e183ce..fc19790ca859ee6769de52b8f82f889d3d344d55 100644 (file)
@@ -116,6 +116,8 @@ struct config_file {
        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;
 
index 31b69779ddaefd512df8e38185309e30a8785704..dd85ecd26d8e3ff4f770989a73ef0d72d6d54dc3 100644 (file)
@@ -240,6 +240,7 @@ tcp-reuse-timeout{COLON}    { YDVAR(1, VAR_TCP_REUSE_TIMEOUT) }
 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) }
index 4f00ecc0dada82ca11abcb6e71b8207be0c91512..06118e04aab10cb44a5584b3eb9d0475e389098a 100644 (file)
@@ -76,6 +76,7 @@ extern struct config_parser_state* cfg_parser;
 %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
@@ -227,6 +228,7 @@ content_server: server_num_threads | server_verbosity | server_port |
        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 |
@@ -974,6 +976,19 @@ server_tcp_keepalive_timeout: VAR_EDNS_TCP_KEEPALIVE_TIMEOUT STRING_ARG
                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));
index ca5b9e165f21b91162dbb02012c3db9e035074e5..6ca51622b54ccd41890c503e73009f59f379b915 100644 (file)
@@ -72,7 +72,9 @@
 #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
@@ -907,6 +909,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
                                        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);
@@ -918,6 +921,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
                        } else if( cmsg->cmsg_level == SOL_SOCKET &&
                                cmsg->cmsg_type == SO_TIMESTAMP) {
                                memmove(&rep.c->recv_tv, CMSG_DATA(cmsg), sizeof(struct timeval));
+#endif
                        }
                }