Skip to content

Commit 0b109a2

Browse files
committed
added context_set_upstream_recursive_servers(context, [address_list]), created generic getdns_dict address dict converter
1 parent fbc660b commit 0b109a2

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

getdns.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,66 @@ context_set_edns_do_bit(PyObject *self, PyObject *args, PyObject *keywds)
10191019
}
10201020

10211021

1022+
static PyObject *
1023+
context_set_upstream_recursive_servers(PyObject *self, PyObject *args, PyObject *keywds)
1024+
{
1025+
static char *kwlist[] = {
1026+
"context",
1027+
"upstream_list",
1028+
0
1029+
};
1030+
PyObject *context_capsule;
1031+
struct getdns_context *context;
1032+
PyObject *py_upstream_list;
1033+
int len;
1034+
PyObject *py_upstream;
1035+
struct getdns_list *upstream_list;
1036+
int i;
1037+
getdns_return_t ret;
1038+
1039+
if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO", kwlist,
1040+
&context_capsule, &py_upstream_list)) {
1041+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
1042+
return NULL;
1043+
}
1044+
context = PyCapsule_GetPointer(context_capsule, "context");
1045+
if (!PyList_Check(py_upstream_list)) {
1046+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
1047+
return NULL;
1048+
}
1049+
if ((len = (int)PyList_Size(py_upstream_list)) == 0) {
1050+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
1051+
return NULL;
1052+
}
1053+
1054+
upstream_list = getdns_list_create();
1055+
for (i = 0 ; i < len ; i++) {
1056+
getdns_dict *a_upstream;
1057+
1058+
if ((py_upstream = PyList_GetItem(py_upstream_list, (Py_ssize_t)i)) != NULL) {
1059+
if ((a_upstream = getdnsify_addressdict(py_upstream)) == NULL) {
1060+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
1061+
return NULL;
1062+
}
1063+
if (getdns_list_set_dict(upstream_list, i, a_upstream) != GETDNS_RETURN_GOOD) {
1064+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
1065+
return NULL;
1066+
}
1067+
} else {
1068+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
1069+
return NULL;
1070+
}
1071+
}
1072+
if ((ret = getdns_context_set_upstream_recursive_servers(context, upstream_list)) != GETDNS_RETURN_GOOD) {
1073+
char err_buf[256];
1074+
getdns_strerror(ret, err_buf, sizeof err_buf);
1075+
PyErr_SetString(getdns_error, err_buf);
1076+
return NULL;
1077+
}
1078+
return Py_None;
1079+
1080+
}
1081+
10221082

10231083
static PyObject *
10241084
context_get_api_information(PyObject *self, PyObject *args, PyObject *keywds)
@@ -1292,6 +1352,7 @@ static struct PyMethodDef getdns_methods[] = {
12921352
{ "context_get_api_information", (PyCFunction)context_get_api_information, METH_KEYWORDS },
12931353
{ "context_fd", (PyCFunction)context_fd, METH_KEYWORDS },
12941354
{ "context_get_num_pending_requests", (PyCFunction)context_get_num_pending_requests, METH_KEYWORDS },
1355+
{ "context_set_upstream_recursive_servers", (PyCFunction)context_set_upstream_recursive_servers, METH_KEYWORDS },
12951356
{ "context_process_async", (PyCFunction)context_process_async, METH_KEYWORDS },
12961357
{ 0, 0, 0 }
12971358
};

pygetdns.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ char *reverse_address(struct getdns_bindata *address_data);
4242
PyObject *context_fd(PyObject *self, PyObject *args, PyObject *keywds);
4343
PyObject *context_get_num_pending_requests(PyObject *self, PyObject *args, PyObject *keywds);
4444
PyObject *context_process_async(PyObject *self, PyObject *args, PyObject *keywds);
45+
getdns_dict *getdnsify_addressdict(PyObject *pydict);
4546

4647
typedef struct pygetdns_libevent_callback_data {
4748
char *callback_func;

pygetdns_util.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
*/
3333

3434
#include <Python.h>
35+
#include <arpa/inet.h>
3536
#include <stdio.h>
3637
#include <string.h>
3738
#include <getdns/getdns.h>
@@ -184,6 +185,75 @@ extensions_to_getdnsdict(PyDictObject *pydict)
184185
return newdict;
185186
}
186187

188+
189+
/*
190+
* turn a Python address dictionary into a getdns data structure (inc. validation)
191+
*/
192+
193+
194+
getdns_dict *
195+
getdnsify_addressdict(PyObject *pydict)
196+
{
197+
getdns_dict *addr_dict;
198+
getdns_bindata addr_data;
199+
getdns_bindata addr_type;
200+
PyObject *str;
201+
unsigned char buf[sizeof(struct in6_addr)];
202+
int domain;
203+
204+
205+
if (!PyDict_Check(pydict)) {
206+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
207+
return NULL;
208+
}
209+
if (PyDict_Size(pydict) != 2) {
210+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
211+
return NULL;
212+
}
213+
addr_dict = getdns_dict_create();
214+
if ((str = PyDict_GetItemString(pydict, "address_type")) == NULL) {
215+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
216+
return NULL;
217+
}
218+
if (!PyString_Check(str)) {
219+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
220+
return NULL;
221+
}
222+
addr_type.data = (uint8_t *)strdup(PyString_AsString(str));
223+
addr_type.size = strlen((char *)addr_type.data);
224+
if (strlen((char *)addr_type.data) != 4) {
225+
PyErr_SetString(getdns_error, GETDNS_RETURN_WRONG_TYPE_REQUESTED_TEXT);
226+
return NULL;
227+
}
228+
if (!strncasecmp((char *)addr_type.data, "IPv4", 4))
229+
domain = AF_INET;
230+
else if (!strncasecmp((char *)addr_type.data, "IPv6", 4))
231+
domain = AF_INET6;
232+
else {
233+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
234+
return NULL;
235+
}
236+
getdns_dict_set_bindata(addr_dict, "address_type", &addr_type);
237+
238+
if ((str = PyDict_GetItemString(pydict, "address_data")) == NULL) {
239+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
240+
return NULL;
241+
}
242+
if (!PyString_Check(str)) {
243+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
244+
return NULL;
245+
}
246+
if (inet_pton(domain, PyString_AsString(str), buf) <= 0) {
247+
PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
248+
return NULL;
249+
}
250+
addr_data.data = (uint8_t *)buf;
251+
addr_data.size = (domain == AF_INET ? 4 : 16);
252+
getdns_dict_set_bindata(addr_dict, "address_data", &addr_data);
253+
return addr_dict;
254+
}
255+
256+
187257
PyObject *
188258
decode_getdns_response(struct getdns_dict *response)
189259
{

0 commit comments

Comments
 (0)