1245803Stheraven#!/usr/bin/env python 2330449Seadler 3330449Seadlerimport hashlib 4245803Stheravenimport sys 5245803Stheravenimport struct 6245803Stheravenimport socket 7245803Stheravenimport time 8245803Stheravenfrom optparse import OptionParser 9245803Stheraven 10245803Stheravenimport dns.message 11245803Stheravenimport dns.name 12245803Stheravenimport dns.rdataclass 13245803Stheravenimport dns.rdatatype 14245803Stheraven 15245803Stheravendef _calc_hashkey(qname, secret, qtype): 16245803Stheraven qclass = 'IN' # CLASS is fixed for simplicity 17245803Stheraven hobj = hashlib.sha256() 18245803Stheraven hobj.update(dns.name.from_text(qname).to_wire()) 19245803Stheraven hobj.update(struct.pack('HH', 20245803Stheraven socket.htons(dns.rdatatype.from_text(qtype)), 21245803Stheraven socket.htons(dns.rdataclass.from_text(qclass)))) 22245803Stheraven hobj.update(secret) 23245803Stheraven return hobj.hexdigest().upper() 24245803Stheraven 25245803Stheravendef _redis_get(options, key): 26245803Stheraven import redis 27245803Stheraven return redis.Redis(options.address, int(options.port)).get(key) 28245803Stheraven 29245803Stheravendef _dump_value(options, qname, key, value): 30245803Stheraven print(';; query=%s/IN/%s' % (qname, options.qtype)) 31245803Stheraven print(';; key=%s' % key) 32245803Stheraven if value is None: 33245803Stheraven print(';; no value') 34245803Stheraven return 35245803Stheraven if len(value) < 16: 36245839Stheraven print(';; broken value, short length: %d' % len(value)) 37245803Stheraven return 38245839Stheraven now = int(time.time()) 39358206Skevans timestamp = struct.unpack('!Q', value[-16:-8])[0] 40245839Stheraven expire = struct.unpack('!Q', value[-8:])[0] 41345881Skevans print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' % 42245803Stheraven (now, timestamp, expire, max(expire - now, 0))) 43318093Sgonzo print(dns.message.from_wire(value[:-16])) 44245839Stheraven 45345881Skevansdef main(): 46345881Skevans parser = OptionParser(usage='usage: %prog [options] query_name') 47345881Skevans parser.add_option("-a", "--address", dest="address", action="store", 48345881Skevans default='127.0.0.1', help="backend-server address", 49345881Skevans metavar='ADDRESS') 50345881Skevans parser.add_option("-b", "--backend", dest="backend", action="store", 51345881Skevans default='redis', help="backend name", 52345881Skevans metavar='BACKEND') 53345881Skevans parser.add_option("-p", "--port", dest="port", action="store", 54345881Skevans default='6379', help="backend-server port", 55345881Skevans metavar='PORT') 56345881Skevans parser.add_option("-s", "--secret", dest="secret", action="store", 57345881Skevans default='default', help="secret seed", metavar='SECRET') 58345881Skevans parser.add_option("-t", "--qtype", dest="qtype", action="store", 59345881Skevans default='A', help="query RR type", metavar='QTYPE') 60345881Skevans 61345881Skevans (options, args) = parser.parse_args() 62345881Skevans if len(args) < 1: 63345881Skevans parser.error('qname is missing') 64345881Skevans if options.backend == 'redis': 65345881Skevans get_func = _redis_get 66345881Skevans else: 67345881Skevans raise Exception('unknown backend name: %s\n' % options.backend) 68245803Stheraven key = _calc_hashkey(args[0], options.secret, options.qtype) 69245803Stheraven value = get_func(options, key) 70245803Stheraven _dump_value(options, args[0], key, value) 71245803Stheraven 72245803Stheravenif __name__ == '__main__': 73245803Stheraven try: 74245803Stheraven main() 75289935Stheraven except Exception as e: 76245803Stheraven sys.stderr.write('%s\n' % e) 77289935Stheraven exit(1) 78245803Stheraven