1.. _example_handler: 2 3Fundamentals 4================ 5 6This basic example shows how to create simple python module which will pass on the requests to the iterator. 7 8How to enable python module 9---------------------------- 10If you look into unbound configuration file, you can find the option `module-config` which specifies the names and the order of modules to be used. 11Example configuration:: 12 13 module-config: "validator python iterator" 14 15As soon as the DNS query arrives, Unbound calls modules starting from leftmost - the validator *(it is the first module on the list)*. 16The validator does not know the answer *(it can only validate)*, thus it will pass on the event to the next module. 17Next module is python which can 18 19 a) generate answer *(response)* 20 When python module generates the response unbound calls validator. Validator grabs the answer and determines the security flag. 21 22 b) pass on the event to the iterator. 23 When iterator resolves the query, Unbound informs python module (event :data:`module_event_moddone`). In the end, when the python module is done, validator is called. 24 25Note that the python module is called with :data:`module_event_pass` event, because new DNS event was already handled by validator. 26 27Another situation occurs when we use the following configuration:: 28 29 module-config: "python validator iterator" 30 31Python module is the first module here, so it's invoked with :data:`module_event_new` event *(new query)*. 32 33On Python module initialization, module loads script from `python-script` option:: 34 35 python-script: "/unbound/test/ubmodule.py" 36 37Simple python module step by step 38--------------------------------- 39 40Script file must contain four compulsory functions: 41 42.. function:: init(id, cfg) 43 44 Initialize module internals, like database etc. 45 Called just once on module load. 46 47 :param id: module identifier (integer) 48 :param cfg: :class:`config_file` configuration structure 49 50:: 51 52 def init(id, cfg): 53 log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script)) 54 return True 55 56 57.. function:: deinit(id) 58 59 Deinitialize module internals. 60 Called just once on module unload. 61 62 :param id: module identifier (integer) 63 64:: 65 66 def deinit(id): 67 log_info("pythonmod: deinit called, module id is %d" % id) 68 return True 69 70 71.. function:: inform_super(id, qstate, superqstate, qdata) 72 73 Inform super querystate about the results from this subquerystate. 74 Is called when the querystate is finished. 75 76 :param id: module identifier (integer) 77 :param qstate: :class:`module_qstate` Query state 78 :param superqstate: :class:`pythonmod_qstate` Mesh state 79 :param qdata: :class:`query_info` Query data 80 81:: 82 83 def inform_super(id, qstate, superqstate, qdata): 84 return True 85 86 87 88.. function:: operate(id, event, qstate, qdata) 89 90 Perform action on pending query. Accepts a new query, or work on pending query. 91 92 You have to set qstate.ext_state on exit. 93 The state informs unbound about result and controls the following states. 94 95 :param id: module identifier (integer) 96 :param qstate: :class:`module_qstate` query state structure 97 :param qdata: :class:`query_info` per query data, here you can store your own data 98 99:: 100 101 def operate(id, event, qstate, qdata): 102 log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event))) 103 if event == MODULE_EVENT_NEW: 104 qstate.ext_state[id] = MODULE_WAIT_MODULE 105 return True 106 107 if event == MODULE_EVENT_MODDONE: 108 qstate.ext_state[id] = MODULE_FINISHED 109 return True 110 111 if event == MODULE_EVENT_PASS: 112 qstate.ext_state[id] = MODULE_WAIT_MODULE 113 return True 114 115 log_err("pythonmod: BAD event") 116 qstate.ext_state[id] = MODULE_ERROR 117 return True 118 119 120Complete source code 121-------------------- 122 123.. literalinclude:: example0-1.py 124 :language: python 125 126As you can see, the source code is much more flexible in contrast to C modules. 127Moreover, compulsory functions called on appropriate module events allows to handle almost 128anything from web control to query analysis. 129 130