summaryrefslogtreecommitdiffstats
path: root/iputils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'iputils.cc')
-rw-r--r--iputils.cc96
1 files changed, 82 insertions, 14 deletions
diff --git a/iputils.cc b/iputils.cc
index e0c7218..4409997 100644
--- a/iputils.cc
+++ b/iputils.cc
@@ -25,23 +25,24 @@
#include "iputils.hh"
+#include <fstream>
#include <sys/socket.h>
#include <boost/format.hpp>
-#if HAVE_GETIFADDRS
+#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
#endif
/** these functions provide a very lightweight wrapper to the Berkeley sockets API. Errors -> exceptions! */
-static void RuntimeError(std::string&& error)
+static void RuntimeError(const std::string& error)
{
- throw runtime_error(std::move(error));
+ throw runtime_error(error);
}
-static void NetworkErr(std::string&& error)
+static void NetworkErr(const std::string& error)
{
- throw NetworkError(std::move(error));
+ throw NetworkError(error);
}
int SSocket(int family, int type, int flags)
@@ -147,7 +148,7 @@ int SSetsockopt(int sockfd, int level, int opname, int value)
return ret;
}
-void setSocketIgnorePMTU(int sockfd, int family)
+void setSocketIgnorePMTU([[maybe_unused]] int sockfd, [[maybe_unused]] int family)
{
if (family == AF_INET) {
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
@@ -191,6 +192,27 @@ void setSocketIgnorePMTU(int sockfd, int family)
}
}
+void setSocketForcePMTU([[maybe_unused]] int sockfd, [[maybe_unused]] int family)
+{
+ if (family == AF_INET) {
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+ /* IP_PMTUDISC_DO enables Path MTU discovery and prevents fragmentation */
+ SSetsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO);
+#elif defined(IP_DONTFRAG)
+ /* at least this prevents fragmentation */
+ SSetsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, 1);
+#endif /* defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) */
+ }
+ else {
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+ /* IPV6_PMTUDISC_DO enables Path MTU discovery and prevents fragmentation */
+ SSetsockopt(sockfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, IPV6_PMTUDISC_DO);
+#elif defined(IPV6_DONTFRAG)
+ /* at least this prevents fragmentation */
+ SSetsockopt(sockfd, IPPROTO_IPV6, IPV6_DONTFRAG, 1);
+#endif /* defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) */
+ }
+}
bool setReusePort(int sockfd)
{
@@ -537,10 +559,44 @@ void setSocketSendBuffer(int fd, uint32_t size)
setSocketBuffer(fd, SO_SNDBUF, size);
}
+#ifdef __linux__
+static uint32_t raiseSocketBufferToMax(int socket, int optname, const std::string& readMaxFromFile)
+{
+ std::ifstream ifs(readMaxFromFile);
+ if (ifs) {
+ std::string line;
+ if (getline(ifs, line)) {
+ auto max = pdns::checked_stoi<uint32_t>(line);
+ setSocketBuffer(socket, optname, max);
+ return max;
+ }
+ }
+ return 0;
+}
+#endif
+
+uint32_t raiseSocketReceiveBufferToMax([[maybe_unused]] int socket)
+{
+#ifdef __linux__
+ return raiseSocketBufferToMax(socket, SO_RCVBUF, "/proc/sys/net/core/rmem_max");
+#else
+ return 0;
+#endif
+}
+
+uint32_t raiseSocketSendBufferToMax([[maybe_unused]] int socket)
+{
+#ifdef __linux__
+ return raiseSocketBufferToMax(socket, SO_SNDBUF, "/proc/sys/net/core/wmem_max");
+#else
+ return 0;
+#endif
+}
+
std::set<std::string> getListOfNetworkInterfaces()
{
std::set<std::string> result;
-#if HAVE_GETIFADDRS
+#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifaddr;
if (getifaddrs(&ifaddr) == -1) {
return result;
@@ -558,11 +614,11 @@ std::set<std::string> getListOfNetworkInterfaces()
return result;
}
+#ifdef HAVE_GETIFADDRS
std::vector<ComboAddress> getListOfAddressesOfNetworkInterface(const std::string& itf)
{
std::vector<ComboAddress> result;
-#if HAVE_GETIFADDRS
- struct ifaddrs *ifaddr;
+ struct ifaddrs *ifaddr = nullptr;
if (getifaddrs(&ifaddr) == -1) {
return result;
}
@@ -586,11 +642,17 @@ std::vector<ComboAddress> getListOfAddressesOfNetworkInterface(const std::string
}
freeifaddrs(ifaddr);
-#endif
return result;
}
+#else
+std::vector<ComboAddress> getListOfAddressesOfNetworkInterface(const std::string& /* itf */)
+{
+ std::vector<ComboAddress> result;
+ return result;
+}
+#endif // HAVE_GETIFADDRS
-#if HAVE_GETIFADDRS
+#ifdef HAVE_GETIFADDRS
static uint8_t convertNetmaskToBits(const uint8_t* mask, socklen_t len)
{
if (mask == nullptr || len > 16) {
@@ -611,11 +673,11 @@ static uint8_t convertNetmaskToBits(const uint8_t* mask, socklen_t len)
}
#endif /* HAVE_GETIFADDRS */
+#ifdef HAVE_GETIFADDRS
std::vector<Netmask> getListOfRangesOfNetworkInterface(const std::string& itf)
{
std::vector<Netmask> result;
-#if HAVE_GETIFADDRS
- struct ifaddrs *ifaddr;
+ struct ifaddrs *ifaddr = nullptr;
if (getifaddrs(&ifaddr) == -1) {
return result;
}
@@ -648,6 +710,12 @@ std::vector<Netmask> getListOfRangesOfNetworkInterface(const std::string& itf)
}
freeifaddrs(ifaddr);
-#endif
return result;
}
+#else
+std::vector<Netmask> getListOfRangesOfNetworkInterface(const std::string& /* itf */)
+{
+ std::vector<Netmask> result;
+ return result;
+}
+#endif // HAVE_GETIFADDRS