diff options
author | Riccardo Spagni <ric@spagni.net> | 2014-10-05 23:44:31 +0200 |
---|---|---|
committer | Riccardo Spagni <ric@spagni.net> | 2014-10-05 23:44:31 +0200 |
commit | 9ef094b356b4da7542c3cab898dac7e135b76903 (patch) | |
tree | 99b5876712b0b1551fc042fe75447b998e4b0fc1 /external/unbound/pythonmod/interface.i | |
parent | split mnemonic printout over 3 lines (diff) | |
download | monero-9ef094b356b4da7542c3cab898dac7e135b76903.tar.xz |
added unbound to external deps
Diffstat (limited to 'external/unbound/pythonmod/interface.i')
-rw-r--r-- | external/unbound/pythonmod/interface.i | 916 |
1 files changed, 916 insertions, 0 deletions
diff --git a/external/unbound/pythonmod/interface.i b/external/unbound/pythonmod/interface.i new file mode 100644 index 000000000..4f1a25f21 --- /dev/null +++ b/external/unbound/pythonmod/interface.i @@ -0,0 +1,916 @@ +/* + * interface.i: unbound python module + */ + +%module unboundmodule +%{ +/** + * \file + * This is the interface between the unbound server and a python module + * called to perform operations on queries. + */ + #include <sys/types.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + #include <stdarg.h> + #include "config.h" + #include "util/log.h" + #include "util/module.h" + #include "util/netevent.h" + #include "util/regional.h" + #include "util/config_file.h" + #include "util/data/msgreply.h" + #include "util/data/packed_rrset.h" + #include "util/data/dname.h" + #include "util/storage/lruhash.h" + #include "services/cache/dns.h" + #include "services/mesh.h" + #include "ldns/wire2str.h" + #include "ldns/str2wire.h" + #include "ldns/pkthdr.h" +%} + +%include "stdint.i" // uint_16_t can be known type now + +%inline %{ + //converts [len][data][len][data][0] string to a List of labels (PyStrings) + PyObject* GetNameAsLabelList(const char* name, int len) { + PyObject* list; + int cnt=0, i; + + i = 0; + while (i < len) { + i += name[i] + 1; + cnt++; + } + + list = PyList_New(cnt); + i = 0; cnt = 0; + while (i < len) { + PyList_SetItem(list, cnt, PyBytes_FromStringAndSize(name + i + 1, name[i])); + i += name[i] + 1; + cnt++; + } + return list; + } +%} + +/* ************************************************************************************ * + Structure query_info + * ************************************************************************************ */ +/* Query info */ +%ignore query_info::qname; +%ignore query_info::qname_len; + + +struct query_info { + %immutable; + char* qname; + size_t qname_len; + uint16_t qtype; + uint16_t qclass; + %mutable; +}; + +%inline %{ + enum enum_rr_class { + RR_CLASS_IN = 1, + RR_CLASS_CH = 3, + RR_CLASS_HS = 4, + RR_CLASS_NONE = 254, + RR_CLASS_ANY = 255, + }; + + enum enum_rr_type { + RR_TYPE_A = 1, + RR_TYPE_NS = 2, + RR_TYPE_MD = 3, + RR_TYPE_MF = 4, + RR_TYPE_CNAME = 5, + RR_TYPE_SOA = 6, + RR_TYPE_MB = 7, + RR_TYPE_MG = 8, + RR_TYPE_MR = 9, + RR_TYPE_NULL = 10, + RR_TYPE_WKS = 11, + RR_TYPE_PTR = 12, + RR_TYPE_HINFO = 13, + RR_TYPE_MINFO = 14, + RR_TYPE_MX = 15, + RR_TYPE_TXT = 16, + RR_TYPE_RP = 17, + RR_TYPE_AFSDB = 18, + RR_TYPE_X25 = 19, + RR_TYPE_ISDN = 20, + RR_TYPE_RT = 21, + RR_TYPE_NSAP = 22, + RR_TYPE_NSAP_PTR = 23, + RR_TYPE_SIG = 24, + RR_TYPE_KEY = 25, + RR_TYPE_PX = 26, + RR_TYPE_GPOS = 27, + RR_TYPE_AAAA = 28, + RR_TYPE_LOC = 29, + RR_TYPE_NXT = 30, + RR_TYPE_EID = 31, + RR_TYPE_NIMLOC = 32, + RR_TYPE_SRV = 33, + RR_TYPE_ATMA = 34, + RR_TYPE_NAPTR = 35, + RR_TYPE_KX = 36, + RR_TYPE_CERT = 37, + RR_TYPE_A6 = 38, + RR_TYPE_DNAME = 39, + RR_TYPE_SINK = 40, + RR_TYPE_OPT = 41, + RR_TYPE_APL = 42, + RR_TYPE_DS = 43, + RR_TYPE_SSHFP = 44, + RR_TYPE_IPSECKEY = 45, + RR_TYPE_RRSIG = 46, + RR_TYPE_NSEC = 47, + RR_TYPE_DNSKEY = 48, + RR_TYPE_DHCID = 49, + RR_TYPE_NSEC3 = 50, + RR_TYPE_NSEC3PARAMS = 51, + RR_TYPE_UINFO = 100, + RR_TYPE_UID = 101, + RR_TYPE_GID = 102, + RR_TYPE_UNSPEC = 103, + RR_TYPE_TSIG = 250, + RR_TYPE_IXFR = 251, + RR_TYPE_AXFR = 252, + RR_TYPE_MAILB = 253, + RR_TYPE_MAILA = 254, + RR_TYPE_ANY = 255, + RR_TYPE_DLV = 32769, + }; + + PyObject* _get_qname(struct query_info* q) { + return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len); + } + + PyObject* _get_qname_components(struct query_info* q) { + return GetNameAsLabelList((const char*)q->qname, q->qname_len); + } +%} + +%inline %{ + PyObject* dnameAsStr(const char* dname) { + char buf[LDNS_MAX_DOMAINLEN+1]; + buf[0] = '\0'; + dname_str((uint8_t*)dname, buf); + return PyString_FromString(buf); + } +%} + +%extend query_info { + %pythoncode %{ + def _get_qtype_str(self): return sldns_wire2str_type(self.qtype) + __swig_getmethods__["qtype_str"] = _get_qtype_str + if _newclass:qtype_str = _swig_property(_get_qtype_str) + + def _get_qclass_str(self): return sldns_wire2str_class(self.qclass) + __swig_getmethods__["qclass_str"] = _get_qclass_str + if _newclass:qclass_str = _swig_property(_get_qclass_str) + + __swig_getmethods__["qname"] = _unboundmodule._get_qname + if _newclass:qname = _swig_property(_unboundmodule._get_qname) + + __swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components + if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components) + + def _get_qname_str(self): return dnameAsStr(self.qname) + __swig_getmethods__["qname_str"] = _get_qname_str + if _newclass:qname_str = _swig_property(_get_qname_str) + %} +} + +/* ************************************************************************************ * + Structure packed_rrset_key + * ************************************************************************************ */ +%ignore packed_rrset_key::dname; +%ignore packed_rrset_key::dname_len; + +/* RRsets */ +struct packed_rrset_key { + %immutable; + char* dname; + size_t dname_len; + uint32_t flags; + uint16_t type; //rrset type in network format + uint16_t rrset_class; //rrset class in network format + %mutable; +}; + +//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. +uint16_t ntohs(uint16_t netshort); + +%inline %{ + PyObject* _get_dname(struct packed_rrset_key* k) { + return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len); + } + PyObject* _get_dname_components(struct packed_rrset_key* k) { + return GetNameAsLabelList((char*)k->dname, k->dname_len); + } +%} + +%extend packed_rrset_key { + %pythoncode %{ + def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type)) + __swig_getmethods__["type_str"] = _get_type_str + if _newclass:type_str = _swig_property(_get_type_str) + + def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class)) + __swig_getmethods__["rrset_class_str"] = _get_class_str + if _newclass:rrset_class_str = _swig_property(_get_class_str) + + __swig_getmethods__["dname"] = _unboundmodule._get_dname + if _newclass:dname = _swig_property(_unboundmodule._get_dname) + + __swig_getmethods__["dname_list"] = _unboundmodule._get_dname_components + if _newclass:dname_list = _swig_property(_unboundmodule._get_dname_components) + + def _get_dname_str(self): return dnameAsStr(self.dname) + __swig_getmethods__["dname_str"] = _get_dname_str + if _newclass:dname_str = _swig_property(_get_dname_str) + %} +} + +#if defined(SWIGWORDSIZE64) +typedef long int rrset_id_t; +#else +typedef long long int rrset_id_t; +#endif + +struct ub_packed_rrset_key { + struct lruhash_entry entry; + rrset_id_t id; + struct packed_rrset_key rk; +}; + +struct lruhash_entry { + lock_rw_t lock; + struct lruhash_entry* overflow_next; + struct lruhash_entry* lru_next; + struct lruhash_entry* lru_prev; + hashvalue_t hash; + void* key; + struct packed_rrset_data* data; +}; + +%ignore packed_rrset_data::rr_len; +%ignore packed_rrset_data::rr_ttl; +%ignore packed_rrset_data::rr_data; + +struct packed_rrset_data { + uint32_t ttl; //TTL (in seconds like time()) + + size_t count; //number of rrs + size_t rrsig_count; //number of rrsigs + + enum rrset_trust trust; + enum sec_status security; + + size_t* rr_len; //length of every rr's rdata + uint32_t *rr_ttl; //ttl of every rr + uint8_t** rr_data; //array of pointers to every rr's rdata; The rr_data[i] rdata is stored in uncompressed wireformat. +}; + +%pythoncode %{ + class RRSetData_RRLen: + def __init__(self, obj): self.obj = obj + def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index) + def __len__(self): return obj.count + obj.rrsig_count + class RRSetData_RRTTL: + def __init__(self, obj): self.obj = obj + def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index) + def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value) + def __len__(self): return obj.count + obj.rrsig_count + class RRSetData_RRData: + def __init__(self, obj): self.obj = obj + def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index) + def __len__(self): return obj.count + obj.rrsig_count +%} + +%inline %{ + PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) { + if ((d != NULL) && (idx >= 0) && + ((size_t)idx < (d->count+d->rrsig_count))) + return PyInt_FromLong(d->rr_len[idx]); + return Py_None; + } + void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl) + { + if ((d != NULL) && (idx >= 0) && + ((size_t)idx < (d->count+d->rrsig_count))) + d->rr_ttl[idx] = ttl; + } + PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) { + if ((d != NULL) && (idx >= 0) && + ((size_t)idx < (d->count+d->rrsig_count))) + return PyInt_FromLong(d->rr_ttl[idx]); + return Py_None; + } + PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) { + if ((d != NULL) && (idx >= 0) && + ((size_t)idx < (d->count+d->rrsig_count))) + return PyBytes_FromStringAndSize((char*)d->rr_data[idx], + d->rr_len[idx]); + return Py_None; + } +%} + +%extend packed_rrset_data { + %pythoncode %{ + def _get_data_rr_len(self): return RRSetData_RRLen(self) + __swig_getmethods__["rr_len"] = _get_data_rr_len + if _newclass:rr_len = _swig_property(_get_data_rr_len) + def _get_data_rr_ttl(self): return RRSetData_RRTTL(self) + __swig_getmethods__["rr_ttl"] =_get_data_rr_ttl + if _newclass:rr_len = _swig_property(_get_data_rr_ttl) + def _get_data_rr_data(self): return RRSetData_RRData(self) + __swig_getmethods__["rr_data"] = _get_data_rr_data + if _newclass:rr_len = _swig_property(_get_data_rr_data) + %} +} + +/* ************************************************************************************ * + Structure reply_info + * ************************************************************************************ */ +/* Messages */ +%ignore reply_info::rrsets; +%ignore reply_info::ref; + +struct reply_info { + uint16_t flags; + uint16_t qdcount; + uint32_t ttl; + uint32_t prefetch_ttl; + + uint16_t authoritative; + enum sec_status security; + + size_t an_numrrsets; + size_t ns_numrrsets; + size_t ar_numrrsets; + size_t rrset_count; // an_numrrsets + ns_numrrsets + ar_numrrsets + + struct ub_packed_rrset_key** rrsets; + struct rrset_ref ref[1]; //? +}; + +struct rrset_ref { + struct ub_packed_rrset_key* key; + rrset_id_t id; +}; + +struct dns_msg { + struct query_info qinfo; + struct reply_info *rep; +}; + +%pythoncode %{ + class ReplyInfo_RRSet: + def __init__(self, obj): self.obj = obj + def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index) + def __len__(self): return obj.rrset_count + + class ReplyInfo_Ref: + def __init__(self, obj): self.obj = obj + def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index) + def __len__(self): return obj.rrset_count +%} + +%inline %{ + struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) { + if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) + return r->rrsets[idx]; + return NULL; + } + + struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) { + if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) { +//printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); + return &(r->ref[idx]); +// return &(r->ref[idx]); + } +//printf("_rrset_ref_get: NULL\n"); + return NULL; + } +%} + +%extend reply_info { + %pythoncode %{ + def _rrset_ref_get(self): return ReplyInfo_Ref(self) + __swig_getmethods__["ref"] = _rrset_ref_get + if _newclass:ref = _swig_property(_rrset_ref_get) + + def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self) + __swig_getmethods__["rrsets"] = _rrset_rrsets_get + if _newclass:rrsets = _swig_property(_rrset_rrsets_get) + %} +} + +/* ************************************************************************************ * + Structure mesh_state + * ************************************************************************************ */ +struct mesh_state { + struct mesh_reply* reply_list; +}; + +struct mesh_reply { + struct mesh_reply* next; + struct comm_reply query_reply; +}; + +struct comm_reply { + +}; + +%inline %{ + + PyObject* _comm_reply_addr_get(struct comm_reply* reply) { + char dest[64]; + reply_addr2str(reply, dest, 64); + if (dest[0] == 0) + return Py_None; + return PyString_FromString(dest); + } + + PyObject* _comm_reply_family_get(struct comm_reply* reply) { + + int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family; + + switch(af) { + case AF_INET: return PyString_FromString("ip4"); + case AF_INET6: return PyString_FromString("ip6"); + case AF_UNIX: return PyString_FromString("unix"); + } + + return Py_None; + } + + PyObject* _comm_reply_port_get(struct comm_reply* reply) { + uint16_t port; + port = ntohs(((struct sockaddr_in*)&(reply->addr))->sin_port); + return PyInt_FromLong(port); + } + +%} + +%extend comm_reply { + %pythoncode %{ + def _addr_get(self): return _comm_reply_addr_get(self) + __swig_getmethods__["addr"] = _addr_get + if _newclass:addr = _swig_property(_addr_get) + + def _port_get(self): return _comm_reply_port_get(self) + __swig_getmethods__["port"] = _port_get + if _newclass:port = _swig_property(_port_get) + + def _family_get(self): return _comm_reply_family_get(self) + __swig_getmethods__["family"] = _family_get + if _newclass:family = _swig_property(_family_get) + %} +} +/* ************************************************************************************ * + Structure module_qstate + * ************************************************************************************ */ +%ignore module_qstate::ext_state; +%ignore module_qstate::minfo; + +/* Query state */ +struct module_qstate { + struct query_info qinfo; + uint16_t query_flags; //See QF_BIT_xx constants + int is_priming; + + struct comm_reply* reply; + struct dns_msg* return_msg; + int return_rcode; + struct regional* region; /* unwrapped */ + + int curmod; + + enum module_ext_state ext_state[MAX_MODULE]; + void* minfo[MAX_MODULE]; + + struct module_env* env; /* unwrapped */ + struct mesh_state* mesh_info; +}; + +%constant int MODULE_COUNT = MAX_MODULE; + +%constant int QF_BIT_CD = 0x0010; +%constant int QF_BIT_AD = 0x0020; +%constant int QF_BIT_Z = 0x0040; +%constant int QF_BIT_RA = 0x0080; +%constant int QF_BIT_RD = 0x0100; +%constant int QF_BIT_TC = 0x0200; +%constant int QF_BIT_AA = 0x0400; +%constant int QF_BIT_QR = 0x8000; + +%inline %{ + enum enum_return_rcode { + RCODE_NOERROR = 0, + RCODE_FORMERR = 1, + RCODE_SERVFAIL = 2, + RCODE_NXDOMAIN = 3, + RCODE_NOTIMPL = 4, + RCODE_REFUSED = 5, + RCODE_YXDOMAIN = 6, + RCODE_YXRRSET = 7, + RCODE_NXRRSET = 8, + RCODE_NOTAUTH = 9, + RCODE_NOTZONE = 10 + }; +%} + +%pythoncode %{ + class ExtState: + def __init__(self, obj): self.obj = obj + def __str__(self): + return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)]) + def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index) + def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value) + def __len__(self): return _unboundmodule.MODULE_COUNT +%} + +%inline %{ + enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) { + if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) { + return q->ext_state[idx]; + } + return 0; + } + + void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) { + if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) { + q->ext_state[idx] = state; + } + } +%} + +%extend module_qstate { + %pythoncode %{ + def set_ext_state(self, id, state): + """Sets the ext state""" + _unboundmodule._ext_state_set(self, id, state) + + def __ext_state_get(self): return ExtState(self) + __swig_getmethods__["ext_state"] = __ext_state_get + if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set) + %} +} + +/* ************************************************************************************ * + Structure config_strlist + * ************************************************************************************ */ +struct config_strlist { + struct config_strlist* next; + char* str; +}; + +/* ************************************************************************************ * + Structure config_str2list + * ************************************************************************************ */ +struct config_str2list { + struct config_str2list* next; + char* str; + char* str2; +}; + +/* ************************************************************************************ * + Structure config_file + * ************************************************************************************ */ +struct config_file { + int verbosity; + int stat_interval; + int stat_cumulative; + int stat_extended; + int num_threads; + int port; + int do_ip4; + int do_ip6; + int do_udp; + int do_tcp; + int outgoing_num_ports; + size_t outgoing_num_tcp; + size_t incoming_num_tcp; + int* outgoing_avail_ports; + size_t msg_buffer_size; + size_t msg_cache_size; + size_t msg_cache_slabs; + size_t num_queries_per_thread; + size_t jostle_time; + size_t rrset_cache_size; + size_t rrset_cache_slabs; + int host_ttl; + size_t infra_cache_slabs; + size_t infra_cache_numhosts; + char* target_fetch_policy; + int if_automatic; + int num_ifs; + char **ifs; + int num_out_ifs; + char **out_ifs; + struct config_strlist* root_hints; + struct config_stub* stubs; + struct config_stub* forwards; + struct config_strlist* donotqueryaddrs; + struct config_str2list* acls; + int donotquery_localhost; + int harden_short_bufsize; + int harden_large_queries; + int harden_glue; + int harden_dnssec_stripped; + int harden_referral_path; + int use_caps_bits_for_id; + struct config_strlist* private_address; + struct config_strlist* private_domain; + size_t unwanted_threshold; + char* chrootdir; + char* username; + char* directory; + char* logfile; + char* pidfile; + int use_syslog; + int hide_identity; + int hide_version; + char* identity; + char* version; + char* module_conf; + struct config_strlist* trust_anchor_file_list; + struct config_strlist* trust_anchor_list; + struct config_strlist* trusted_keys_file_list; + char* dlv_anchor_file; + struct config_strlist* dlv_anchor_list; + int max_ttl; + int32_t val_date_override; + int bogus_ttl; + int val_clean_additional; + int val_permissive_mode; + char* val_nsec3_key_iterations; + size_t key_cache_size; + size_t key_cache_slabs; + size_t neg_cache_size; + struct config_str2list* local_zones; + struct config_strlist* local_zones_nodefault; + struct config_strlist* local_data; + int remote_control_enable; + struct config_strlist* control_ifs; + int control_port; + char* server_key_file; + char* server_cert_file; + char* control_key_file; + char* control_cert_file; + int do_daemonize; + char* python_script; +}; + +/* ************************************************************************************ * + Enums + * ************************************************************************************ */ +%rename ("MODULE_STATE_INITIAL") "module_state_initial"; +%rename ("MODULE_WAIT_REPLY") "module_wait_reply"; +%rename ("MODULE_WAIT_MODULE") "module_wait_module"; +%rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery"; +%rename ("MODULE_ERROR") "module_error"; +%rename ("MODULE_FINISHED") "module_finished"; + +enum module_ext_state { + module_state_initial = 0, + module_wait_reply, + module_wait_module, + module_wait_subquery, + module_error, + module_finished +}; + +%rename ("MODULE_EVENT_NEW") "module_event_new"; +%rename ("MODULE_EVENT_PASS") "module_event_pass"; +%rename ("MODULE_EVENT_REPLY") "module_event_reply"; +%rename ("MODULE_EVENT_NOREPLY") "module_event_noreply"; +%rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail"; +%rename ("MODULE_EVENT_MODDONE") "module_event_moddone"; +%rename ("MODULE_EVENT_ERROR") "module_event_error"; + +enum module_ev { + module_event_new = 0, + module_event_pass, + module_event_reply, + module_event_noreply, + module_event_capsfail, + module_event_moddone, + module_event_error +}; + +enum sec_status { + sec_status_unchecked = 0, + sec_status_bogus, + sec_status_indeterminate, + sec_status_insecure, + sec_status_secure +}; + +enum verbosity_value { + NO_VERBOSE = 0, + VERB_OPS, + VERB_DETAIL, + VERB_QUERY, + VERB_ALGO +}; + +%constant uint16_t PKT_QR = 1; /* QueRy - query flag */ +%constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */ +%constant uint16_t PKT_TC = 4; /* TrunCated - server flag */ +%constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */ +%constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */ +%constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */ +%constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */ + +%{ +int checkList(PyObject *l) +{ + PyObject* item; + int i; + + if (l == Py_None) + return 1; + + if (PyList_Check(l)) + { + for (i=0; i < PyList_Size(l); i++) + { + item = PyList_GetItem(l, i); + if (!PyString_Check(item)) + return 0; + } + return 1; + } + + return 0; +} + +int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec, + size_t count_offset) +{ + PyObject* item; + int i; + size_t len; + + for (i=0; i < PyList_Size(l); i++) + { + item = PyList_GetItem(l, i); + + len = sldns_buffer_remaining(qb); + if(qsec) { + if(sldns_str2wire_rr_question_buf(PyString_AsString(item), + sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0) + != 0) + return 0; + } else { + if(sldns_str2wire_rr_buf(PyString_AsString(item), + sldns_buffer_current(qb), &len, NULL, default_ttl, + NULL, 0, NULL, 0) != 0) + return 0; + } + sldns_buffer_skip(qb, len); + + sldns_buffer_write_u16_at(qb, count_offset, + sldns_buffer_read_u16_at(qb, count_offset)+1); + } + return 1; +} + +int set_return_msg(struct module_qstate* qstate, + const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl, + PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional) +{ + sldns_buffer *qb = 0; + int res = 1; + size_t l; + uint16_t PKT_QR = 1; + uint16_t PKT_AA = 2; + uint16_t PKT_TC = 4; + uint16_t PKT_RD = 8; + uint16_t PKT_CD = 16; + uint16_t PKT_RA = 32; + uint16_t PKT_AD = 64; + + if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional))) + return 0; + if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0; + + /* write header */ + sldns_buffer_write_u16(qb, 0); /* ID */ + sldns_buffer_write_u16(qb, 0); /* flags */ + sldns_buffer_write_u16(qb, 1); /* qdcount */ + sldns_buffer_write_u16(qb, 0); /* ancount */ + sldns_buffer_write_u16(qb, 0); /* nscount */ + sldns_buffer_write_u16(qb, 0); /* arcount */ + if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb)); + if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb)); + if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb)); + if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb)); + if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb)); + if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb)); + if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb)); + + /* write the query */ + l = sldns_buffer_remaining(qb); + if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) { + sldns_buffer_free(qb); + return 0; + } + sldns_buffer_skip(qb, l); + if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; } + if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; } + sldns_buffer_write_u16(qb, rr_type); + sldns_buffer_write_u16(qb, rr_class); + + /* write RR sections */ + if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF)) + res = 0; + if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF)) + res = 0; + if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF)) + res = 0; + if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF)) + res = 0; + + if (res) res = createResponse(qstate, qb); + + if (qb) sldns_buffer_free(qb); + return res; +} +%} + +int set_return_msg(struct module_qstate* qstate, + const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl, + PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional); + +%pythoncode %{ + class DNSMessage: + def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0): + """Query flags is a combination of PKT_xx contants""" + self.rr_name = rr_name + self.rr_type = rr_type + self.rr_class = rr_class + self.default_ttl = default_ttl + self.query_flags = query_flags + self.question = [] + self.answer = [] + self.authority = [] + self.additional = [] + + def set_return_msg(self, qstate): + """Returns 1 if OK""" + status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class, + self.query_flags, self.default_ttl, + self.question, self.answer, self.authority, self.additional) + + if (status) and (PKT_AA & self.query_flags): + qstate.return_msg.rep.authoritative = 1 + + return status + +%} +/* ************************************************************************************ * + Functions + * ************************************************************************************ */ + +// Various debuging functions +void verbose(enum verbosity_value level, const char* format, ...); +void log_info(const char* format, ...); +void log_err(const char* format, ...); +void log_warn(const char* format, ...); +void log_hex(const char* msg, void* data, size_t length); +void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep); +void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf); +void regional_log_stats(struct regional *r); + +// Free allocated memory from marked sources returning corresponding types +%typemap(newfree, noblock = 1) char * { + free($1); +} + +// Mark as source returning newly allocated memory +%newobject sldns_wire2str_type; +%newobject sldns_wire2str_class; + +// LDNS functions +char *sldns_wire2str_type(const uint16_t atype); +char *sldns_wire2str_class(const uint16_t aclass); + +// Functions from pythonmod_utils +int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral); +void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo); + +// Module conversion functions +const char* strextstate(enum module_ext_state s); +const char* strmodulevent(enum module_ev e); + |