dnshelper.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* Copyright (c) 2011 Denis Bilenko. See LICENSE for details. */
  2. #include "Python.h"
  3. #ifdef CARES_EMBED
  4. #include "ares_setup.h"
  5. #endif
  6. #ifdef HAVE_NETDB_H
  7. #include <netdb.h>
  8. #endif
  9. #include "ares.h"
  10. #include "cares_ntop.h"
  11. #include "cares_pton.h"
  12. #if PY_VERSION_HEX < 0x02060000
  13. #define PyUnicode_FromString PyString_FromString
  14. #elif PY_MAJOR_VERSION < 3
  15. #define PyUnicode_FromString PyBytes_FromString
  16. #endif
  17. static PyObject* _socket_error = 0;
  18. static PyObject*
  19. get_socket_object(PyObject** pobject, const char* name)
  20. {
  21. if (!*pobject) {
  22. PyObject* _socket;
  23. _socket = PyImport_ImportModule("_socket");
  24. if (_socket) {
  25. *pobject = PyObject_GetAttrString(_socket, name);
  26. if (!*pobject) {
  27. PyErr_WriteUnraisable(Py_None);
  28. }
  29. Py_DECREF(_socket);
  30. }
  31. else {
  32. PyErr_WriteUnraisable(Py_None);
  33. }
  34. if (!*pobject) {
  35. *pobject = PyExc_IOError;
  36. }
  37. }
  38. return *pobject;
  39. }
  40. static int
  41. gevent_append_addr(PyObject* list, int family, void* src, char* tmpbuf, size_t tmpsize) {
  42. int status = -1;
  43. PyObject* tmp;
  44. if (ares_inet_ntop(family, src, tmpbuf, tmpsize)) {
  45. tmp = PyUnicode_FromString(tmpbuf);
  46. if (tmp) {
  47. status = PyList_Append(list, tmp);
  48. Py_DECREF(tmp);
  49. }
  50. }
  51. return status;
  52. }
  53. static PyObject*
  54. parse_h_name(struct hostent *h)
  55. {
  56. return PyUnicode_FromString(h->h_name);
  57. }
  58. static PyObject*
  59. parse_h_aliases(struct hostent *h)
  60. {
  61. char **pch;
  62. PyObject *result = NULL;
  63. PyObject *tmp;
  64. result = PyList_New(0);
  65. if (result && h->h_aliases) {
  66. for (pch = h->h_aliases; *pch != NULL; pch++) {
  67. if (*pch != h->h_name && strcmp(*pch, h->h_name)) {
  68. int status;
  69. tmp = PyUnicode_FromString(*pch);
  70. if (tmp == NULL) {
  71. break;
  72. }
  73. status = PyList_Append(result, tmp);
  74. Py_DECREF(tmp);
  75. if (status) {
  76. break;
  77. }
  78. }
  79. }
  80. }
  81. return result;
  82. }
  83. static PyObject *
  84. parse_h_addr_list(struct hostent *h)
  85. {
  86. char **pch;
  87. PyObject *result = NULL;
  88. result = PyList_New(0);
  89. if (result) {
  90. switch (h->h_addrtype) {
  91. case AF_INET:
  92. {
  93. char tmpbuf[sizeof "255.255.255.255"];
  94. for (pch = h->h_addr_list; *pch != NULL; pch++) {
  95. if (gevent_append_addr(result, AF_INET, *pch, tmpbuf, sizeof(tmpbuf))) {
  96. break;
  97. }
  98. }
  99. break;
  100. }
  101. case AF_INET6:
  102. {
  103. char tmpbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
  104. for (pch = h->h_addr_list; *pch != NULL; pch++) {
  105. if (gevent_append_addr(result, AF_INET6, *pch, tmpbuf, sizeof(tmpbuf))) {
  106. break;
  107. }
  108. }
  109. break;
  110. }
  111. default:
  112. PyErr_SetString(get_socket_object(&_socket_error, "error"), "unsupported address family");
  113. Py_DECREF(result);
  114. result = NULL;
  115. }
  116. }
  117. return result;
  118. }
  119. static int
  120. gevent_make_sockaddr(char* hostp, int port, int flowinfo, int scope_id, struct sockaddr_in6* sa6) {
  121. if ( ares_inet_pton(AF_INET, hostp, &((struct sockaddr_in*)sa6)->sin_addr.s_addr) > 0 ) {
  122. ((struct sockaddr_in*)sa6)->sin_family = AF_INET;
  123. ((struct sockaddr_in*)sa6)->sin_port = htons(port);
  124. return sizeof(struct sockaddr_in);
  125. }
  126. else if ( ares_inet_pton(AF_INET6, hostp, &sa6->sin6_addr.s6_addr) > 0 ) {
  127. sa6->sin6_family = AF_INET6;
  128. sa6->sin6_port = htons(port);
  129. sa6->sin6_flowinfo = flowinfo;
  130. sa6->sin6_scope_id = scope_id;
  131. return sizeof(struct sockaddr_in6);
  132. }
  133. return -1;
  134. }