summaryrefslogtreecommitdiff
path: root/contrib/unbound-querycachedb.py
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2018-05-12 11:56:52 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2018-05-12 11:56:52 +0000
commit4289761a7b61df4b64c11ada446a187df61e6a1e (patch)
treeed7ceb7a1652fb9f865fafd21fbe18d1a3b5f79d /contrib/unbound-querycachedb.py
parent197f1a0fe3e81cde0cd25a3a1f37ebedf9a99488 (diff)
Diffstat (limited to 'contrib/unbound-querycachedb.py')
-rw-r--r--contrib/unbound-querycachedb.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/contrib/unbound-querycachedb.py b/contrib/unbound-querycachedb.py
new file mode 100644
index 0000000000000..5b4485ba87adc
--- /dev/null
+++ b/contrib/unbound-querycachedb.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+import hashlib
+import sys
+import struct
+import socket
+import time
+from optparse import OptionParser
+
+import dns.message
+import dns.name
+import dns.rdataclass
+import dns.rdatatype
+
+def _calc_hashkey(qname, secret, qtype):
+ qclass = 'IN' # CLASS is fixed for simplicity
+ hobj = hashlib.sha256()
+ hobj.update(dns.name.from_text(qname).to_wire())
+ hobj.update(struct.pack('HH',
+ socket.htons(dns.rdatatype.from_text(qtype)),
+ socket.htons(dns.rdataclass.from_text(qclass))))
+ hobj.update(secret)
+ return hobj.hexdigest().upper()
+
+def _redis_get(options, key):
+ import redis
+ return redis.Redis(options.address, int(options.port)).get(key)
+
+def _dump_value(options, qname, key, value):
+ print(';; query=%s/IN/%s' % (qname, options.qtype))
+ print(';; key=%s' % key)
+ if value is None:
+ print(';; no value')
+ return
+ if len(value) < 16:
+ print(';; broken value, short length: %d' % len(value))
+ return
+ now = int(time.time())
+ timestamp = struct.unpack('!Q', value[-16:-8])[0]
+ expire = struct.unpack('!Q', value[-8:])[0]
+ print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
+ (now, timestamp, expire, max(expire - now, 0)))
+ print(dns.message.from_wire(value[:-16]))
+
+def main():
+ parser = OptionParser(usage='usage: %prog [options] query_name')
+ parser.add_option("-a", "--address", dest="address", action="store",
+ default='127.0.0.1', help="backend-server address",
+ metavar='ADDRESS')
+ parser.add_option("-b", "--backend", dest="backend", action="store",
+ default='redis', help="backend name",
+ metavar='BACKEND')
+ parser.add_option("-p", "--port", dest="port", action="store",
+ default='6379', help="backend-server port",
+ metavar='PORT')
+ parser.add_option("-s", "--secret", dest="secret", action="store",
+ default='default', help="secret seed", metavar='SECRET')
+ parser.add_option("-t", "--qtype", dest="qtype", action="store",
+ default='A', help="query RR type", metavar='QTYPE')
+
+ (options, args) = parser.parse_args()
+ if len(args) < 1:
+ parser.error('qname is missing')
+ if options.backend == 'redis':
+ get_func = _redis_get
+ else:
+ raise Exception('unknown backend name: %s\n' % options.backend)
+ key = _calc_hashkey(args[0], options.secret, options.qtype)
+ value = get_func(options, key)
+ _dump_value(options, args[0], key, value)
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Exception as e:
+ sys.stderr.write('%s\n' % e)
+ exit(1)