asyncengine 0.0.1.testing

Sign up to get free protection for your applications and to get access to all the features.
Files changed (317) hide show
  1. data/README.markdown +0 -0
  2. data/asyncengine.gemspec +26 -0
  3. data/ext/asyncengine_ext/asyncengine_ruby.c +82 -0
  4. data/ext/asyncengine_ext/extconf.rb +47 -0
  5. data/ext/asyncengine_ext/libuv/AUTHORS +45 -0
  6. data/ext/asyncengine_ext/libuv/LICENSE +42 -0
  7. data/ext/asyncengine_ext/libuv/Makefile +119 -0
  8. data/ext/asyncengine_ext/libuv/README.md +88 -0
  9. data/ext/asyncengine_ext/libuv/build/gcc_version.py +20 -0
  10. data/ext/asyncengine_ext/libuv/common.gypi +176 -0
  11. data/ext/asyncengine_ext/libuv/config-mingw.mk +61 -0
  12. data/ext/asyncengine_ext/libuv/config-unix.mk +173 -0
  13. data/ext/asyncengine_ext/libuv/gyp_uv +60 -0
  14. data/ext/asyncengine_ext/libuv/include/ares.h +591 -0
  15. data/ext/asyncengine_ext/libuv/include/ares_version.h +24 -0
  16. data/ext/asyncengine_ext/libuv/include/uv-private/eio.h +403 -0
  17. data/ext/asyncengine_ext/libuv/include/uv-private/ev.h +838 -0
  18. data/ext/asyncengine_ext/libuv/include/uv-private/ngx-queue.h +106 -0
  19. data/ext/asyncengine_ext/libuv/include/uv-private/tree.h +768 -0
  20. data/ext/asyncengine_ext/libuv/include/uv-private/uv-unix.h +256 -0
  21. data/ext/asyncengine_ext/libuv/include/uv-private/uv-win.h +458 -0
  22. data/ext/asyncengine_ext/libuv/include/uv.h +1556 -0
  23. data/ext/asyncengine_ext/libuv/src/ares/AUTHORS +37 -0
  24. data/ext/asyncengine_ext/libuv/src/ares/CHANGES +1218 -0
  25. data/ext/asyncengine_ext/libuv/src/ares/CMakeLists.txt +22 -0
  26. data/ext/asyncengine_ext/libuv/src/ares/NEWS +21 -0
  27. data/ext/asyncengine_ext/libuv/src/ares/README +60 -0
  28. data/ext/asyncengine_ext/libuv/src/ares/README.cares +13 -0
  29. data/ext/asyncengine_ext/libuv/src/ares/README.msvc +142 -0
  30. data/ext/asyncengine_ext/libuv/src/ares/README.node +21 -0
  31. data/ext/asyncengine_ext/libuv/src/ares/RELEASE-NOTES +26 -0
  32. data/ext/asyncengine_ext/libuv/src/ares/TODO +23 -0
  33. data/ext/asyncengine_ext/libuv/src/ares/ares__close_sockets.c +66 -0
  34. data/ext/asyncengine_ext/libuv/src/ares/ares__get_hostent.c +263 -0
  35. data/ext/asyncengine_ext/libuv/src/ares/ares__read_line.c +71 -0
  36. data/ext/asyncengine_ext/libuv/src/ares/ares__timeval.c +111 -0
  37. data/ext/asyncengine_ext/libuv/src/ares/ares_cancel.c +63 -0
  38. data/ext/asyncengine_ext/libuv/src/ares/ares_data.c +190 -0
  39. data/ext/asyncengine_ext/libuv/src/ares/ares_data.h +65 -0
  40. data/ext/asyncengine_ext/libuv/src/ares/ares_destroy.c +105 -0
  41. data/ext/asyncengine_ext/libuv/src/ares/ares_dns.h +90 -0
  42. data/ext/asyncengine_ext/libuv/src/ares/ares_expand_name.c +200 -0
  43. data/ext/asyncengine_ext/libuv/src/ares/ares_expand_string.c +75 -0
  44. data/ext/asyncengine_ext/libuv/src/ares/ares_fds.c +63 -0
  45. data/ext/asyncengine_ext/libuv/src/ares/ares_free_hostent.c +42 -0
  46. data/ext/asyncengine_ext/libuv/src/ares/ares_free_string.c +25 -0
  47. data/ext/asyncengine_ext/libuv/src/ares/ares_getenv.c +30 -0
  48. data/ext/asyncengine_ext/libuv/src/ares/ares_getenv.h +26 -0
  49. data/ext/asyncengine_ext/libuv/src/ares/ares_gethostbyaddr.c +301 -0
  50. data/ext/asyncengine_ext/libuv/src/ares/ares_gethostbyname.c +523 -0
  51. data/ext/asyncengine_ext/libuv/src/ares/ares_getnameinfo.c +427 -0
  52. data/ext/asyncengine_ext/libuv/src/ares/ares_getopt.c +122 -0
  53. data/ext/asyncengine_ext/libuv/src/ares/ares_getopt.h +53 -0
  54. data/ext/asyncengine_ext/libuv/src/ares/ares_getsock.c +72 -0
  55. data/ext/asyncengine_ext/libuv/src/ares/ares_init.c +1809 -0
  56. data/ext/asyncengine_ext/libuv/src/ares/ares_iphlpapi.h +221 -0
  57. data/ext/asyncengine_ext/libuv/src/ares/ares_ipv6.h +78 -0
  58. data/ext/asyncengine_ext/libuv/src/ares/ares_library_init.c +142 -0
  59. data/ext/asyncengine_ext/libuv/src/ares/ares_library_init.h +42 -0
  60. data/ext/asyncengine_ext/libuv/src/ares/ares_llist.c +86 -0
  61. data/ext/asyncengine_ext/libuv/src/ares/ares_llist.h +42 -0
  62. data/ext/asyncengine_ext/libuv/src/ares/ares_mkquery.c +195 -0
  63. data/ext/asyncengine_ext/libuv/src/ares/ares_nowarn.c +181 -0
  64. data/ext/asyncengine_ext/libuv/src/ares/ares_nowarn.h +55 -0
  65. data/ext/asyncengine_ext/libuv/src/ares/ares_options.c +248 -0
  66. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_a_reply.c +263 -0
  67. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_aaaa_reply.c +259 -0
  68. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_mx_reply.c +170 -0
  69. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_ns_reply.c +182 -0
  70. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_ptr_reply.c +217 -0
  71. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_srv_reply.c +179 -0
  72. data/ext/asyncengine_ext/libuv/src/ares/ares_parse_txt_reply.c +201 -0
  73. data/ext/asyncengine_ext/libuv/src/ares/ares_platform.c +11035 -0
  74. data/ext/asyncengine_ext/libuv/src/ares/ares_platform.h +43 -0
  75. data/ext/asyncengine_ext/libuv/src/ares/ares_private.h +355 -0
  76. data/ext/asyncengine_ext/libuv/src/ares/ares_process.c +1295 -0
  77. data/ext/asyncengine_ext/libuv/src/ares/ares_query.c +183 -0
  78. data/ext/asyncengine_ext/libuv/src/ares/ares_rules.h +144 -0
  79. data/ext/asyncengine_ext/libuv/src/ares/ares_search.c +321 -0
  80. data/ext/asyncengine_ext/libuv/src/ares/ares_send.c +134 -0
  81. data/ext/asyncengine_ext/libuv/src/ares/ares_setup.h +199 -0
  82. data/ext/asyncengine_ext/libuv/src/ares/ares_strcasecmp.c +66 -0
  83. data/ext/asyncengine_ext/libuv/src/ares/ares_strcasecmp.h +30 -0
  84. data/ext/asyncengine_ext/libuv/src/ares/ares_strdup.c +42 -0
  85. data/ext/asyncengine_ext/libuv/src/ares/ares_strdup.h +26 -0
  86. data/ext/asyncengine_ext/libuv/src/ares/ares_strerror.c +56 -0
  87. data/ext/asyncengine_ext/libuv/src/ares/ares_timeout.c +80 -0
  88. data/ext/asyncengine_ext/libuv/src/ares/ares_version.c +11 -0
  89. data/ext/asyncengine_ext/libuv/src/ares/ares_writev.c +79 -0
  90. data/ext/asyncengine_ext/libuv/src/ares/ares_writev.h +36 -0
  91. data/ext/asyncengine_ext/libuv/src/ares/bitncmp.c +59 -0
  92. data/ext/asyncengine_ext/libuv/src/ares/bitncmp.h +26 -0
  93. data/ext/asyncengine_ext/libuv/src/ares/config_cygwin/ares_config.h +512 -0
  94. data/ext/asyncengine_ext/libuv/src/ares/config_darwin/ares_config.h +512 -0
  95. data/ext/asyncengine_ext/libuv/src/ares/config_freebsd/ares_config.h +512 -0
  96. data/ext/asyncengine_ext/libuv/src/ares/config_linux/ares_config.h +512 -0
  97. data/ext/asyncengine_ext/libuv/src/ares/config_netbsd/ares_config.h +512 -0
  98. data/ext/asyncengine_ext/libuv/src/ares/config_openbsd/ares_config.h +512 -0
  99. data/ext/asyncengine_ext/libuv/src/ares/config_sunos/ares_config.h +512 -0
  100. data/ext/asyncengine_ext/libuv/src/ares/config_win32/ares_config.h +369 -0
  101. data/ext/asyncengine_ext/libuv/src/ares/get_ver.awk +35 -0
  102. data/ext/asyncengine_ext/libuv/src/ares/inet_net_pton.c +451 -0
  103. data/ext/asyncengine_ext/libuv/src/ares/inet_net_pton.h +31 -0
  104. data/ext/asyncengine_ext/libuv/src/ares/inet_ntop.c +208 -0
  105. data/ext/asyncengine_ext/libuv/src/ares/inet_ntop.h +26 -0
  106. data/ext/asyncengine_ext/libuv/src/ares/nameser.h +203 -0
  107. data/ext/asyncengine_ext/libuv/src/ares/setup_once.h +504 -0
  108. data/ext/asyncengine_ext/libuv/src/ares/windows_port.c +22 -0
  109. data/ext/asyncengine_ext/libuv/src/unix/async.c +58 -0
  110. data/ext/asyncengine_ext/libuv/src/unix/cares.c +194 -0
  111. data/ext/asyncengine_ext/libuv/src/unix/check.c +80 -0
  112. data/ext/asyncengine_ext/libuv/src/unix/core.c +588 -0
  113. data/ext/asyncengine_ext/libuv/src/unix/cygwin.c +84 -0
  114. data/ext/asyncengine_ext/libuv/src/unix/darwin.c +341 -0
  115. data/ext/asyncengine_ext/libuv/src/unix/dl.c +91 -0
  116. data/ext/asyncengine_ext/libuv/src/unix/eio/Changes +63 -0
  117. data/ext/asyncengine_ext/libuv/src/unix/eio/LICENSE +36 -0
  118. data/ext/asyncengine_ext/libuv/src/unix/eio/Makefile.am +15 -0
  119. data/ext/asyncengine_ext/libuv/src/unix/eio/aclocal.m4 +8957 -0
  120. data/ext/asyncengine_ext/libuv/src/unix/eio/autogen.sh +3 -0
  121. data/ext/asyncengine_ext/libuv/src/unix/eio/config.h.in +86 -0
  122. data/ext/asyncengine_ext/libuv/src/unix/eio/config_cygwin.h +80 -0
  123. data/ext/asyncengine_ext/libuv/src/unix/eio/config_darwin.h +141 -0
  124. data/ext/asyncengine_ext/libuv/src/unix/eio/config_freebsd.h +81 -0
  125. data/ext/asyncengine_ext/libuv/src/unix/eio/config_linux.h +94 -0
  126. data/ext/asyncengine_ext/libuv/src/unix/eio/config_netbsd.h +81 -0
  127. data/ext/asyncengine_ext/libuv/src/unix/eio/config_openbsd.h +137 -0
  128. data/ext/asyncengine_ext/libuv/src/unix/eio/config_sunos.h +84 -0
  129. data/ext/asyncengine_ext/libuv/src/unix/eio/configure.ac +22 -0
  130. data/ext/asyncengine_ext/libuv/src/unix/eio/demo.c +194 -0
  131. data/ext/asyncengine_ext/libuv/src/unix/eio/ecb.h +370 -0
  132. data/ext/asyncengine_ext/libuv/src/unix/eio/eio.3 +3428 -0
  133. data/ext/asyncengine_ext/libuv/src/unix/eio/eio.c +2593 -0
  134. data/ext/asyncengine_ext/libuv/src/unix/eio/eio.pod +969 -0
  135. data/ext/asyncengine_ext/libuv/src/unix/eio/libeio.m4 +195 -0
  136. data/ext/asyncengine_ext/libuv/src/unix/eio/xthread.h +164 -0
  137. data/ext/asyncengine_ext/libuv/src/unix/error.c +98 -0
  138. data/ext/asyncengine_ext/libuv/src/unix/ev/Changes +388 -0
  139. data/ext/asyncengine_ext/libuv/src/unix/ev/LICENSE +36 -0
  140. data/ext/asyncengine_ext/libuv/src/unix/ev/Makefile.am +18 -0
  141. data/ext/asyncengine_ext/libuv/src/unix/ev/Makefile.in +771 -0
  142. data/ext/asyncengine_ext/libuv/src/unix/ev/README +58 -0
  143. data/ext/asyncengine_ext/libuv/src/unix/ev/aclocal.m4 +8957 -0
  144. data/ext/asyncengine_ext/libuv/src/unix/ev/autogen.sh +6 -0
  145. data/ext/asyncengine_ext/libuv/src/unix/ev/config.guess +1526 -0
  146. data/ext/asyncengine_ext/libuv/src/unix/ev/config.h.in +125 -0
  147. data/ext/asyncengine_ext/libuv/src/unix/ev/config.sub +1658 -0
  148. data/ext/asyncengine_ext/libuv/src/unix/ev/config_cygwin.h +123 -0
  149. data/ext/asyncengine_ext/libuv/src/unix/ev/config_darwin.h +122 -0
  150. data/ext/asyncengine_ext/libuv/src/unix/ev/config_freebsd.h +120 -0
  151. data/ext/asyncengine_ext/libuv/src/unix/ev/config_linux.h +141 -0
  152. data/ext/asyncengine_ext/libuv/src/unix/ev/config_netbsd.h +120 -0
  153. data/ext/asyncengine_ext/libuv/src/unix/ev/config_openbsd.h +126 -0
  154. data/ext/asyncengine_ext/libuv/src/unix/ev/config_sunos.h +122 -0
  155. data/ext/asyncengine_ext/libuv/src/unix/ev/configure +13037 -0
  156. data/ext/asyncengine_ext/libuv/src/unix/ev/configure.ac +18 -0
  157. data/ext/asyncengine_ext/libuv/src/unix/ev/depcomp +630 -0
  158. data/ext/asyncengine_ext/libuv/src/unix/ev/ev++.h +816 -0
  159. data/ext/asyncengine_ext/libuv/src/unix/ev/ev.3 +5311 -0
  160. data/ext/asyncengine_ext/libuv/src/unix/ev/ev.c +3921 -0
  161. data/ext/asyncengine_ext/libuv/src/unix/ev/ev.pod +5243 -0
  162. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_epoll.c +266 -0
  163. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_kqueue.c +235 -0
  164. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_poll.c +148 -0
  165. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_port.c +179 -0
  166. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_select.c +310 -0
  167. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_vars.h +203 -0
  168. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_win32.c +153 -0
  169. data/ext/asyncengine_ext/libuv/src/unix/ev/ev_wrap.h +196 -0
  170. data/ext/asyncengine_ext/libuv/src/unix/ev/event.c +402 -0
  171. data/ext/asyncengine_ext/libuv/src/unix/ev/event.h +170 -0
  172. data/ext/asyncengine_ext/libuv/src/unix/ev/install-sh +294 -0
  173. data/ext/asyncengine_ext/libuv/src/unix/ev/libev.m4 +39 -0
  174. data/ext/asyncengine_ext/libuv/src/unix/ev/ltmain.sh +8413 -0
  175. data/ext/asyncengine_ext/libuv/src/unix/ev/missing +336 -0
  176. data/ext/asyncengine_ext/libuv/src/unix/ev/mkinstalldirs +111 -0
  177. data/ext/asyncengine_ext/libuv/src/unix/freebsd.c +312 -0
  178. data/ext/asyncengine_ext/libuv/src/unix/fs.c +707 -0
  179. data/ext/asyncengine_ext/libuv/src/unix/idle.c +79 -0
  180. data/ext/asyncengine_ext/libuv/src/unix/internal.h +161 -0
  181. data/ext/asyncengine_ext/libuv/src/unix/kqueue.c +127 -0
  182. data/ext/asyncengine_ext/libuv/src/unix/linux/core.c +474 -0
  183. data/ext/asyncengine_ext/libuv/src/unix/linux/inotify.c +211 -0
  184. data/ext/asyncengine_ext/libuv/src/unix/linux/syscalls.c +230 -0
  185. data/ext/asyncengine_ext/libuv/src/unix/linux/syscalls.h +87 -0
  186. data/ext/asyncengine_ext/libuv/src/unix/loop.c +58 -0
  187. data/ext/asyncengine_ext/libuv/src/unix/netbsd.c +108 -0
  188. data/ext/asyncengine_ext/libuv/src/unix/openbsd.c +295 -0
  189. data/ext/asyncengine_ext/libuv/src/unix/pipe.c +266 -0
  190. data/ext/asyncengine_ext/libuv/src/unix/prepare.c +79 -0
  191. data/ext/asyncengine_ext/libuv/src/unix/process.c +369 -0
  192. data/ext/asyncengine_ext/libuv/src/unix/stream.c +1033 -0
  193. data/ext/asyncengine_ext/libuv/src/unix/sunos.c +466 -0
  194. data/ext/asyncengine_ext/libuv/src/unix/tcp.c +327 -0
  195. data/ext/asyncengine_ext/libuv/src/unix/thread.c +154 -0
  196. data/ext/asyncengine_ext/libuv/src/unix/timer.c +127 -0
  197. data/ext/asyncengine_ext/libuv/src/unix/tty.c +146 -0
  198. data/ext/asyncengine_ext/libuv/src/unix/udp.c +670 -0
  199. data/ext/asyncengine_ext/libuv/src/unix/uv-eio.c +124 -0
  200. data/ext/asyncengine_ext/libuv/src/unix/uv-eio.h +13 -0
  201. data/ext/asyncengine_ext/libuv/src/uv-common.c +354 -0
  202. data/ext/asyncengine_ext/libuv/src/uv-common.h +87 -0
  203. data/ext/asyncengine_ext/libuv/src/win/async.c +127 -0
  204. data/ext/asyncengine_ext/libuv/src/win/cares.c +290 -0
  205. data/ext/asyncengine_ext/libuv/src/win/core.c +270 -0
  206. data/ext/asyncengine_ext/libuv/src/win/dl.c +82 -0
  207. data/ext/asyncengine_ext/libuv/src/win/error.c +132 -0
  208. data/ext/asyncengine_ext/libuv/src/win/fs-event.c +514 -0
  209. data/ext/asyncengine_ext/libuv/src/win/fs.c +1576 -0
  210. data/ext/asyncengine_ext/libuv/src/win/getaddrinfo.c +372 -0
  211. data/ext/asyncengine_ext/libuv/src/win/handle.c +225 -0
  212. data/ext/asyncengine_ext/libuv/src/win/internal.h +352 -0
  213. data/ext/asyncengine_ext/libuv/src/win/loop-watcher.c +131 -0
  214. data/ext/asyncengine_ext/libuv/src/win/pipe.c +1661 -0
  215. data/ext/asyncengine_ext/libuv/src/win/process.c +1140 -0
  216. data/ext/asyncengine_ext/libuv/src/win/req.c +174 -0
  217. data/ext/asyncengine_ext/libuv/src/win/stream.c +201 -0
  218. data/ext/asyncengine_ext/libuv/src/win/tcp.c +1282 -0
  219. data/ext/asyncengine_ext/libuv/src/win/thread.c +332 -0
  220. data/ext/asyncengine_ext/libuv/src/win/threadpool.c +73 -0
  221. data/ext/asyncengine_ext/libuv/src/win/timer.c +276 -0
  222. data/ext/asyncengine_ext/libuv/src/win/tty.c +1795 -0
  223. data/ext/asyncengine_ext/libuv/src/win/udp.c +709 -0
  224. data/ext/asyncengine_ext/libuv/src/win/util.c +719 -0
  225. data/ext/asyncengine_ext/libuv/src/win/winapi.c +117 -0
  226. data/ext/asyncengine_ext/libuv/src/win/winapi.h +4419 -0
  227. data/ext/asyncengine_ext/libuv/src/win/winsock.c +470 -0
  228. data/ext/asyncengine_ext/libuv/src/win/winsock.h +138 -0
  229. data/ext/asyncengine_ext/libuv/test/benchmark-ares.c +118 -0
  230. data/ext/asyncengine_ext/libuv/test/benchmark-getaddrinfo.c +94 -0
  231. data/ext/asyncengine_ext/libuv/test/benchmark-list.h +105 -0
  232. data/ext/asyncengine_ext/libuv/test/benchmark-ping-pongs.c +213 -0
  233. data/ext/asyncengine_ext/libuv/test/benchmark-pound.c +324 -0
  234. data/ext/asyncengine_ext/libuv/test/benchmark-pump.c +462 -0
  235. data/ext/asyncengine_ext/libuv/test/benchmark-sizes.c +40 -0
  236. data/ext/asyncengine_ext/libuv/test/benchmark-spawn.c +156 -0
  237. data/ext/asyncengine_ext/libuv/test/benchmark-tcp-write-batch.c +140 -0
  238. data/ext/asyncengine_ext/libuv/test/benchmark-thread.c +64 -0
  239. data/ext/asyncengine_ext/libuv/test/benchmark-udp-packet-storm.c +247 -0
  240. data/ext/asyncengine_ext/libuv/test/blackhole-server.c +118 -0
  241. data/ext/asyncengine_ext/libuv/test/dns-server.c +321 -0
  242. data/ext/asyncengine_ext/libuv/test/echo-server.c +370 -0
  243. data/ext/asyncengine_ext/libuv/test/fixtures/empty_file +0 -0
  244. data/ext/asyncengine_ext/libuv/test/fixtures/load_error.node +1 -0
  245. data/ext/asyncengine_ext/libuv/test/run-benchmarks.c +64 -0
  246. data/ext/asyncengine_ext/libuv/test/run-tests.c +108 -0
  247. data/ext/asyncengine_ext/libuv/test/runner-unix.c +315 -0
  248. data/ext/asyncengine_ext/libuv/test/runner-unix.h +36 -0
  249. data/ext/asyncengine_ext/libuv/test/runner-win.c +343 -0
  250. data/ext/asyncengine_ext/libuv/test/runner-win.h +42 -0
  251. data/ext/asyncengine_ext/libuv/test/runner.c +317 -0
  252. data/ext/asyncengine_ext/libuv/test/runner.h +159 -0
  253. data/ext/asyncengine_ext/libuv/test/task.h +117 -0
  254. data/ext/asyncengine_ext/libuv/test/test-async.c +216 -0
  255. data/ext/asyncengine_ext/libuv/test/test-callback-stack.c +203 -0
  256. data/ext/asyncengine_ext/libuv/test/test-connection-fail.c +148 -0
  257. data/ext/asyncengine_ext/libuv/test/test-counters-init.c +216 -0
  258. data/ext/asyncengine_ext/libuv/test/test-cwd-and-chdir.c +64 -0
  259. data/ext/asyncengine_ext/libuv/test/test-delayed-accept.c +197 -0
  260. data/ext/asyncengine_ext/libuv/test/test-dlerror.c +49 -0
  261. data/ext/asyncengine_ext/libuv/test/test-eio-overflow.c +90 -0
  262. data/ext/asyncengine_ext/libuv/test/test-error.c +59 -0
  263. data/ext/asyncengine_ext/libuv/test/test-fail-always.c +29 -0
  264. data/ext/asyncengine_ext/libuv/test/test-fs-event.c +442 -0
  265. data/ext/asyncengine_ext/libuv/test/test-fs.c +1731 -0
  266. data/ext/asyncengine_ext/libuv/test/test-get-currentexe.c +63 -0
  267. data/ext/asyncengine_ext/libuv/test/test-get-loadavg.c +36 -0
  268. data/ext/asyncengine_ext/libuv/test/test-get-memory.c +38 -0
  269. data/ext/asyncengine_ext/libuv/test/test-getaddrinfo.c +122 -0
  270. data/ext/asyncengine_ext/libuv/test/test-gethostbyname.c +189 -0
  271. data/ext/asyncengine_ext/libuv/test/test-getsockname.c +342 -0
  272. data/ext/asyncengine_ext/libuv/test/test-hrtime.c +51 -0
  273. data/ext/asyncengine_ext/libuv/test/test-idle.c +81 -0
  274. data/ext/asyncengine_ext/libuv/test/test-ipc-send-recv.c +209 -0
  275. data/ext/asyncengine_ext/libuv/test/test-ipc.c +614 -0
  276. data/ext/asyncengine_ext/libuv/test/test-list.h +371 -0
  277. data/ext/asyncengine_ext/libuv/test/test-loop-handles.c +359 -0
  278. data/ext/asyncengine_ext/libuv/test/test-multiple-listen.c +102 -0
  279. data/ext/asyncengine_ext/libuv/test/test-mutexes.c +63 -0
  280. data/ext/asyncengine_ext/libuv/test/test-pass-always.c +28 -0
  281. data/ext/asyncengine_ext/libuv/test/test-ping-pong.c +253 -0
  282. data/ext/asyncengine_ext/libuv/test/test-pipe-bind-error.c +140 -0
  283. data/ext/asyncengine_ext/libuv/test/test-pipe-connect-error.c +96 -0
  284. data/ext/asyncengine_ext/libuv/test/test-platform-output.c +87 -0
  285. data/ext/asyncengine_ext/libuv/test/test-process-title.c +42 -0
  286. data/ext/asyncengine_ext/libuv/test/test-ref.c +322 -0
  287. data/ext/asyncengine_ext/libuv/test/test-run-once.c +44 -0
  288. data/ext/asyncengine_ext/libuv/test/test-shutdown-close.c +103 -0
  289. data/ext/asyncengine_ext/libuv/test/test-shutdown-eof.c +183 -0
  290. data/ext/asyncengine_ext/libuv/test/test-spawn.c +499 -0
  291. data/ext/asyncengine_ext/libuv/test/test-stdio-over-pipes.c +256 -0
  292. data/ext/asyncengine_ext/libuv/test/test-tcp-bind-error.c +191 -0
  293. data/ext/asyncengine_ext/libuv/test/test-tcp-bind6-error.c +154 -0
  294. data/ext/asyncengine_ext/libuv/test/test-tcp-close.c +129 -0
  295. data/ext/asyncengine_ext/libuv/test/test-tcp-connect-error.c +70 -0
  296. data/ext/asyncengine_ext/libuv/test/test-tcp-connect6-error.c +68 -0
  297. data/ext/asyncengine_ext/libuv/test/test-tcp-flags.c +51 -0
  298. data/ext/asyncengine_ext/libuv/test/test-tcp-write-error.c +168 -0
  299. data/ext/asyncengine_ext/libuv/test/test-tcp-write-to-half-open-connection.c +135 -0
  300. data/ext/asyncengine_ext/libuv/test/test-tcp-writealot.c +195 -0
  301. data/ext/asyncengine_ext/libuv/test/test-thread.c +183 -0
  302. data/ext/asyncengine_ext/libuv/test/test-threadpool.c +57 -0
  303. data/ext/asyncengine_ext/libuv/test/test-timer-again.c +141 -0
  304. data/ext/asyncengine_ext/libuv/test/test-timer.c +130 -0
  305. data/ext/asyncengine_ext/libuv/test/test-tty.c +110 -0
  306. data/ext/asyncengine_ext/libuv/test/test-udp-dgram-too-big.c +86 -0
  307. data/ext/asyncengine_ext/libuv/test/test-udp-ipv6.c +156 -0
  308. data/ext/asyncengine_ext/libuv/test/test-udp-multicast-join.c +139 -0
  309. data/ext/asyncengine_ext/libuv/test/test-udp-multicast-ttl.c +86 -0
  310. data/ext/asyncengine_ext/libuv/test/test-udp-options.c +86 -0
  311. data/ext/asyncengine_ext/libuv/test/test-udp-send-and-recv.c +208 -0
  312. data/ext/asyncengine_ext/libuv/test/test-util.c +97 -0
  313. data/ext/asyncengine_ext/libuv/uv.gyp +435 -0
  314. data/ext/asyncengine_ext/libuv/vcbuild.bat +105 -0
  315. data/lib/asyncengine/version.rb +3 -0
  316. data/lib/asyncengine.rb +41 -0
  317. metadata +384 -0
@@ -0,0 +1,1809 @@
1
+
2
+ /* Copyright 1998 by the Massachusetts Institute of Technology.
3
+ * Copyright (C) 2007-2011 by Daniel Stenberg
4
+ *
5
+ * Permission to use, copy, modify, and distribute this
6
+ * software and its documentation for any purpose and without
7
+ * fee is hereby granted, provided that the above copyright
8
+ * notice appear in all copies and that both that copyright
9
+ * notice and this permission notice appear in supporting
10
+ * documentation, and that the name of M.I.T. not be used in
11
+ * advertising or publicity pertaining to distribution of the
12
+ * software without specific, written prior permission.
13
+ * M.I.T. makes no representations about the suitability of
14
+ * this software for any purpose. It is provided "as is"
15
+ * without express or implied warranty.
16
+ */
17
+
18
+ #include "ares_setup.h"
19
+
20
+ #ifdef HAVE_SYS_PARAM_H
21
+ #include <sys/param.h>
22
+ #endif
23
+
24
+ #ifdef HAVE_SYS_TIME_H
25
+ #include <sys/time.h>
26
+ #endif
27
+
28
+ #ifdef HAVE_SYS_SOCKET_H
29
+ #include <sys/socket.h>
30
+ #endif
31
+
32
+ #ifdef HAVE_NETINET_IN_H
33
+ #include <netinet/in.h>
34
+ #endif
35
+
36
+ #ifdef HAVE_NETDB_H
37
+ #include <netdb.h>
38
+ #endif
39
+
40
+ #ifdef HAVE_ARPA_INET_H
41
+ #include <arpa/inet.h>
42
+ #endif
43
+
44
+ #ifdef HAVE_ARPA_NAMESER_H
45
+ # include <arpa/nameser.h>
46
+ #else
47
+ # include "nameser.h"
48
+ #endif
49
+ #ifdef HAVE_ARPA_NAMESER_COMPAT_H
50
+ # include <arpa/nameser_compat.h>
51
+ #endif
52
+
53
+ #ifdef HAVE_UNISTD_H
54
+ #include <unistd.h>
55
+ #endif
56
+
57
+ #include <stdio.h>
58
+ #include <stdlib.h>
59
+ #include <string.h>
60
+ #include <ctype.h>
61
+ #include <time.h>
62
+
63
+ #ifdef ANDROID
64
+ #include <sys/system_properties.h>
65
+ #endif
66
+
67
+ #include "ares.h"
68
+ #include "inet_net_pton.h"
69
+ #include "ares_library_init.h"
70
+ #include "ares_nowarn.h"
71
+ #include "ares_platform.h"
72
+ #include "inet_ntop.h"
73
+ #include "ares_private.h"
74
+
75
+ #ifdef WATT32
76
+ #undef WIN32 /* Redefined in MingW/MSVC headers */
77
+ #endif
78
+
79
+ static int init_by_options(ares_channel channel, const struct ares_options *options,
80
+ int optmask);
81
+ static int init_by_environment(ares_channel channel);
82
+ static int init_by_resolv_conf(ares_channel channel);
83
+ static int init_by_defaults(ares_channel channel);
84
+
85
+ #ifndef WATT32
86
+ static int config_nameserver(struct server_state **servers, int *nservers,
87
+ char *str);
88
+ #endif
89
+ static int set_search(ares_channel channel, const char *str);
90
+ static int set_options(ares_channel channel, const char *str);
91
+ static const char *try_option(const char *p, const char *q, const char *opt);
92
+ static int init_id_key(rc4_key* key,int key_data_len);
93
+
94
+ #if !defined(WIN32) && !defined(WATT32)
95
+ static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
96
+ static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
97
+ static void natural_mask(struct apattern *pat);
98
+ static int config_domain(ares_channel channel, char *str);
99
+ static int config_lookup(ares_channel channel, const char *str,
100
+ const char *bindch, const char *filech);
101
+ static int config_sortlist(struct apattern **sortlist, int *nsort,
102
+ const char *str);
103
+ static char *try_config(char *s, const char *opt, char scc);
104
+ #endif
105
+
106
+ #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
107
+ x->nservers > -1 && \
108
+ x->ndomains > -1 && \
109
+ x->ndots > -1 && x->timeout > -1 && \
110
+ x->tries > -1)
111
+
112
+ int ares_init(ares_channel *channelptr)
113
+ {
114
+ return ares_init_options(channelptr, NULL, 0);
115
+ }
116
+
117
+ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
118
+ int optmask)
119
+ {
120
+ ares_channel channel;
121
+ int i;
122
+ int status = ARES_SUCCESS;
123
+ struct timeval now;
124
+
125
+ #ifdef CURLDEBUG
126
+ const char *env = getenv("CARES_MEMDEBUG");
127
+
128
+ if (env)
129
+ curl_memdebug(env);
130
+ env = getenv("CARES_MEMLIMIT");
131
+ if (env) {
132
+ char *endptr;
133
+ long num = strtol(env, &endptr, 10);
134
+ if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
135
+ curl_memlimit(num);
136
+ }
137
+ #endif
138
+
139
+ if (ares_library_initialized() != ARES_SUCCESS)
140
+ return ARES_ENOTINITIALIZED;
141
+
142
+ channel = malloc(sizeof(struct ares_channeldata));
143
+ if (!channel) {
144
+ *channelptr = NULL;
145
+ return ARES_ENOMEM;
146
+ }
147
+
148
+ now = ares__tvnow();
149
+
150
+ /* Set everything to distinguished values so we know they haven't
151
+ * been set yet.
152
+ */
153
+ channel->flags = -1;
154
+ channel->timeout = -1;
155
+ channel->tries = -1;
156
+ channel->ndots = -1;
157
+ channel->rotate = -1;
158
+ channel->udp_port = -1;
159
+ channel->tcp_port = -1;
160
+ channel->socket_send_buffer_size = -1;
161
+ channel->socket_receive_buffer_size = -1;
162
+ channel->nservers = -1;
163
+ channel->ndomains = -1;
164
+ channel->nsort = -1;
165
+ channel->tcp_connection_generation = 0;
166
+ channel->lookups = NULL;
167
+ channel->domains = NULL;
168
+ channel->sortlist = NULL;
169
+ channel->servers = NULL;
170
+ channel->sock_state_cb = NULL;
171
+ channel->sock_state_cb_data = NULL;
172
+ channel->sock_create_cb = NULL;
173
+ channel->sock_create_cb_data = NULL;
174
+
175
+ channel->last_server = 0;
176
+ channel->last_timeout_processed = (time_t)now.tv_sec;
177
+
178
+ memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
179
+ channel->local_ip4 = 0;
180
+ memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
181
+
182
+ /* Initialize our lists of queries */
183
+ ares__init_list_head(&(channel->all_queries));
184
+ for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
185
+ {
186
+ ares__init_list_head(&(channel->queries_by_qid[i]));
187
+ }
188
+ for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
189
+ {
190
+ ares__init_list_head(&(channel->queries_by_timeout[i]));
191
+ }
192
+
193
+ /* Initialize configuration by each of the four sources, from highest
194
+ * precedence to lowest.
195
+ */
196
+
197
+ if (status == ARES_SUCCESS) {
198
+ status = init_by_options(channel, options, optmask);
199
+ if (status != ARES_SUCCESS)
200
+ DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
201
+ ares_strerror(status)));
202
+ }
203
+ if (status == ARES_SUCCESS) {
204
+ status = init_by_environment(channel);
205
+ if (status != ARES_SUCCESS)
206
+ DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
207
+ ares_strerror(status)));
208
+ }
209
+ if (status == ARES_SUCCESS) {
210
+ status = init_by_resolv_conf(channel);
211
+ if (status != ARES_SUCCESS)
212
+ DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
213
+ ares_strerror(status)));
214
+ }
215
+
216
+ /*
217
+ * No matter what failed or succeeded, seed defaults to provide
218
+ * useful behavior for things that we missed.
219
+ */
220
+ status = init_by_defaults(channel);
221
+ if (status != ARES_SUCCESS)
222
+ DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
223
+ ares_strerror(status)));
224
+
225
+ /* Generate random key */
226
+
227
+ if (status == ARES_SUCCESS) {
228
+ status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
229
+ if (status == ARES_SUCCESS)
230
+ channel->next_id = ares__generate_new_id(&channel->id_key);
231
+ else
232
+ DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
233
+ ares_strerror(status)));
234
+ }
235
+
236
+ if (status != ARES_SUCCESS)
237
+ {
238
+ /* Something failed; clean up memory we may have allocated. */
239
+ if (channel->servers)
240
+ free(channel->servers);
241
+ if (channel->domains)
242
+ {
243
+ for (i = 0; i < channel->ndomains; i++)
244
+ free(channel->domains[i]);
245
+ free(channel->domains);
246
+ }
247
+ if (channel->sortlist)
248
+ free(channel->sortlist);
249
+ if(channel->lookups)
250
+ free(channel->lookups);
251
+ free(channel);
252
+ return status;
253
+ }
254
+
255
+ /* Trim to one server if ARES_FLAG_PRIMARY is set. */
256
+ if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
257
+ channel->nservers = 1;
258
+
259
+ ares__init_servers_state(channel);
260
+
261
+ *channelptr = channel;
262
+ return ARES_SUCCESS;
263
+ }
264
+
265
+ /* ares_dup() duplicates a channel handle with all its options and returns a
266
+ new channel handle */
267
+ int ares_dup(ares_channel *dest, ares_channel src)
268
+ {
269
+ struct ares_options opts;
270
+ struct ares_addr_node *servers;
271
+ int ipv6_nservers = 0;
272
+ int i, rc;
273
+ int optmask;
274
+
275
+ *dest = NULL; /* in case of failure return NULL explicitly */
276
+
277
+ /* First get the options supported by the old ares_save_options() function,
278
+ which is most of them */
279
+ rc = ares_save_options(src, &opts, &optmask);
280
+ if(rc)
281
+ return rc;
282
+
283
+ /* Then create the new channel with those options */
284
+ rc = ares_init_options(dest, &opts, optmask);
285
+
286
+ /* destroy the options copy to not leak any memory */
287
+ ares_destroy_options(&opts);
288
+
289
+ if(rc)
290
+ return rc;
291
+
292
+ /* Now clone the options that ares_save_options() doesn't support. */
293
+ (*dest)->sock_create_cb = src->sock_create_cb;
294
+ (*dest)->sock_create_cb_data = src->sock_create_cb_data;
295
+
296
+ strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name));
297
+ (*dest)->local_ip4 = src->local_ip4;
298
+ memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
299
+
300
+ /* Full name server cloning required when not all are IPv4 */
301
+ for (i = 0; i < src->nservers; i++)
302
+ {
303
+ if (src->servers[i].addr.family != AF_INET) {
304
+ ipv6_nservers++;
305
+ break;
306
+ }
307
+ }
308
+ if (ipv6_nservers) {
309
+ rc = ares_get_servers(src, &servers);
310
+ if (rc != ARES_SUCCESS)
311
+ return rc;
312
+ rc = ares_set_servers(*dest, servers);
313
+ ares_free_data(servers);
314
+ if (rc != ARES_SUCCESS)
315
+ return rc;
316
+ }
317
+
318
+ return ARES_SUCCESS; /* everything went fine */
319
+ }
320
+
321
+ /* Save options from initialized channel */
322
+ int ares_save_options(ares_channel channel, struct ares_options *options,
323
+ int *optmask)
324
+ {
325
+ int i, j;
326
+ int ipv4_nservers = 0;
327
+
328
+ /* Zero everything out */
329
+ memset(options, 0, sizeof(struct ares_options));
330
+
331
+ if (!ARES_CONFIG_CHECK(channel))
332
+ return ARES_ENODATA;
333
+
334
+ /* Traditionally the optmask wasn't saved in the channel struct so it was
335
+ recreated here. ROTATE is the first option that has no struct field of
336
+ its own in the public config struct */
337
+ (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
338
+ ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
339
+ ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
340
+ ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
341
+ (channel->optmask & ARES_OPT_ROTATE);
342
+
343
+ /* Copy easy stuff */
344
+ options->flags = channel->flags;
345
+
346
+ /* We return full millisecond resolution but that's only because we don't
347
+ set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
348
+ options->timeout = channel->timeout;
349
+ options->tries = channel->tries;
350
+ options->ndots = channel->ndots;
351
+ options->udp_port = (unsigned short)channel->udp_port;
352
+ options->tcp_port = (unsigned short)channel->tcp_port;
353
+ options->sock_state_cb = channel->sock_state_cb;
354
+ options->sock_state_cb_data = channel->sock_state_cb_data;
355
+
356
+ /* Copy IPv4 servers */
357
+ if (channel->nservers) {
358
+ for (i = 0; i < channel->nservers; i++)
359
+ {
360
+ if (channel->servers[i].addr.family == AF_INET)
361
+ ipv4_nservers++;
362
+ }
363
+ if (ipv4_nservers) {
364
+ options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
365
+ if (!options->servers)
366
+ return ARES_ENOMEM;
367
+ for (i = j = 0; i < channel->nservers; i++)
368
+ {
369
+ if (channel->servers[i].addr.family == AF_INET)
370
+ memcpy(&options->servers[j++],
371
+ &channel->servers[i].addr.addrV4,
372
+ sizeof(channel->servers[i].addr.addrV4));
373
+ }
374
+ }
375
+ }
376
+ options->nservers = ipv4_nservers;
377
+
378
+ /* copy domains */
379
+ if (channel->ndomains) {
380
+ options->domains = malloc(channel->ndomains * sizeof(char *));
381
+ if (!options->domains)
382
+ return ARES_ENOMEM;
383
+
384
+ for (i = 0; i < channel->ndomains; i++)
385
+ {
386
+ options->ndomains = i;
387
+ options->domains[i] = strdup(channel->domains[i]);
388
+ if (!options->domains[i])
389
+ return ARES_ENOMEM;
390
+ }
391
+ }
392
+ options->ndomains = channel->ndomains;
393
+
394
+ /* copy lookups */
395
+ if (channel->lookups) {
396
+ options->lookups = strdup(channel->lookups);
397
+ if (!options->lookups && channel->lookups)
398
+ return ARES_ENOMEM;
399
+ }
400
+
401
+ /* copy sortlist */
402
+ if (channel->nsort) {
403
+ options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
404
+ if (!options->sortlist)
405
+ return ARES_ENOMEM;
406
+ for (i = 0; i < channel->nsort; i++)
407
+ options->sortlist[i] = channel->sortlist[i];
408
+ }
409
+ options->nsort = channel->nsort;
410
+
411
+ return ARES_SUCCESS;
412
+ }
413
+
414
+ static int init_by_options(ares_channel channel,
415
+ const struct ares_options *options,
416
+ int optmask)
417
+ {
418
+ int i;
419
+
420
+ /* Easy stuff. */
421
+ if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
422
+ channel->flags = options->flags;
423
+ if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
424
+ channel->timeout = options->timeout;
425
+ else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
426
+ channel->timeout = options->timeout * 1000;
427
+ if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
428
+ channel->tries = options->tries;
429
+ if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
430
+ channel->ndots = options->ndots;
431
+ if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
432
+ channel->rotate = 1;
433
+ if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
434
+ channel->udp_port = options->udp_port;
435
+ if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
436
+ channel->tcp_port = options->tcp_port;
437
+ if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
438
+ {
439
+ channel->sock_state_cb = options->sock_state_cb;
440
+ channel->sock_state_cb_data = options->sock_state_cb_data;
441
+ }
442
+ if ((optmask & ARES_OPT_SOCK_SNDBUF)
443
+ && channel->socket_send_buffer_size == -1)
444
+ channel->socket_send_buffer_size = options->socket_send_buffer_size;
445
+ if ((optmask & ARES_OPT_SOCK_RCVBUF)
446
+ && channel->socket_receive_buffer_size == -1)
447
+ channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
448
+
449
+ /* Copy the IPv4 servers, if given. */
450
+ if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
451
+ {
452
+ /* Avoid zero size allocations at any cost */
453
+ if (options->nservers > 0)
454
+ {
455
+ channel->servers =
456
+ malloc(options->nservers * sizeof(struct server_state));
457
+ if (!channel->servers)
458
+ return ARES_ENOMEM;
459
+ for (i = 0; i < options->nservers; i++)
460
+ {
461
+ channel->servers[i].addr.family = AF_INET;
462
+ memcpy(&channel->servers[i].addr.addrV4,
463
+ &options->servers[i],
464
+ sizeof(channel->servers[i].addr.addrV4));
465
+ }
466
+ }
467
+ channel->nservers = options->nservers;
468
+ }
469
+
470
+ /* Copy the domains, if given. Keep channel->ndomains consistent so
471
+ * we can clean up in case of error.
472
+ */
473
+ if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
474
+ {
475
+ /* Avoid zero size allocations at any cost */
476
+ if (options->ndomains > 0)
477
+ {
478
+ channel->domains = malloc(options->ndomains * sizeof(char *));
479
+ if (!channel->domains)
480
+ return ARES_ENOMEM;
481
+ for (i = 0; i < options->ndomains; i++)
482
+ {
483
+ channel->ndomains = i;
484
+ channel->domains[i] = strdup(options->domains[i]);
485
+ if (!channel->domains[i])
486
+ return ARES_ENOMEM;
487
+ }
488
+ }
489
+ channel->ndomains = options->ndomains;
490
+ }
491
+
492
+ /* Set lookups, if given. */
493
+ if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
494
+ {
495
+ channel->lookups = strdup(options->lookups);
496
+ if (!channel->lookups)
497
+ return ARES_ENOMEM;
498
+ }
499
+
500
+ /* copy sortlist */
501
+ if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
502
+ (options->nsort>0)) {
503
+ channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
504
+ if (!channel->sortlist)
505
+ return ARES_ENOMEM;
506
+ for (i = 0; i < options->nsort; i++)
507
+ channel->sortlist[i] = options->sortlist[i];
508
+ channel->nsort = options->nsort;
509
+ }
510
+
511
+ channel->optmask = optmask;
512
+
513
+ return ARES_SUCCESS;
514
+ }
515
+
516
+ static int init_by_environment(ares_channel channel)
517
+ {
518
+ const char *localdomain, *res_options;
519
+ int status;
520
+
521
+ localdomain = getenv("LOCALDOMAIN");
522
+ if (localdomain && channel->ndomains == -1)
523
+ {
524
+ status = set_search(channel, localdomain);
525
+ if (status != ARES_SUCCESS)
526
+ return status;
527
+ }
528
+
529
+ res_options = getenv("RES_OPTIONS");
530
+ if (res_options)
531
+ {
532
+ status = set_options(channel, res_options);
533
+ if (status != ARES_SUCCESS)
534
+ return status;
535
+ }
536
+
537
+ return ARES_SUCCESS;
538
+ }
539
+
540
+ #ifdef WIN32
541
+ /*
542
+ * Warning: returns a dynamically allocated buffer, the user MUST
543
+ * use free() if the function returns 1
544
+ */
545
+ static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
546
+ {
547
+ /* Test for the size we need */
548
+ DWORD size = 0;
549
+ int result;
550
+
551
+ result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
552
+ if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
553
+ return 0;
554
+ *obuf = malloc(size+1);
555
+ if (!*obuf)
556
+ return 0;
557
+
558
+ if (RegQueryValueEx(hKey, subkey, 0, NULL,
559
+ (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
560
+ {
561
+ free(*obuf);
562
+ return 0;
563
+ }
564
+ if (size == 1)
565
+ {
566
+ free(*obuf);
567
+ return 0;
568
+ }
569
+ return 1;
570
+ }
571
+
572
+ static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
573
+ {
574
+ char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
575
+ DWORD enum_size = 39;
576
+ int idx = 0;
577
+ HKEY hVal;
578
+
579
+ while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
580
+ NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
581
+ {
582
+ int rc;
583
+
584
+ enum_size = 39;
585
+ if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
586
+ ERROR_SUCCESS)
587
+ continue;
588
+ rc = get_res_nt(hVal, subkey, obuf);
589
+ RegCloseKey(hVal);
590
+ if (rc)
591
+ return 1;
592
+ }
593
+ return 0;
594
+ }
595
+
596
+ /**
597
+ * The desired output for this method is that we set "ret_buf" to
598
+ * something like:
599
+ *
600
+ * 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
601
+ *
602
+ * The only ordering requirement is that primary servers are listed
603
+ * before secondary. There is no requirement that IPv4 addresses should
604
+ * necessarily be before IPv6.
605
+ *
606
+ * Note that ret_size should ideally be big enough to hold around
607
+ * 2-3 IPv4 and 2-3 IPv6 addresses.
608
+ *
609
+ * Finally, we need to return the total number of DNS servers located.
610
+ */
611
+ static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
612
+ {
613
+ const size_t ipv4_size = INET_ADDRSTRLEN + 1; /* +1 for ',' at end */
614
+ const size_t ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," at end */
615
+ size_t left = ret_size;
616
+ char *ret = ret_buf;
617
+ int count = 0;
618
+
619
+ /* Use the GetAdaptersAddresses method if it's available, otherwise
620
+ fall back to GetNetworkParams. */
621
+ if (ares_fpGetAdaptersAddresses != ZERO_NULL)
622
+ {
623
+ const ULONG working_buf_size = 15000;
624
+ IP_ADAPTER_ADDRESSES *pFirstEntry = NULL;
625
+ IP_ADAPTER_ADDRESSES *pEntry = NULL;
626
+ ULONG bufSize = 0;
627
+ ULONG result = 0;
628
+
629
+ /* According to MSDN, the recommended way to do this is to use a temporary
630
+ buffer of 15K, to "dramatically reduce the chance that the GetAdaptersAddresses
631
+ method returns ERROR_BUFFER_OVERFLOW" */
632
+ pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) malloc( working_buf_size );
633
+ bufSize = working_buf_size;
634
+ if( !pFirstEntry )
635
+ return 0;
636
+
637
+ /* Call the method one time */
638
+ result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
639
+ if( result == ERROR_BUFFER_OVERFLOW )
640
+ {
641
+ /* Reallocate, bufSize should now be set to the required size */
642
+ pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
643
+ if( !pFirstEntry )
644
+ return 0;
645
+
646
+ /* Call the method a second time */
647
+ result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
648
+ if( result == ERROR_BUFFER_OVERFLOW )
649
+ {
650
+ /* Reallocate, bufSize should now be set to the required size */
651
+ pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
652
+ if( !pFirstEntry )
653
+ return 0;
654
+
655
+ /* Call the method a third time. The maximum number of times we're going to do
656
+ this is 3. Three shall be the number thou shalt count, and the number of the
657
+ counting shall be three. Five is right out. */
658
+ result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
659
+ }
660
+ }
661
+
662
+ /* Check the current result for failure */
663
+ if( result != ERROR_SUCCESS )
664
+ {
665
+ free( pFirstEntry );
666
+ return 0;
667
+ }
668
+
669
+ /* process the results */
670
+ for( pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next )
671
+ {
672
+ IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
673
+ for( ; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next )
674
+ {
675
+ struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
676
+ size_t stringlen = 0;
677
+
678
+ if( pGenericAddr->sa_family == AF_INET && left > ipv4_size )
679
+ {
680
+ /* Handle the v4 case */
681
+ struct sockaddr_in *pIPv4Addr = ( struct sockaddr_in * ) pGenericAddr;
682
+ ares_inet_ntop( AF_INET, &pIPv4Addr->sin_addr, ret, ipv4_size - 1 ); /* -1 for comma */
683
+
684
+ /* Append a comma to the end, THEN NULL. Should be OK because we
685
+ already tested the size at the top of the if statement. */
686
+ stringlen = strlen( ret );
687
+ ret[ stringlen ] = ',';
688
+ ret[ stringlen + 1 ] = '\0';
689
+ ret += stringlen + 1;
690
+ left -= ret - ret_buf;
691
+ ++count;
692
+ }
693
+ else if( pGenericAddr->sa_family == AF_INET6 && left > ipv6_size )
694
+ {
695
+ /* Handle the v6 case */
696
+ struct sockaddr_in6 *pIPv6Addr = ( struct sockaddr_in6 * ) pGenericAddr;
697
+ ares_inet_ntop( AF_INET6, &pIPv6Addr->sin6_addr, ret, ipv6_size - 1 ); /* -1 for comma */
698
+
699
+ stringlen = strlen( ret );
700
+
701
+ /* Windows apparently always reports some IPv6 DNS servers that
702
+ prefixed with fec0:0:0:ffff. These ususally do not point to
703
+ working DNS servers, so we ignore them. */
704
+ if (strncmp(ret, "fec0:0:0:ffff:", 14) != 0) {
705
+ /* Append a comma to the end, THEN NULL. Should be OK because we
706
+ already tested the size at the top of the if statement. */
707
+ ret[ stringlen ] = ',';
708
+ ret[ stringlen + 1 ] = '\0';
709
+ ret += stringlen + 1;
710
+ left -= ret - ret_buf;
711
+ ++count;
712
+ }
713
+ }
714
+ }
715
+ }
716
+
717
+ if( pFirstEntry )
718
+ free( pFirstEntry );
719
+ if (ret > ret_buf)
720
+ ret[-1] = '\0';
721
+ return count;
722
+ }
723
+ else
724
+ {
725
+ FIXED_INFO *fi, *newfi;
726
+ DWORD size = sizeof (*fi);
727
+ IP_ADDR_STRING *ipAddr;
728
+ int i;
729
+ int debug = 0;
730
+ HRESULT res;
731
+
732
+ fi = malloc(size);
733
+ if (!fi)
734
+ return 0;
735
+
736
+ res = (*ares_fpGetNetworkParams) (fi, &size);
737
+ if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
738
+ goto quit;
739
+
740
+ newfi = realloc(fi, size);
741
+ if (!newfi)
742
+ goto quit;
743
+
744
+ fi = newfi;
745
+ res = (*ares_fpGetNetworkParams) (fi, &size);
746
+ if (res != ERROR_SUCCESS)
747
+ goto quit;
748
+
749
+ if (debug)
750
+ {
751
+ printf ("Host Name: %s\n", fi->HostName);
752
+ printf ("Domain Name: %s\n", fi->DomainName);
753
+ printf ("DNS Servers:\n"
754
+ " %s (primary)\n", fi->DnsServerList.IpAddress.String);
755
+ }
756
+ if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
757
+ inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
758
+ left > ipv4_size)
759
+ {
760
+ ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
761
+ left -= ret - ret_buf;
762
+ ++count;
763
+ }
764
+
765
+ for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
766
+ ipAddr = ipAddr->Next, i++)
767
+ {
768
+ if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
769
+ {
770
+ ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
771
+ left -= ret - ret_buf;
772
+ ++count;
773
+ }
774
+ if (debug)
775
+ printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
776
+ }
777
+
778
+ quit:
779
+ if (fi)
780
+ free(fi);
781
+
782
+ if (debug && left <= ipv4_size)
783
+ printf ("Too many nameservers. Truncating to %d addressess", count);
784
+ if (ret > ret_buf)
785
+ ret[-1] = '\0';
786
+ return count;
787
+ }
788
+ }
789
+ #endif
790
+
791
+ static int init_by_resolv_conf(ares_channel channel)
792
+ {
793
+ #ifndef WATT32
794
+ char *line = NULL;
795
+ #endif
796
+ int status = -1, nservers = 0, nsort = 0;
797
+ struct server_state *servers = NULL;
798
+ struct apattern *sortlist = NULL;
799
+
800
+ #ifdef WIN32
801
+
802
+ /*
803
+ NameServer info via IPHLPAPI (IP helper API):
804
+ GetNetworkParams() should be the trusted source for this.
805
+ Available in Win-98/2000 and later. If that fail, fall-back to
806
+ registry information.
807
+
808
+ NameServer Registry:
809
+
810
+ On Windows 9X, the DNS server can be found in:
811
+ HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
812
+
813
+ On Windows NT/2000/XP/2003:
814
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
815
+ or
816
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
817
+ or
818
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
819
+ NameServer
820
+ or
821
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
822
+ DhcpNameServer
823
+ */
824
+
825
+ HKEY mykey;
826
+ HKEY subkey;
827
+ DWORD data_type;
828
+ DWORD bytes;
829
+ DWORD result;
830
+ char buf[512];
831
+ win_platform platform;
832
+
833
+ if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
834
+ return ARES_SUCCESS;
835
+
836
+ if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
837
+ {
838
+ status = config_nameserver(&servers, &nservers, buf);
839
+ if (status == ARES_SUCCESS)
840
+ goto okay;
841
+ }
842
+
843
+ platform = ares__getplatform();
844
+
845
+ if (platform == WIN_NT)
846
+ {
847
+ if (RegOpenKeyEx(
848
+ HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
849
+ KEY_READ, &mykey
850
+ ) == ERROR_SUCCESS)
851
+ {
852
+ RegOpenKeyEx(mykey, "Interfaces", 0,
853
+ KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
854
+ if (get_res_nt(mykey, NAMESERVER, &line))
855
+ {
856
+ status = config_nameserver(&servers, &nservers, line);
857
+ free(line);
858
+ }
859
+ else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
860
+ {
861
+ status = config_nameserver(&servers, &nservers, line);
862
+ free(line);
863
+ }
864
+ /* Try the interfaces */
865
+ else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
866
+ {
867
+ status = config_nameserver(&servers, &nservers, line);
868
+ free(line);
869
+ }
870
+ else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
871
+ {
872
+ status = config_nameserver(&servers, &nservers, line);
873
+ free(line);
874
+ }
875
+ RegCloseKey(subkey);
876
+ RegCloseKey(mykey);
877
+ }
878
+ }
879
+ else if (platform == WIN_9X)
880
+ {
881
+ if (RegOpenKeyEx(
882
+ HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
883
+ KEY_READ, &mykey
884
+ ) == ERROR_SUCCESS)
885
+ {
886
+ if ((result = RegQueryValueEx(
887
+ mykey, NAMESERVER, NULL, &data_type,
888
+ NULL, &bytes
889
+ )
890
+ ) == ERROR_SUCCESS ||
891
+ result == ERROR_MORE_DATA)
892
+ {
893
+ if (bytes)
894
+ {
895
+ line = malloc(bytes+1);
896
+ if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
897
+ (unsigned char *)line, &bytes) ==
898
+ ERROR_SUCCESS)
899
+ {
900
+ status = config_nameserver(&servers, &nservers, line);
901
+ }
902
+ free(line);
903
+ }
904
+ }
905
+ }
906
+ RegCloseKey(mykey);
907
+ }
908
+
909
+ if (status == ARES_SUCCESS)
910
+ status = ARES_EOF;
911
+ else
912
+ /* Catch the case when all the above checks fail (which happens when there
913
+ is no network card or the cable is unplugged) */
914
+ status = ARES_EFILE;
915
+
916
+ #elif defined(__riscos__)
917
+
918
+ /* Under RISC OS, name servers are listed in the
919
+ system variable Inet$Resolvers, space separated. */
920
+
921
+ line = getenv("Inet$Resolvers");
922
+ status = ARES_EOF;
923
+ if (line) {
924
+ char *resolvers = strdup(line), *pos, *space;
925
+
926
+ if (!resolvers)
927
+ return ARES_ENOMEM;
928
+
929
+ pos = resolvers;
930
+ do {
931
+ space = strchr(pos, ' ');
932
+ if (space)
933
+ *space = '\0';
934
+ status = config_nameserver(&servers, &nservers, pos);
935
+ if (status != ARES_SUCCESS)
936
+ break;
937
+ pos = space + 1;
938
+ } while (space);
939
+
940
+ if (status == ARES_SUCCESS)
941
+ status = ARES_EOF;
942
+
943
+ free(resolvers);
944
+ }
945
+
946
+ #elif defined(WATT32)
947
+ int i;
948
+
949
+ sock_init();
950
+ for (i = 0; def_nameservers[i]; i++)
951
+ ;
952
+ if (i == 0)
953
+ return ARES_SUCCESS; /* use localhost DNS server */
954
+
955
+ nservers = i;
956
+ servers = calloc(i, sizeof(struct server_state));
957
+ if (!servers)
958
+ return ARES_ENOMEM;
959
+
960
+ for (i = 0; def_nameservers[i]; i++)
961
+ {
962
+ servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
963
+ servers[i].addr.family = AF_INET;
964
+ }
965
+ status = ARES_EOF;
966
+
967
+ #elif defined(ANDROID)
968
+ char value[PROP_VALUE_MAX]="";
969
+ __system_property_get("net.dns1", value);
970
+ status = config_nameserver(&servers, &nservers, value);
971
+ if (status == ARES_SUCCESS)
972
+ status = ARES_EOF;
973
+ #else
974
+ {
975
+ char *p;
976
+ FILE *fp;
977
+ size_t linesize;
978
+ int error;
979
+
980
+ /* Don't read resolv.conf and friends if we don't have to */
981
+ if (ARES_CONFIG_CHECK(channel))
982
+ return ARES_SUCCESS;
983
+
984
+ fp = fopen(PATH_RESOLV_CONF, "r");
985
+ if (fp) {
986
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
987
+ {
988
+ if ((p = try_config(line, "domain", ';')))
989
+ status = config_domain(channel, p);
990
+ else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
991
+ status = config_lookup(channel, p, "bind", "file");
992
+ else if ((p = try_config(line, "search", ';')))
993
+ status = set_search(channel, p);
994
+ else if ((p = try_config(line, "nameserver", ';')) &&
995
+ channel->nservers == -1)
996
+ status = config_nameserver(&servers, &nservers, p);
997
+ else if ((p = try_config(line, "sortlist", ';')) &&
998
+ channel->nsort == -1)
999
+ status = config_sortlist(&sortlist, &nsort, p);
1000
+ else if ((p = try_config(line, "options", ';')))
1001
+ status = set_options(channel, p);
1002
+ else
1003
+ status = ARES_SUCCESS;
1004
+ if (status != ARES_SUCCESS)
1005
+ break;
1006
+ }
1007
+ fclose(fp);
1008
+ }
1009
+ else {
1010
+ error = ERRNO;
1011
+ switch(error) {
1012
+ case ENOENT:
1013
+ case ESRCH:
1014
+ status = ARES_EOF;
1015
+ break;
1016
+ default:
1017
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1018
+ error, strerror(error)));
1019
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1020
+ status = ARES_EFILE;
1021
+ }
1022
+ }
1023
+
1024
+ if ((status == ARES_EOF) && (!channel->lookups)) {
1025
+ /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1026
+ fp = fopen("/etc/nsswitch.conf", "r");
1027
+ if (fp) {
1028
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1029
+ {
1030
+ if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1031
+ /* ignore errors */
1032
+ (void)config_lookup(channel, p, "dns", "files");
1033
+ }
1034
+ fclose(fp);
1035
+ }
1036
+ else {
1037
+ error = ERRNO;
1038
+ switch(error) {
1039
+ case ENOENT:
1040
+ case ESRCH:
1041
+ status = ARES_EOF;
1042
+ break;
1043
+ default:
1044
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1045
+ error, strerror(error)));
1046
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
1047
+ status = ARES_EFILE;
1048
+ }
1049
+ }
1050
+ }
1051
+
1052
+ if ((status == ARES_EOF) && (!channel->lookups)) {
1053
+ /* Linux / GNU libc 2.x and possibly others have host.conf */
1054
+ fp = fopen("/etc/host.conf", "r");
1055
+ if (fp) {
1056
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1057
+ {
1058
+ if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1059
+ /* ignore errors */
1060
+ (void)config_lookup(channel, p, "bind", "hosts");
1061
+ }
1062
+ fclose(fp);
1063
+ }
1064
+ else {
1065
+ error = ERRNO;
1066
+ switch(error) {
1067
+ case ENOENT:
1068
+ case ESRCH:
1069
+ status = ARES_EOF;
1070
+ break;
1071
+ default:
1072
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1073
+ error, strerror(error)));
1074
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
1075
+ status = ARES_EFILE;
1076
+ }
1077
+ }
1078
+ }
1079
+
1080
+ if ((status == ARES_EOF) && (!channel->lookups)) {
1081
+ /* Tru64 uses /etc/svc.conf */
1082
+ fp = fopen("/etc/svc.conf", "r");
1083
+ if (fp) {
1084
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1085
+ {
1086
+ if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1087
+ /* ignore errors */
1088
+ (void)config_lookup(channel, p, "bind", "local");
1089
+ }
1090
+ fclose(fp);
1091
+ }
1092
+ else {
1093
+ error = ERRNO;
1094
+ switch(error) {
1095
+ case ENOENT:
1096
+ case ESRCH:
1097
+ status = ARES_EOF;
1098
+ break;
1099
+ default:
1100
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1101
+ error, strerror(error)));
1102
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1103
+ status = ARES_EFILE;
1104
+ }
1105
+ }
1106
+ }
1107
+
1108
+ if(line)
1109
+ free(line);
1110
+ }
1111
+
1112
+ #endif
1113
+
1114
+ /* Handle errors. */
1115
+ if (status != ARES_EOF)
1116
+ {
1117
+ if (servers != NULL)
1118
+ free(servers);
1119
+ if (sortlist != NULL)
1120
+ free(sortlist);
1121
+ return status;
1122
+ }
1123
+
1124
+ /* If we got any name server entries, fill them in. */
1125
+ #ifdef WIN32
1126
+ okay:
1127
+ #endif
1128
+ if (servers)
1129
+ {
1130
+ channel->servers = servers;
1131
+ channel->nservers = nservers;
1132
+ }
1133
+
1134
+ /* If we got any sortlist entries, fill them in. */
1135
+ if (sortlist)
1136
+ {
1137
+ channel->sortlist = sortlist;
1138
+ channel->nsort = nsort;
1139
+ }
1140
+
1141
+ return ARES_SUCCESS;
1142
+ }
1143
+
1144
+ static int init_by_defaults(ares_channel channel)
1145
+ {
1146
+ char *hostname = NULL;
1147
+ int rc = ARES_SUCCESS;
1148
+ #ifdef HAVE_GETHOSTNAME
1149
+ char *dot;
1150
+ #endif
1151
+
1152
+ if (channel->flags == -1)
1153
+ channel->flags = 0;
1154
+ if (channel->timeout == -1)
1155
+ channel->timeout = DEFAULT_TIMEOUT;
1156
+ if (channel->tries == -1)
1157
+ channel->tries = DEFAULT_TRIES;
1158
+ if (channel->ndots == -1)
1159
+ channel->ndots = 1;
1160
+ if (channel->rotate == -1)
1161
+ channel->rotate = 0;
1162
+ if (channel->udp_port == -1)
1163
+ channel->udp_port = htons(NAMESERVER_PORT);
1164
+ if (channel->tcp_port == -1)
1165
+ channel->tcp_port = htons(NAMESERVER_PORT);
1166
+
1167
+ if (channel->nservers == -1) {
1168
+ /* If nobody specified servers, try a local named. */
1169
+ channel->servers = malloc(sizeof(struct server_state));
1170
+ if (!channel->servers) {
1171
+ rc = ARES_ENOMEM;
1172
+ goto error;
1173
+ }
1174
+ channel->servers[0].addr.family = AF_INET;
1175
+ channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1176
+ channel->nservers = 1;
1177
+ }
1178
+
1179
+ #if defined(USE_WINSOCK)
1180
+ #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1181
+ #elif defined(ENAMETOOLONG)
1182
+ #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1183
+ (SOCKERRNO == EINVAL))
1184
+ #else
1185
+ #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1186
+ #endif
1187
+
1188
+ if (channel->ndomains == -1) {
1189
+ /* Derive a default domain search list from the kernel hostname,
1190
+ * or set it to empty if the hostname isn't helpful.
1191
+ */
1192
+ size_t len = 64;
1193
+ int res;
1194
+ channel->ndomains = 0; /* default to none */
1195
+
1196
+ #ifdef HAVE_GETHOSTNAME
1197
+ hostname = malloc(len);
1198
+ if(!hostname) {
1199
+ rc = ARES_ENOMEM;
1200
+ goto error;
1201
+ }
1202
+
1203
+ do {
1204
+ res = gethostname(hostname, len);
1205
+
1206
+ if(toolong(res)) {
1207
+ char *p;
1208
+ len *= 2;
1209
+ p = realloc(hostname, len);
1210
+ if(!p) {
1211
+ rc = ARES_ENOMEM;
1212
+ goto error;
1213
+ }
1214
+ hostname = p;
1215
+ continue;
1216
+ }
1217
+ else if(res) {
1218
+ rc = ARES_EBADNAME;
1219
+ goto error;
1220
+ }
1221
+
1222
+ } while(0);
1223
+
1224
+ dot = strchr(hostname, '.');
1225
+ if (dot) {
1226
+ /* a dot was found */
1227
+ channel->domains = malloc(sizeof(char *));
1228
+ if (!channel->domains) {
1229
+ rc = ARES_ENOMEM;
1230
+ goto error;
1231
+ }
1232
+ channel->domains[0] = strdup(dot + 1);
1233
+ if (!channel->domains[0]) {
1234
+ rc = ARES_ENOMEM;
1235
+ goto error;
1236
+ }
1237
+ channel->ndomains = 1;
1238
+ }
1239
+ #endif
1240
+ }
1241
+
1242
+ if (channel->nsort == -1) {
1243
+ channel->sortlist = NULL;
1244
+ channel->nsort = 0;
1245
+ }
1246
+
1247
+ if (!channel->lookups) {
1248
+ channel->lookups = strdup("fb");
1249
+ if (!channel->lookups)
1250
+ rc = ARES_ENOMEM;
1251
+ }
1252
+
1253
+ error:
1254
+ if(rc) {
1255
+ if(channel->servers)
1256
+ free(channel->servers);
1257
+
1258
+ if(channel->domains && channel->domains[0])
1259
+ free(channel->domains[0]);
1260
+ if(channel->domains)
1261
+ free(channel->domains);
1262
+ if(channel->lookups)
1263
+ free(channel->lookups);
1264
+ }
1265
+
1266
+ if(hostname)
1267
+ free(hostname);
1268
+
1269
+ return rc;
1270
+ }
1271
+
1272
+ #if !defined(WIN32) && !defined(WATT32)
1273
+ static int config_domain(ares_channel channel, char *str)
1274
+ {
1275
+ char *q;
1276
+
1277
+ /* Set a single search domain. */
1278
+ q = str;
1279
+ while (*q && !ISSPACE(*q))
1280
+ q++;
1281
+ *q = '\0';
1282
+ return set_search(channel, str);
1283
+ }
1284
+
1285
+ #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1286
+ defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1287
+ /* workaround icc 9.1 optimizer issue */
1288
+ # define vqualifier volatile
1289
+ #else
1290
+ # define vqualifier
1291
+ #endif
1292
+
1293
+ static int config_lookup(ares_channel channel, const char *str,
1294
+ const char *bindch, const char *filech)
1295
+ {
1296
+ char lookups[3], *l;
1297
+ const char *vqualifier p;
1298
+
1299
+ /* Set the lookup order. Only the first letter of each work
1300
+ * is relevant, and it has to be "b" for DNS or "f" for the
1301
+ * host file. Ignore everything else.
1302
+ */
1303
+ l = lookups;
1304
+ p = str;
1305
+ while (*p)
1306
+ {
1307
+ if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1308
+ if (*p == *bindch) *l++ = 'b';
1309
+ else *l++ = 'f';
1310
+ }
1311
+ while (*p && !ISSPACE(*p) && (*p != ','))
1312
+ p++;
1313
+ while (*p && (ISSPACE(*p) || (*p == ',')))
1314
+ p++;
1315
+ }
1316
+ *l = '\0';
1317
+ channel->lookups = strdup(lookups);
1318
+ return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1319
+ }
1320
+ #endif /* !WIN32 & !WATT32 */
1321
+
1322
+ #ifndef WATT32
1323
+ static int config_nameserver(struct server_state **servers, int *nservers,
1324
+ char *str)
1325
+ {
1326
+ struct ares_addr host;
1327
+ struct server_state *newserv;
1328
+ char *p, *txtaddr;
1329
+ /* On Windows, there may be more than one nameserver specified in the same
1330
+ * registry key, so we parse input as a space or comma seperated list.
1331
+ */
1332
+ for (p = str; p;)
1333
+ {
1334
+ /* Skip whitespace and commas. */
1335
+ while (*p && (ISSPACE(*p) || (*p == ',')))
1336
+ p++;
1337
+ if (!*p)
1338
+ /* No more input, done. */
1339
+ break;
1340
+
1341
+ /* Pointer to start of IPv4 or IPv6 address part. */
1342
+ txtaddr = p;
1343
+
1344
+ /* Advance past this address. */
1345
+ while (*p && !ISSPACE(*p) && (*p != ','))
1346
+ p++;
1347
+ if (*p)
1348
+ /* Null terminate this address. */
1349
+ *p++ = '\0';
1350
+ else
1351
+ /* Reached end of input, done when this address is processed. */
1352
+ p = NULL;
1353
+
1354
+ /* Convert textual address to binary format. */
1355
+ if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1356
+ host.family = AF_INET;
1357
+ else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1358
+ host.family = AF_INET6;
1359
+ else
1360
+ continue;
1361
+
1362
+ /* Resize servers state array. */
1363
+ newserv = realloc(*servers, (*nservers + 1) *
1364
+ sizeof(struct server_state));
1365
+ if (!newserv)
1366
+ return ARES_ENOMEM;
1367
+
1368
+ /* Store address data. */
1369
+ newserv[*nservers].addr.family = host.family;
1370
+ if (host.family == AF_INET)
1371
+ memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1372
+ sizeof(host.addrV4));
1373
+ else
1374
+ memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1375
+ sizeof(host.addrV6));
1376
+
1377
+ /* Update arguments. */
1378
+ *servers = newserv;
1379
+ *nservers += 1;
1380
+ }
1381
+
1382
+ return ARES_SUCCESS;
1383
+ }
1384
+
1385
+ #ifndef WIN32
1386
+ static int config_sortlist(struct apattern **sortlist, int *nsort,
1387
+ const char *str)
1388
+ {
1389
+ struct apattern pat;
1390
+ const char *q;
1391
+
1392
+ /* Add sortlist entries. */
1393
+ while (*str && *str != ';')
1394
+ {
1395
+ int bits;
1396
+ char ipbuf[16], ipbufpfx[32];
1397
+ /* Find just the IP */
1398
+ q = str;
1399
+ while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1400
+ q++;
1401
+ memcpy(ipbuf, str, q-str);
1402
+ ipbuf[q-str] = '\0';
1403
+ /* Find the prefix */
1404
+ if (*q == '/')
1405
+ {
1406
+ const char *str2 = q+1;
1407
+ while (*q && *q != ';' && !ISSPACE(*q))
1408
+ q++;
1409
+ memcpy(ipbufpfx, str, q-str);
1410
+ ipbufpfx[q-str] = '\0';
1411
+ str = str2;
1412
+ }
1413
+ else
1414
+ ipbufpfx[0] = '\0';
1415
+ /* Lets see if it is CIDR */
1416
+ /* First we'll try IPv6 */
1417
+ if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1418
+ &pat.addrV6,
1419
+ sizeof(pat.addrV6))) > 0)
1420
+ {
1421
+ pat.type = PATTERN_CIDR;
1422
+ pat.mask.bits = (unsigned short)bits;
1423
+ pat.family = AF_INET6;
1424
+ if (!sortlist_alloc(sortlist, nsort, &pat))
1425
+ return ARES_ENOMEM;
1426
+ }
1427
+ else if (ipbufpfx[0] &&
1428
+ (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1429
+ sizeof(pat.addrV4))) > 0)
1430
+ {
1431
+ pat.type = PATTERN_CIDR;
1432
+ pat.mask.bits = (unsigned short)bits;
1433
+ pat.family = AF_INET;
1434
+ if (!sortlist_alloc(sortlist, nsort, &pat))
1435
+ return ARES_ENOMEM;
1436
+ }
1437
+ /* See if it is just a regular IP */
1438
+ else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1439
+ {
1440
+ if (ipbufpfx[0])
1441
+ {
1442
+ memcpy(ipbuf, str, q-str);
1443
+ ipbuf[q-str] = '\0';
1444
+ if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1445
+ natural_mask(&pat);
1446
+ }
1447
+ else
1448
+ natural_mask(&pat);
1449
+ pat.family = AF_INET;
1450
+ pat.type = PATTERN_MASK;
1451
+ if (!sortlist_alloc(sortlist, nsort, &pat))
1452
+ return ARES_ENOMEM;
1453
+ }
1454
+ else
1455
+ {
1456
+ while (*q && *q != ';' && !ISSPACE(*q))
1457
+ q++;
1458
+ }
1459
+ str = q;
1460
+ while (ISSPACE(*str))
1461
+ str++;
1462
+ }
1463
+
1464
+ return ARES_SUCCESS;
1465
+ }
1466
+ #endif /* !WIN32 */
1467
+ #endif /* !WATT32 */
1468
+
1469
+ static int set_search(ares_channel channel, const char *str)
1470
+ {
1471
+ int n;
1472
+ const char *p, *q;
1473
+
1474
+ if(channel->ndomains != -1) {
1475
+ /* if we already have some domains present, free them first */
1476
+ for(n=0; n < channel->ndomains; n++)
1477
+ free(channel->domains[n]);
1478
+ free(channel->domains);
1479
+ channel->domains = NULL;
1480
+ channel->ndomains = -1;
1481
+ }
1482
+
1483
+ /* Count the domains given. */
1484
+ n = 0;
1485
+ p = str;
1486
+ while (*p)
1487
+ {
1488
+ while (*p && !ISSPACE(*p))
1489
+ p++;
1490
+ while (ISSPACE(*p))
1491
+ p++;
1492
+ n++;
1493
+ }
1494
+
1495
+ if (!n)
1496
+ {
1497
+ channel->ndomains = 0;
1498
+ return ARES_SUCCESS;
1499
+ }
1500
+
1501
+ channel->domains = malloc(n * sizeof(char *));
1502
+ if (!channel->domains)
1503
+ return ARES_ENOMEM;
1504
+
1505
+ /* Now copy the domains. */
1506
+ n = 0;
1507
+ p = str;
1508
+ while (*p)
1509
+ {
1510
+ channel->ndomains = n;
1511
+ q = p;
1512
+ while (*q && !ISSPACE(*q))
1513
+ q++;
1514
+ channel->domains[n] = malloc(q - p + 1);
1515
+ if (!channel->domains[n])
1516
+ return ARES_ENOMEM;
1517
+ memcpy(channel->domains[n], p, q - p);
1518
+ channel->domains[n][q - p] = 0;
1519
+ p = q;
1520
+ while (ISSPACE(*p))
1521
+ p++;
1522
+ n++;
1523
+ }
1524
+ channel->ndomains = n;
1525
+
1526
+ return ARES_SUCCESS;
1527
+ }
1528
+
1529
+ static int set_options(ares_channel channel, const char *str)
1530
+ {
1531
+ const char *p, *q, *val;
1532
+
1533
+ p = str;
1534
+ while (*p)
1535
+ {
1536
+ q = p;
1537
+ while (*q && !ISSPACE(*q))
1538
+ q++;
1539
+ val = try_option(p, q, "ndots:");
1540
+ if (val && channel->ndots == -1)
1541
+ channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1542
+ val = try_option(p, q, "retrans:");
1543
+ if (val && channel->timeout == -1)
1544
+ channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1545
+ val = try_option(p, q, "retry:");
1546
+ if (val && channel->tries == -1)
1547
+ channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1548
+ val = try_option(p, q, "rotate");
1549
+ if (val && channel->rotate == -1)
1550
+ channel->rotate = 1;
1551
+ p = q;
1552
+ while (ISSPACE(*p))
1553
+ p++;
1554
+ }
1555
+
1556
+ return ARES_SUCCESS;
1557
+ }
1558
+
1559
+ static const char *try_option(const char *p, const char *q, const char *opt)
1560
+ {
1561
+ size_t len = strlen(opt);
1562
+ return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1563
+ }
1564
+
1565
+ #if !defined(WIN32) && !defined(WATT32)
1566
+ static char *try_config(char *s, const char *opt, char scc)
1567
+ {
1568
+ size_t len;
1569
+ char *p;
1570
+ char *q;
1571
+
1572
+ if (!s || !opt)
1573
+ /* no line or no option */
1574
+ return NULL;
1575
+
1576
+ /* Hash '#' character is always used as primary comment char, additionally
1577
+ a not-NUL secondary comment char will be considered when specified. */
1578
+
1579
+ /* trim line comment */
1580
+ p = s;
1581
+ if(scc)
1582
+ while (*p && (*p != '#') && (*p != scc))
1583
+ p++;
1584
+ else
1585
+ while (*p && (*p != '#'))
1586
+ p++;
1587
+ *p = '\0';
1588
+
1589
+ /* trim trailing whitespace */
1590
+ q = p - 1;
1591
+ while ((q >= s) && ISSPACE(*q))
1592
+ q--;
1593
+ *++q = '\0';
1594
+
1595
+ /* skip leading whitespace */
1596
+ p = s;
1597
+ while (*p && ISSPACE(*p))
1598
+ p++;
1599
+
1600
+ if (!*p)
1601
+ /* empty line */
1602
+ return NULL;
1603
+
1604
+ if ((len = strlen(opt)) == 0)
1605
+ /* empty option */
1606
+ return NULL;
1607
+
1608
+ if (strncmp(p, opt, len) != 0)
1609
+ /* line and option do not match */
1610
+ return NULL;
1611
+
1612
+ /* skip over given option name */
1613
+ p += len;
1614
+
1615
+ if (!*p)
1616
+ /* no option value */
1617
+ return NULL;
1618
+
1619
+ if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1620
+ /* whitespace between option name and value is mandatory
1621
+ for given option names which do not end with ':' or '=' */
1622
+ return NULL;
1623
+
1624
+ /* skip over whitespace */
1625
+ while (*p && ISSPACE(*p))
1626
+ p++;
1627
+
1628
+ if (!*p)
1629
+ /* no option value */
1630
+ return NULL;
1631
+
1632
+ /* return pointer to option value */
1633
+ return p;
1634
+ }
1635
+
1636
+ static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1637
+ struct apattern *pat)
1638
+ {
1639
+ struct apattern *newsort;
1640
+ newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1641
+ if (!newsort)
1642
+ return 0;
1643
+ newsort[*nsort] = *pat;
1644
+ *sortlist = newsort;
1645
+ (*nsort)++;
1646
+ return 1;
1647
+ }
1648
+
1649
+ static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1650
+ {
1651
+
1652
+ /* Four octets and three periods yields at most 15 characters. */
1653
+ if (len > 15)
1654
+ return -1;
1655
+
1656
+ addr->s_addr = inet_addr(ipbuf);
1657
+ if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1658
+ return -1;
1659
+ return 0;
1660
+ }
1661
+
1662
+ static void natural_mask(struct apattern *pat)
1663
+ {
1664
+ struct in_addr addr;
1665
+
1666
+ /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1667
+ * but portable.
1668
+ */
1669
+ addr.s_addr = ntohl(pat->addrV4.s_addr);
1670
+
1671
+ /* This is out of date in the CIDR world, but some people might
1672
+ * still rely on it.
1673
+ */
1674
+ if (IN_CLASSA(addr.s_addr))
1675
+ pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1676
+ else if (IN_CLASSB(addr.s_addr))
1677
+ pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1678
+ else
1679
+ pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1680
+ }
1681
+ #endif /* !WIN32 && !WATT32 */
1682
+
1683
+ /* initialize an rc4 key. If possible a cryptographically secure random key
1684
+ is generated using a suitable function (for example win32's RtlGenRandom as
1685
+ described in
1686
+ http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1687
+ otherwise the code defaults to cross-platform albeit less secure mechanism
1688
+ using rand
1689
+ */
1690
+ static void randomize_key(unsigned char* key,int key_data_len)
1691
+ {
1692
+ int randomized = 0;
1693
+ int counter=0;
1694
+ #ifdef WIN32
1695
+ BOOLEAN res;
1696
+ if (ares_fpSystemFunction036)
1697
+ {
1698
+ res = (*ares_fpSystemFunction036) (key, key_data_len);
1699
+ if (res)
1700
+ randomized = 1;
1701
+ }
1702
+ #else /* !WIN32 */
1703
+ #ifdef RANDOM_FILE
1704
+ FILE *f = fopen(RANDOM_FILE, "rb");
1705
+ if(f) {
1706
+ counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1707
+ fclose(f);
1708
+ }
1709
+ #endif
1710
+ #endif /* WIN32 */
1711
+
1712
+ if ( !randomized ) {
1713
+ for (;counter<key_data_len;counter++)
1714
+ key[counter]=(unsigned char)(rand() % 256);
1715
+ }
1716
+ }
1717
+
1718
+ static int init_id_key(rc4_key* key,int key_data_len)
1719
+ {
1720
+ unsigned char index1;
1721
+ unsigned char index2;
1722
+ unsigned char* state;
1723
+ short counter;
1724
+ unsigned char *key_data_ptr = 0;
1725
+
1726
+ key_data_ptr = calloc(1,key_data_len);
1727
+ if (!key_data_ptr)
1728
+ return ARES_ENOMEM;
1729
+
1730
+ state = &key->state[0];
1731
+ for(counter = 0; counter < 256; counter++)
1732
+ /* unnecessary AND but it keeps some compilers happier */
1733
+ state[counter] = (unsigned char)(counter & 0xff);
1734
+ randomize_key(key->state,key_data_len);
1735
+ key->x = 0;
1736
+ key->y = 0;
1737
+ index1 = 0;
1738
+ index2 = 0;
1739
+ for(counter = 0; counter < 256; counter++)
1740
+ {
1741
+ index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1742
+ index2) % 256);
1743
+ ARES_SWAP_BYTE(&state[counter], &state[index2]);
1744
+
1745
+ index1 = (unsigned char)((index1 + 1) % key_data_len);
1746
+ }
1747
+ free(key_data_ptr);
1748
+ return ARES_SUCCESS;
1749
+ }
1750
+
1751
+ unsigned short ares__generate_new_id(rc4_key* key)
1752
+ {
1753
+ unsigned short r=0;
1754
+ ares__rc4(key, (unsigned char *)&r, sizeof(r));
1755
+ return r;
1756
+ }
1757
+
1758
+ void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1759
+ {
1760
+ channel->local_ip4 = local_ip;
1761
+ }
1762
+
1763
+ /* local_ip6 should be 16 bytes in length */
1764
+ void ares_set_local_ip6(ares_channel channel,
1765
+ const unsigned char* local_ip6)
1766
+ {
1767
+ memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1768
+ }
1769
+
1770
+ /* local_dev_name should be null terminated. */
1771
+ void ares_set_local_dev(ares_channel channel,
1772
+ const char* local_dev_name)
1773
+ {
1774
+ strncpy(channel->local_dev_name, local_dev_name,
1775
+ sizeof(channel->local_dev_name));
1776
+ channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1777
+ }
1778
+
1779
+
1780
+ void ares_set_socket_callback(ares_channel channel,
1781
+ ares_sock_create_callback cb,
1782
+ void *data)
1783
+ {
1784
+ channel->sock_create_cb = cb;
1785
+ channel->sock_create_cb_data = data;
1786
+ }
1787
+
1788
+ void ares__init_servers_state(ares_channel channel)
1789
+ {
1790
+ struct server_state *server;
1791
+ int i;
1792
+
1793
+ for (i = 0; i < channel->nservers; i++)
1794
+ {
1795
+ server = &channel->servers[i];
1796
+ server->udp_socket = ARES_SOCKET_BAD;
1797
+ server->tcp_socket = ARES_SOCKET_BAD;
1798
+ server->tcp_connection_generation = ++channel->tcp_connection_generation;
1799
+ server->tcp_lenbuf_pos = 0;
1800
+ server->tcp_buffer_pos = 0;
1801
+ server->tcp_buffer = NULL;
1802
+ server->tcp_length = 0;
1803
+ server->qhead = NULL;
1804
+ server->qtail = NULL;
1805
+ ares__init_list_head(&server->queries_to_server);
1806
+ server->channel = channel;
1807
+ server->is_broken = 0;
1808
+ }
1809
+ }