]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - pythonmod/ubmodule-tst.py
Apply upstream fix 08968baec1122a58bb90d8f97ad948a75f8a5d69:
[FreeBSD/FreeBSD.git] / pythonmod / ubmodule-tst.py
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 '''
35 def init(id, cfg):
36     log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
37     return True
38
39 def deinit(id):
40     log_info("pythonmod: deinit called, module id is %d" % id)
41     return True
42
43 def inform_super(id, qstate, superqstate, qdata):
44     return True
45
46 def 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
56 def dataHex(data, prefix=""):
57     res = ""
58     for i in range(0, (len(data)+15)/16):
59         res += "%s0x%02X | " % (prefix, i*16)
60         d = map(lambda x:ord(x), data[i*16:i*16+17])
61         for ch in d:
62             res += "%02X " % ch
63         for i in range(0,17-len(d)):
64             res += "   "
65         res += "| "
66         for ch in d:
67             if (ch < 32) or (ch > 127):
68                 res += ". "
69             else:
70                 res += "%c " % ch
71         res += "\n"
72     return res
73
74 def printReturnMsg(qstate):
75     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)
76     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
77     if (qstate.return_msg.rep):
78         print "RRSets:",qstate.return_msg.rep.rrset_count
79         prevkey = None
80         for i in range(0,qstate.return_msg.rep.rrset_count):
81             r = qstate.return_msg.rep.rrsets[i]
82             rk = r.rk
83             print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
84             print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
85
86             d = r.entry.data
87             print "    RRDatas:",d.count+d.rrsig_count
88             for j in range(0,d.count+d.rrsig_count):
89                 print "    ",j,":","TTL=",d.rr_ttl[j],"RR data:"
90                 print dataHex(d.rr_data[j],"         ")
91
92 def operate(id, event, qstate, qdata):
93     log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
94     #print "pythonmod: per query data", qdata
95
96     print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list, 
97     print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype,
98     print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass
99     print
100
101     # TEST:
102     #   > dig @127.0.0.1 www.seznam.cz A
103     #   > dig @127.0.0.1 3.76.75.77.in-addr.arpa. PTR
104     #   prvni dva dotazy vrati TTL 100
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     #   dalsi dva dotazy vrati TTL 10, ktere se bude s dalsimi dotazy snizovat, nez vyprsi a znovu se zaktivuje mesh
108  
109     if qstate.return_msg:
110         printReturnMsg(qstate)
111
112         #qdn = '.'.join(qstate.qinfo.qname_list)
113         qdn = qstate.qinfo.qname_str
114
115         #Pokud dotaz konci na nasledujici, pozmenime TTL zpravy, ktera se posle klientovi (return_msg) i zpravy v CACHE 
116         if qdn.endswith(".seznam.cz.") or qdn.endswith('.in-addr.arpa.'):
117             #pokud je v cache odpoved z iteratoru, pak ji zneplatnime, jinak se moduly nazavolaji do te doby, nez vyprsi TTL
118             invalidateQueryInCache(qstate, qstate.return_msg.qinfo)
119
120             if (qstate.return_msg.rep.authoritative):
121                 print "X"*300
122
123             setTTL(qstate, 10) #do cache nastavime TTL na 10
124             if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):
125                 qstate.ext_state[id] = MODULE_ERROR
126                 return False
127
128             setTTL(qstate, 100) #odpoved klientovi prijde s TTL 100
129             qstate.return_rcode = RCODE_NOERROR
130
131     if event == MODULE_EVENT_NEW:
132         qstate.ext_state[id] = MODULE_WAIT_MODULE 
133         return True
134
135     if event == MODULE_EVENT_MODDONE:
136         log_info("pythonmod: previous module done")
137         qstate.ext_state[id] = MODULE_FINISHED 
138         return True
139       
140     if event == MODULE_EVENT_PASS:
141         log_info("pythonmod: event_pass")
142         qstate.ext_state[id] = MODULE_WAIT_MODULE 
143         return True
144
145     log_err("pythonmod: BAD event")
146     qstate.ext_state[id] = MODULE_ERROR
147     return True
148
149 log_info("pythonmod: script loaded.")