From f41e5faeaae94973ef1040356532afa277ae130f Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 21 Jul 2021 12:15:59 +0200 Subject: [PATCH] Avoid unhelpful warnings about UDP buffer sizes. Don't log a warning if we never explicitly configured the SO_RCVBUF/SO_SNDBUF sizes, and don't warn if the system allocates a larger buffer than the one requested, as at least on Linux, it will always double the requested size unless you hit the maximum. With this change, we only warn when we explicitly request a buffer size and the system allocated a smaller one. --- src/net.h | 2 ++ src/net_setup.c | 4 +++ src/net_socket.c | 74 +++++++++++++++++++++--------------------------- 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/net.h b/src/net.h index cf0ddc79..1bb267f8 100644 --- a/src/net.h +++ b/src/net.h @@ -146,6 +146,8 @@ extern io_t unix_socket; extern int keylifetime; extern int udp_rcvbuf; extern int udp_sndbuf; +extern bool udp_rcvbuf_warnings; +extern bool udp_sndbuf_warnings; extern int max_connection_burst; extern int fwmark; extern bool do_prune; diff --git a/src/net_setup.c b/src/net_setup.c index 1ecb3c65..d7891261 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -935,6 +935,8 @@ static bool setup_myself(void) { logger(DEBUG_ALWAYS, LOG_ERR, "UDPRcvBuf cannot be negative!"); return false; } + + udp_rcvbuf_warnings = true; } if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { @@ -942,6 +944,8 @@ static bool setup_myself(void) { logger(DEBUG_ALWAYS, LOG_ERR, "UDPSndBuf cannot be negative!"); return false; } + + udp_sndbuf_warnings = true; } get_config_int(lookup_config(config_tree, "FWMark"), &fwmark); diff --git a/src/net_socket.c b/src/net_socket.c index afe349d9..05ee3b17 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -41,6 +41,8 @@ int maxtimeout = 900; int seconds_till_retry = 5; int udp_rcvbuf = 1024 * 1024; int udp_sndbuf = 1024 * 1024; +bool udp_rcvbuf_warnings; +bool udp_sndbuf_warnings; int max_connection_burst = 10; int fwmark; @@ -242,6 +244,35 @@ int setup_listen_socket(const sockaddr_t *sa) { return nfd; } +static void set_udp_buffer(int nfd, int type, const char *name, int size, bool warnings) { + if(!size) { + return; + } + + if(setsockopt(nfd, SOL_SOCKET, type, (void *)&size, sizeof(size))) { + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP %s to %i: %s", name, size, sockstrerror(sockerrno)); + return; + } + + if(!warnings) { + return; + } + + // The system may cap the requested buffer size. + // Read back the value and check if it is now as requested. + int actual = -1; + socklen_t optlen = sizeof(actual); + + if(getsockopt(nfd, SOL_SOCKET, type, (void *)&actual, &optlen)) { + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP %s: %s", name, sockstrerror(sockerrno)); + } else if(optlen != sizeof(actual)) { + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP %s: unexpected returned optlen %d", name, (int)optlen); + } else if(actual < size) { + logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP %s to %i, the system set it to %i instead", name, size, actual); + } +} + + int setup_vpn_in_socket(const sockaddr_t *sa) { int nfd; char *addrstr; @@ -285,47 +316,8 @@ int setup_vpn_in_socket(const sockaddr_t *sa) { setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); setsockopt(nfd, SOL_SOCKET, SO_BROADCAST, (void *)&option, sizeof(option)); - if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf))) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, sockstrerror(sockerrno)); - } - - { - // The system may cap the requested buffer size. - // Read back the value and check if it is now as requested. - int udp_rcvbuf_actual = -1; - socklen_t optlen = sizeof(udp_rcvbuf_actual); - - if(getsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf_actual, &optlen)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_RCVBUF: %s", sockstrerror(sockerrno)); - } else if(optlen != sizeof(udp_rcvbuf_actual)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_RCVBUF: Unexpected returned optlen %jd", (intmax_t) optlen); - } else { - if(udp_rcvbuf_actual != udp_rcvbuf) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_RCVBUF to %i, the system set it to %i instead", udp_rcvbuf, udp_rcvbuf_actual); - } - } - } - - if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf))) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, sockstrerror(sockerrno)); - } - - { - // The system may cap the requested buffer size. - // Read back the value and check if it is now as requested. - int udp_sndbuf_actual = -1; - socklen_t optlen = sizeof(udp_sndbuf_actual); - - if(getsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf_actual, &optlen)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_SNDBUF: %s", sockstrerror(sockerrno)); - } else if(optlen != sizeof(udp_sndbuf_actual)) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't read back UDP SO_SNDBUF: Unexpected returned optlen %jd", (intmax_t) optlen); - } else { - if(udp_sndbuf_actual != udp_sndbuf) { - logger(DEBUG_ALWAYS, LOG_WARNING, "Can't set UDP SO_SNDBUF to %i, the system set it to %i instead", udp_sndbuf, udp_sndbuf_actual); - } - } - } + set_udp_buffer(nfd, SO_RCVBUF, "SO_RCVBUF", udp_rcvbuf, udp_rcvbuf_warnings); + set_udp_buffer(nfd, SO_SNDBUF, "SO_SNDBUF", udp_sndbuf, udp_sndbuf_warnings); #if defined(IPV6_V6ONLY) -- 2.20.1