xref: /netbsd-src/external/bsd/unbound/dist/pythonmod/ubmodule-tst.py (revision 91f7d55fb697b5e0475da4718fa34c3a3ebeac85)
1# -*- coding: utf-8 -*-
2'''
3 ubmodule-tst.py:
4
5 Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
6          Marek Vavrusa  (xvavru00 AT stud.fit.vutbr.cz)
7
8 Copyright (c) 2008. All rights reserved.
9
10 This software is open source.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
18
19 Redistributions in binary form must reproduce the above copyright notice,
20 this list of conditions and the following disclaimer in the documentation
21 and/or other materials provided with the distribution.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34'''
35def init(id, cfg):
36    log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
37    return True
38
39def deinit(id):
40    log_info("pythonmod: deinit called, module id is %d" % id)
41    return True
42
43def inform_super(id, qstate, superqstate, qdata):
44    return True
45
46def setTTL(qstate, ttl):
47    """Sets return_msg TTL and all the RRs TTL"""
48    if qstate.return_msg:
49        qstate.return_msg.rep.ttl = ttl
50        if (qstate.return_msg.rep):
51            for i in range(0,qstate.return_msg.rep.rrset_count):
52                d = qstate.return_msg.rep.rrsets[i].entry.data
53                for j in range(0,d.count+d.rrsig_count):
54                    d.rr_ttl[j] = ttl
55
56def dataHex(data, prefix=""):
57    res = ""
58    for i in range(0, int((len(data)+15)/16)):
59        res += "%s0x%02X | " % (prefix, i*16)
60        if type(data[0]) == type(1):
61            d = map(lambda x:int(x), data[i*16:i*16+17])
62        else:
63            d = map(lambda x:ord(x), data[i*16:i*16+17])
64        for ch in d:
65            res += "%02X " % ch
66        for i in range(0,17-len(data[i*16:i*16+17])):
67            res += "   "
68        res += "| "
69        for ch in d:
70            if (ch < 32) or (ch > 127):
71                res += ". "
72            else:
73                res += "%c " % ch
74        res += "\n"
75    return res
76
77def printReturnMsg(qstate):
78    print("Return MSG rep   :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl))
79    print("           qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str)
80    if (qstate.return_msg.rep):
81        print("RRSets:",qstate.return_msg.rep.rrset_count)
82        prevkey = None
83        for i in range(0,qstate.return_msg.rep.rrset_count):
84            r = qstate.return_msg.rep.rrsets[i]
85            rk = r.rk
86            print(i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags)
87            print("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
88
89            d = r.entry.data
90            print("    RRDatas:",d.count+d.rrsig_count)
91            for j in range(0,d.count+d.rrsig_count):
92                print("    ",j,":","TTL=",d.rr_ttl[j],"RR data:")
93                print(dataHex(d.rr_data[j],"         "))
94
95def operate(id, event, qstate, qdata):
96    log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
97    #print("pythonmod: per query data", qdata)
98
99    print("Query:", qstate.qinfo.qname, qstate.qinfo.qname_list, qstate.qinfo.qname_str)
100    print("Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype)
101    print("Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass)
102    print("")
103
104    # TEST:
105    #   > dig @127.0.0.1 www.seznam.cz A
106    #   > dig @127.0.0.1 3.76.75.77.in-addr.arpa. PTR
107    #   prvni dva dotazy vrati TTL 100
108    #   > dig @127.0.0.1 www.seznam.cz A
109    #   > dig @127.0.0.1 3.76.75.77.in-addr.arpa. PTR
110    #   dalsi dva dotazy vrati TTL 10, ktere se bude s dalsimi dotazy snizovat, nez vyprsi a znovu se zaktivuje mesh
111
112    if qstate.return_msg:
113        printReturnMsg(qstate)
114
115        #qdn = '.'.join(qstate.qinfo.qname_list)
116        qdn = qstate.qinfo.qname_str
117
118        #Pokud dotaz konci na nasledujici, pozmenime TTL zpravy, ktera se posle klientovi (return_msg) i zpravy v CACHE
119        if qdn.endswith(".seznam.cz.") or qdn.endswith('.in-addr.arpa.'):
120            #pokud je v cache odpoved z iteratoru, pak ji zneplatnime, jinak se moduly nazavolaji do te doby, nez vyprsi TTL
121            invalidateQueryInCache(qstate, qstate.return_msg.qinfo)
122
123            if (qstate.return_msg.rep.authoritative):
124                print("X"*300)
125
126            setTTL(qstate, 10) #do cache nastavime TTL na 10
127            if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):
128                qstate.ext_state[id] = MODULE_ERROR
129                return False
130
131            setTTL(qstate, 100) #odpoved klientovi prijde s TTL 100
132            qstate.return_rcode = RCODE_NOERROR
133
134    if event == MODULE_EVENT_NEW:
135        qstate.ext_state[id] = MODULE_WAIT_MODULE
136        return True
137
138    if event == MODULE_EVENT_MODDONE:
139        log_info("pythonmod: previous module done")
140        qstate.ext_state[id] = MODULE_FINISHED
141        return True
142
143    if event == MODULE_EVENT_PASS:
144        log_info("pythonmod: event_pass")
145        qstate.ext_state[id] = MODULE_WAIT_MODULE
146        return True
147
148    log_err("pythonmod: BAD event")
149    qstate.ext_state[id] = MODULE_ERROR
150    return True
151
152log_info("pythonmod: script loaded.")
153