mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-21 07:02:28 +02:00
- Add patch from Jan Vcelak for pythonmod,
add sockaddr_storage getters, add support for query callbacks, allow raw address access via comm_reply and update API documentation. git-svn-id: file:///svn/unbound/trunk@4962 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
+206
-35
@@ -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"
|
||||
@@ -426,6 +428,155 @@ struct dns_msg {
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure sockaddr_storage
|
||||
* ************************************************************************************ */
|
||||
|
||||
struct sockaddr_storage {};
|
||||
|
||||
%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;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
const struct sockaddr *sa = (struct sockaddr *)ss;
|
||||
size_t sa_len = _sockaddr_storage_len(ss);
|
||||
if (sa_len == 0) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
char name[NI_MAXHOST] = {0};
|
||||
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) {
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
size_t 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);
|
||||
}
|
||||
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
if (ss->ss_family == AF_INET) {
|
||||
const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
|
||||
return PyInt_FromLong(ntohs(sa4->sin_port));
|
||||
}
|
||||
|
||||
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 *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
|
||||
if (ss == NULL || ss->ss_family != AF_INET6) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
|
||||
return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
|
||||
if (ss == NULL || ss->ss_family != AF_INET6) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
const struct sockaddr_in6 *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
|
||||
* ************************************************************************************ */
|
||||
@@ -438,52 +589,22 @@ struct mesh_reply {
|
||||
struct comm_reply query_reply;
|
||||
};
|
||||
|
||||
%rename(_addr) comm_reply::addr;
|
||||
struct comm_reply {
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
};
|
||||
|
||||
%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 PyBytes_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 PyBytes_FromString("ip4");
|
||||
case AF_INET6: return PyBytes_FromString("ip6");
|
||||
case AF_UNIX: return PyBytes_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)
|
||||
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)
|
||||
%}
|
||||
@@ -1437,6 +1558,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 +1620,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);
|
||||
|
||||
Reference in New Issue
Block a user