xref: /netbsd-src/external/bsd/unbound/dist/testdata/pymod_thread.tdir/pymod_thread.py (revision 91f7d55fb697b5e0475da4718fa34c3a3ebeac85)
10cd9f4ecSchristos# -*- coding: utf-8 -*-
20cd9f4ecSchristos'''
30cd9f4ecSchristos ubmodule-msg.py: simple response packet logger
40cd9f4ecSchristos
50cd9f4ecSchristos Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
60cd9f4ecSchristos          Marek Vavrusa  (xvavru00 AT stud.fit.vutbr.cz)
70cd9f4ecSchristos
80cd9f4ecSchristos Copyright (c) 2008. All rights reserved.
90cd9f4ecSchristos
100cd9f4ecSchristos This software is open source.
110cd9f4ecSchristos
120cd9f4ecSchristos Redistribution and use in source and binary forms, with or without
130cd9f4ecSchristos modification, are permitted provided that the following conditions
140cd9f4ecSchristos are met:
150cd9f4ecSchristos
160cd9f4ecSchristos Redistributions of source code must retain the above copyright notice,
170cd9f4ecSchristos this list of conditions and the following disclaimer.
180cd9f4ecSchristos
190cd9f4ecSchristos Redistributions in binary form must reproduce the above copyright notice,
200cd9f4ecSchristos this list of conditions and the following disclaimer in the documentation
210cd9f4ecSchristos and/or other materials provided with the distribution.
220cd9f4ecSchristos
230cd9f4ecSchristos THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
240cd9f4ecSchristos "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
250cd9f4ecSchristos TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
260cd9f4ecSchristos PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
270cd9f4ecSchristos LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
280cd9f4ecSchristos CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
290cd9f4ecSchristos SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
300cd9f4ecSchristos INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
310cd9f4ecSchristos CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
320cd9f4ecSchristos ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
330cd9f4ecSchristos POSSIBILITY OF SUCH DAMAGE.
340cd9f4ecSchristos
350cd9f4ecSchristos Modified for unit test by Wouter Wijngaards, NLnet Labs, 2009.
360cd9f4ecSchristos'''
370cd9f4ecSchristosimport os
380cd9f4ecSchristos
390cd9f4ecSchristosdef init(id, cfg):
40*91f7d55fSchristos    log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
410cd9f4ecSchristos    return True
420cd9f4ecSchristos
430cd9f4ecSchristosdef deinit(id):
440cd9f4ecSchristos    log_info("pythonmod: deinit called, module id is %d" % id)
450cd9f4ecSchristos    return True
460cd9f4ecSchristos
470cd9f4ecSchristosdef inform_super(id, qstate, superqstate, qdata):
480cd9f4ecSchristos    return True
490cd9f4ecSchristos
500cd9f4ecSchristosdef setTTL(qstate, ttl):
510cd9f4ecSchristos    """Sets return_msg TTL and all the RRs TTL"""
520cd9f4ecSchristos    if qstate.return_msg:
530cd9f4ecSchristos        qstate.return_msg.rep.ttl = ttl
540cd9f4ecSchristos        if (qstate.return_msg.rep):
550cd9f4ecSchristos            for i in range(0,qstate.return_msg.rep.rrset_count):
560cd9f4ecSchristos                d = qstate.return_msg.rep.rrsets[i].entry.data
570cd9f4ecSchristos                for j in range(0,d.count+d.rrsig_count):
580cd9f4ecSchristos                    d.rr_ttl[j] = ttl
590cd9f4ecSchristos
600cd9f4ecSchristosdef dataHex(data, prefix=""):
610cd9f4ecSchristos    res = ""
62f42d8de7Schristos    for i in range(0, int((len(data)+15)/16)):
630cd9f4ecSchristos        res += "%s0x%02X | " % (prefix, i*16)
64f42d8de7Schristos        if type(data[0]) == type(1):
65f42d8de7Schristos            d = map(lambda x:int(x), data[i*16:i*16+17])
66f42d8de7Schristos        else:
670cd9f4ecSchristos            d = map(lambda x:ord(x), data[i*16:i*16+17])
680cd9f4ecSchristos        for ch in d:
69f42d8de7Schristos            res += "%02X " % int(ch)
70f42d8de7Schristos        for i in range(0,17-len(data[i*16:i*16+17])):
710cd9f4ecSchristos            res += "   "
720cd9f4ecSchristos        res += "| "
730cd9f4ecSchristos        for ch in d:
740cd9f4ecSchristos            if (ch < 32) or (ch > 127):
750cd9f4ecSchristos                res += ". "
760cd9f4ecSchristos            else:
770cd9f4ecSchristos                res += "%c " % ch
780cd9f4ecSchristos        res += "\n"
790cd9f4ecSchristos    return res
800cd9f4ecSchristos
810cd9f4ecSchristosdef printReturnMsg(qstate):
82f42d8de7Schristos    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))
83f42d8de7Schristos    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)
840cd9f4ecSchristos    if (qstate.return_msg.rep):
85f42d8de7Schristos        print ("RRSets:",qstate.return_msg.rep.rrset_count)
860cd9f4ecSchristos        prevkey = None
870cd9f4ecSchristos        for i in range(0,qstate.return_msg.rep.rrset_count):
880cd9f4ecSchristos            r = qstate.return_msg.rep.rrsets[i]
890cd9f4ecSchristos            rk = r.rk
90f42d8de7Schristos            print (i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags)
91f42d8de7Schristos            print ("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
920cd9f4ecSchristos
930cd9f4ecSchristos            d = r.entry.data
94f42d8de7Schristos            print ("    RRDatas:",d.count+d.rrsig_count)
950cd9f4ecSchristos            for j in range(0,d.count+d.rrsig_count):
96f42d8de7Schristos                print ("    ",j,":","TTL=",d.rr_ttl[j],"RR data:")
97f42d8de7Schristos                print (dataHex(d.rr_data[j],"         "))
980cd9f4ecSchristos
990cd9f4ecSchristos
1000cd9f4ecSchristosdef operate(id, event, qstate, qdata):
1010cd9f4ecSchristos    log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
102f42d8de7Schristos    #print ("pythonmod: per query data", qdata)
1030cd9f4ecSchristos
104f42d8de7Schristos    print ("Query:", qstate.qinfo.qname, qstate.qinfo.qname_list, qstate.qinfo.qname_str)
105f42d8de7Schristos    print ("Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype)
106f42d8de7Schristos    print ("Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass)
107f42d8de7Schristos    print ()
1080cd9f4ecSchristos
1090cd9f4ecSchristos    if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("example.com.")):
110f42d8de7Schristos        print (qstate.qinfo.qname_str)
1110cd9f4ecSchristos
1120cd9f4ecSchristos        qstate.ext_state[id] = MODULE_FINISHED
1130cd9f4ecSchristos
1140cd9f4ecSchristos        # eat time
1150cd9f4ecSchristos        y = 20
1160cd9f4ecSchristos        for z in range(2, 10000):
1170cd9f4ecSchristos                y = y*2 - z/2
1180cd9f4ecSchristos                y = y/2 + z
1190cd9f4ecSchristos
1200cd9f4ecSchristos        msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300)
1210cd9f4ecSchristos        #msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1")
1220cd9f4ecSchristos        #msg.additional.append("yyy.seznam.cz. 10 IN A 1.1.1.2.")
1230cd9f4ecSchristos
1240cd9f4ecSchristos	# answer can be returned to the client without further checking.
1250cd9f4ecSchristos
1260cd9f4ecSchristos        if qstate.qinfo.qtype == RR_TYPE_A:
1270cd9f4ecSchristos            msg.answer.append("%s 10 IN A 192.168.1.1" % qstate.qinfo.qname_str)
1280cd9f4ecSchristos        if (qstate.qinfo.qtype == RR_TYPE_SRV) or (qstate.qinfo.qtype == RR_TYPE_ANY):
1290cd9f4ecSchristos            msg.answer.append("%s 10 IN SRV 0 0 80 neinfo.example.com." % qstate.qinfo.qname_str)
1300cd9f4ecSchristos        if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
1310cd9f4ecSchristos            msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str)
1320cd9f4ecSchristos
1330cd9f4ecSchristos        if not msg.set_return_msg(qstate):
1340cd9f4ecSchristos            qstate.ext_state[id] = MODULE_ERROR
1350cd9f4ecSchristos            return True
1360cd9f4ecSchristos
1370cd9f4ecSchristos        #qstate.return_msg.rep.security = 2 #pokud nebude nasledovat validator, je zapotrebi nastavit security, aby nebyl paket zahozen v mesh_send_reply
1380cd9f4ecSchristos        printReturnMsg(qstate)
1390cd9f4ecSchristos
1400cd9f4ecSchristos        #Authoritative result can't be stored in cache
1410cd9f4ecSchristos        #if (not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0)):
1420cd9f4ecSchristos        #    print "Can't store in cache"
1430cd9f4ecSchristos        #    qstate.ext_state[id] = MODULE_ERROR
1440cd9f4ecSchristos        #    return False
1450cd9f4ecSchristos        #print "Store OK"
1460cd9f4ecSchristos
1470cd9f4ecSchristos        qstate.return_rcode = RCODE_NOERROR
1480cd9f4ecSchristos        return True
1490cd9f4ecSchristos
1500cd9f4ecSchristos    if event == MODULE_EVENT_NEW:
1510cd9f4ecSchristos        qstate.ext_state[id] = MODULE_WAIT_MODULE
1520cd9f4ecSchristos        return True
1530cd9f4ecSchristos
1540cd9f4ecSchristos    if event == MODULE_EVENT_MODDONE:
1550cd9f4ecSchristos        log_info("pythonmod: previous module done")
1560cd9f4ecSchristos        qstate.ext_state[id] = MODULE_FINISHED
1570cd9f4ecSchristos        return True
1580cd9f4ecSchristos
1590cd9f4ecSchristos    if event == MODULE_EVENT_PASS:
1600cd9f4ecSchristos        log_info("pythonmod: event_pass")
1610cd9f4ecSchristos        qstate.ext_state[id] = MODULE_WAIT_MODULE
1620cd9f4ecSchristos        return True
1630cd9f4ecSchristos
1640cd9f4ecSchristos    log_err("pythonmod: BAD event")
1650cd9f4ecSchristos    qstate.ext_state[id] = MODULE_ERROR
1660cd9f4ecSchristos    return True
1670cd9f4ecSchristos
1680cd9f4ecSchristoslog_info("pythonmod: script loaded.")
169