aboutsummaryrefslogtreecommitdiffstats
path: root/python/gevent/dnshelper.c
diff options
context:
space:
mode:
authorJames Taylor <user234683@users.noreply.github.com>2018-07-12 23:40:30 -0700
committerJames Taylor <user234683@users.noreply.github.com>2018-07-12 23:41:07 -0700
commitc3b9f8c4582882cd1f768b0727eca75475bb4f94 (patch)
tree5b4a1c693fd5b7416f1d5a75862e633502e77ca7 /python/gevent/dnshelper.c
parentfe9fe8257740529f5880693992e4eeca35c7ea3e (diff)
downloadyt-local-c3b9f8c4582882cd1f768b0727eca75475bb4f94.tar.lz
yt-local-c3b9f8c4582882cd1f768b0727eca75475bb4f94.tar.xz
yt-local-c3b9f8c4582882cd1f768b0727eca75475bb4f94.zip
track embedded python distribution
Diffstat (limited to 'python/gevent/dnshelper.c')
-rw-r--r--python/gevent/dnshelper.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/python/gevent/dnshelper.c b/python/gevent/dnshelper.c
new file mode 100644
index 0000000..3befb69
--- /dev/null
+++ b/python/gevent/dnshelper.c
@@ -0,0 +1,159 @@
+/* Copyright (c) 2011 Denis Bilenko. See LICENSE for details. */
+#include "Python.h"
+#ifdef CARES_EMBED
+#include "ares_setup.h"
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "ares.h"
+
+#include "cares_ntop.h"
+#include "cares_pton.h"
+
+#if PY_VERSION_HEX < 0x02060000
+ #define PyUnicode_FromString PyString_FromString
+#elif PY_MAJOR_VERSION < 3
+ #define PyUnicode_FromString PyBytes_FromString
+#endif
+
+
+static PyObject* _socket_error = 0;
+
+static PyObject*
+get_socket_object(PyObject** pobject, const char* name)
+{
+ if (!*pobject) {
+ PyObject* _socket;
+ _socket = PyImport_ImportModule("_socket");
+ if (_socket) {
+ *pobject = PyObject_GetAttrString(_socket, name);
+ if (!*pobject) {
+ PyErr_WriteUnraisable(Py_None);
+ }
+ Py_DECREF(_socket);
+ }
+ else {
+ PyErr_WriteUnraisable(Py_None);
+ }
+ if (!*pobject) {
+ *pobject = PyExc_IOError;
+ }
+ }
+ return *pobject;
+}
+
+
+static int
+gevent_append_addr(PyObject* list, int family, void* src, char* tmpbuf, size_t tmpsize) {
+ int status = -1;
+ PyObject* tmp;
+ if (ares_inet_ntop(family, src, tmpbuf, tmpsize)) {
+ tmp = PyUnicode_FromString(tmpbuf);
+ if (tmp) {
+ status = PyList_Append(list, tmp);
+ Py_DECREF(tmp);
+ }
+ }
+ return status;
+}
+
+
+static PyObject*
+parse_h_name(struct hostent *h)
+{
+ return PyUnicode_FromString(h->h_name);
+}
+
+
+static PyObject*
+parse_h_aliases(struct hostent *h)
+{
+ char **pch;
+ PyObject *result = NULL;
+ PyObject *tmp;
+
+ result = PyList_New(0);
+
+ if (result && h->h_aliases) {
+ for (pch = h->h_aliases; *pch != NULL; pch++) {
+ if (*pch != h->h_name && strcmp(*pch, h->h_name)) {
+ int status;
+ tmp = PyUnicode_FromString(*pch);
+ if (tmp == NULL) {
+ break;
+ }
+
+ status = PyList_Append(result, tmp);
+ Py_DECREF(tmp);
+
+ if (status) {
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+
+static PyObject *
+parse_h_addr_list(struct hostent *h)
+{
+ char **pch;
+ PyObject *result = NULL;
+
+ result = PyList_New(0);
+
+ if (result) {
+ switch (h->h_addrtype) {
+ case AF_INET:
+ {
+ char tmpbuf[sizeof "255.255.255.255"];
+ for (pch = h->h_addr_list; *pch != NULL; pch++) {
+ if (gevent_append_addr(result, AF_INET, *pch, tmpbuf, sizeof(tmpbuf))) {
+ break;
+ }
+ }
+ break;
+ }
+ case AF_INET6:
+ {
+ char tmpbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+ for (pch = h->h_addr_list; *pch != NULL; pch++) {
+ if (gevent_append_addr(result, AF_INET6, *pch, tmpbuf, sizeof(tmpbuf))) {
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ PyErr_SetString(get_socket_object(&_socket_error, "error"), "unsupported address family");
+ Py_DECREF(result);
+ result = NULL;
+ }
+ }
+
+ return result;
+}
+
+
+static int
+gevent_make_sockaddr(char* hostp, int port, int flowinfo, int scope_id, struct sockaddr_in6* sa6) {
+ if ( ares_inet_pton(AF_INET, hostp, &((struct sockaddr_in*)sa6)->sin_addr.s_addr) > 0 ) {
+ ((struct sockaddr_in*)sa6)->sin_family = AF_INET;
+ ((struct sockaddr_in*)sa6)->sin_port = htons(port);
+ return sizeof(struct sockaddr_in);
+ }
+ else if ( ares_inet_pton(AF_INET6, hostp, &sa6->sin6_addr.s6_addr) > 0 ) {
+ sa6->sin6_family = AF_INET6;
+ sa6->sin6_port = htons(port);
+ sa6->sin6_flowinfo = flowinfo;
+ sa6->sin6_scope_id = scope_id;
+ return sizeof(struct sockaddr_in6);
+ }
+ return -1;
+}