]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - pythonmod/interface.i
import unbound 1.4.22
[FreeBSD/FreeBSD.git] / pythonmod / interface.i
1 /*
2  * interface.i: unbound python module
3  */
4
5 %module unboundmodule
6 %{
7 /**
8  * \file 
9  * This is the interface between the unbound server and a python module
10  * called to perform operations on queries.
11  */
12    #include <sys/types.h>
13    #include <sys/socket.h>
14    #include <netinet/in.h>
15    #include <arpa/inet.h>
16    #include <stdarg.h>
17    #include "config.h"
18    #include "util/log.h"
19    #include "util/module.h"
20    #include "util/netevent.h"
21    #include "util/regional.h"
22    #include "util/config_file.h"
23    #include "util/data/msgreply.h"
24    #include "util/data/packed_rrset.h"
25    #include "util/data/dname.h"
26    #include "util/storage/lruhash.h"
27    #include "services/cache/dns.h"
28    #include "services/mesh.h"
29    #include "ldns/wire2str.h"
30    #include "ldns/str2wire.h"
31    #include "ldns/pkthdr.h"
32 %}
33
34 %include "stdint.i" // uint_16_t can be known type now
35
36 %inline %{
37    //converts [len][data][len][data][0] string to a List of labels (PyStrings)
38    PyObject* GetNameAsLabelList(const char* name, int len) {
39      PyObject* list;
40      int cnt=0, i;
41
42      i = 0;
43      while (i < len) {
44         i += name[i] + 1;
45         cnt++;
46      }
47
48      list = PyList_New(cnt);
49      i = 0; cnt = 0;
50      while (i < len) {
51         PyList_SetItem(list, cnt, PyString_FromStringAndSize(name + i + 1, name[i]));
52         i += name[i] + 1;
53         cnt++;
54      }
55      return list;
56    }
57 %}
58
59 /* ************************************************************************************ * 
60    Structure query_info
61  * ************************************************************************************ */
62 /* Query info */
63 %ignore query_info::qname;
64 %ignore query_info::qname_len;
65
66
67 struct query_info {
68    %immutable;
69    char* qname;
70    size_t qname_len;
71    uint16_t qtype;
72    uint16_t qclass;
73    %mutable;
74 };
75
76 %inline %{
77    enum enum_rr_class  { 
78       RR_CLASS_IN = 1,
79       RR_CLASS_CH       = 3,
80       RR_CLASS_HS       = 4,
81       RR_CLASS_NONE = 254,
82       RR_CLASS_ANY = 255,
83    };
84    
85    enum enum_rr_type {
86       RR_TYPE_A = 1, 
87       RR_TYPE_NS = 2, 
88       RR_TYPE_MD = 3, 
89       RR_TYPE_MF = 4, 
90       RR_TYPE_CNAME = 5, 
91       RR_TYPE_SOA = 6, 
92       RR_TYPE_MB = 7, 
93       RR_TYPE_MG = 8, 
94       RR_TYPE_MR = 9, 
95       RR_TYPE_NULL = 10,
96       RR_TYPE_WKS = 11,
97       RR_TYPE_PTR = 12,
98       RR_TYPE_HINFO = 13,
99       RR_TYPE_MINFO = 14,
100       RR_TYPE_MX = 15,
101       RR_TYPE_TXT = 16,
102       RR_TYPE_RP = 17,
103       RR_TYPE_AFSDB = 18,
104       RR_TYPE_X25 = 19,
105       RR_TYPE_ISDN = 20,
106       RR_TYPE_RT = 21,
107       RR_TYPE_NSAP = 22,
108       RR_TYPE_NSAP_PTR = 23,
109       RR_TYPE_SIG = 24,
110       RR_TYPE_KEY = 25,
111       RR_TYPE_PX = 26,
112       RR_TYPE_GPOS = 27,
113       RR_TYPE_AAAA = 28,
114       RR_TYPE_LOC = 29,
115       RR_TYPE_NXT = 30,
116       RR_TYPE_EID = 31,
117       RR_TYPE_NIMLOC = 32,
118       RR_TYPE_SRV = 33,
119       RR_TYPE_ATMA = 34,
120       RR_TYPE_NAPTR = 35,
121       RR_TYPE_KX = 36,
122       RR_TYPE_CERT = 37,
123       RR_TYPE_A6 = 38,
124       RR_TYPE_DNAME = 39,
125       RR_TYPE_SINK = 40,
126       RR_TYPE_OPT = 41,
127       RR_TYPE_APL = 42,
128       RR_TYPE_DS = 43,
129       RR_TYPE_SSHFP = 44,
130       RR_TYPE_IPSECKEY = 45,
131       RR_TYPE_RRSIG = 46,
132       RR_TYPE_NSEC = 47,      
133       RR_TYPE_DNSKEY = 48,
134       RR_TYPE_DHCID = 49,
135       RR_TYPE_NSEC3 = 50,
136       RR_TYPE_NSEC3PARAMS = 51,
137       RR_TYPE_UINFO = 100,
138       RR_TYPE_UID = 101,
139       RR_TYPE_GID = 102,
140       RR_TYPE_UNSPEC = 103,
141       RR_TYPE_TSIG = 250,
142       RR_TYPE_IXFR = 251,
143       RR_TYPE_AXFR = 252,
144       RR_TYPE_MAILB = 253,
145       RR_TYPE_MAILA = 254,
146       RR_TYPE_ANY = 255,
147       RR_TYPE_DLV = 32769,
148    };
149
150    PyObject* _get_qname(struct query_info* q) {
151       return PyString_FromStringAndSize((char*)q->qname, q->qname_len);
152    } 
153
154    PyObject* _get_qname_components(struct query_info* q) {
155       return GetNameAsLabelList((const char*)q->qname, q->qname_len);
156    }
157 %}
158
159 %inline %{
160    PyObject* dnameAsStr(const char* dname) {
161        char buf[LDNS_MAX_DOMAINLEN+1];
162        buf[0] = '\0';
163        dname_str((uint8_t*)dname, buf);
164        return PyString_FromString(buf);
165    }
166 %}
167
168 %extend query_info {
169    %pythoncode %{
170         def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
171         __swig_getmethods__["qtype_str"] = _get_qtype_str
172         if _newclass:qtype_str = _swig_property(_get_qtype_str)
173
174         def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
175         __swig_getmethods__["qclass_str"] = _get_qclass_str
176         if _newclass:qclass_str = _swig_property(_get_qclass_str)
177
178         __swig_getmethods__["qname"] = _unboundmodule._get_qname
179         if _newclass:qname = _swig_property(_unboundmodule._get_qname)
180         
181         __swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components
182         if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components)
183
184         def _get_qname_str(self): return dnameAsStr(self.qname)
185         __swig_getmethods__["qname_str"] = _get_qname_str
186         if _newclass:qname_str = _swig_property(_get_qname_str)
187    %}
188 }
189
190 /* ************************************************************************************ * 
191    Structure packed_rrset_key
192  * ************************************************************************************ */
193 %ignore packed_rrset_key::dname;
194 %ignore packed_rrset_key::dname_len;
195
196 /* RRsets */
197 struct packed_rrset_key {
198    %immutable;
199    char*    dname;
200    size_t   dname_len;
201    uint32_t flags; 
202    uint16_t type;  //rrset type in network format
203    uint16_t rrset_class; //rrset class in network format
204    %mutable;
205 };
206
207 //This subroutine converts values between the host and network byte order. 
208 //Specifically, ntohs() converts 16-bit quantities from network byte order to host byte order.
209 uint16_t ntohs(uint16_t netshort);
210
211 %inline %{
212    PyObject* _get_dname(struct packed_rrset_key* k) {
213       return PyString_FromStringAndSize((char*)k->dname, k->dname_len);
214    } 
215    PyObject* _get_dname_components(struct packed_rrset_key* k) {
216       return GetNameAsLabelList((char*)k->dname, k->dname_len);
217    }
218 %}
219
220 %extend packed_rrset_key {
221    %pythoncode %{
222         def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
223         __swig_getmethods__["type_str"] = _get_type_str
224         if _newclass:type_str = _swig_property(_get_type_str)
225
226         def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
227         __swig_getmethods__["rrset_class_str"] = _get_class_str
228         if _newclass:rrset_class_str = _swig_property(_get_class_str)
229
230         __swig_getmethods__["dname"] = _unboundmodule._get_dname
231         if _newclass:dname = _swig_property(_unboundmodule._get_dname)
232
233         __swig_getmethods__["dname_list"] = _unboundmodule._get_dname_components
234         if _newclass:dname_list = _swig_property(_unboundmodule._get_dname_components)
235
236         def _get_dname_str(self): return dnameAsStr(self.dname)
237         __swig_getmethods__["dname_str"] = _get_dname_str
238         if _newclass:dname_str = _swig_property(_get_dname_str)
239    %}
240 }
241
242 #if defined(SWIGWORDSIZE64) 
243 typedef long int                rrset_id_t;
244 #else 
245 typedef long long int           rrset_id_t;
246 #endif 
247
248 struct ub_packed_rrset_key {
249    struct lruhash_entry entry;
250    rrset_id_t id;
251    struct packed_rrset_key rk;
252 };
253
254 struct lruhash_entry {
255   lock_rw_t lock;
256   struct lruhash_entry* overflow_next;
257   struct lruhash_entry* lru_next;
258   struct lruhash_entry* lru_prev;
259   hashvalue_t hash;
260   void* key;
261   struct packed_rrset_data* data;
262 };
263
264 %ignore packed_rrset_data::rr_len;
265 %ignore packed_rrset_data::rr_ttl;
266 %ignore packed_rrset_data::rr_data;
267
268 struct packed_rrset_data {
269   uint32_t ttl; //TTL (in seconds like time())
270
271   size_t count; //number of rrs
272   size_t rrsig_count; //number of rrsigs
273
274   enum rrset_trust trust; 
275   enum sec_status security;
276
277   size_t* rr_len;   //length of every rr's rdata
278   uint32_t *rr_ttl; //ttl of every rr
279   uint8_t** rr_data; //array of pointers to every rr's rdata; The rr_data[i] rdata is stored in uncompressed wireformat. 
280 };
281
282 %pythoncode %{
283     class RRSetData_RRLen:
284         def __init__(self, obj): self.obj = obj
285         def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index)
286         def __len__(self): return obj.count + obj.rrsig_count
287     class RRSetData_RRTTL:
288         def __init__(self, obj): self.obj = obj
289         def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index)
290         def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value)
291         def __len__(self): return obj.count + obj.rrsig_count
292     class RRSetData_RRData:
293         def __init__(self, obj): self.obj = obj
294         def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index)
295         def __len__(self): return obj.count + obj.rrsig_count
296 %}
297
298 %inline %{
299    PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
300      if ((d != NULL) && (idx >= 0) && 
301              ((size_t)idx < (d->count+d->rrsig_count))) 
302         return PyInt_FromLong(d->rr_len[idx]);
303      return Py_None;
304    }
305    void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
306    {
307      if ((d != NULL) && (idx >= 0) && 
308              ((size_t)idx < (d->count+d->rrsig_count))) 
309         d->rr_ttl[idx] = ttl;
310    }
311    PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
312      if ((d != NULL) && (idx >= 0) && 
313              ((size_t)idx < (d->count+d->rrsig_count))) 
314         return PyInt_FromLong(d->rr_ttl[idx]);
315      return Py_None;
316    }
317    PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
318      if ((d != NULL) && (idx >= 0) && 
319              ((size_t)idx < (d->count+d->rrsig_count))) 
320         return PyString_FromStringAndSize((char*)d->rr_data[idx],
321                 d->rr_len[idx]);
322      return Py_None;
323    }
324 %}
325
326 %extend packed_rrset_data {
327    %pythoncode %{
328         def _get_data_rr_len(self): return RRSetData_RRLen(self)
329         __swig_getmethods__["rr_len"] = _get_data_rr_len
330         if _newclass:rr_len = _swig_property(_get_data_rr_len)
331         def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
332         __swig_getmethods__["rr_ttl"] =_get_data_rr_ttl
333         if _newclass:rr_len = _swig_property(_get_data_rr_ttl)
334         def _get_data_rr_data(self): return RRSetData_RRData(self)
335         __swig_getmethods__["rr_data"] = _get_data_rr_data
336         if _newclass:rr_len = _swig_property(_get_data_rr_data)
337    %}
338 }
339
340 /* ************************************************************************************ * 
341    Structure reply_info
342  * ************************************************************************************ */
343 /* Messages */
344 %ignore reply_info::rrsets;
345 %ignore reply_info::ref;
346
347 struct reply_info {
348    uint16_t flags;
349    uint16_t qdcount;
350    uint32_t ttl;
351    uint32_t prefetch_ttl;
352
353    uint16_t authoritative;
354    enum sec_status security;
355
356    size_t an_numrrsets;
357    size_t ns_numrrsets;
358    size_t ar_numrrsets;
359    size_t rrset_count; // an_numrrsets + ns_numrrsets + ar_numrrsets
360
361    struct ub_packed_rrset_key** rrsets;
362    struct rrset_ref ref[1]; //?
363 };
364
365 struct rrset_ref {
366    struct ub_packed_rrset_key* key;
367    rrset_id_t id;
368 };
369
370 struct dns_msg {
371    struct query_info qinfo;
372    struct reply_info *rep;
373 };
374
375 %pythoncode %{
376     class ReplyInfo_RRSet:
377         def __init__(self, obj): self.obj = obj
378         def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index)
379         def __len__(self): return obj.rrset_count
380
381     class ReplyInfo_Ref:
382         def __init__(self, obj): self.obj = obj
383         def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index)
384         def __len__(self): return obj.rrset_count
385 %}
386
387 %inline %{
388    struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) {
389      if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count))
390         return r->rrsets[idx];
391      return NULL;
392    }
393
394    struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
395      if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) {
396 //printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key);
397              return &(r->ref[idx]);
398 //        return &(r->ref[idx]);
399      }
400 //printf("_rrset_ref_get: NULL\n");
401      return NULL;
402    }
403 %}
404
405 %extend reply_info {
406    %pythoncode %{
407         def _rrset_ref_get(self): return ReplyInfo_Ref(self)
408         __swig_getmethods__["ref"] = _rrset_ref_get
409         if _newclass:ref = _swig_property(_rrset_ref_get)
410
411         def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
412         __swig_getmethods__["rrsets"] = _rrset_rrsets_get
413         if _newclass:rrsets = _swig_property(_rrset_rrsets_get)
414    %}
415 }
416
417 /* ************************************************************************************ * 
418    Structure mesh_state
419  * ************************************************************************************ */
420 struct mesh_state {
421    struct mesh_reply* reply_list;
422 };
423
424 struct mesh_reply {
425    struct mesh_reply* next;
426    struct comm_reply query_reply;
427 };
428
429 struct comm_reply {
430    
431 };
432
433 %inline %{
434
435   PyObject* _comm_reply_addr_get(struct comm_reply* reply) {
436      char dest[64];
437      reply_addr2str(reply, dest, 64);
438      if (dest[0] == 0)
439         return Py_None;
440      return PyString_FromString(dest);
441   }
442
443   PyObject* _comm_reply_family_get(struct comm_reply* reply) {
444
445         int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
446
447         switch(af) {
448            case AF_INET: return PyString_FromString("ip4");
449            case AF_INET6: return PyString_FromString("ip6"); 
450            case AF_UNIX: return PyString_FromString("unix");
451         }
452
453         return Py_None;
454   }
455
456   PyObject* _comm_reply_port_get(struct comm_reply* reply) {
457      uint16_t port;
458      port = ntohs(((struct sockaddr_in*)&(reply->addr))->sin_port);
459      return PyInt_FromLong(port);
460   }
461
462 %}
463
464 %extend comm_reply {
465    %pythoncode %{
466         def _addr_get(self): return _comm_reply_addr_get(self)
467         __swig_getmethods__["addr"] = _addr_get
468         if _newclass:addr = _swig_property(_addr_get)
469
470         def _port_get(self): return _comm_reply_port_get(self)
471         __swig_getmethods__["port"] = _port_get
472         if _newclass:port = _swig_property(_port_get)
473
474         def _family_get(self): return _comm_reply_family_get(self)
475         __swig_getmethods__["family"] = _family_get
476         if _newclass:family = _swig_property(_family_get)
477    %}
478 }
479 /* ************************************************************************************ * 
480    Structure module_qstate
481  * ************************************************************************************ */
482 %ignore module_qstate::ext_state;
483 %ignore module_qstate::minfo;
484
485 /* Query state */
486 struct module_qstate {
487    struct query_info qinfo;
488    uint16_t query_flags; //See QF_BIT_xx constants
489    int      is_priming;
490
491    struct comm_reply* reply;
492    struct dns_msg* return_msg;
493    int    return_rcode;
494    struct regional* region; /* unwrapped */
495
496    int    curmod;
497
498    enum   module_ext_state ext_state[MAX_MODULE];
499    void*  minfo[MAX_MODULE];
500
501    struct module_env* env;         /* unwrapped */
502    struct mesh_state* mesh_info;
503 };
504
505 %constant int MODULE_COUNT = MAX_MODULE;
506
507 %constant int QF_BIT_CD = 0x0010;
508 %constant int QF_BIT_AD = 0x0020;
509 %constant int QF_BIT_Z  = 0x0040;
510 %constant int QF_BIT_RA = 0x0080;
511 %constant int QF_BIT_RD = 0x0100;
512 %constant int QF_BIT_TC = 0x0200;
513 %constant int QF_BIT_AA = 0x0400;
514 %constant int QF_BIT_QR = 0x8000;
515
516 %inline %{
517  enum enum_return_rcode {
518    RCODE_NOERROR = 0,
519    RCODE_FORMERR = 1,
520    RCODE_SERVFAIL = 2,
521    RCODE_NXDOMAIN = 3,
522    RCODE_NOTIMPL = 4,
523    RCODE_REFUSED = 5,
524    RCODE_YXDOMAIN = 6,
525    RCODE_YXRRSET = 7,
526    RCODE_NXRRSET = 8,
527    RCODE_NOTAUTH = 9,
528    RCODE_NOTZONE = 10
529  };
530 %}
531
532 %pythoncode %{
533     class ExtState:
534         def __init__(self, obj): self.obj = obj
535         def __str__(self):
536             return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)])
537         def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index)
538         def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value)
539         def __len__(self): return _unboundmodule.MODULE_COUNT
540 %}
541
542 %inline %{
543    enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
544      if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
545         return q->ext_state[idx];
546      } 
547      return 0;
548    }
549   
550    void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
551      if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
552         q->ext_state[idx] = state;
553      } 
554    }
555 %}
556
557 %extend module_qstate {
558    %pythoncode %{
559         def set_ext_state(self, id, state):
560             """Sets the ext state"""
561             _unboundmodule._ext_state_set(self, id, state)
562
563         def __ext_state_get(self): return ExtState(self)
564         __swig_getmethods__["ext_state"] = __ext_state_get
565         if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
566    %}
567 }
568
569 /* ************************************************************************************ * 
570    Structure config_strlist
571  * ************************************************************************************ */
572 struct config_strlist {
573    struct config_strlist* next;
574    char* str;
575 };
576
577 /* ************************************************************************************ * 
578    Structure config_str2list
579  * ************************************************************************************ */
580 struct config_str2list {
581    struct config_str2list* next;
582    char* str;
583    char* str2;
584 };
585
586 /* ************************************************************************************ * 
587    Structure config_file
588  * ************************************************************************************ */
589 struct config_file {
590    int verbosity;
591    int stat_interval;
592    int stat_cumulative;
593    int stat_extended;
594    int num_threads;
595    int port;
596    int do_ip4;
597    int do_ip6;
598    int do_udp;
599    int do_tcp;
600    int outgoing_num_ports;
601    size_t outgoing_num_tcp;
602    size_t incoming_num_tcp;
603    int* outgoing_avail_ports;
604    size_t msg_buffer_size;
605    size_t msg_cache_size;
606    size_t msg_cache_slabs;
607    size_t num_queries_per_thread;
608    size_t jostle_time;
609    size_t rrset_cache_size;
610    size_t rrset_cache_slabs;
611    int host_ttl;
612    size_t infra_cache_slabs;
613    size_t infra_cache_numhosts;
614    char* target_fetch_policy;
615    int if_automatic;
616    int num_ifs;
617    char **ifs;
618    int num_out_ifs;
619    char **out_ifs;
620    struct config_strlist* root_hints;
621    struct config_stub* stubs;
622    struct config_stub* forwards;
623    struct config_strlist* donotqueryaddrs;
624    struct config_str2list* acls;
625    int donotquery_localhost;
626    int harden_short_bufsize;
627    int harden_large_queries;
628    int harden_glue;
629    int harden_dnssec_stripped;
630    int harden_referral_path;
631    int use_caps_bits_for_id;
632    struct config_strlist* private_address;
633    struct config_strlist* private_domain;
634    size_t unwanted_threshold;
635    char* chrootdir;
636    char* username;
637    char* directory;
638    char* logfile;
639    char* pidfile;
640    int use_syslog;
641    int hide_identity;
642    int hide_version;
643    char* identity;
644    char* version;
645    char* module_conf;
646    struct config_strlist* trust_anchor_file_list;
647    struct config_strlist* trust_anchor_list;
648    struct config_strlist* trusted_keys_file_list;
649    char* dlv_anchor_file;
650    struct config_strlist* dlv_anchor_list;
651    int max_ttl;
652    int32_t val_date_override;
653    int bogus_ttl; 
654    int val_clean_additional;
655    int val_permissive_mode;
656    char* val_nsec3_key_iterations;
657    size_t key_cache_size;
658    size_t key_cache_slabs;
659    size_t neg_cache_size;
660    struct config_str2list* local_zones;
661    struct config_strlist* local_zones_nodefault;
662    struct config_strlist* local_data;
663    int remote_control_enable;
664    struct config_strlist* control_ifs;
665    int control_port;
666    char* server_key_file;
667    char* server_cert_file;
668    char* control_key_file;
669    char* control_cert_file;
670    int do_daemonize;
671    char* python_script;
672 };
673
674 /* ************************************************************************************ * 
675    Enums
676  * ************************************************************************************ */
677 %rename ("MODULE_STATE_INITIAL") "module_state_initial";
678 %rename ("MODULE_WAIT_REPLY") "module_wait_reply";
679 %rename ("MODULE_WAIT_MODULE") "module_wait_module";
680 %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
681 %rename ("MODULE_ERROR") "module_error";
682 %rename ("MODULE_FINISHED") "module_finished";
683
684 enum module_ext_state {
685    module_state_initial = 0,
686    module_wait_reply,
687    module_wait_module,
688    module_wait_subquery,
689    module_error,
690    module_finished
691 };
692
693 %rename ("MODULE_EVENT_NEW") "module_event_new";
694 %rename ("MODULE_EVENT_PASS") "module_event_pass";
695 %rename ("MODULE_EVENT_REPLY") "module_event_reply";
696 %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply";
697 %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail";
698 %rename ("MODULE_EVENT_MODDONE") "module_event_moddone";
699 %rename ("MODULE_EVENT_ERROR") "module_event_error";
700
701 enum module_ev {
702    module_event_new = 0,
703    module_event_pass,
704    module_event_reply,
705    module_event_noreply,
706    module_event_capsfail,
707    module_event_moddone,
708    module_event_error
709 };
710
711 enum sec_status {
712    sec_status_unchecked = 0,
713    sec_status_bogus,
714    sec_status_indeterminate,
715    sec_status_insecure,
716    sec_status_secure
717 };
718
719 enum verbosity_value {
720    NO_VERBOSE = 0,
721    VERB_OPS,
722    VERB_DETAIL,
723    VERB_QUERY,
724    VERB_ALGO
725 };
726
727 %constant uint16_t PKT_QR = 1;      /* QueRy - query flag */
728 %constant uint16_t PKT_AA = 2;      /* Authoritative Answer - server flag */
729 %constant uint16_t PKT_TC = 4;      /* TrunCated - server flag */
730 %constant uint16_t PKT_RD = 8;      /* Recursion Desired - query flag */
731 %constant uint16_t PKT_CD = 16;     /* Checking Disabled - query flag */
732 %constant uint16_t PKT_RA = 32;     /* Recursion Available - server flag */
733 %constant uint16_t PKT_AD = 64;     /* Authenticated Data - server flag */
734
735 %{
736 int checkList(PyObject *l) 
737 {
738     PyObject* item;
739     int i;
740
741     if (l == Py_None) 
742        return 1;
743
744     if (PyList_Check(l)) 
745     {
746        for (i=0; i < PyList_Size(l); i++) 
747        {
748            item = PyList_GetItem(l, i);
749            if (!PyString_Check(item))
750               return 0;
751        }
752        return 1;
753     }
754
755     return 0;
756 }
757
758 int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
759         size_t count_offset)
760 {
761     PyObject* item;
762     int i;
763     size_t len;
764
765     for (i=0; i < PyList_Size(l); i++) 
766     {
767         item = PyList_GetItem(l, i);
768
769         len = sldns_buffer_remaining(qb);
770         if(qsec) {
771                 if(sldns_str2wire_rr_question_buf(PyString_AsString(item),
772                         sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
773                         != 0)
774                         return 0;
775         } else {
776                 if(sldns_str2wire_rr_buf(PyString_AsString(item),
777                         sldns_buffer_current(qb), &len, NULL, default_ttl,
778                         NULL, 0, NULL, 0) != 0)
779                         return 0;
780         }
781         sldns_buffer_skip(qb, len);
782
783         sldns_buffer_write_u16_at(qb, count_offset,
784                 sldns_buffer_read_u16_at(qb, count_offset)+1);
785     }
786     return 1;
787 }
788
789 int set_return_msg(struct module_qstate* qstate, 
790                    const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
791                    PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional) 
792 {
793      sldns_buffer *qb = 0;
794      int res = 1;
795      size_t l;
796      uint16_t PKT_QR = 1;
797      uint16_t PKT_AA = 2;
798      uint16_t PKT_TC = 4;
799      uint16_t PKT_RD = 8;
800      uint16_t PKT_CD = 16;
801      uint16_t PKT_RA = 32;
802      uint16_t PKT_AD = 64;
803  
804      if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
805         return 0;
806      if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0;
807
808      /* write header */
809      sldns_buffer_write_u16(qb, 0); /* ID */
810      sldns_buffer_write_u16(qb, 0); /* flags */
811      sldns_buffer_write_u16(qb, 1); /* qdcount */
812      sldns_buffer_write_u16(qb, 0); /* ancount */
813      sldns_buffer_write_u16(qb, 0); /* nscount */
814      sldns_buffer_write_u16(qb, 0); /* arcount */
815      if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb));
816      if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb));
817      if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb));
818      if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb));
819      if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb));
820      if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb));
821      if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb));
822
823      /* write the query */
824      l = sldns_buffer_remaining(qb);
825      if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) {
826              sldns_buffer_free(qb);
827              return 0;
828      }
829      sldns_buffer_skip(qb, l);
830      if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; }
831      if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; }
832      sldns_buffer_write_u16(qb, rr_type);
833      sldns_buffer_write_u16(qb, rr_class);
834
835      /* write RR sections */
836      if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF))
837              res = 0;
838      if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF))
839              res = 0;
840      if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF))
841              res = 0;
842      if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF))
843              res = 0;
844
845      if (res) res = createResponse(qstate, qb);
846
847      if (qb) sldns_buffer_free(qb);
848      return res;
849 }
850 %}
851
852 int set_return_msg(struct module_qstate* qstate, 
853                    const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
854                    PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
855
856 %pythoncode %{
857     class DNSMessage:
858         def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0):
859             """Query flags is a combination of PKT_xx contants"""
860             self.rr_name = rr_name
861             self.rr_type = rr_type
862             self.rr_class = rr_class
863             self.default_ttl = default_ttl
864             self.query_flags = query_flags
865             self.question = []
866             self.answer = []
867             self.authority = []
868             self.additional = []
869
870         def set_return_msg(self, qstate):
871             """Returns 1 if OK"""
872             status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class, 
873                                            self.query_flags, self.default_ttl,
874                                            self.question, self.answer, self.authority, self.additional)
875
876             if (status) and (PKT_AA & self.query_flags):
877                 qstate.return_msg.rep.authoritative = 1
878
879             return status 
880
881 %}
882 /* ************************************************************************************ * 
883    Functions
884  * ************************************************************************************ */
885
886 // Various debuging functions
887 void verbose(enum verbosity_value level, const char* format, ...);
888 void log_info(const char* format, ...);
889 void log_err(const char* format, ...);
890 void log_warn(const char* format, ...);
891 void log_hex(const char* msg, void* data, size_t length);
892 void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep);
893 void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
894 void regional_log_stats(struct regional *r);
895
896 // Free allocated memory from marked sources returning corresponding types
897 %typemap(newfree, noblock = 1) char * {
898   free($1);
899 }
900
901 // Mark as source returning newly allocated memory
902 %newobject sldns_wire2str_type;
903 %newobject sldns_wire2str_class;
904
905 // LDNS functions
906 char *sldns_wire2str_type(const uint16_t atype);
907 char *sldns_wire2str_class(const uint16_t aclass);
908
909 // Functions from pythonmod_utils
910 int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
911 void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
912
913 // Module conversion functions
914 const char* strextstate(enum module_ext_state s);
915 const char* strmodulevent(enum module_ev e);
916