aboutsummaryrefslogtreecommitdiff
path: root/pythonmod/interface.i
diff options
context:
space:
mode:
Diffstat (limited to 'pythonmod/interface.i')
-rw-r--r--pythonmod/interface.i289
1 files changed, 246 insertions, 43 deletions
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
index 96accb69cca6..5f2559bacffa 100644
--- a/pythonmod/interface.i
+++ b/pythonmod/interface.i
@@ -12,6 +12,8 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+ #include <netdb.h>
+ #include <sys/un.h>
#include <stdarg.h>
#include "config.h"
#include "util/log.h"
@@ -43,15 +45,21 @@
i = 0;
while (i < len) {
- i += name[i] + 1;
+ i += ((unsigned int)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;
+ char buf[LDNS_MAX_LABELLEN+1];
+ if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) &&
+ i+(int)((unsigned int)name[i]) < len) {
+ memmove(buf, name + i + 1, (unsigned int)name[i]);
+ buf[(unsigned int)name[i]] = 0;
+ PyList_SetItem(list, cnt, PyString_FromString(buf));
+ }
+ i += ((unsigned int)name[i]) + 1;
cnt++;
}
return list;
@@ -159,11 +167,11 @@ struct query_info {
%}
%inline %{
- PyObject* dnameAsStr(const char* dname) {
+ PyObject* dnameAsStr(PyObject* dname) {
char buf[LDNS_MAX_DOMAINLEN+1];
buf[0] = '\0';
- dname_str((uint8_t*)dname, buf);
- return PyBytes_FromString(buf);
+ dname_str((uint8_t*)PyBytes_AsString(dname), buf);
+ return PyString_FromString(buf);
}
%}
@@ -427,63 +435,191 @@ struct dns_msg {
}
/* ************************************************************************************ *
- Structure mesh_state
+ Structure sockaddr_storage
* ************************************************************************************ */
-struct mesh_state {
- struct mesh_reply* reply_list;
-};
-struct mesh_reply {
- struct mesh_reply* next;
- struct comm_reply query_reply;
-};
+struct sockaddr_storage {};
-struct comm_reply {
+%inline %{
+ static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) {
+ if (ss == NULL) {
+ return 0;
+ }
-};
+ switch (ss->ss_family) {
+ case AF_INET: return sizeof(struct sockaddr_in);
+ case AF_INET6: return sizeof(struct sockaddr_in6);
+ case AF_UNIX: return sizeof(struct sockaddr_un);
+ default:
+ return 0;
+ }
+ }
-%inline %{
+ PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) {
+ if (ss == NULL) {
+ return Py_None;
+ }
+
+ switch (ss->ss_family) {
+ case AF_INET: return PyUnicode_FromString("ip4");
+ case AF_INET6: return PyUnicode_FromString("ip6");
+ case AF_UNIX: return PyUnicode_FromString("unix");
+ default:
+ return Py_None;
+ }
+ }
+
+ PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) {
+ const struct sockaddr *sa;
+ size_t sa_len;
+ char name[NI_MAXHOST] = {0};
+
+ if (ss == NULL) {
+ return Py_None;
+ }
+
+ sa = (struct sockaddr *)ss;
+ sa_len = _sockaddr_storage_len(ss);
+ if (sa_len == 0) {
+ return Py_None;
+ }
+
+ if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) {
+ return Py_None;
+ }
+
+ return PyUnicode_FromString(name);
+ }
+
+ PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) {
+ size_t sa_len;
+
+ if (ss == NULL) {
+ return Py_None;
+ }
+
+ sa_len = _sockaddr_storage_len(ss);
+ if (sa_len == 0) {
+ return Py_None;
+ }
+
+ if (ss->ss_family == AF_INET) {
+ const struct sockaddr_in *sa = (struct sockaddr_in *)ss;
+ const struct in_addr *raw = (struct in_addr *)&sa->sin_addr;
+ return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
+ }
+
+ if (ss->ss_family == AF_INET6) {
+ const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
+ const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr;
+ return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
+ }
+
+ if (ss->ss_family == AF_UNIX) {
+ const struct sockaddr_un *sa = (struct sockaddr_un *)ss;
+ return PyBytes_FromString(sa->sun_path);
+ }
- 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 PyBytes_FromString(dest);
- }
+ }
- PyObject* _comm_reply_family_get(struct comm_reply* reply) {
+ PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
+ if (ss == NULL) {
+ return Py_None;
+ }
- int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
+ if (ss->ss_family == AF_INET) {
+ const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
+ return PyInt_FromLong(ntohs(sa4->sin_port));
+ }
- switch(af) {
- case AF_INET: return PyBytes_FromString("ip4");
- case AF_INET6: return PyBytes_FromString("ip6");
- case AF_UNIX: return PyBytes_FromString("unix");
+ if (ss->ss_family == AF_INET6) {
+ const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
+ return PyInt_FromLong(ntohs(sa6->sin6_port));
}
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);
- }
+ PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
+ const struct sockaddr_in6 *sa6;
+
+ if (ss == NULL || ss->ss_family != AF_INET6) {
+ return Py_None;
+ }
+ sa6 = (struct sockaddr_in6 *)ss;
+ return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
+ }
+
+ PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
+ const struct sockaddr_in6 *sa6;
+
+ if (ss == NULL || ss->ss_family != AF_INET6) {
+ return Py_None;
+ }
+
+ sa6 = (struct sockaddr_in6 *)ss;
+ return PyInt_FromLong(ntohl(sa6->sin6_scope_id));
+ }
%}
+%extend sockaddr_storage {
+ %pythoncode %{
+ def _family_get(self): return _sockaddr_storage_family(self)
+ __swig_getmethods__["family"] = _family_get
+ if _newclass: family = _swig_property(_family_get)
+
+ def _addr_get(self): return _sockaddr_storage_addr(self)
+ __swig_getmethods__["addr"] = _addr_get
+ if _newclass: addr = _swig_property(_addr_get)
+
+ def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self)
+ __swig_getmethods__["raw_addr"] = _raw_addr_get
+ if _newclass: raw_addr = _swig_property(_raw_addr_get)
+
+ def _port_get(self): return _sockaddr_storage_port(self)
+ __swig_getmethods__["port"] = _port_get
+ if _newclass: port = _swig_property(_port_get)
+
+ def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self)
+ __swig_getmethods__["flowinfo"] = _flowinfo_get
+ if _newclass: flowinfo = _swig_property(_flowinfo_get)
+
+ def _scope_id_get(self): return _sockaddr_storage_scope_id(self)
+ __swig_getmethods__["scope_id"] = _scope_id_get
+ if _newclass: scope_id = _swig_property(_scope_id_get)
+ %}
+}
+
+/* ************************************************************************************ *
+ Structure mesh_state
+ * ************************************************************************************ */
+struct mesh_state {
+ struct mesh_reply* reply_list;
+};
+
+struct mesh_reply {
+ struct mesh_reply* next;
+ struct comm_reply query_reply;
+};
+
+%rename(_addr) comm_reply::addr;
+struct comm_reply {
+ struct sockaddr_storage addr;
+};
+
%extend comm_reply {
%pythoncode %{
- def _addr_get(self): return _comm_reply_addr_get(self)
+ def _addr_get(self): return _sockaddr_storage_addr(self._addr)
__swig_getmethods__["addr"] = _addr_get
if _newclass:addr = _swig_property(_addr_get)
- def _port_get(self): return _comm_reply_port_get(self)
+ def _port_get(self): return _sockaddr_storage_port(self._addr)
__swig_getmethods__["port"] = _port_get
if _newclass:port = _swig_property(_port_get)
- def _family_get(self): return _comm_reply_family_get(self)
+ def _family_get(self): return _sockaddr_storage_family(self._addr)
__swig_getmethods__["family"] = _family_get
if _newclass:family = _swig_property(_family_get)
%}
@@ -1081,7 +1217,7 @@ int checkList(PyObject *l)
for (i=0; i < PyList_Size(l); i++)
{
item = PyList_GetItem(l, i);
- if (!PyBytes_Check(item))
+ if (!PyBytes_Check(item) && !PyUnicode_Check(item))
return 0;
}
return 1;
@@ -1096,23 +1232,40 @@ int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
PyObject* item;
int i;
size_t len;
+ char* s;
+ PyObject* ascstr;
for (i=0; i < PyList_Size(l); i++)
{
+ ascstr = NULL;
item = PyList_GetItem(l, i);
+ if(PyObject_TypeCheck(item, &PyBytes_Type)) {
+ s = PyBytes_AsString(item);
+ } else {
+ ascstr = PyUnicode_AsASCIIString(item);
+ s = PyBytes_AsString(ascstr);
+ }
len = sldns_buffer_remaining(qb);
if(qsec) {
- if(sldns_str2wire_rr_question_buf(PyBytes_AsString(item),
+ if(sldns_str2wire_rr_question_buf(s,
sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
- != 0)
+ != 0) {
+ if(ascstr)
+ Py_DECREF(ascstr);
return 0;
+ }
} else {
- if(sldns_str2wire_rr_buf(PyBytes_AsString(item),
+ if(sldns_str2wire_rr_buf(s,
sldns_buffer_current(qb), &len, NULL, default_ttl,
- NULL, 0, NULL, 0) != 0)
+ NULL, 0, NULL, 0) != 0) {
+ if(ascstr)
+ Py_DECREF(ascstr);
return 0;
+ }
}
+ if(ascstr)
+ Py_DECREF(ascstr);
sldns_buffer_skip(qb, len);
sldns_buffer_write_u16_at(qb, count_offset,
@@ -1437,6 +1590,54 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
return python_inplace_cb_register(inplace_cb_reply_servfail,
py_cb, env, id);
}
+
+ int python_inplace_cb_query_generic(
+ struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
+ struct sockaddr_storage* addr, socklen_t addrlen,
+ uint8_t* zone, size_t zonelen, struct regional* region, int id,
+ void* python_callback)
+ {
+ int res = 0;
+ PyObject *func = python_callback;
+
+ PyGILState_STATE gstate = PyGILState_Ensure();
+
+ PyObject *py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
+ PyObject *py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
+ PyObject *py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
+ PyObject *py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
+ PyObject *py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
+
+ PyObject *py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
+ PyObject *py_kwargs = Py_BuildValue("{}");
+ PyObject *result = PyObject_Call(func, py_args, py_kwargs);
+ if (result) {
+ res = PyInt_AsLong(result);
+ }
+
+ Py_XDECREF(py_qinfo);
+ Py_XDECREF(py_qstate);
+ Py_XDECREF(py_addr);
+ Py_XDECREF(py_zone);
+ Py_XDECREF(py_region);
+
+ Py_XDECREF(py_args);
+ Py_XDECREF(py_kwargs);
+ Py_XDECREF(result);
+
+ PyGILState_Release(gstate);
+
+ return res;
+ }
+
+ static int register_inplace_cb_query(PyObject* py_cb,
+ struct module_env* env, int id)
+ {
+ int ret = inplace_cb_register(python_inplace_cb_query_generic,
+ inplace_cb_query, (void*) py_cb, env, id);
+ if (ret) Py_INCREF(py_cb);
+ return ret;
+ }
%}
/* C declarations */
int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
@@ -1451,3 +1652,5 @@ static int register_inplace_cb_reply_local(PyObject* py_cb,
struct module_env* env, int id);
static int register_inplace_cb_reply_servfail(PyObject* py_cb,
struct module_env* env, int id);
+static int register_inplace_cb_query(PyObject *py_cb,
+ struct module_env* env, int id);