Skip to content

Commit

Permalink
added context_set_upstream_recursive_servers(context, [address_list])…
Browse files Browse the repository at this point in the history
…, created generic getdns_dict address dict converter
  • Loading branch information
MelindaShore committed Jun 5, 2014
1 parent fbc660b commit 0b109a2
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
61 changes: 61 additions & 0 deletions getdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,66 @@ context_set_edns_do_bit(PyObject *self, PyObject *args, PyObject *keywds)
}


static PyObject *
context_set_upstream_recursive_servers(PyObject *self, PyObject *args, PyObject *keywds)
{
static char *kwlist[] = {
"context",
"upstream_list",
0
};
PyObject *context_capsule;
struct getdns_context *context;
PyObject *py_upstream_list;
int len;
PyObject *py_upstream;
struct getdns_list *upstream_list;
int i;
getdns_return_t ret;

if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO", kwlist,
&context_capsule, &py_upstream_list)) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
context = PyCapsule_GetPointer(context_capsule, "context");
if (!PyList_Check(py_upstream_list)) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
if ((len = (int)PyList_Size(py_upstream_list)) == 0) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}

upstream_list = getdns_list_create();
for (i = 0 ; i < len ; i++) {
getdns_dict *a_upstream;

if ((py_upstream = PyList_GetItem(py_upstream_list, (Py_ssize_t)i)) != NULL) {
if ((a_upstream = getdnsify_addressdict(py_upstream)) == NULL) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
if (getdns_list_set_dict(upstream_list, i, a_upstream) != GETDNS_RETURN_GOOD) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
} else {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
}
if ((ret = getdns_context_set_upstream_recursive_servers(context, upstream_list)) != GETDNS_RETURN_GOOD) {
char err_buf[256];
getdns_strerror(ret, err_buf, sizeof err_buf);
PyErr_SetString(getdns_error, err_buf);
return NULL;
}
return Py_None;

}


static PyObject *
context_get_api_information(PyObject *self, PyObject *args, PyObject *keywds)
Expand Down Expand Up @@ -1292,6 +1352,7 @@ static struct PyMethodDef getdns_methods[] = {
{ "context_get_api_information", (PyCFunction)context_get_api_information, METH_KEYWORDS },
{ "context_fd", (PyCFunction)context_fd, METH_KEYWORDS },
{ "context_get_num_pending_requests", (PyCFunction)context_get_num_pending_requests, METH_KEYWORDS },
{ "context_set_upstream_recursive_servers", (PyCFunction)context_set_upstream_recursive_servers, METH_KEYWORDS },
{ "context_process_async", (PyCFunction)context_process_async, METH_KEYWORDS },
{ 0, 0, 0 }
};
Expand Down
1 change: 1 addition & 0 deletions pygetdns.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ char *reverse_address(struct getdns_bindata *address_data);
PyObject *context_fd(PyObject *self, PyObject *args, PyObject *keywds);
PyObject *context_get_num_pending_requests(PyObject *self, PyObject *args, PyObject *keywds);
PyObject *context_process_async(PyObject *self, PyObject *args, PyObject *keywds);
getdns_dict *getdnsify_addressdict(PyObject *pydict);

typedef struct pygetdns_libevent_callback_data {
char *callback_func;
Expand Down
70 changes: 70 additions & 0 deletions pygetdns_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/

#include <Python.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <getdns/getdns.h>
Expand Down Expand Up @@ -184,6 +185,75 @@ extensions_to_getdnsdict(PyDictObject *pydict)
return newdict;
}


/*
* turn a Python address dictionary into a getdns data structure (inc. validation)
*/


getdns_dict *
getdnsify_addressdict(PyObject *pydict)
{
getdns_dict *addr_dict;
getdns_bindata addr_data;
getdns_bindata addr_type;
PyObject *str;
unsigned char buf[sizeof(struct in6_addr)];
int domain;


if (!PyDict_Check(pydict)) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
if (PyDict_Size(pydict) != 2) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
addr_dict = getdns_dict_create();
if ((str = PyDict_GetItemString(pydict, "address_type")) == NULL) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
if (!PyString_Check(str)) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
addr_type.data = (uint8_t *)strdup(PyString_AsString(str));
addr_type.size = strlen((char *)addr_type.data);
if (strlen((char *)addr_type.data) != 4) {
PyErr_SetString(getdns_error, GETDNS_RETURN_WRONG_TYPE_REQUESTED_TEXT);
return NULL;
}
if (!strncasecmp((char *)addr_type.data, "IPv4", 4))
domain = AF_INET;
else if (!strncasecmp((char *)addr_type.data, "IPv6", 4))
domain = AF_INET6;
else {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
getdns_dict_set_bindata(addr_dict, "address_type", &addr_type);

if ((str = PyDict_GetItemString(pydict, "address_data")) == NULL) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
if (!PyString_Check(str)) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
if (inet_pton(domain, PyString_AsString(str), buf) <= 0) {
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
return NULL;
}
addr_data.data = (uint8_t *)buf;
addr_data.size = (domain == AF_INET ? 4 : 16);
getdns_dict_set_bindata(addr_dict, "address_data", &addr_data);
return addr_dict;
}


PyObject *
decode_getdns_response(struct getdns_dict *response)
{
Expand Down

0 comments on commit 0b109a2

Please sign in to comment.