#include <boost/shared_array.hpp>
#include <boost/function.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/container/flat_set.hpp>
#ifdef MALLOC_TRACE
#include "malloctrace.hh"
#endif
static time_t g_statisticsInterval;
static bool g_useIncomingECS;
std::atomic<uint32_t> g_maxCacheEntries, g_maxPacketCacheEntries;
+static boost::container::flat_set<uint16_t> s_avoidUdpSourcePorts;
+static uint16_t s_minUdpSourcePort;
+static uint16_t s_maxUdpSourcePort;
RecursorControlChannel s_rcc; // only active in thread 0
RecursorStats g_stats;
if(tries==1) // fall back to kernel 'random'
port = 0;
- else
- port = 1025 + dns_random(64510);
+ else {
+ do {
+ port = s_minUdpSourcePort + dns_random(s_maxUdpSourcePort - s_minUdpSourcePort + 1);
+ }
+ while (s_avoidUdpSourcePorts.count(port));
+ }
sin=getQueryLocalAddress(family, port); // does htons for us
g_snmpAgent->run();
}
+ int port = ::arg().asNum("min-udp-source-port");
+ if(port < 1025 || port > 65535){
+ L<<Logger::Error<<"Unable to launch, min-udp-source-port is not a valid port number"<<endl;
+ exit(99); // this isn't going to fix itself either
+ }
+ s_minUdpSourcePort = port;
+ port = ::arg().asNum("max-udp-source-port");
+ if(port < 1025 || port > 65535 || port < s_minUdpSourcePort){
+ L<<Logger::Error<<"Unable to launch, max-udp-source-port is not a valid port number or is smaller than min-udp-source-port"<<endl;
+ exit(99); // this isn't going to fix itself either
+ }
+ s_maxUdpSourcePort = port;
+ std::vector<string> parts {};
+ stringtok(parts, ::arg()["avoid-udp-source-port"], ", ");
+ for (const auto &part : parts)
+ {
+ port = std::stoi(part);
+ if(port < 1025 || port > 65535){
+ L<<Logger::Error<<"Unable to launch, avoid-udp-source-port contains an invalid port number: "<<part<<endl;
+ exit(99); // this isn't going to fix itself either
+ }
+ s_avoidUdpSourcePorts.insert(port);
+ }
+
const auto cpusMap = parseCPUMap();
if(g_numThreads == 1) {
L<<Logger::Warning<<"Operating unthreaded"<<endl;
::arg().set("xpf-allow-from","XPF information is only processed from these subnets")="";
::arg().set("xpf-rr-code","XPF option code to use")="0";
+ ::arg().set("min-udp-source-port", "Minimum UDP port to bind on")="1025";
+ ::arg().set("max-udp-source-port", "Maximum UDP port to bind on")="65535";
+ ::arg().set("avoid-udp-source-port", "List of comma separated UDP port number to avoid")="11211";
+
::arg().setCmd("help","Provide a helpful message");
::arg().setCmd("version","Print version string");
::arg().setCmd("config","Output blank configuration");