]> git.saurik.com Git - apple/network_cmds.git/blob - unbound/pythonmod/interface.i
network_cmds-480.tar.gz
[apple/network_cmds.git] / unbound / 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, PyBytes_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 PyBytes_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 PyBytes_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 PyBytes_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