diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2012-07-04 14:24:26 +0000 | 
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2012-07-04 14:24:26 +0000 | 
| commit | afb79913ce00d885b8b43f7478e1e054edadb567 (patch) | |
| tree | b9037afac70edd3c6342318cedbbadc648b799ca /pythonmod/doc | |
Diffstat (limited to 'pythonmod/doc')
| -rw-r--r-- | pythonmod/doc/_static/readme | 1 | ||||
| -rw-r--r-- | pythonmod/doc/conf.py | 179 | ||||
| -rw-r--r-- | pythonmod/doc/examples/example0-1.py | 37 | ||||
| -rw-r--r-- | pythonmod/doc/examples/example0.rst | 129 | ||||
| -rw-r--r-- | pythonmod/doc/examples/example1.rst | 42 | ||||
| -rw-r--r-- | pythonmod/doc/examples/example2.rst | 46 | ||||
| -rw-r--r-- | pythonmod/doc/examples/example3.rst | 63 | ||||
| -rw-r--r-- | pythonmod/doc/examples/example4.rst | 164 | ||||
| -rw-r--r-- | pythonmod/doc/examples/index.rst | 15 | ||||
| -rw-r--r-- | pythonmod/doc/index.rst | 34 | ||||
| -rw-r--r-- | pythonmod/doc/install.rst | 59 | ||||
| -rw-r--r-- | pythonmod/doc/modules/config.rst | 350 | ||||
| -rw-r--r-- | pythonmod/doc/modules/env.rst | 412 | ||||
| -rw-r--r-- | pythonmod/doc/modules/functions.rst | 120 | ||||
| -rw-r--r-- | pythonmod/doc/modules/index.rst | 11 | ||||
| -rw-r--r-- | pythonmod/doc/modules/struct.rst | 427 | ||||
| -rw-r--r-- | pythonmod/doc/usecase.rst | 38 | 
17 files changed, 2127 insertions, 0 deletions
| diff --git a/pythonmod/doc/_static/readme b/pythonmod/doc/_static/readme new file mode 100644 index 000000000000..db676aebbde9 --- /dev/null +++ b/pythonmod/doc/_static/readme @@ -0,0 +1 @@ +this directory exists to pacify sphinx-build. diff --git a/pythonmod/doc/conf.py b/pythonmod/doc/conf.py new file mode 100644 index 000000000000..bc7a5aba68d5 --- /dev/null +++ b/pythonmod/doc/conf.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# +# Unbound scripting interface documentation build configuration file +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). +# +# All configuration values have a default value; values that are commented out +# serve to show the default value. + +import sys, os + +# If your extensions are in another directory, add it here. If the directory +# is relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../..'))) +#print sys.path + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General substitutions. +project = 'Unbound scriptable interface' +copyright = '2009, Zdenek Vasicek, Marek Vavrusa' + +# The default replacements for |version| and |release|, also used in various +# other places throughout the built documents. +# +# The short X.Y version. +version = '1.0' +# The full version, including alpha/beta/rc tags. +release = '1.0.0' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directories, that shouldn't be searched +# for source files. +#exclude_dirs = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# Options for HTML output +# ----------------------- + +# The style sheet to use for HTML and HTML Help pages. A file of that name +# must exist either in Sphinx' static/ path, or in one of the custom paths +# given in html_static_path. +html_style = 'default.css' + +# The name for this set of Sphinx documents.  If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar.  Default is the same as html_title. +#html_short_title = None + +# The name of an image file (within the static path) to place at the top of +# the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +html_use_modindex = False + +# If false, no index is generated. +html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, the reST sources are included in the HTML build as _sources/<name>. +html_copy_source = False + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it.  The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'unbound_interface' + + +# Options for LaTeX output +# ------------------------ + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +latex_documents = [ +  ('index', 'Unbound_interface.tex', 'Unbound scriptable interface', +   'Zdenek Vasicek, Marek Vavrusa', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True diff --git a/pythonmod/doc/examples/example0-1.py b/pythonmod/doc/examples/example0-1.py new file mode 100644 index 000000000000..98a9acccdeaf --- /dev/null +++ b/pythonmod/doc/examples/example0-1.py @@ -0,0 +1,37 @@ + +print mod_env.fname   # Print module script name +mod_env.data = "test" # Store global module data + +def init(id, cfg): +   log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script)) +   return True + +def deinit(id): +   log_info("pythonmod: deinit called, module id is %d" % id) +   return True + +def inform_super(id, qstate, superqstate, qdata): +   return True + +def operate(id, event, qstate, qdata): +   log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event))) + +   if event == MODULE_EVENT_NEW: +      qstate.ext_state[id] = MODULE_WAIT_MODULE  +      return True + +   if event == MODULE_EVENT_MODDONE: +      log_info("pythonmod: module we are waiting for is done") +      qstate.ext_state[id] = MODULE_FINISHED  +      return True + +   if event == MODULE_EVENT_PASS: +      log_info("pythonmod: event_pass") +      qstate.ext_state[id] = MODULE_ERROR  +      return True + +   log_err("pythonmod: BAD event") +   qstate.ext_state[id] = MODULE_ERROR +   return True + +log_info("pythonmod: script loaded.") diff --git a/pythonmod/doc/examples/example0.rst b/pythonmod/doc/examples/example0.rst new file mode 100644 index 000000000000..80eca5ea6ebb --- /dev/null +++ b/pythonmod/doc/examples/example0.rst @@ -0,0 +1,129 @@ +.. _example_handler: + +Fundamentals +================ + +This basic example shows how to create simple python module which will pass on the requests to the iterator. + +How to enable python module +---------------------------- +If 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. +Example configuration:: + +	module-config: "validator python iterator" + +As soon as the DNS query arrives, Unbound calls modules starting from leftmost - the validator *(it is the first module on the list)*. +The validator does not know the answer *(it can only validate)*, thus it will pass on the event to the next module. +Next module is python which can + +	a) generate answer *(response)* +		When python module generates the response unbound calls validator. Validator grabs the answer and determines the security flag. + +	b) pass on the event to the iterator. +		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. + +Note that the python module is called with :data:`module_event_pass` event, because new DNS event was already handled by validator. + +Another situation occurs when we use the following configuration:: + +	module-config: "python validator iterator" + +Python module is the first module here, so it's invoked with :data:`module_event_new` event *(new query)*. + +On Python module initialization, module loads script from `python-script` option:: + +	python-script: "/unbound/test/ubmodule.py" + +Simple python module step by step +--------------------------------- + +Script file must contain four compulsory functions: + +.. function:: init(id, cfg) + +   Initialize module internals, like database etc. +   Called just once on module load. + +   :param id: module identifier (integer) +   :param cfg: :class:`config_file` configuration structure + +:: + +   def init(id, cfg): +      log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script)) +      return True + + +.. function:: deinit(id) + +   Deinitialize module internals. +   Called just once on module unload. + +   :param id: module identifier (integer) + +:: + +   def deinit(id): +      log_info("pythonmod: deinit called, module id is %d" % id) +      return True + + +.. function:: inform_super(id, qstate, superqstate, qdata) + +   Inform super querystate about the results from this subquerystate. +   Is called when the querystate is finished. + +   :param id: module identifier (integer) +   :param qstate: :class:`module_qstate` Query state +   :param superqstate: :class:`pythonmod_qstate` Mesh state +   :param qdata: :class:`query_info` Query data + +:: + +   def inform_super(id, qstate, superqstate, qdata): +      return True + + + +.. function:: operate(id, event, qstate, qdata) + +   Perform action on pending query. Accepts a new query, or work on pending query. + +   You have to set qstate.ext_state on exit. +   The state informs unbound about result and controls the following states. + +   :param id: module identifier (integer) +   :param qstate: :class:`module_qstate` query state structure +   :param qdata: :class:`query_info` per query data, here you can store your own data + +:: + +   def operate(id, event, qstate, qdata): +      log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event))) +      if event == MODULE_EVENT_NEW: +         qstate.ext_state[id] = MODULE_WAIT_MODULE  +         return True + +      if event == MODULE_EVENT_MODDONE: +         qstate.ext_state[id] = MODULE_FINISHED  +         return True + +      if event == MODULE_EVENT_PASS: +         qstate.ext_state[id] = MODULE_ERROR  +         return True + +      log_err("pythonmod: BAD event") +      qstate.ext_state[id] = MODULE_ERROR +      return True + + +Complete source code +-------------------- + +..	literalinclude:: example0-1.py +	:language: python + +As you can see, the source code is much more flexible in contrast to C modules.  +Moreover, compulsory functions called on appropriate module events allows to handle almost +anything from web control to query analysis. + diff --git a/pythonmod/doc/examples/example1.rst b/pythonmod/doc/examples/example1.rst new file mode 100644 index 000000000000..b49e64409255 --- /dev/null +++ b/pythonmod/doc/examples/example1.rst @@ -0,0 +1,42 @@ +.. _log_handler: + +Packet logger +========================= + +This example shows how to log and print details about query and response. +As soon as the ``iterator`` has finished (event is :data:`module_event_moddone`), ``qstate.return_msg`` contains response packet or ``None``. +This packet will be send to a client that asked for it. + +Complete source code +-------------------- + +.. literalinclude:: ../../examples/log.py +   :language: python + +Testing +------------------ +Run the unbound server: + +``root@localhost>unbound -dv -c ./test-log.conf`` + +In case you use own configuration file, don't forget to enable python module: ``module-config: "validator python iterator"`` and use valid script path: ``python-script: "./examples/log.py"``. + +Example of output::	 + +   [1231790168] unbound[7941:0] info: response for <f.gtld-servers.NET. AAAA IN> +   [1231790168] unbound[7941:0] info: reply from <gtld-servers.NET.> 192.5.6.31#53 +   [1231790168] unbound[7941:0] info: query response was ANSWER +   [1231790168] unbound[7941:0] info: pythonmod: operate called, id: 1, event:module_event_moddone +   ---------------------------------------------------------------------------------------------------- +   Query: f.gtld-servers.NET., type: AAAA (28), class: IN (1)  +   ---------------------------------------------------------------------------------------------------- +   Return    reply :: flags: 8080, QDcount: 1, Security:0, TTL=86400 +             qinfo :: qname: ['f', 'gtld-servers', 'NET', ''] f.gtld-servers.NET., qtype: AAAA, qclass: IN +   Reply: +   0 : ['gtld-servers', 'NET', ''] gtld-servers.NET. flags: 0000 type: SOA (6) class: IN (1) +      0 : TTL= 86400 +          0x00 | 00 3A 02 41 32 05 4E 53 54 4C 44 03 43 4F 4D 00 05 | . : . A 2 . N S T L D . C O M . .  +          0x10 | 05 6E 73 74 6C 64 0C 76 65 72 69 73 69 67 6E 2D 67 | . n s t l d . v e r i s i g n - g  +          0x20 | 67 72 73 03 43 4F 4D 00 77 74 2D 64 00 00 0E 10 00 | g r s . C O M . w t - d . . . . .  +          0x30 | 00 00 03 84 00 12 75 00 00 01 51 80                | . . . . . . u . . . Q .  + diff --git a/pythonmod/doc/examples/example2.rst b/pythonmod/doc/examples/example2.rst new file mode 100644 index 000000000000..f00fcc239609 --- /dev/null +++ b/pythonmod/doc/examples/example2.rst @@ -0,0 +1,46 @@ +Response generation +===================== + +This example shows how to handle queries and generate response packet. + +.. note:: +   If the python module is the first module and validator module is enabled (``module-config: "python validator iterator"``), +   a return_msg security flag has to be set at least to 2. Leaving security flag untouched causes that the +   response will be refused by unbound worker as unbound will consider it as non-valid response. + +Complete source code +-------------------- + +.. literalinclude:: ../../examples/resgen.py +   :language: python + +Testing +------- + +Run the unbound server: + +``root@localhost>unbound -dv -c ./test-resgen.conf`` + +Query for a A record ending with .localdomain + +``dig A test.xxx.localdomain @127.0.0.1`` + +Dig produces the following output:: + +	;; global options:  printcmd +	;; Got answer: +	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48426 +	;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 +	 +	;; QUESTION SECTION: +	;test.xxx.localdomain.		IN	A +	 +	;; ANSWER SECTION: +	test.xxx.localdomain.	10	IN	A	127.0.0.1 +	 +	;; Query time: 2 msec +	;; SERVER: 127.0.0.1#53(127.0.0.1) +	;; WHEN: Mon Jan 01 12:46:02 2009 +	;; MSG SIZE  rcvd: 54 + +As we handle (override) in python module only queries ending with "localdomain.", the unboud can still resolve host names. diff --git a/pythonmod/doc/examples/example3.rst b/pythonmod/doc/examples/example3.rst new file mode 100644 index 000000000000..6213dc188f12 --- /dev/null +++ b/pythonmod/doc/examples/example3.rst @@ -0,0 +1,63 @@ +Response modification +===================== + +This example shows how to modify the response produced by the ``iterator`` module. + +As soon as the iterator module returns the response, we : + +1. invalidate the data in cache +2. modify the response *TTL* +3. rewrite the data in cache +4. return modified packet + +Note that the steps 1 and 3 are neccessary only in case, the python module is the first module in the processing chain. +In other cases, the validator module guarantees updating data which are produced by iterator module. + +Complete source code +-------------------- + +.. literalinclude:: ../../examples/resmod.py +   :language: python + +Testing +------- + +Run Unbound server: + +``root@localhost>unbound -dv -c ./test-resmod.conf`` + +Issue a query for name ending with "nic.cz." + +``>>>dig A @127.0.0.1 www.nic.cz`` + +:: + +	;; global options:  printcmd +	;; Got answer: +	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48831 +	;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5 +	 +	;; QUESTION SECTION: +	;www.nic.cz.			IN	A +	 +	;; ANSWER SECTION: +	www.nic.cz.		10	IN	A	217.31.205.50 +	 +	;; AUTHORITY SECTION: +	nic.cz.			10	IN	NS	e.ns.nic.cz. +	nic.cz.			10	IN	NS	a.ns.nic.cz. +	nic.cz.			10	IN	NS	c.ns.nic.cz. +	 +	;; ADDITIONAL SECTION: +	a.ns.nic.cz.		10	IN	A	217.31.205.180 +	a.ns.nic.cz.		10	IN	AAAA	2001:1488:dada:176::180 +	c.ns.nic.cz.		10	IN	A	195.66.241.202 +	c.ns.nic.cz.		10	IN	AAAA	2a01:40:1000::2 +	e.ns.nic.cz.		10	IN	A	194.146.105.38 +	 +	;; Query time: 166 msec +	;; SERVER: 127.0.0.1#53(127.0.0.1) +	;; WHEN: Mon Jan 02 13:39:43 2009 +	;; MSG SIZE  rcvd: 199 + +As you can see, TTL of all the records is set to 10. diff --git a/pythonmod/doc/examples/example4.rst b/pythonmod/doc/examples/example4.rst new file mode 100644 index 000000000000..6cc484797826 --- /dev/null +++ b/pythonmod/doc/examples/example4.rst @@ -0,0 +1,164 @@ +DNS-based language dictionary +=============================== + +This example shows how to create a simple language dictionary based on **DNS** +service within 15 minutes. The translation will be performed using TXT resource records. + +Key parts +----------- + +Initialization +~~~~~~~~~~~~~~~~~~~~~~~ +On **init()** module loads dictionary from a text file containing records in ``word [tab] translation`` format. +:: + +   def init(id, cfg): +      log_info("pythonmod: dict init") +      f = open("examples/dict_data.txt", "r") +      ... + +The suitable file can be found at http://slovnik.zcu.cz + +DNS query and word lookup +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's define the following format od DNS queries: ``word1[.]word2[.] ... wordN[.]{en,cs}[._dict_.cz.]``. +Word lookup is done by simple ``dict`` lookup from broken DNS request. +Query name is divided into a list of labels. This list is accesible as qname_list attribute. +:: + +   aword = ' '.join(qstate.qinfo.qname_list[0:-4]) #skip last four labels +   adict = qstate.qinfo.qname_list[-4] #get 4th label from the end + +   words = [] #list of words +   if (adict == "en") and (aword in en_dict): +      words = en_dict[aword]  + +   if (adict == "cs") and (aword in cz_dict): +      words = cz_dict[aword] # CS -> EN + +In the first step, we get a string in the form: ``word1[space]word2[space]...word[space]``. +In the second assignment, fourth label from the end is obtained. This label should contains *"cs"* or *"en"*. +This label determines the direction of translation. + + +Forming of a DNS reply +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +DNS reply is formed only on valid match and added as TXT answer. +:: + +	msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_AA) + +	for w in words: +		msg.answer.append("%s 300 IN TXT \"%s\"" % (qstate.qinfo.qname_str, w.replace("\"", "\\\""))) + +	if not msg.set_return_msg(qstate): +		qstate.ext_state[id] = MODULE_ERROR  +		return True + +	qstate.return_rcode = RCODE_NOERROR +	qstate.ext_state[id] = MODULE_FINISHED  +	return True + +In the first step, a :class:`DNSMessage` instance is created for a given query *(type TXT)*. +The fourth argument specifies the flags *(authoritative answer)*. +In the second step, we append TXT records containing the translation *(on the right side of RR)*. +Then, the response is finished and ``qstate.return_msg`` contains new response. +If no error, the module sets :attr:`module_qstate.return_rcode` and :attr:`module_qstate.ext_state`. + +**Steps:** + +1. create :class:`DNSMessage` instance +2. append TXT records containing the translation +3. set response to ``qstate.return_msg`` + +Testing +------- + +Run the Unbound server: + +``root@localhost>unbound -dv -c ./test-dict.conf`` + +In case you use own configuration file, don't forget to enable Python module:: + +	module-config: "validator python iterator" + +and use valid script path:: + +	python-script: "./examples/dict.py" + +The translation from english word *"a bar fly"* to Czech can be done by doing: + +``>>>dig TXT @127.0.0.1 a.bar.fly.en._dict_.cz`` + +::	 + +	; (1 server found) +	;; global options:  printcmd +	;; Got answer: +	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48691 +	;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 +	 +	;; QUESTION SECTION: +	;a.bar.fly.en._dict_.cz.		IN	TXT +	 +	;; ANSWER SECTION: +	a.bar.fly.en._dict_.cz.	300	IN	TXT	"barov\253 povale\232" +	 +	;; Query time: 5 msec +	;; SERVER: 127.0.0.1#53(127.0.0.1) +	;; WHEN: Mon Jan 01 17:44:18 2009 +	;; MSG SIZE  rcvd: 67 +	 +``>>>dig TXT @127.0.0.1 nic.cs._dict_.cz`` +:: +	 +	; <<>> DiG 9.5.0-P2 <<>> TXT @127.0.0.1 nic.cs._dict_.cz +	; (1 server found) +	;; global options:  printcmd +	;; Got answer: +	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58710 +	;; flags: aa rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0 +	 +	;; QUESTION SECTION: +	;nic.cs._dict_.cz.		IN	TXT +	 +	;; ANSWER SECTION: +	nic.cs._dict_.cz.	300	IN	TXT	"aught" +	nic.cs._dict_.cz.	300	IN	TXT	"naught" +	nic.cs._dict_.cz.	300	IN	TXT	"nihil" +	nic.cs._dict_.cz.	300	IN	TXT	"nix" +	nic.cs._dict_.cz.	300	IN	TXT	"nothing" +	nic.cs._dict_.cz.	300	IN	TXT	"zilch" +	 +	;; Query time: 0 msec +	;; SERVER: 127.0.0.1#53(127.0.0.1) +	;; WHEN: Mon Jan 01 17:45:39 2009 +	;; MSG SIZE  rcvd: 143 + +Proof that the unbound still works as resolver. + +``>>>dig A @127.0.0.1 www.nic.cz`` +:: + +	; (1 server found) +	;; global options:  printcmd +	;; Got answer: +	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19996 +	;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5 +	 +	;; QUESTION SECTION: +	;www.nic.cz.			IN	A +	 +	;; ANSWER SECTION: +	www.nic.cz.		1662	IN	A	217.31.205.50 +	 +	;; AUTHORITY SECTION: +	... + +Complete source code +-------------------- + +.. literalinclude:: ../../examples/dict.py +   :language: python diff --git a/pythonmod/doc/examples/index.rst b/pythonmod/doc/examples/index.rst new file mode 100644 index 000000000000..6c50225810ef --- /dev/null +++ b/pythonmod/doc/examples/index.rst @@ -0,0 +1,15 @@ +.. _Tutorials: + +============================== +Tutorials +============================== + +Here you can find several tutorials which clarify the usage and capabilities of Unbound scriptable interface.  + +`Tutorials` + +.. toctree:: +	:maxdepth: 2 +	:glob: + +	example* diff --git a/pythonmod/doc/index.rst b/pythonmod/doc/index.rst new file mode 100644 index 000000000000..fe9bcf42b962 --- /dev/null +++ b/pythonmod/doc/index.rst @@ -0,0 +1,34 @@ +Unbound scriptable interface +======================================= + +Python module for **Unbound** provides easy-to-use flexible solution, +for scripting query events and much more! + +Along with extensible **SWIG** interface, it turns **Unbound** into dynamic *DNS* service +designed for rapid development of *DNS* based applications, like detailed *(per query/domain)* statistics, +monitoring with anything Python can offer *(database backend, http server)*. + +**Key features** +   * Rapid dynamic DNS-based application development in **Python** +   * Extensible interface with **SWIG** +   * Easy to use debugging and analysis tool +   * Capable to produce authoritative answers +   * Support for logging or doing detailed statistics +   * Allows to manipulate with content of cache memory + +Contents +-------- +.. toctree:: +   :maxdepth: 2 + +   install +   examples/index +   usecase +   modules/index + +Indices and tables +------------------- + +* :ref:`genindex` +* :ref:`search` + diff --git a/pythonmod/doc/install.rst b/pythonmod/doc/install.rst new file mode 100644 index 000000000000..991e2b4becf9 --- /dev/null +++ b/pythonmod/doc/install.rst @@ -0,0 +1,59 @@ +Installation +=================================== + +**Prerequisites** + +Python 2.4 or higher, SWIG 1.3 or higher, GNU make + +**Download** + +You can download the source codes `here`_. +The latest release is 1.1.1, Jan 15, 2009. + +.. _here: unbound-1.1.1-py.tar.gz + +**Compiling** + +After downloading, you can compile the Unbound library by doing:: + +	> tar -xzf unbound-1.1.1-py.tar.gz +	> cd unbound-1.1.1 +	> ./configure --with-pythonmodule +	> make + +You need GNU make to compile sources. +SWIG and Python devel libraries to compile extension module.  + +**Testing** + +If the compilation is successful, you can test the extension module by:: + +	> cd pythonmod +	> make sudo # or "make test" or "make suexec" + +This will start unbound server with language dictionary service (see :ref:`Tutorials`). +In order to test this service, type:: +   +   > dig TXT @127.0.0.1 aught.en._dict_.cz + +Dig should print this message (czech equivalent of aught):: + +   ; <<>> DiG 9.5.0-P2 <<>> TXT @127.0.0.1 aught.en._dict_.cz +   ; (1 server found) +   ;; global options:  printcmd +   ;; Got answer: +   ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30085 +   ;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 +    +   ;; QUESTION SECTION: +   ;aught.en._dict_.cz.		IN	TXT +    +   ;; ANSWER SECTION: +   aught.en._dict_.cz.	300	IN	TXT	"nic" +    +   ;; Query time: 11 msec +   ;; SERVER: 127.0.0.1#53(127.0.0.1) +   ;; WHEN: Thu Jan 10 16:45:58 2009 +   ;; MSG SIZE  rcvd: 52 + +The ``pythonmod/examples`` directory contains simple applications written in Python. diff --git a/pythonmod/doc/modules/config.rst b/pythonmod/doc/modules/config.rst new file mode 100644 index 000000000000..1277bceddf90 --- /dev/null +++ b/pythonmod/doc/modules/config.rst @@ -0,0 +1,350 @@ +Configuration interface +======================= + +Currently passed to Python module in init(module_id, cfg). + +config_file +-------------------- + +.. class:: config_file + +   This class provides these data attributes: + +   .. attribute:: verbosity +    +      Verbosity level as specified in the config file. + +   .. attribute:: stat_interval +    +      Statistics interval (in seconds). +    +   .. attribute:: stat_cumulative +    +      If false, statistics values are reset after printing them. +    +   .. attribute:: stat_extended +    +      If true, the statistics are kept in greater detail. + +   .. attribute:: num_threads +    +      Number of threads to create. + +   .. attribute:: port +    +      Port on which queries are answered. + +   .. attribute:: do_ip4 +    +      Do ip4 query support. + +   .. attribute:: do_ip6 +    +      Do ip6 query support. + +   .. attribute:: do_udp +    +      Do udp query support. +    +   .. attribute:: do_tcp +    +      Do tcp query support. + +   .. attribute:: outgoing_num_ports +    +      Outgoing port range number of ports (per thread). + +   .. attribute:: outgoing_num_tcp +    +      Number of outgoing tcp buffers per (per thread). + +   .. attribute:: incoming_num_tcp +    +      Number of incoming tcp buffers per (per thread). + +   .. attribute:: outgoing_avail_ports +    +      Allowed udp port numbers, array with 0 if not allowed. + +   .. attribute:: msg_buffer_size +    +      Number of bytes buffer size for DNS messages. + +   .. attribute:: msg_cache_size +    +      Size of the message cache. +    +   .. attribute:: msg_cache_slabs +    +      Slabs in the message cache. +    +   .. attribute:: num_queries_per_thread +    +      Number of queries every thread can service. +    +   .. attribute:: jostle_time +    +      Number of msec to wait before items can be jostled out. +    +   .. attribute:: rrset_cache_size +    +      Size of the rrset cache. +    +   .. attribute:: rrset_cache_slabs +    +      Slabs in the rrset cache. +    +   .. attribute:: host_ttl +    +      Host cache ttl in seconds. + +   .. attribute:: lame_ttl +    +      Host is lame for a zone ttl, in seconds. + +   .. attribute:: infra_cache_slabs +    +      Number of slabs in the infra host cache. +    +   .. attribute:: infra_cache_numhosts +    +      Max number of hosts in the infra cache. +    +   .. attribute:: infra_cache_lame_size +    +      Max size of lame zones per host in the infra cache. + +   .. attribute:: target_fetch_policy +    +      The target fetch policy for the iterator. + +   .. attribute:: if_automatic +    +      Automatic interface for incoming messages. Uses ipv6 remapping, +      and recvmsg/sendmsg ancillary data to detect interfaces, boolean. +    +   .. attribute:: num_ifs +    +      Number of interfaces to open. If 0 default all interfaces. +    +   .. attribute:: ifs +    +      Interface description strings (IP addresses). + +   .. attribute:: num_out_ifs +    +      Number of outgoing interfaces to open.  +      If 0 default all interfaces. + +   .. attribute:: out_ifs +    +      Outgoing interface description strings (IP addresses). +       +   .. attribute:: root_hints +    +      The root hints. +    +   .. attribute:: stubs +    +      The stub definitions, linked list. +    +   .. attribute:: forwards +    +      The forward zone definitions, linked list. +    +   .. attribute:: donotqueryaddrs +    +      List of donotquery addresses, linked list. +    +   .. attribute:: acls +    +      List of access control entries, linked list. +    +   .. attribute:: donotquery_localhost +    +      Use default localhost donotqueryaddr entries. + +   .. attribute:: harden_short_bufsize +    +      Harden against very small edns buffer sizes. +    +   .. attribute:: harden_large_queries +    +      Harden against very large query sizes. +    +   .. attribute:: harden_glue +    +      Harden against spoofed glue (out of zone data). +    +   .. attribute:: harden_dnssec_stripped +    +      Harden against receiving no DNSSEC data for trust anchor. +    +   .. attribute:: harden_referral_path +    +      Harden the referral path, query for NS,A,AAAA and validate. +    +   .. attribute:: use_caps_bits_for_id +    +      Use 0x20 bits in query as random ID bits. +    +   .. attribute:: private_address +    +      Strip away these private addrs from answers, no DNS Rebinding. +    +   .. attribute:: private_domain +    +      Allow domain (and subdomains) to use private address space. +    +   .. attribute:: unwanted_threshold +    +      What threshold for unwanted action. + +   .. attribute:: chrootdir +    +      Chrootdir, if not "" or chroot will be done. +    +   .. attribute:: username +    +      Username to change to, if not "". +    +   .. attribute:: directory +    +      Working directory. +    +   .. attribute:: logfile +    +      Filename to log to. +    +   .. attribute:: pidfile +    +      Pidfile to write pid to. + +   .. attribute:: use_syslog +    +      Should log messages be sent to syslogd. + +   .. attribute:: hide_identity +    +      Do not report identity (id.server, hostname.bind). +    +   .. attribute:: hide_version +    +      Do not report version (version.server, version.bind). +    +   .. attribute:: identity +    +      Identity, hostname is returned if "". +    +   .. attribute:: version +    +      Version, package version returned if "". + +   .. attribute:: module_conf +    +      The module configuration string. +    +   .. attribute:: trust_anchor_file_list +    +      Files with trusted DS and DNSKEYs in zonefile format, list. +    +   .. attribute:: trust_anchor_list +    +      List of trustanchor keys, linked list. +    +   .. attribute:: trusted_keys_file_list +    +      Files with trusted DNSKEYs in named.conf format, list. +    +   .. attribute:: dlv_anchor_file +    +      DLV anchor file. +    +   .. attribute:: dlv_anchor_list +    +      DLV anchor inline. + +   .. attribute:: max_ttl +    +      The number of seconds maximal TTL used for RRsets and messages. +    +   .. attribute:: val_date_override +    +      If not 0, this value is the validation date for RRSIGs. +    +   .. attribute:: bogus_ttl  +    +      This value sets the number of seconds before revalidating bogus. +    +   .. attribute:: val_clean_additional +    +      Should validator clean additional section for secure msgs. +    +   .. attribute:: val_permissive_mode +    +      Should validator allow bogus messages to go through. +    +   .. attribute:: val_nsec3_key_iterations +    +      Nsec3 maximum iterations per key size, string. +    +   .. attribute:: key_cache_size +    +      Size of the key cache. +    +   .. attribute:: key_cache_slabs +    +      Slabs in the key cache. +    +   .. attribute:: neg_cache_size +    +      Size of the neg cache. + +    +   .. attribute:: local_zones +    +      Local zones config. +    +   .. attribute:: local_zones_nodefault +    +      Local zones nodefault list. +    +   .. attribute:: local_data +    +      Local data RRs configged. + +   .. attribute:: remote_control_enable +    +      Remote control section. enable toggle. +    +   .. attribute:: control_ifs +    +      The interfaces the remote control should listen on. +    +   .. attribute:: control_port +    +      Port number for the control port. +    +   .. attribute:: server_key_file +    +      Private key file for server. +    +   .. attribute:: server_cert_file +    +      Certificate file for server. +    +   .. attribute:: control_key_file +    +      Private key file for unbound-control. +    +   .. attribute:: control_cert_file +    +      Certificate file for unbound-control. + +   .. attribute:: do_daemonize +    +      Daemonize, i.e. fork into the background. + +   .. attribute:: python_script +    +      Python script file. diff --git a/pythonmod/doc/modules/env.rst b/pythonmod/doc/modules/env.rst new file mode 100644 index 000000000000..42dbbd1cfa3b --- /dev/null +++ b/pythonmod/doc/modules/env.rst @@ -0,0 +1,412 @@ +Global environment +================== + +Global variables +---------------- + +.. envvar:: mod_env + +   Module environment, contains data pointer for module-specific data. +   See :class:`pythonmod_env`. + + +Predefined constants +----------------------- + +Module extended state +~~~~~~~~~~~~~~~~~~~~~~~ + +.. data:: module_state_initial + +   Initial state - new DNS query. + +.. data:: module_wait_reply + +   Waiting for reply to outgoing network query. + +.. data:: module_wait_module + +   Module is waiting for another module. +    +.. data:: module_wait_subquery + +   Module is waiting for sub-query. +    +.. data:: module_error + +   Module could not finish the query. +    +.. data:: module_finished + +   Module is finished with query. + +Module event +~~~~~~~~~~~~~ +.. data:: module_event_new + +   New DNS query. +    +.. data:: module_event_pass + +   Query passed by other module. +    +.. data:: module_event_reply + +   Reply inbound from server. +    +.. data:: module_event_noreply + +   No reply, timeout or other error. +    +.. data:: module_event_capsfail + +   Reply is there, but capitalisation check failed. +    +.. data:: module_event_moddone + +   Next module is done, and its reply is awaiting you. +    +.. data:: module_event_error + +   Error occured. + +Security status +~~~~~~~~~~~~~~~~ + +.. data:: sec_status_unchecked + +   Means that object has yet to be validated. + +.. data:: sec_status_bogus + +   Means that the object *(RRset or message)* failed to validate +   *(according to local policy)*, but should have validated. +    +.. data:: sec_status_indeterminate + +   Means that the object is insecure, but not  +   authoritatively so. Generally this means that the RRset is not  +   below a configured trust anchor. +    +.. data:: sec_status_insecure + +   Means that the object is authoritatively known to be  +   insecure. Generally this means that this RRset is below a trust  +   anchor, but also below a verified, insecure delegation. + +.. data:: sec_status_secure + +   Means that the object (RRset or message) validated according to local policy. + +Resource records (RR sets) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The different RR classes. + +   .. data:: RR_CLASS_IN +    +      Internet. +       +   .. data:: RR_CLASS_CH +    +      Chaos. +       +   .. data:: RR_CLASS_HS +    +      Hesiod (Dyer 87) +       +   .. data:: RR_CLASS_NONE +    +      None class, dynamic update. +       +   .. data:: RR_CLASS_ANY +       +      Any class. +    + +The different RR types. + + +   .. data:: RR_TYPE_A  +    +      A host address. +       +   .. data:: RR_TYPE_NS +    +      An authoritative name server. +       +   .. data:: RR_TYPE_MD  +       +      A mail destination (Obsolete - use MX). +       +   .. data:: RR_TYPE_MF  +    +      A mail forwarder (Obsolete - use MX). +       +   .. data:: RR_TYPE_CNAME  +       +      The canonical name for an alias. +       +   .. data:: RR_TYPE_SOA  +       +      Marks the start of a zone of authority. +       +   .. data:: RR_TYPE_MB  +       +      A mailbox domain name (EXPERIMENTAL). +       +   .. data:: RR_TYPE_MG  +       +      A mail group member (EXPERIMENTAL). +       +   .. data:: RR_TYPE_MR  +       +      A mail rename domain name (EXPERIMENTAL). +       +   .. data:: RR_TYPE_NULL +       +      A null RR (EXPERIMENTAL). +       +   .. data:: RR_TYPE_WKS +       +      A well known service description. +       +   .. data:: RR_TYPE_PTR +    +      A domain name pointer. +       +   .. data:: RR_TYPE_HINFO +    +      Host information. +       +   .. data:: RR_TYPE_MINFO +    +      Mailbox or mail list information. +       +   .. data:: RR_TYPE_MX +    +      Mail exchange. +       +   .. data:: RR_TYPE_TXT +    +      Text strings. +    +   .. data:: RR_TYPE_RP +    +      RFC1183. +       +   .. data:: RR_TYPE_AFSDB +       +      RFC1183. +       +   .. data:: RR_TYPE_X25 +       +      RFC1183. +       +   .. data:: RR_TYPE_ISDN +    +      RFC1183. +       +   .. data:: RR_TYPE_RT +       +      RFC1183. +       +   .. data:: RR_TYPE_NSAP +       +      RFC1706. +       +   .. data:: RR_TYPE_NSAP_PTR +       +      RFC1348. +       +   .. data:: RR_TYPE_SIG +       +      2535typecode. +       +   .. data:: RR_TYPE_KEY +       +      2535typecode. +       +   .. data:: RR_TYPE_PX +       +      RFC2163. +       +   .. data:: RR_TYPE_GPOS +       +      RFC1712. +       +   .. data:: RR_TYPE_AAAA +       +      IPv6 address. +       +   .. data:: RR_TYPE_LOC +       +      LOC record  RFC1876. +       +   .. data:: RR_TYPE_NXT +       +      2535typecode. +       +   .. data:: RR_TYPE_EID +       +      draft-ietf-nimrod-dns-01.txt. +       +   .. data:: RR_TYPE_NIMLOC +       +      draft-ietf-nimrod-dns-01.txt. +       +   .. data:: RR_TYPE_SRV +       +      SRV record RFC2782. +       +   .. data:: RR_TYPE_ATMA +    +      http://www.jhsoft.com/rfc/af-saa-0069.000.rtf. +       +   .. data:: RR_TYPE_NAPTR +       +      RFC2915. +       +   .. data:: RR_TYPE_KX +       +      RFC2230. +       +   .. data:: RR_TYPE_CERT +       +      RFC2538. +       +   .. data:: RR_TYPE_A6 +       +      RFC2874. +       +   .. data:: RR_TYPE_DNAME +       +      RFC2672. +       +   .. data:: RR_TYPE_SINK +       +      dnsind-kitchen-sink-02.txt. +       +   .. data:: RR_TYPE_OPT +       +      Pseudo OPT record. +       +   .. data:: RR_TYPE_APL +       +      RFC3123. +       +   .. data:: RR_TYPE_DS +       +      draft-ietf-dnsext-delegation. +       +   .. data:: RR_TYPE_SSHFP +       +      SSH Key Fingerprint. +    +   .. data:: RR_TYPE_IPSECKEY +       +      draft-richardson-ipseckey-rr-11.txt. +       +   .. data:: RR_TYPE_RRSIG +       +      draft-ietf-dnsext-dnssec-25. +       +   .. data:: RR_TYPE_NSEC       +   .. data:: RR_TYPE_DNSKEY +   .. data:: RR_TYPE_DHCID +   .. data:: RR_TYPE_NSEC3 +   .. data:: RR_TYPE_NSEC3PARAMS +   .. data:: RR_TYPE_UINFO +   .. data:: RR_TYPE_UID +   .. data:: RR_TYPE_GID +   .. data:: RR_TYPE_UNSPEC +   .. data:: RR_TYPE_TSIG +   .. data:: RR_TYPE_IXFR +   .. data:: RR_TYPE_AXFR +   .. data:: RR_TYPE_MAILB +       +      A request for mailbox-related records (MB, MG or MR). +       +   .. data:: RR_TYPE_MAILA +       +      A request for mail agent RRs (Obsolete - see MX). +       +   .. data:: RR_TYPE_ANY +       +      Any type *(wildcard)*. +    +   .. data:: RR_TYPE_DLV +       +      RFC 4431, 5074, DNSSEC Lookaside Validation. +    +Return codes +~~~~~~~~~~~~ + +Return codes for packets. + +.. data:: RCODE_NOERROR +.. data:: RCODE_FORMERR +.. data:: RCODE_SERVFAIL +.. data:: RCODE_NXDOMAIN +.. data:: RCODE_NOTIMPL +.. data:: RCODE_REFUSED +.. data:: RCODE_YXDOMAIN +.. data:: RCODE_YXRRSET +.. data:: RCODE_NXRRSET +.. data:: RCODE_NOTAUTH +.. data:: RCODE_NOTZONE +    +Packet data +~~~~~~~~~~~~ + +.. data:: PKT_QR + +   Query - query flag. +    +.. data:: PKT_AA + +   Authoritative Answer - server flag. +    +.. data:: PKT_TC +    +   Truncated - server flag. +    +.. data:: PKT_RD +    +   Recursion desired - query flag. +    +.. data:: PKT_CD + +   Checking disabled - query flag. +    +.. data:: PKT_RA +    +   Recursion available - server flag. +    +.. data:: PKT_AD +    +   Authenticated data - server flag. + + +Verbosity value +~~~~~~~~~~~~~~~~ + +.. data:: NO_VERBOSE + +   No verbose messages. +    +.. data:: VERB_OPS + +   Operational information. +    +.. data:: VERB_DETAIL + +   Detailed information. +    +.. data:: VERB_QUERY + +   Query level information. +    +.. data:: VERB_ALGO + +   Algorithm level information. diff --git a/pythonmod/doc/modules/functions.rst b/pythonmod/doc/modules/functions.rst new file mode 100644 index 000000000000..45a469fec04e --- /dev/null +++ b/pythonmod/doc/modules/functions.rst @@ -0,0 +1,120 @@ +Scriptable functions +==================== + +Network +------- + +.. function:: ntohs(netshort) + +   This subroutine converts values between the host and network byte order.  +   Specifically, **ntohs()** converts 16-bit quantities from network byte order to host byte order. +    +   :param netshort: 16-bit short addr +   :rtype: converted addr +    +    +Cache +----- + +.. function:: storeQueryInCache(qstate, qinfo, msgrep, is_referral) + +   Store pending query in local cache. +    +   :param qstate: :class:`module_qstate` +   :param qinfo: :class:`query_info` +   :param msgrep: :class:`reply_info` +   :param is_referal: integer +   :rtype: boolean +    +.. function:: invalidateQueryInCache(qstate, qinfo) + +   Invalidate record in local cache. + +   :param qstate: :class:`module_qstate` +   :param qinfo: :class:`query_info` + + +Logging +------- + +.. function:: verbose(level, msg) + +   Log a verbose message, pass the level for this message. +   No trailing newline is needed. + +   :param level: verbosity level for this message, compared to global verbosity setting. +   :param msg: string message + +.. function:: log_info(msg) + +   Log informational message. No trailing newline is needed. + +   :param msg: string message + +.. function:: log_err(msg) + +   Log error message. No trailing newline is needed. + +   :param msg: string message + +.. function:: log_warn(msg) + +   Log warning message. No trailing newline is needed. + +   :param msg: string message + +.. function:: log_hex(msg, data, length) + +   Log a hex-string to the log. Can be any length. +   performs mallocs to do so, slow. But debug useful. + +   :param msg: string desc to accompany the hexdump. +   :param data: data to dump in hex format. +   :param length: length of data. +    +.. function:: log_dns_msg(str, qinfo, reply) + +   Log DNS message. +    +   :param str: string message +   :param qinfo: :class:`query_info` +   :param reply: :class:`reply_info` +    +.. function:: log_query_info(verbosity_value, str, qinf) + +   Log query information. +    +   :param verbosity_value: see constants +   :param str: string message +   :param qinf: :class:`query_info` +    +.. function:: regional_log_stats(r) + +   Log regional statistics. +    +   :param r: :class:`regional` + +Debugging +--------- + +.. function:: strextstate(module_ext_state) + +   Debug utility, module external qstate to string. +    +   :param module_ext_state: the state value. +   :rtype: descriptive string. + +.. function:: strmodulevent(module_event) + +   Debug utility, module event to string. +    +   :param module_event: the module event value. +   :rtype: descriptive string. +    +.. function:: ldns_rr_type2str(atype) + +   Convert RR type to string. +    +.. function:: ldns_rr_class2str(aclass) + +   Convert RR class to string. diff --git a/pythonmod/doc/modules/index.rst b/pythonmod/doc/modules/index.rst new file mode 100644 index 000000000000..ff0b956956ed --- /dev/null +++ b/pythonmod/doc/modules/index.rst @@ -0,0 +1,11 @@ +Unbound module documentation +======================================= + +.. toctree:: +   :maxdepth: 2 + +   env +   struct +   functions +   config + diff --git a/pythonmod/doc/modules/struct.rst b/pythonmod/doc/modules/struct.rst new file mode 100644 index 000000000000..c41e10b73df5 --- /dev/null +++ b/pythonmod/doc/modules/struct.rst @@ -0,0 +1,427 @@ +Scriptable structures +===================== + +module_qstate +----------------------- + +.. class:: module_qstate + +   Module state, per query. +    +   This class provides these data attributes: +    +   .. attribute:: qinfo +    +      (:class:`query_info`) Informations about query being answered. Name, RR type, RR class. +    +   .. attribute:: query_flags +    +      (uint16) Flags for query. See QF_BIT\_ predefined constants. +       +   .. attribute:: is_priming +    +      If this is a (stub or root) priming query (with hints). +    +   .. attribute:: reply +    +      comm_reply contains server replies. +       +   .. attribute:: return_msg +    +      (:class:`dns_msg`) The reply message, with message for client and calling module (read-only attribute). +		Note that if you want to create of modify return_msg you should use :class:`DNSMessage`. +       +   .. attribute:: return_rcode +    +      The rcode, in case of error, instead of a reply message. Determines whether the return_msg contains reply. +    +   .. attribute:: region +    +      Region for this query. Cleared when query process finishes. +    +   .. attribute:: curmod +    +      Which module is executing. +       +   .. attribute:: ext_state[] +    +      Module states. +       +   .. attribute:: env +    +      Environment for this query. +       +   .. attribute:: mesh_info +    +      Mesh related information for this query. + + +query_info +---------------- + +.. class:: query_info + +   This class provides these data attributes: + +   .. attribute:: qname +    +      The original question in the wireformat format (e.g. \\x03www\\x03nic\\x02cz\\x00 for www.nic.cz) +    +   .. attribute:: qname_len +    +      Lenght of question name (number of bytes). +	 +   .. attribute:: qname_list[] +    +      The question ``qname`` converted into list of labels (e.g. ['www','nic','cz',''] for www.nic.cz) +    +   .. attribute:: qname_str +    +      The question ``qname`` converted into string (e.g. www.nic.cz. for www.nic.cz) + +   .. attribute:: qtype +    +      The class type asked for. See RR_TYPE\_ predefined constants. +    +   .. attribute:: qtype_str +    +      The ``qtype`` in display presentation format (string) (e.g 'A' for RR_TYPE_A) + +   .. attribute:: qclass +    +      The question class. See RR_CLASS\_ predefined constants. +    +   .. attribute:: qclass_str +    +      The ``qclass`` in display presentation format (string). +    +reply_info +-------------------- + +.. class:: reply_info + +   This class provides these data attributes: + +   .. attribute:: flags +    +      The flags for the answer, host byte order. +    +   .. attribute:: qdcount +    +      Number of RRs in the query section. +      If qdcount is not 0, then it is 1, and the data that appears +      in the reply is the same as the query_info. +      Host byte order. +    +   .. attribute:: ttl +    +      TTL of the entire reply (for negative caching). +      only for use when there are 0 RRsets in this message. +      if there are RRsets, check those instead. +    +   .. attribute:: security +    +      The security status from DNSSEC validation of this message. See sec_status\_ predefined constants. +    +   .. attribute:: an_numrrsets +    +      Number of RRsets in each section. +      The answer section. Add up the RRs in every RRset to calculate +      the number of RRs, and the count for the dns packet.  +      The number of RRs in RRsets can change due to RRset updates. +    +   .. attribute:: ns_numrrsets +    +      Count of authority section RRsets +    +   .. attribute:: ar_numrrsets +    +      Count of additional section RRsets  +    +   .. attribute:: rrset_count +    +      Number of RRsets: an_numrrsets + ns_numrrsets + ar_numrrsets  +    +   .. attribute:: rrsets[] +    +         (:class:`ub_packed_rrset_key`) List of RR sets in the order in which they appear in the reply message.   +         Number of elements is ancount + nscount + arcount RRsets. +    +   .. attribute:: ref[] +    +         (:class:`rrset_ref`) Packed array of ids (see counts) and pointers to packed_rrset_key. +         The number equals ancount + nscount + arcount RRsets.  +         These are sorted in ascending pointer, the locking order. So +         this list can be locked (and id, ttl checked), to see if  +         all the data is available and recent enough. +    + +dns_msg +-------------- + +.. class:: dns_msg + +   Region allocated message reply + +   This class provides these data attributes: + +   .. attribute:: qinfo +    +      (:class:`query_info`) Informations about query. +    +   .. attribute:: rep +    +      (:class:`reply_info`) This attribute points to the packed reply structure. + + +packed_rrset_key +---------------------- +    +.. class:: packed_rrset_key + +   The identifying information for an RRset. + +   This class provides these data attributes: + +   .. attribute:: dname +    +      The domain name. If not empty (for ``id = None``) it is allocated, and +      contains the wireformat domain name. This dname is not canonicalized. +      E.g., the dname contains \\x03www\\x03nic\\x02cz\\x00 for www.nic.cz. +    +   .. attribute:: dname_len +    +      Length of the domain name, including last 0 root octet.  +       +   .. attribute:: dname_list[] +    +      The domain name ``dname`` converted into list of labels (see :attr:`query_info.qname_list`). +    +   .. attribute:: dname_str +    +      The domain name ``dname`` converted into string (see :attr:`query_info.qname_str`). + +   .. attribute:: flags +    +      Flags. +       +   .. attribute:: type +    +      The rrset type in network format. + +   .. attribute:: type_str +    +      The rrset type in display presentation format. +       +   .. attribute:: rrset_class +    +      The rrset class in network format. + +   .. attribute:: rrset_class_str +    +      The rrset class in display presentation format. + +ub_packed_rrset_key +------------------------- + +.. class:: ub_packed_rrset_key + +   This structure contains an RRset. A set of resource records that +   share the same domain name, type and class. +   Due to memory management and threading, the key structure cannot be +   deleted, although the data can be. The id can be set to 0 to store and the +   structure can be recycled with a new id. +    +   The :class:`ub_packed_rrset_key` provides these data attributes: +    +   .. attribute:: entry +       +      (:class:`lruhash_entry`) Entry into hashtable. Note the lock is never destroyed, +      even when this key is retired to the cache.  +      the data pointer (if not None) points to a :class:`packed_rrset`. +     +   .. attribute:: id +       +      The ID of this rrset. unique, based on threadid + sequenceno.  +      ids are not reused, except after flushing the cache. +      zero is an unused entry, and never a valid id. +      Check this value after getting entry.lock. +      The other values in this struct may only be altered after changing +      the id (which needs a writelock on entry.lock). +       +   .. attribute:: rk +    +      (:class:`packed_rrset_key`) RR set data. + + +lruhash_entry +------------------------- + +.. class:: lruhash_entry + +   The :class:`ub_packed_rrset_key` provides these data attributes: + +   .. attribute:: lock + +      rwlock for access to the contents of the entry. Note that you cannot change hash and key, if so, you have to delete it to change hash or key. + +   .. attribute:: data + +      (:class:`packed_rrset_data`) entry data stored in wireformat (RRs and RRsigs). + +packed_rrset_data +----------------------- +    +.. class:: packed_rrset_data + +   Rdata is stored in wireformat. The dname is stored in wireformat. +    +   TTLs are stored as absolute values (and could be expired). +    +   RRSIGs are stored in the arrays after the regular rrs. +    +   You need the packed_rrset_key to know dname, type, class of the +   resource records in this RRset. (if signed the rrsig gives the type too). + +   The :class:`packed_rrset_data` provides these data attributes: + +   .. attribute:: ttl +    +      TTL (in seconds like time()) of the RRset. +      Same for all RRs see rfc2181(5.2). +    +   .. attribute:: count +       +      Number of RRs. +    +   .. attribute:: rrsig_count +       +      Number of rrsigs, if 0 no rrsigs. +       +   .. attribute:: trust +    +      The trustworthiness of the RRset data. +       +   .. attribute:: security +    +      Security status of the RRset data. See sec_status\_ predefined constants. +       +   .. attribute:: rr_len[] +    +      Length of every RR's rdata, rr_len[i] is size of rr_data[i]. +       +   .. attribute:: rr_ttl[] +    +      TTL of every rr. rr_ttl[i] ttl of rr i. +       +   .. attribute:: rr_data[] +    +      Array of RR's rdata (list of strings). The rdata is stored in uncompressed wireformat.  +      The first 16B of rr_data[i] is rdlength in network format. +    + +DNSMessage +---------------- +    +.. class:: DNSMessage + +   Abstract representation of DNS message. +    +   **Usage** + +      This example shows how to create an authoritative answer response +		 +      :: + +         msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_AA) + +         #append RR +         if (qstate.qinfo.qtype == RR_TYPE_A) or (qstate.qinfo.qtype == RR_TYPE_ANY): +             msg.answer.append("%s 10 IN A 127.0.0.1" % qstate.qinfo.qname_str) +          +         #set qstate.return_msg  +         if not msg.set_return_msg(qstate): +             raise Exception("Can't create response") + +   The :class:`DNSMessage` provides these methods and data attributes: +    +   .. method:: __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0) +    +      Prepares an answer (DNS packet) from qiven information. Query flags are combination of PKT_xx contants. +       +   .. method:: set_return_msg(self, qstate) +    +      This method fills qstate return message according to the given informations.  +		It takes lists of RRs in each section of answer, created necessray RRsets in wire format and store the result in :attr:`qstate.return_msg`. +		Returns 1 if OK. +    +   .. attribute:: rr_name +    +      RR name of question. +       +   .. attribute:: rr_type +    +      RR type of question. +       +   .. attribute:: rr_class +    +      RR class of question. +       +   .. attribute:: default_ttl +    +      Default time-to-live. +       +   .. attribute:: query_flags +    +      Query flags. See PKT\_ predefined constants. +       +   .. attribute:: question[] +    +      List of resource records that should appear (in the same order) in question section of answer. +       +   .. attribute:: answer[] +    +      List of resource records that should appear (in the same order) in answer section of answer. +      +   .. attribute:: authority[] +    +      List of resource records that should appear (in the same order) in authority section of answer. +       +   .. attribute:: additional[] +    +      List of resource records that should appear (in the same order) in additional section of answer. + +pythonmod_env +----------------------- + +.. class:: pythonmod_env + +   Global state for the module.  + +   This class provides these data attributes: + +   .. attribute:: data +    +      Here you can keep your own data shared across each thread. + +   .. attribute:: fname +    +   	Python script filename. +    +   .. attribute:: qstate +    +      Module query state. + +pythonmod_qstate +----------------------- + +.. class:: pythonmod_qstate + +   Per query state for the iterator module. +	 +   This class provides these data attributes: +	 +   .. attribute:: data +	 +	   Here you can keep your own private data (each thread has own data object). + diff --git a/pythonmod/doc/usecase.rst b/pythonmod/doc/usecase.rst new file mode 100644 index 000000000000..7a77349f1e49 --- /dev/null +++ b/pythonmod/doc/usecase.rst @@ -0,0 +1,38 @@ +Use cases (examples) +==================== + +Dynamic DNS Service discovery (DNS-SD_) +------------------------------------------- +Synchronized with database engine, for example *MySQL*.  + +.. _DNS-SD: http://www.dns-sd.org/ + +Firewall control +---------------- +Control firewall (e.g. enable incomming SSH connection) with DNS query signed with private key.  +So firewall can blocks every service during normal operation. + +Scriptable DNS-based blacklist (DNS-BL_) +------------------------------------------- +Scripted in Python with already provided features, takes advantage of DNS reply, because +almost every mail server supports DNS based blacklisting. + +.. _DNS-BL: http://www.dnsbl.org + +DNS based Wake-On-Lan +--------------------- +Controled by secured queries secured with private key. + +Dynamic translation service +--------------------------- +DNS request can be translated to virtualy any answer, that's easy to implement in client side +because of many DNS libraries available. + +Examples : + * **Dictionary** - using *IDN* for non-ascii strings transfer, ``dig TXT slovo.en._dict_.nic.cz`` returns translation of "slovo" to EN. + * **Translation** - Extends *DNS-SD*, for example DNS to Jabber to find out people logged in. + * **Exchange rate calculator** - ``dig TXT 1000.99.czk.eur._rates_.nic.cz`` returns the given sum (1000.99 CZK) in EURs. + +Dynamic ENUM service  +-------------------- +Support for redirection, synchronization, etc. | 
