From: Remi Gacogne Date: Mon, 5 Dec 2016 15:01:00 +0000 (+0100) Subject: rec: Add SNMP support X-Git-Tag: rec-4.1.0-alpha1~261^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d705aad980d07f6d885a33368a1770d5b7458208;p=pdns rec: Add SNMP support --- diff --git a/docs/MIBS/RECURSOR-MIB.txt b/docs/MIBS/RECURSOR-MIB.txt new file mode 100644 index 000000000..ccbacf889 --- /dev/null +++ b/docs/MIBS/RECURSOR-MIB.txt @@ -0,0 +1,908 @@ +-- -*- snmpv2 -*- +-- ---------------------------------------------------------------------- +-- MIB file for PowerDNS Recursor +-- ---------------------------------------------------------------------- + +PDNSRECURSOR-MIB DEFINITIONS ::= BEGIN + +IMPORTS + OBJECT-TYPE, MODULE-IDENTITY, enterprises, + Counter64, NOTIFICATION-TYPE + FROM SNMPv2-SMI + CounterBasedGauge64 + FROM HCNUM-TC + OBJECT-GROUP, MODULE-COMPLIANCE, NOTIFICATION-GROUP + FROM SNMPv2-CONF; + +rec MODULE-IDENTITY + LAST-UPDATED "201611290000Z" + ORGANIZATION "PowerDNS BV" + CONTACT-INFO "support@powerdns.com" + DESCRIPTION + "This MIB module describes information gathered through PowerDNS Recursor." + + REVISION "201611290000Z" + DESCRIPTION "Initial revision." + + ::= { powerdns 2 } + +powerdns OBJECT IDENTIFIER ::= { enterprises 43315 } + +stats OBJECT IDENTIFIER ::= { rec 1 } + +questions OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of questions" + ::= { stats 1 } + +ipv6Questions OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 questions" + ::= { stats 2 } + +tcpQuestions OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of TCP questions" + ::= { stats 3 } + +cacheHits OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of cache hits" + ::= { stats 4 } + +cacheMisses OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of cache misses" + ::= { stats 5 } + +cacheEntries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of cache entries" + ::= { stats 6 } + +cacheBytes OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Size of the cache in bytes" + ::= { stats 7 } + +packetcacheHits OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packetcache hits" + ::= { stats 8 } + +packetcacheMisses OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packetcache misses" + ::= { stats 9 } + +packetcacheEntries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packetcache entries" + ::= { stats 10 } + +packetcacheBytes OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Size of the packetcache in bytes" + ::= { stats 11 } + +mallocBytes OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of bytes allocated by malloc" + ::= { stats 12 } + +servfailAnswers OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of servfail answers" + ::= { stats 13 } + +nxdomainAnswers OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of nxdomain answers" + ::= { stats 14 } + +noerrorAnswers OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of noerror answers" + ::= { stats 15 } + +unauthorizedUdp OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of unauthorized UDP queries" + ::= { stats 16 } + +unauthorizedTcp OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of unauthorized TCP queries" + ::= { stats 17 } + +tcpClientOverflow OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of TCP client connections refused because of too many connections" + ::= { stats 18 } + +clientParseErrors OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of client parse errors" + ::= { stats 19 } + +serverParseErrors OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of server parse errors" + ::= { stats 20 } + +tooOldDrops OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of responses dropped because of a timeout" + ::= { stats 21 } + +answers01 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries answered in less than 1 ms" + ::= { stats 22 } + +answers110 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries answered in 1-10 ms" + ::= { stats 23 } + +answers10100 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries answered in 10-100 ms" + ::= { stats 24 } + +answers1001000 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries answered in 100-1000 ms" + ::= { stats 25 } + +answersSlow OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries answered in more than 1000 ms" + ::= { stats 26 } + +auth4Answers01 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 queries answered in less than 1 ms" + ::= { stats 27 } + +auth4Answers110 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 queries answered in 1-10 ms" + ::= { stats 28 } + +auth4Answers10100 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 queries answered in 10-100 ms" + ::= { stats 29 } + +auth4Answers1001000 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 queries answered in 100-1000 ms" + ::= { stats 30 } + +auth4Answersslow OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 queries answered in more than 1000 ms" + ::= { stats 31 } + +auth6Answers01 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 queries answered in less than 1 ms" + ::= { stats 32 } + +auth6Answers110 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 queries answered in 1-10 ms" + ::= { stats 33 } + +auth6Answers10100 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 queries answered in 10-100 ms" + ::= { stats 34 } + +auth6Answers1001000 OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 queries answered in 100-1000 ms" + ::= { stats 35 } + +auth6AnswersSlow OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 queries answered in more than 1000 ms" + ::= { stats 36 } + +qaLatency OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Average latency in microseconds" + ::= { stats 37 } + +unexpectedPackets OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of unexpected packets" + ::= { stats 38 } + +caseMismatches OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of case mismatches" + ::= { stats 39 } + +spoofPrevents OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of spoof prevents" + ::= { stats 40 } + +nssetInvalidations OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of nsset invalidations" + ::= { stats 41 } + +resourceLimits OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of resolution aborted because of a local resource limit" + ::= { stats 42 } + +overCapacityDrops OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries dropped because the threads limit was reached" + ::= { stats 43 } + +policyDrops OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of queries dropped because of a policy" + ::= { stats 44 } + +noPacketError OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of noPacketError" + ::= { stats 45 } + +dlgOnlyDrops OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of records dropped because of they belonged to a delegation-only zone" + ::= { stats 46 } + +ignoredPackets OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of ignored packets" + ::= { stats 47 } + +maxMthreadStack OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum size of the Mthread stack" + ::= { stats 48 } + +negcacheEntries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of negcache entries" + ::= { stats 49 } + +throttleEntries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of throttle entries" + ::= { stats 50 } + +nsspeedsEntries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of nsspeeds entries" + ::= { stats 51 } + +failedHostEntries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of failed host entries" + ::= { stats 52 } + +concurrentQueries OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of concurrent queries" + ::= { stats 53 } + +securityStatus OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Current security status" + ::= { stats 54 } + +outgoingTimeouts OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of outgoing timeouts" + ::= { stats 55 } + +outgoing4Timeouts OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv4 outgoing timeouts" + ::= { stats 56 } + +outgoing6Timeouts OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 outgoing timeouts" + ::= { stats 57 } + +tcpOutqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of outgoing TCP queries sent" + ::= { stats 58 } + +allOutqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of outgoing queries sent" + ::= { stats 59 } + +ipv6Outqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of IPv6 outgoing queries sent" + ::= { stats 60 } + +throttledOutqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of throttled outgoing queries" + ::= { stats 61 } + +dontOutqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of outgoing queries not sent because of a 'dont-query' setting" + ::= { stats 62 } + +unreachables OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of errors due to an unreachable server" + ::= { stats 63 } + +chainResends OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of chain resends" + ::= { stats 64 } + +tcpClients OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of TCP clients" + ::= { stats 65 } + +udpRecvbufErrors OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of UDP recvbuf errors (Linux only)" + ::= { stats 66 } + +udpSndbufErrors OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of UDP sndbuf errors (Linux only)" + ::= { stats 67 } + +udpNoportErrors OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of UDP noport errors (Linux only)" + ::= { stats 68 } + +udpinErrors OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of UDP in errors (Linux only)" + ::= { stats 69 } + +ednsPingMatches OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of EDNS Ping matches" + ::= { stats 70 } + +ednsPingMismatches OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of EDNS Ping mismatches" + ::= { stats 71 } + +dnssecQueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC queries" + ::= { stats 72 } + +nopingOutqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of outgoing queries w/o ping" + ::= { stats 73 } + +noednsOutqueries OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of outgoing queries w/o EDNS" + ::= { stats 74 } + +uptime OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Process uptime in seconds" + ::= { stats 75 } + +realMemoryUsage OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Memory usage" + ::= { stats 76 } + +fdUsage OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "File descriptors usage" + ::= { stats 77 } + +userMsec OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "CPU usage (user) in ms" + ::= { stats 78 } + +sysMsec OBJECT-TYPE + SYNTAX CounterBasedGauge64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "CPU usage (system) in ms" + ::= { stats 79 } + +dnssecValidations OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC validations" + ::= { stats 80 } + +dnssecResultInsecure OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC insecure results" + ::= { stats 81 } + +dnssecResultSecure OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC secure results" + ::= { stats 82 } + +dnssecResultBogus OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC bogus results" + ::= { stats 83 } + +dnssecResultIndeterminate OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC indeterminate results" + ::= { stats 84 } + +dnssecResultNta OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of DNSSEC NTA results" + ::= { stats 85 } + +policyResultNoaction OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of policy-mandated no-action results" + ::= { stats 86 } + +policyResultDrop OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of policy-mandated drops" + ::= { stats 87 } + +policyResultNxdomain OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of policy-mandated NXdomain results" + ::= { stats 88 } + +policyResultNodata OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of policy-mandated nodata results" + ::= { stats 89 } + +policyResultTruncate OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of policy-mandated truncate results" + ::= { stats 90 } + +policyResultCustom OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of policy-mandated custom results" + ::= { stats 91 } + +--- +--- Traps / Notifications +--- + +trap OBJECT IDENTIFIER ::= { rec 10 } +traps OBJECT IDENTIFIER ::= { trap 0 } --- reverse-mappable +trapObjects OBJECT IDENTIFIER ::= { rec 11 } + +trapReason OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Reason for this trap" + ::= { trapObjects 1 } + +customTrap NOTIFICATION-TYPE + OBJECTS { + trapReason + } + STATUS current + DESCRIPTION "Trap sent by sendCustomTrap" + ::= { traps 1 } + +--- +--- Conformance +--- + +recConformance OBJECT IDENTIFIER ::= { rec 100 } + +recCompliances MODULE-COMPLIANCE + STATUS current + DESCRIPTION "PowerDNS Recursor compliance statement" + MODULE + MANDATORY-GROUPS { + recGroup, + recTrapsGroup + } + ::= { recConformance 1 } + +recGroup OBJECT-GROUP + OBJECTS { + questions, + ipv6Questions, + tcpQuestions, + cacheHits, + cacheMisses, + cacheEntries, + cacheBytes, + packetcacheHits, + packetcacheMisses, + packetcacheEntries, + packetcacheBytes, + mallocBytes, + servfailAnswers, + nxdomainAnswers, + noerrorAnswers, + unauthorizedUdp, + unauthorizedTcp, + tcpClientOverflow, + clientParseErrors, + serverParseErrors, + tooOldDrops, + answers01, + answers110, + answers10100, + answers1001000, + answersSlow, + auth4Answers01, + auth4Answers110, + auth4Answers10100, + auth4Answers1001000, + auth4Answersslow, + auth6Answers01, + auth6Answers110, + auth6Answers10100, + auth6Answers1001000, + auth6AnswersSlow, + qaLatency, + unexpectedPackets, + caseMismatches, + spoofPrevents, + nssetInvalidations, + resourceLimits, + overCapacityDrops, + policyDrops, + noPacketError, + dlgOnlyDrops, + ignoredPackets, + maxMthreadStack, + negcacheEntries, + throttleEntries, + nsspeedsEntries, + failedHostEntries, + concurrentQueries, + securityStatus, + outgoingTimeouts, + outgoing4Timeouts, + outgoing6Timeouts, + tcpOutqueries, + allOutqueries, + ipv6Outqueries, + throttledOutqueries, + dontOutqueries, + unreachables, + chainResends, + tcpClients, + udpRecvbufErrors, + udpSndbufErrors, + udpNoportErrors, + udpinErrors, + ednsPingMatches, + ednsPingMismatches, + dnssecQueries, + nopingOutqueries, + noednsOutqueries, + uptime, + realMemoryUsage, + fdUsage, + userMsec, + sysMsec, + dnssecValidations, + dnssecResultInsecure, + dnssecResultSecure, + dnssecResultBogus, + dnssecResultIndeterminate, + dnssecResultNta, + policyResultNoaction, + policyResultDrop, + policyResultNxdomain, + policyResultNodata, + policyResultTruncate, + policyResultCustom, + trapReason + } + STATUS current + DESCRIPTION "Objects conformance group for PowerDNS Recursor" + ::= { recConformance 2 } + +recTrapsGroup NOTIFICATION-GROUP + NOTIFICATIONS { + customTrap + } + STATUS current + DESCRIPTION "Traps conformance group for PowerDNS Recursor" + ::= { recConformance 3 } + +END diff --git a/docs/markdown/recursor/scripting.md b/docs/markdown/recursor/scripting.md index 086f7f1c1..bc8927a87 100644 --- a/docs/markdown/recursor/scripting.md +++ b/docs/markdown/recursor/scripting.md @@ -525,3 +525,16 @@ The kind of policy response, there are several policy kinds: These fields are only used when `dq.appliedPolicy.policyKind` is set to `pdns.policykinds.Custom`. `dq.appliedPolicy.policyCustom` contains the name for the CNAME target as a string. And `dq.appliedPolicy.policyTTL` is the TTL field (in seconds) for the CNAME response. + +## SNMP Traps +PowerDNS Recursor, when compiled with SNMP support, has the ability to act as a +SNMP agent to provide SNMP statistics and to be able to send traps from Lua. + +For example, to send a custom SNMP trap containing the qname from the `preresolve` hook: + +``` +function preresolve(dq) + sendCustomSNMPTrap('Trap from preresolve, qname is '..dq.qname:toString()) + return false +end +``` diff --git a/docs/markdown/recursor/settings.md b/docs/markdown/recursor/settings.md index c55c4fba1..8f0c685ee 100644 --- a/docs/markdown/recursor/settings.md +++ b/docs/markdown/recursor/settings.md @@ -796,6 +796,20 @@ used for better [security](security.md). Use only a single socket for outgoing queries. +## `snmp-agent` +* Boolean +* Default: no + +If set to true and PowerDNS has been compiled with SNMP support, it will register +as an SNMP agent to provide statistics and be able to send traps. + +## `snmp-master-socket` +* String +* Default: empty + +If not empty and `snmp-agent` is set to true, indicates how PowerDNS should contact +the SNMP master to register as an SNMP agent. + ## `socket-dir` * Path diff --git a/pdns/lua-recursor4.cc b/pdns/lua-recursor4.cc index 850a97d17..e8a9d0b9f 100644 --- a/pdns/lua-recursor4.cc +++ b/pdns/lua-recursor4.cc @@ -28,6 +28,7 @@ #include "rec_channel.hh" #include "ednssubnet.hh" #include "filterpo.hh" +#include "rec-snmp.hh" #include #if !defined(HAVE_LUA) @@ -568,6 +569,11 @@ RecursorLua4::RecursorLua4(const std::string& fname) return getRecursorThreadId(); }); + d_lw->writeFunction("sendCustomSNMPTrap", [](const std::string& str) { + if (g_snmpAgent) { + g_snmpAgent->sendCustomTrap(str); + } + }); ifstream ifs(fname); if(!ifs) { diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 7be428fa9..3445b5d57 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -85,6 +85,7 @@ extern SortList g_sortlist; #include "gettime.hh" #include "rec-protobuf.hh" +#include "rec-snmp.hh" #ifdef HAVE_SYSTEMD #include @@ -2812,6 +2813,11 @@ int serviceMain(int argc, char*argv[]) g_maxTCPPerClient=::arg().asNum("max-tcp-per-client"); g_tcpMaxQueriesPerConn=::arg().asNum("max-tcp-queries-per-connection"); + if (::arg().mustDo("snmp-agent")) { + g_snmpAgent = std::make_shared("recursor", ::arg()["snmp-master-socket"]); + g_snmpAgent->run(); + } + if(g_numThreads == 1) { L< + +#include "rec-snmp.hh" +#include "rec_channel.hh" + +#include "logger.hh" + +#ifdef HAVE_NET_SNMP + +#define RECURSOR_OID 1, 3, 6, 1, 4, 1, 43315, 2 +#define RECURSOR_STATS_OID RECURSOR_OID, 1 +#define RECURSOR_TRAPS_OID RECURSOR_OID, 10, 0 +#define RECURSOR_TRAP_OBJECTS_OID RECURSOR_OID, 11 + +static const oid trapReasonOID[] = { RECURSOR_TRAP_OBJECTS_OID, 1, 0 }; +static const oid customTrapOID[] = { RECURSOR_TRAPS_OID, 1 }; + +static const oid questionsOID[] = { RECURSOR_STATS_OID, 1 }; +static const oid ipv6QuestionsOID[] = { RECURSOR_STATS_OID, 2 }; +static const oid tcpQuestionsOID[] = { RECURSOR_STATS_OID, 3 }; +static const oid cacheHitsOID[] = { RECURSOR_STATS_OID, 4 }; +static const oid cacheMissesOID[] = { RECURSOR_STATS_OID, 5 }; +static const oid cacheEntriesOID[] = { RECURSOR_STATS_OID, 6 }; +static const oid cacheBytesOID[] = { RECURSOR_STATS_OID, 7 }; +static const oid packetcacheHitsOID[] = { RECURSOR_STATS_OID, 8 }; +static const oid packetcacheMissesOID[] = { RECURSOR_STATS_OID, 9 }; +static const oid packetcacheEntriesOID[] = { RECURSOR_STATS_OID, 10 }; +static const oid packetcacheBytesOID[] = { RECURSOR_STATS_OID, 11 }; +static const oid mallocBytesOID[] = { RECURSOR_STATS_OID, 12 }; +static const oid servfailAnswersOID[] = { RECURSOR_STATS_OID, 13 }; +static const oid nxdomainAnswersOID[] = { RECURSOR_STATS_OID, 14 }; +static const oid noerrorAnswersOID[] = { RECURSOR_STATS_OID, 15 }; +static const oid unauthorizedUdpOID[] = { RECURSOR_STATS_OID, 16 }; +static const oid unauthorizedTcpOID[] = { RECURSOR_STATS_OID, 17 }; +static const oid tcpClientOverflowOID[] = { RECURSOR_STATS_OID, 18 }; +static const oid clientParseErrorsOID[] = { RECURSOR_STATS_OID, 19 }; +static const oid serverParseErrorsOID[] = { RECURSOR_STATS_OID, 20 }; +static const oid tooOldDropsOID[] = { RECURSOR_STATS_OID, 21 }; +static const oid answers01OID[] = { RECURSOR_STATS_OID, 22 }; +static const oid answers110OID[] = { RECURSOR_STATS_OID, 23 }; +static const oid answers10100OID[] = { RECURSOR_STATS_OID, 24 }; +static const oid answers1001000OID[] = { RECURSOR_STATS_OID, 25 }; +static const oid answersSlowOID[] = { RECURSOR_STATS_OID, 26 }; +static const oid auth4Answers01OID[] = { RECURSOR_STATS_OID, 27 }; +static const oid auth4Answers110OID[] = { RECURSOR_STATS_OID, 28 }; +static const oid auth4Answers10100OID[] = { RECURSOR_STATS_OID, 29 }; +static const oid auth4Answers1001000OID[] = { RECURSOR_STATS_OID, 30 }; +static const oid auth4AnswersslowOID[] = { RECURSOR_STATS_OID, 31 }; +static const oid auth6Answers01OID[] = { RECURSOR_STATS_OID, 32 }; +static const oid auth6Answers110OID[] = { RECURSOR_STATS_OID, 33 }; +static const oid auth6Answers10100OID[] = { RECURSOR_STATS_OID, 34 }; +static const oid auth6Answers1001000OID[] = { RECURSOR_STATS_OID, 35 }; +static const oid auth6AnswersSlowOID[] = { RECURSOR_STATS_OID, 36 }; +static const oid qaLatencyOID[] = { RECURSOR_STATS_OID, 37 }; +static const oid unexpectedPacketsOID[] = { RECURSOR_STATS_OID, 38 }; +static const oid caseMismatchesOID[] = { RECURSOR_STATS_OID, 39 }; +static const oid spoofPreventsOID[] = { RECURSOR_STATS_OID, 40 }; +static const oid nssetInvalidationsOID[] = { RECURSOR_STATS_OID, 41 }; +static const oid resourceLimitsOID[] = { RECURSOR_STATS_OID, 42 }; +static const oid overCapacityDropsOID[] = { RECURSOR_STATS_OID, 43 }; +static const oid policyDropsOID[] = { RECURSOR_STATS_OID, 44 }; +static const oid noPacketErrorOID[] = { RECURSOR_STATS_OID, 45 }; +static const oid dlgOnlyDropsOID[] = { RECURSOR_STATS_OID, 46 }; +static const oid ignoredPacketsOID[] = { RECURSOR_STATS_OID, 47 }; +static const oid maxMthreadStackOID[] = { RECURSOR_STATS_OID, 48 }; +static const oid negcacheEntriesOID[] = { RECURSOR_STATS_OID, 49 }; +static const oid throttleEntriesOID[] = { RECURSOR_STATS_OID, 50 }; +static const oid nsspeedsEntriesOID[] = { RECURSOR_STATS_OID, 51 }; +static const oid failedHostEntriesOID[] = { RECURSOR_STATS_OID, 52 }; +static const oid concurrentQueriesOID[] = { RECURSOR_STATS_OID, 53 }; +static const oid securityStatusOID[] = { RECURSOR_STATS_OID, 54 }; +static const oid outgoingTimeoutsOID[] = { RECURSOR_STATS_OID, 55 }; +static const oid outgoing4TimeoutsOID[] = { RECURSOR_STATS_OID, 56 }; +static const oid outgoing6TimeoutsOID[] = { RECURSOR_STATS_OID, 57 }; +static const oid tcpOutqueriesOID[] = { RECURSOR_STATS_OID, 58 }; +static const oid allOutqueriesOID[] = { RECURSOR_STATS_OID, 59 }; +static const oid ipv6OutqueriesOID[] = { RECURSOR_STATS_OID, 60 }; +static const oid throttledOutqueriesOID[] = { RECURSOR_STATS_OID, 61 }; +static const oid dontOutqueriesOID[] = { RECURSOR_STATS_OID, 62 }; +static const oid unreachablesOID[] = { RECURSOR_STATS_OID, 63 }; +static const oid chainResendsOID[] = { RECURSOR_STATS_OID, 64 }; +static const oid tcpClientsOID[] = { RECURSOR_STATS_OID, 65 }; +static const oid udpRecvbufErrorsOID[] = { RECURSOR_STATS_OID, 66 }; +static const oid udpSndbufErrorsOID[] = { RECURSOR_STATS_OID, 67 }; +static const oid udpNoportErrorsOID[] = { RECURSOR_STATS_OID, 68 }; +static const oid udpinErrorsOID[] = { RECURSOR_STATS_OID, 69 }; +static const oid ednsPingMatchesOID[] = { RECURSOR_STATS_OID, 70 }; +static const oid ednsPingMismatchesOID[] = { RECURSOR_STATS_OID, 71 }; +static const oid dnssecQueriesOID[] = { RECURSOR_STATS_OID, 72 }; +static const oid nopingOutqueriesOID[] = { RECURSOR_STATS_OID, 73 }; +static const oid noednsOutqueriesOID[] = { RECURSOR_STATS_OID, 74 }; +static const oid uptimeOID[] = { RECURSOR_STATS_OID, 75 }; +static const oid realMemoryUsageOID[] = { RECURSOR_STATS_OID, 76 }; +static const oid fdUsageOID[] = { RECURSOR_STATS_OID, 77 }; +static const oid userMsecOID[] = { RECURSOR_STATS_OID, 78 }; +static const oid sysMsecOID[] = { RECURSOR_STATS_OID, 79 }; +static const oid dnssecValidationsOID[] = { RECURSOR_STATS_OID, 80 }; +static const oid dnssecResultInsecureOID[] = { RECURSOR_STATS_OID, 81 }; +static const oid dnssecResultSecureOID[] = { RECURSOR_STATS_OID, 82 }; +static const oid dnssecResultBogusOID[] = { RECURSOR_STATS_OID, 83 }; +static const oid dnssecResultIndeterminateOID[] = { RECURSOR_STATS_OID, 84 }; +static const oid dnssecResultNtaOID[] = { RECURSOR_STATS_OID, 85 }; +static const oid policyResultNoactionOID[] = { RECURSOR_STATS_OID, 86 }; +static const oid policyResultDropOID[] = { RECURSOR_STATS_OID, 87 }; +static const oid policyResultNxdomainOID[] = { RECURSOR_STATS_OID, 88 }; +static const oid policyResultNodataOID[] = { RECURSOR_STATS_OID, 89 }; +static const oid policyResultTruncateOID[] = { RECURSOR_STATS_OID, 90 }; +static const oid policyResultCustomOID[] = { RECURSOR_STATS_OID, 91 }; + +static std::unordered_map s_statsMap; + +/* We are never called for a GETNEXT if it's registered as a + "instance", as it's "magically" handled for us. */ +/* a instance handler also only hands us one request at a time, so + we don't need to loop over a list of requests; we'll only get one. */ + +static int handleCounter64Stats(netsnmp_mib_handler* handler, + netsnmp_handler_registration* reginfo, + netsnmp_agent_request_info* reqinfo, + netsnmp_request_info* requests) +{ + if (reqinfo->mode != MODE_GET) { + return SNMP_ERR_GENERR; + } + + if (reginfo->rootoid_len != OID_LENGTH(questionsOID) + 1) { + return SNMP_ERR_GENERR; + } + + const auto& it = s_statsMap.find(reginfo->rootoid[reginfo->rootoid_len - 2]); + if (it == s_statsMap.end()) { + return SNMP_ERR_GENERR; + } + + optional value = getStatByName(it->second); + if (value) { + return RecursorSNMPAgent::setCounter64Value(requests, *value); + } else { + return RecursorSNMPAgent::setCounter64Value(requests, 0); + } +} + +static void registerCounter64Stat(const char* name, const oid statOID[], size_t statOIDLength) +{ + if (statOIDLength != OID_LENGTH(questionsOID)) { + L< g_snmpAgent{nullptr}; + +bool RecursorSNMPAgent::sendCustomTrap(const std::string& reason) +{ +#ifdef HAVE_NET_SNMP + netsnmp_variable_list* varList = nullptr; + + snmp_varlist_add_variable(&varList, + snmpTrapOID, + snmpTrapOIDLen, + ASN_OBJECT_ID, + customTrapOID, + OID_LENGTH(customTrapOID) * sizeof(oid)); + + snmp_varlist_add_variable(&varList, + trapReasonOID, + OID_LENGTH(trapReasonOID), + ASN_OCTET_STR, + reason.c_str(), + reason.size()); + + return sendTrap(d_trapPipe[1], varList); +#endif /* HAVE_NET_SNMP */ + return true; +} + + +RecursorSNMPAgent::RecursorSNMPAgent(const std::string& name, const std::string& masterSocket): SNMPAgent(name, masterSocket) +{ +#ifdef HAVE_NET_SNMP + /* This is done so that the statistics maps are + initialized. */ + RecursorControlParser rcp; + + registerCounter64Stat("questions", questionsOID, OID_LENGTH(questionsOID)); + registerCounter64Stat("ipv6-questions", ipv6QuestionsOID, OID_LENGTH(ipv6QuestionsOID)); + registerCounter64Stat("tcp-questions", tcpQuestionsOID, OID_LENGTH(tcpQuestionsOID)); + registerCounter64Stat("cache-hits", cacheHitsOID, OID_LENGTH(cacheHitsOID)); + registerCounter64Stat("cache-misses", cacheMissesOID, OID_LENGTH(cacheMissesOID)); + registerCounter64Stat("cache-entries", cacheEntriesOID, OID_LENGTH(cacheEntriesOID)); + registerCounter64Stat("cache-bytes", cacheBytesOID, OID_LENGTH(cacheBytesOID)); + registerCounter64Stat("packetcache-hits", packetcacheHitsOID, OID_LENGTH(packetcacheHitsOID)); + registerCounter64Stat("packetcache-misses", packetcacheMissesOID, OID_LENGTH(packetcacheMissesOID)); + registerCounter64Stat("packetcache-entries", packetcacheEntriesOID, OID_LENGTH(packetcacheEntriesOID)); + registerCounter64Stat("packetcache-bytes", packetcacheBytesOID, OID_LENGTH(packetcacheBytesOID)); + registerCounter64Stat("malloc-bytes", mallocBytesOID, OID_LENGTH(mallocBytesOID)); + registerCounter64Stat("servfail-answers", servfailAnswersOID, OID_LENGTH(servfailAnswersOID)); + registerCounter64Stat("nxdomain-answers", nxdomainAnswersOID, OID_LENGTH(nxdomainAnswersOID)); + registerCounter64Stat("noerror-answers", noerrorAnswersOID, OID_LENGTH(noerrorAnswersOID)); + registerCounter64Stat("unauthorized-udp", unauthorizedUdpOID, OID_LENGTH(unauthorizedUdpOID)); + registerCounter64Stat("unauthorized-tcp", unauthorizedTcpOID, OID_LENGTH(unauthorizedTcpOID)); + registerCounter64Stat("tcp-client-overflow", tcpClientOverflowOID, OID_LENGTH(tcpClientOverflowOID)); + registerCounter64Stat("client-parse-errors", clientParseErrorsOID, OID_LENGTH(clientParseErrorsOID)); + registerCounter64Stat("server-parse-errors", serverParseErrorsOID, OID_LENGTH(serverParseErrorsOID)); + registerCounter64Stat("too-old-drops", tooOldDropsOID, OID_LENGTH(tooOldDropsOID)); + registerCounter64Stat("answers0-1", answers01OID, OID_LENGTH(answers01OID)); + registerCounter64Stat("answers1-10", answers110OID, OID_LENGTH(answers110OID)); + registerCounter64Stat("answers10-100", answers10100OID, OID_LENGTH(answers10100OID)); + registerCounter64Stat("answers100-1000", answers1001000OID, OID_LENGTH(answers1001000OID)); + registerCounter64Stat("answers-slow", answersSlowOID, OID_LENGTH(answersSlowOID)); + registerCounter64Stat("auth4-answers0-1", auth4Answers01OID, OID_LENGTH(auth4Answers01OID)); + registerCounter64Stat("auth4-answers1-10", auth4Answers110OID, OID_LENGTH(auth4Answers110OID)); + registerCounter64Stat("auth4-answers10-100", auth4Answers10100OID, OID_LENGTH(auth4Answers10100OID)); + registerCounter64Stat("auth4-answers100-1000", auth4Answers1001000OID, OID_LENGTH(auth4Answers1001000OID)); + registerCounter64Stat("auth4-answers-slow", auth4AnswersslowOID, OID_LENGTH(auth4AnswersslowOID)); + registerCounter64Stat("auth6-answers0-1", auth6Answers01OID, OID_LENGTH(auth6Answers01OID)); + registerCounter64Stat("auth6-answers1-10", auth6Answers110OID, OID_LENGTH(auth6Answers110OID)); + registerCounter64Stat("auth6-answers10-100", auth6Answers10100OID, OID_LENGTH(auth6Answers10100OID)); + registerCounter64Stat("auth6-answers100-1000", auth6Answers1001000OID, OID_LENGTH(auth6Answers1001000OID)); + registerCounter64Stat("auth6-answers-slow", auth6AnswersSlowOID, OID_LENGTH(auth6AnswersSlowOID)); + registerCounter64Stat("qa-latency", qaLatencyOID, OID_LENGTH(qaLatencyOID)); + registerCounter64Stat("unexpected-packets", unexpectedPacketsOID, OID_LENGTH(unexpectedPacketsOID)); + registerCounter64Stat("case-mismatches", caseMismatchesOID, OID_LENGTH(caseMismatchesOID)); + registerCounter64Stat("spoof-prevents", spoofPreventsOID, OID_LENGTH(spoofPreventsOID)); + registerCounter64Stat("nsset-invalidations", nssetInvalidationsOID, OID_LENGTH(nssetInvalidationsOID)); + registerCounter64Stat("resource-limits", resourceLimitsOID, OID_LENGTH(resourceLimitsOID)); + registerCounter64Stat("over-capacity-drops", overCapacityDropsOID, OID_LENGTH(overCapacityDropsOID)); + registerCounter64Stat("policy-drops", policyDropsOID, OID_LENGTH(policyDropsOID)); + registerCounter64Stat("no-packet-error", noPacketErrorOID, OID_LENGTH(noPacketErrorOID)); + registerCounter64Stat("dlg-only-drops", dlgOnlyDropsOID, OID_LENGTH(dlgOnlyDropsOID)); + registerCounter64Stat("ignored-packets", ignoredPacketsOID, OID_LENGTH(ignoredPacketsOID)); + registerCounter64Stat("max-mthread-stack", maxMthreadStackOID, OID_LENGTH(maxMthreadStackOID)); + registerCounter64Stat("negcache-entries", negcacheEntriesOID, OID_LENGTH(negcacheEntriesOID)); + registerCounter64Stat("throttle-entries", throttleEntriesOID, OID_LENGTH(throttleEntriesOID)); + registerCounter64Stat("nsspeeds-entries", nsspeedsEntriesOID, OID_LENGTH(nsspeedsEntriesOID)); + registerCounter64Stat("failed-host-entries", failedHostEntriesOID, OID_LENGTH(failedHostEntriesOID)); + registerCounter64Stat("concurrent-queries", concurrentQueriesOID, OID_LENGTH(concurrentQueriesOID)); + registerCounter64Stat("security-status", securityStatusOID, OID_LENGTH(securityStatusOID)); + registerCounter64Stat("outgoing-timeouts", outgoingTimeoutsOID, OID_LENGTH(outgoingTimeoutsOID)); + registerCounter64Stat("outgoing4-timeouts", outgoing4TimeoutsOID, OID_LENGTH(outgoing4TimeoutsOID)); + registerCounter64Stat("outgoing6-timeouts", outgoing6TimeoutsOID, OID_LENGTH(outgoing6TimeoutsOID)); + registerCounter64Stat("tcp-outqueries", tcpOutqueriesOID, OID_LENGTH(tcpOutqueriesOID)); + registerCounter64Stat("all-outqueries", allOutqueriesOID, OID_LENGTH(allOutqueriesOID)); + registerCounter64Stat("ipv6-outqueries", ipv6OutqueriesOID, OID_LENGTH(ipv6OutqueriesOID)); + registerCounter64Stat("throttled-outqueries", throttledOutqueriesOID, OID_LENGTH(throttledOutqueriesOID)); + registerCounter64Stat("dont-outqueries", dontOutqueriesOID, OID_LENGTH(dontOutqueriesOID)); + registerCounter64Stat("unreachables", unreachablesOID, OID_LENGTH(unreachablesOID)); + registerCounter64Stat("chain-resends", chainResendsOID, OID_LENGTH(chainResendsOID)); + registerCounter64Stat("tcp-clients", tcpClientsOID, OID_LENGTH(tcpClientsOID)); +#ifdef __linux__ + registerCounter64Stat("udp-recvbuf-errors", udpRecvbufErrorsOID, OID_LENGTH(udpRecvbufErrorsOID)); + registerCounter64Stat("udp-sndbuf-errors", udpSndbufErrorsOID, OID_LENGTH(udpSndbufErrorsOID)); + registerCounter64Stat("udp-noport-errors", udpNoportErrorsOID, OID_LENGTH(udpNoportErrorsOID)); + registerCounter64Stat("udp-in-errors", udpinErrorsOID, OID_LENGTH(udpinErrorsOID)); +#endif /* __linux__ */ + registerCounter64Stat("edns-ping-matches", ednsPingMatchesOID, OID_LENGTH(ednsPingMatchesOID)); + registerCounter64Stat("edns-ping-mismatches", ednsPingMismatchesOID, OID_LENGTH(ednsPingMismatchesOID)); + registerCounter64Stat("dnssec-queries", dnssecQueriesOID, OID_LENGTH(dnssecQueriesOID)); + registerCounter64Stat("noping-outqueries", nopingOutqueriesOID, OID_LENGTH(nopingOutqueriesOID)); + registerCounter64Stat("noedns-outqueries", noednsOutqueriesOID, OID_LENGTH(noednsOutqueriesOID)); + registerCounter64Stat("uptime", uptimeOID, OID_LENGTH(uptimeOID)); + registerCounter64Stat("real-memory-usage", realMemoryUsageOID, OID_LENGTH(realMemoryUsageOID)); + registerCounter64Stat("fd-usage", fdUsageOID, OID_LENGTH(fdUsageOID)); + registerCounter64Stat("user-msec", userMsecOID, OID_LENGTH(userMsecOID)); + registerCounter64Stat("sys-msec", sysMsecOID, OID_LENGTH(sysMsecOID)); + registerCounter64Stat("dnssec-validations", dnssecValidationsOID, OID_LENGTH(dnssecValidationsOID)); + registerCounter64Stat("dnssec-result-insecure", dnssecResultInsecureOID, OID_LENGTH(dnssecResultInsecureOID)); + registerCounter64Stat("dnssec-result-secure", dnssecResultSecureOID, OID_LENGTH(dnssecResultSecureOID)); + registerCounter64Stat("dnssec-result-bogus", dnssecResultBogusOID, OID_LENGTH(dnssecResultBogusOID)); + registerCounter64Stat("dnssec-result-indeterminate", dnssecResultIndeterminateOID, OID_LENGTH(dnssecResultIndeterminateOID)); + registerCounter64Stat("dnssec-result-nta", dnssecResultNtaOID, OID_LENGTH(dnssecResultNtaOID)); + registerCounter64Stat("policy-result-noaction", policyResultNoactionOID, OID_LENGTH(policyResultNoactionOID)); + registerCounter64Stat("policy-result-drop", policyResultDropOID, OID_LENGTH(policyResultDropOID)); + registerCounter64Stat("policy-result-nxdomain", policyResultNxdomainOID, OID_LENGTH(policyResultNxdomainOID)); + registerCounter64Stat("policy-result-nodata", policyResultNodataOID, OID_LENGTH(policyResultNodataOID)); + registerCounter64Stat("policy-result-truncate", policyResultTruncateOID, OID_LENGTH(policyResultTruncateOID)); + registerCounter64Stat("policy-result-custom", policyResultCustomOID, OID_LENGTH(policyResultCustomOID)); + +#endif /* HAVE_NET_SNMP */ +} diff --git a/pdns/rec-snmp.hh b/pdns/rec-snmp.hh new file mode 100644 index 000000000..3ccc73fb1 --- /dev/null +++ b/pdns/rec-snmp.hh @@ -0,0 +1,19 @@ +#ifndef REC_SNMP_HH +#define REC_SNMP_HH + +#pragma once + +#include "snmp-agent.hh" + +class RecursorSNMPAgent; + +class RecursorSNMPAgent: public SNMPAgent +{ +public: + RecursorSNMPAgent(const std::string& name, const std::string& masterSocket); + bool sendCustomTrap(const std::string& reason); +}; + +extern std::shared_ptr g_snmpAgent; + +#endif /* REC_SNMP_HH */ diff --git a/pdns/rec_channel.hh b/pdns/rec_channel.hh index bbdf12ff9..168f3af80 100644 --- a/pdns/rec_channel.hh +++ b/pdns/rec_channel.hh @@ -73,4 +73,5 @@ std::vector* pleaseGetServfailRemotes(); std::vector* pleaseGetLargeAnswerRemotes(); DNSName getRegisteredName(const DNSName& dom); std::atomic* getDynMetric(const std::string& str); +optional getStatByName(const std::string& name); #endif diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index c5397bc86..fa40d1d03 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -98,6 +98,11 @@ optional get(const string& name) return ret; } +optional getStatByName(const std::string& name) +{ + return get(name); +} + map getAllStatsMap() { map ret; @@ -637,7 +642,7 @@ static string doCurrentQueries() uint64_t* pleaseGetThrottleSize() { - return new uint64_t(t_sstorage->throttle.size()); + return new uint64_t(t_sstorage ? t_sstorage->throttle.size() : 0); } static uint64_t getThrottleSize() @@ -647,7 +652,7 @@ static uint64_t getThrottleSize() uint64_t* pleaseGetNegCacheSize() { - uint64_t tmp=t_sstorage->negcache.size(); + uint64_t tmp=(t_sstorage ? t_sstorage->negcache.size() : 0); return new uint64_t(tmp); } @@ -658,7 +663,7 @@ uint64_t getNegCacheSize() uint64_t* pleaseGetFailedHostsSize() { - uint64_t tmp=t_sstorage->fails.size(); + uint64_t tmp=(t_sstorage ? t_sstorage->fails.size() : 0); return new uint64_t(tmp); } uint64_t getFailedHostsSize() @@ -668,7 +673,7 @@ uint64_t getFailedHostsSize() uint64_t* pleaseGetNsSpeedsSize() { - return new uint64_t(t_sstorage->nsSpeeds.size()); + return new uint64_t(t_sstorage ? t_sstorage->nsSpeeds.size() : 0); } uint64_t getNsSpeedsSize() @@ -678,7 +683,7 @@ uint64_t getNsSpeedsSize() uint64_t* pleaseGetConcurrentQueries() { - return new uint64_t(MT->numProcesses()); + return new uint64_t(MT ? MT->numProcesses() : 0); } static uint64_t getConcurrentQueries() @@ -688,12 +693,12 @@ static uint64_t getConcurrentQueries() uint64_t* pleaseGetCacheSize() { - return new uint64_t(t_RC->size()); + return new uint64_t(t_RC ? t_RC->size() : 0); } uint64_t* pleaseGetCacheBytes() { - return new uint64_t(t_RC->bytes()); + return new uint64_t(t_RC ? t_RC->bytes() : 0); } @@ -715,7 +720,7 @@ uint64_t doGetCacheBytes() uint64_t* pleaseGetCacheHits() { - return new uint64_t(t_RC->cacheHits); + return new uint64_t(t_RC ? t_RC->cacheHits : 0); } uint64_t doGetCacheHits() @@ -725,7 +730,7 @@ uint64_t doGetCacheHits() uint64_t* pleaseGetCacheMisses() { - return new uint64_t(t_RC->cacheMisses); + return new uint64_t(t_RC ? t_RC->cacheMisses : 0); } uint64_t doGetCacheMisses() @@ -736,12 +741,12 @@ uint64_t doGetCacheMisses() uint64_t* pleaseGetPacketCacheSize() { - return new uint64_t(t_packetCache->size()); + return new uint64_t(t_packetCache ? t_packetCache->size() : 0); } uint64_t* pleaseGetPacketCacheBytes() { - return new uint64_t(t_packetCache->bytes()); + return new uint64_t(t_packetCache ? t_packetCache->bytes() : 0); } @@ -758,7 +763,7 @@ uint64_t doGetPacketCacheBytes() uint64_t* pleaseGetPacketCacheHits() { - return new uint64_t(t_packetCache->d_hits); + return new uint64_t(t_packetCache ? t_packetCache->d_hits : 0); } uint64_t doGetPacketCacheHits() @@ -768,7 +773,7 @@ uint64_t doGetPacketCacheHits() uint64_t* pleaseGetPacketCacheMisses() { - return new uint64_t(t_packetCache->d_misses); + return new uint64_t(t_packetCache ? t_packetCache->d_misses : 0); } uint64_t doGetPacketCacheMisses() diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 90004d729..1cca8d686 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -1,6 +1,6 @@ JSON11_LIBS = $(top_srcdir)/ext/json11/libjson11.la -AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(BOOST_CPPFLAGS) $(BOTAN110_CFLAGS) $(SANITIZER_FLAGS) -O3 -Wall -pthread -DSYSCONFDIR=\"${sysconfdir}\" $(SYSTEMD_CFLAGS) +AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(BOOST_CPPFLAGS) $(BOTAN110_CFLAGS) $(NET_SNMP_CFLAGS) $(SANITIZER_FLAGS) -O3 -Wall -pthread -DSYSCONFDIR=\"${sysconfdir}\" $(SYSTEMD_CFLAGS) AM_CPPFLAGS += \ -I$(top_srcdir)/ext/json11 \ @@ -110,6 +110,7 @@ pdns_recursor_SOURCES = \ rec-carbon.cc \ rec-lua-conf.hh rec-lua-conf.cc \ rec-protobuf.cc rec-protobuf.hh \ + rec-snmp.hh rec-snmp.cc \ rec_channel.cc rec_channel.hh \ rec_channel_rec.cc \ recpacketcache.cc recpacketcache.hh \ @@ -127,6 +128,7 @@ pdns_recursor_SOURCES = \ selectmplexer.cc \ sholder.hh \ sillyrecords.cc \ + snmp-agent.hh snmp-agent.cc \ sortlist.cc sortlist.hh \ sstuff.hh \ syncres.cc syncres.hh \ @@ -152,6 +154,7 @@ pdns_recursor_LDADD = \ $(JSON11_LIBS) \ $(LIBCRYPTO_LIBS) \ $(BOOST_CONTEXT_LIBS) \ + $(NET_SNMP_LIBS) \ $(SYSTEMD_LIBS) \ $(RT_LIBS) diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 64b3af7e3..7a0be9129 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -113,6 +113,8 @@ PDNS_CHECK_LIBCRYPTO([ ) PDNS_CHECK_LIBCRYPTO_ECDSA +PDNS_WITH_NET_SNMP + # check for tools we might need PDNS_CHECK_RAGEL PDNS_CHECK_CURL @@ -205,6 +207,10 @@ AS_IF([test "x$PROTOBUF_LIBS" != "x" -a x"$PROTOC" != "x"], [AC_MSG_NOTICE([Protobuf: yes])], [AC_MSG_NOTICE([Protobuf: no])] ) +AS_IF([test "x$NET_SNMP_LIBS" != "x"], + [AC_MSG_NOTICE([SNMP: yes])], + [AC_MSG_NOTICE([SNMP: no])] +) AS_IF([test "x$systemd" != "xn"], [AC_MSG_NOTICE([systemd: yes])], [AC_MSG_NOTICE([systemd: no])] diff --git a/pdns/recursordist/m4/pdns_with_net_snmp.m4 b/pdns/recursordist/m4/pdns_with_net_snmp.m4 new file mode 120000 index 000000000..676095ba0 --- /dev/null +++ b/pdns/recursordist/m4/pdns_with_net_snmp.m4 @@ -0,0 +1 @@ +../../../m4/pdns_with_net_snmp.m4 \ No newline at end of file diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc new file mode 120000 index 000000000..9883d66bc --- /dev/null +++ b/pdns/recursordist/rec-snmp.cc @@ -0,0 +1 @@ +../rec-snmp.cc \ No newline at end of file diff --git a/pdns/recursordist/rec-snmp.hh b/pdns/recursordist/rec-snmp.hh new file mode 120000 index 000000000..b34bdacfc --- /dev/null +++ b/pdns/recursordist/rec-snmp.hh @@ -0,0 +1 @@ +../rec-snmp.hh \ No newline at end of file diff --git a/pdns/recursordist/snmp-agent.cc b/pdns/recursordist/snmp-agent.cc new file mode 120000 index 000000000..d786b4793 --- /dev/null +++ b/pdns/recursordist/snmp-agent.cc @@ -0,0 +1 @@ +../snmp-agent.cc \ No newline at end of file diff --git a/pdns/recursordist/snmp-agent.hh b/pdns/recursordist/snmp-agent.hh new file mode 120000 index 000000000..b5ddc9988 --- /dev/null +++ b/pdns/recursordist/snmp-agent.hh @@ -0,0 +1 @@ +../snmp-agent.hh \ No newline at end of file