noderb 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (424) hide show
  1. data/LICENSE +19 -0
  2. data/README.md +25 -0
  3. data/ext/noderb_extension/extconf.rb +11 -0
  4. data/ext/noderb_extension/libuv/AUTHORS +11 -0
  5. data/ext/noderb_extension/libuv/LICENSE +48 -0
  6. data/ext/noderb_extension/libuv/Makefile +119 -0
  7. data/ext/noderb_extension/libuv/README +45 -0
  8. data/ext/noderb_extension/libuv/build/all.gyp +254 -0
  9. data/ext/noderb_extension/libuv/build/common.gypi +13 -0
  10. data/ext/noderb_extension/libuv/build/gyp_uv +43 -0
  11. data/ext/noderb_extension/libuv/config-mingw.mk +67 -0
  12. data/ext/noderb_extension/libuv/config-unix.mk +121 -0
  13. data/ext/noderb_extension/libuv/create-msvs-files.bat +14 -0
  14. data/ext/noderb_extension/libuv/deps/pthread-win32/ANNOUNCE +482 -0
  15. data/ext/noderb_extension/libuv/deps/pthread-win32/BUGS +141 -0
  16. data/ext/noderb_extension/libuv/deps/pthread-win32/Bmakefile +268 -0
  17. data/ext/noderb_extension/libuv/deps/pthread-win32/CONTRIBUTORS +140 -0
  18. data/ext/noderb_extension/libuv/deps/pthread-win32/COPYING +150 -0
  19. data/ext/noderb_extension/libuv/deps/pthread-win32/COPYING.LIB +504 -0
  20. data/ext/noderb_extension/libuv/deps/pthread-win32/ChangeLog +5194 -0
  21. data/ext/noderb_extension/libuv/deps/pthread-win32/FAQ +451 -0
  22. data/ext/noderb_extension/libuv/deps/pthread-win32/GNUmakefile +593 -0
  23. data/ext/noderb_extension/libuv/deps/pthread-win32/MAINTAINERS +4 -0
  24. data/ext/noderb_extension/libuv/deps/pthread-win32/Makefile +516 -0
  25. data/ext/noderb_extension/libuv/deps/pthread-win32/NEWS +1245 -0
  26. data/ext/noderb_extension/libuv/deps/pthread-win32/Nmakefile +24 -0
  27. data/ext/noderb_extension/libuv/deps/pthread-win32/Nmakefile.tests +260 -0
  28. data/ext/noderb_extension/libuv/deps/pthread-win32/PROGRESS +4 -0
  29. data/ext/noderb_extension/libuv/deps/pthread-win32/README +601 -0
  30. data/ext/noderb_extension/libuv/deps/pthread-win32/README.Borland +57 -0
  31. data/ext/noderb_extension/libuv/deps/pthread-win32/README.CV +3036 -0
  32. data/ext/noderb_extension/libuv/deps/pthread-win32/README.NONPORTABLE +783 -0
  33. data/ext/noderb_extension/libuv/deps/pthread-win32/README.Watcom +62 -0
  34. data/ext/noderb_extension/libuv/deps/pthread-win32/README.WinCE +6 -0
  35. data/ext/noderb_extension/libuv/deps/pthread-win32/TODO +7 -0
  36. data/ext/noderb_extension/libuv/deps/pthread-win32/WinCE-PORT +222 -0
  37. data/ext/noderb_extension/libuv/deps/pthread-win32/attr.c +53 -0
  38. data/ext/noderb_extension/libuv/deps/pthread-win32/autostatic.c +69 -0
  39. data/ext/noderb_extension/libuv/deps/pthread-win32/barrier.c +47 -0
  40. data/ext/noderb_extension/libuv/deps/pthread-win32/build/all.gyp +207 -0
  41. data/ext/noderb_extension/libuv/deps/pthread-win32/builddmc.bat +9 -0
  42. data/ext/noderb_extension/libuv/deps/pthread-win32/cancel.c +44 -0
  43. data/ext/noderb_extension/libuv/deps/pthread-win32/cleanup.c +148 -0
  44. data/ext/noderb_extension/libuv/deps/pthread-win32/condvar.c +50 -0
  45. data/ext/noderb_extension/libuv/deps/pthread-win32/config.h +153 -0
  46. data/ext/noderb_extension/libuv/deps/pthread-win32/context.h +74 -0
  47. data/ext/noderb_extension/libuv/deps/pthread-win32/create.c +308 -0
  48. data/ext/noderb_extension/libuv/deps/pthread-win32/dll.c +92 -0
  49. data/ext/noderb_extension/libuv/deps/pthread-win32/errno.c +94 -0
  50. data/ext/noderb_extension/libuv/deps/pthread-win32/exit.c +44 -0
  51. data/ext/noderb_extension/libuv/deps/pthread-win32/fork.c +39 -0
  52. data/ext/noderb_extension/libuv/deps/pthread-win32/global.c +107 -0
  53. data/ext/noderb_extension/libuv/deps/pthread-win32/implement.h +944 -0
  54. data/ext/noderb_extension/libuv/deps/pthread-win32/misc.c +50 -0
  55. data/ext/noderb_extension/libuv/deps/pthread-win32/mutex.c +62 -0
  56. data/ext/noderb_extension/libuv/deps/pthread-win32/need_errno.h +145 -0
  57. data/ext/noderb_extension/libuv/deps/pthread-win32/nonportable.c +47 -0
  58. data/ext/noderb_extension/libuv/deps/pthread-win32/private.c +54 -0
  59. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.c +66 -0
  60. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.dsp +142 -0
  61. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.dsw +29 -0
  62. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.h +1368 -0
  63. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_destroy.c +79 -0
  64. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getdetachstate.c +86 -0
  65. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getinheritsched.c +51 -0
  66. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getschedparam.c +52 -0
  67. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getschedpolicy.c +61 -0
  68. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getscope.c +54 -0
  69. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getstackaddr.c +97 -0
  70. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getstacksize.c +100 -0
  71. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_init.c +117 -0
  72. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setdetachstate.c +91 -0
  73. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setinheritsched.c +57 -0
  74. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setschedparam.c +63 -0
  75. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setschedpolicy.c +55 -0
  76. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setscope.c +62 -0
  77. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setstackaddr.c +97 -0
  78. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setstacksize.c +110 -0
  79. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_destroy.c +103 -0
  80. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_init.c +69 -0
  81. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_wait.c +104 -0
  82. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_destroy.c +83 -0
  83. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_getpshared.c +95 -0
  84. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_init.c +85 -0
  85. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_setpshared.c +119 -0
  86. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cancel.c +189 -0
  87. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_destroy.c +253 -0
  88. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_init.c +167 -0
  89. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_signal.c +231 -0
  90. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_wait.c +567 -0
  91. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_destroy.c +86 -0
  92. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_getpshared.c +97 -0
  93. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_init.c +87 -0
  94. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_setpshared.c +117 -0
  95. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_delay_np.c +172 -0
  96. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_detach.c +136 -0
  97. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_equal.c +76 -0
  98. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_exit.c +106 -0
  99. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getconcurrency.c +45 -0
  100. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getschedparam.c +75 -0
  101. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getspecific.c +87 -0
  102. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getunique_np.c +47 -0
  103. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getw32threadhandle_np.c +65 -0
  104. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_join.c +157 -0
  105. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_key_create.c +108 -0
  106. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_key_delete.c +125 -0
  107. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_kill.c +105 -0
  108. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_consistent.c +187 -0
  109. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_destroy.c +148 -0
  110. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_init.c +130 -0
  111. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_lock.c +269 -0
  112. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_timedlock.c +324 -0
  113. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_trylock.c +154 -0
  114. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_unlock.c +175 -0
  115. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_destroy.c +83 -0
  116. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getkind_np.c +44 -0
  117. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getpshared.c +95 -0
  118. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getrobust.c +113 -0
  119. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_gettype.c +56 -0
  120. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_init.c +86 -0
  121. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setkind_np.c +44 -0
  122. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setpshared.c +119 -0
  123. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setrobust.c +119 -0
  124. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_settype.c +143 -0
  125. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_num_processors_np.c +56 -0
  126. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_once.c +79 -0
  127. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_destroy.c +143 -0
  128. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_init.c +109 -0
  129. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_rdlock.c +102 -0
  130. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_timedrdlock.c +109 -0
  131. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_timedwrlock.c +139 -0
  132. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_tryrdlock.c +102 -0
  133. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_trywrlock.c +122 -0
  134. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_unlock.c +93 -0
  135. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_wrlock.c +133 -0
  136. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_destroy.c +84 -0
  137. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_getpshared.c +97 -0
  138. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_init.c +83 -0
  139. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_setpshared.c +120 -0
  140. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_self.c +141 -0
  141. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setcancelstate.c +125 -0
  142. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setcanceltype.c +126 -0
  143. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setconcurrency.c +53 -0
  144. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setschedparam.c +123 -0
  145. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setspecific.c +167 -0
  146. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_destroy.c +111 -0
  147. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_init.c +123 -0
  148. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_lock.c +80 -0
  149. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_trylock.c +77 -0
  150. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_unlock.c +71 -0
  151. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_testcancel.c +103 -0
  152. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_timechange_handler_np.c +108 -0
  153. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_win32_attach_detach_np.c +258 -0
  154. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_MCS_lock.c +278 -0
  155. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_callUserDestroyRoutines.c +232 -0
  156. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_calloc.c +56 -0
  157. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_cond_check_need_init.c +78 -0
  158. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_getprocessors.c +91 -0
  159. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_is_attr.c +47 -0
  160. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_mutex_check_need_init.c +92 -0
  161. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_new.c +94 -0
  162. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_processInitialize.c +92 -0
  163. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_processTerminate.c +105 -0
  164. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_relmillisecs.c +132 -0
  165. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_reuse.c +151 -0
  166. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_rwlock_cancelwrwait.c +50 -0
  167. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_rwlock_check_need_init.c +77 -0
  168. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_semwait.c +135 -0
  169. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_spinlock_check_need_init.c +78 -0
  170. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_threadDestroy.c +79 -0
  171. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_threadStart.c +357 -0
  172. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_throw.c +189 -0
  173. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_timespec.c +83 -0
  174. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_tkAssocCreate.c +118 -0
  175. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_tkAssocDestroy.c +114 -0
  176. data/ext/noderb_extension/libuv/deps/pthread-win32/rwlock.c +51 -0
  177. data/ext/noderb_extension/libuv/deps/pthread-win32/sched.c +53 -0
  178. data/ext/noderb_extension/libuv/deps/pthread-win32/sched.h +183 -0
  179. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_get_priority_max.c +134 -0
  180. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_get_priority_min.c +135 -0
  181. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_getscheduler.c +71 -0
  182. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_setscheduler.c +83 -0
  183. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_yield.c +71 -0
  184. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_close.c +58 -0
  185. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_destroy.c +144 -0
  186. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_getvalue.c +110 -0
  187. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_init.c +169 -0
  188. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_open.c +58 -0
  189. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_post.c +128 -0
  190. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_post_multiple.c +142 -0
  191. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_timedwait.c +238 -0
  192. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_trywait.c +117 -0
  193. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_unlink.c +58 -0
  194. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_wait.c +187 -0
  195. data/ext/noderb_extension/libuv/deps/pthread-win32/semaphore.c +69 -0
  196. data/ext/noderb_extension/libuv/deps/pthread-win32/semaphore.h +169 -0
  197. data/ext/noderb_extension/libuv/deps/pthread-win32/signal.c +179 -0
  198. data/ext/noderb_extension/libuv/deps/pthread-win32/spin.c +46 -0
  199. data/ext/noderb_extension/libuv/deps/pthread-win32/sync.c +43 -0
  200. data/ext/noderb_extension/libuv/deps/pthread-win32/tsd.c +44 -0
  201. data/ext/noderb_extension/libuv/deps/pthread-win32/version.rc +388 -0
  202. data/ext/noderb_extension/libuv/deps/pthread-win32/w32_CancelableWait.c +161 -0
  203. data/ext/noderb_extension/libuv/doc/desired-api.md +159 -0
  204. data/ext/noderb_extension/libuv/doc/iocp-links.html +574 -0
  205. data/ext/noderb_extension/libuv/include/ares.h +582 -0
  206. data/ext/noderb_extension/libuv/include/ares_version.h +24 -0
  207. data/ext/noderb_extension/libuv/include/eio.h +376 -0
  208. data/ext/noderb_extension/libuv/include/ev.h +835 -0
  209. data/ext/noderb_extension/libuv/include/ngx-queue.h +102 -0
  210. data/ext/noderb_extension/libuv/include/tree.h +762 -0
  211. data/ext/noderb_extension/libuv/include/uv-unix.h +138 -0
  212. data/ext/noderb_extension/libuv/include/uv-win.h +187 -0
  213. data/ext/noderb_extension/libuv/include/uv.h +635 -0
  214. data/ext/noderb_extension/libuv/src/ares/AUTHORS +37 -0
  215. data/ext/noderb_extension/libuv/src/ares/CHANGES +1198 -0
  216. data/ext/noderb_extension/libuv/src/ares/CMakeLists.txt +22 -0
  217. data/ext/noderb_extension/libuv/src/ares/NEWS +21 -0
  218. data/ext/noderb_extension/libuv/src/ares/README +60 -0
  219. data/ext/noderb_extension/libuv/src/ares/README.cares +13 -0
  220. data/ext/noderb_extension/libuv/src/ares/README.msvc +118 -0
  221. data/ext/noderb_extension/libuv/src/ares/README.node +21 -0
  222. data/ext/noderb_extension/libuv/src/ares/RELEASE-NOTES +25 -0
  223. data/ext/noderb_extension/libuv/src/ares/TODO +23 -0
  224. data/ext/noderb_extension/libuv/src/ares/ares__close_sockets.c +66 -0
  225. data/ext/noderb_extension/libuv/src/ares/ares__get_hostent.c +263 -0
  226. data/ext/noderb_extension/libuv/src/ares/ares__read_line.c +71 -0
  227. data/ext/noderb_extension/libuv/src/ares/ares__timeval.c +111 -0
  228. data/ext/noderb_extension/libuv/src/ares/ares_cancel.c +63 -0
  229. data/ext/noderb_extension/libuv/src/ares/ares_data.c +190 -0
  230. data/ext/noderb_extension/libuv/src/ares/ares_data.h +65 -0
  231. data/ext/noderb_extension/libuv/src/ares/ares_destroy.c +105 -0
  232. data/ext/noderb_extension/libuv/src/ares/ares_dns.h +90 -0
  233. data/ext/noderb_extension/libuv/src/ares/ares_expand_name.c +193 -0
  234. data/ext/noderb_extension/libuv/src/ares/ares_expand_string.c +75 -0
  235. data/ext/noderb_extension/libuv/src/ares/ares_fds.c +62 -0
  236. data/ext/noderb_extension/libuv/src/ares/ares_free_hostent.c +39 -0
  237. data/ext/noderb_extension/libuv/src/ares/ares_free_string.c +25 -0
  238. data/ext/noderb_extension/libuv/src/ares/ares_gethostbyaddr.c +292 -0
  239. data/ext/noderb_extension/libuv/src/ares/ares_gethostbyname.c +515 -0
  240. data/ext/noderb_extension/libuv/src/ares/ares_getnameinfo.c +426 -0
  241. data/ext/noderb_extension/libuv/src/ares/ares_getopt.c +122 -0
  242. data/ext/noderb_extension/libuv/src/ares/ares_getopt.h +53 -0
  243. data/ext/noderb_extension/libuv/src/ares/ares_getsock.c +72 -0
  244. data/ext/noderb_extension/libuv/src/ares/ares_init.c +1665 -0
  245. data/ext/noderb_extension/libuv/src/ares/ares_ipv6.h +78 -0
  246. data/ext/noderb_extension/libuv/src/ares/ares_library_init.c +132 -0
  247. data/ext/noderb_extension/libuv/src/ares/ares_library_init.h +39 -0
  248. data/ext/noderb_extension/libuv/src/ares/ares_llist.c +86 -0
  249. data/ext/noderb_extension/libuv/src/ares/ares_llist.h +42 -0
  250. data/ext/noderb_extension/libuv/src/ares/ares_mkquery.c +195 -0
  251. data/ext/noderb_extension/libuv/src/ares/ares_nowarn.c +59 -0
  252. data/ext/noderb_extension/libuv/src/ares/ares_nowarn.h +24 -0
  253. data/ext/noderb_extension/libuv/src/ares/ares_options.c +253 -0
  254. data/ext/noderb_extension/libuv/src/ares/ares_parse_a_reply.c +260 -0
  255. data/ext/noderb_extension/libuv/src/ares/ares_parse_aaaa_reply.c +256 -0
  256. data/ext/noderb_extension/libuv/src/ares/ares_parse_mx_reply.c +170 -0
  257. data/ext/noderb_extension/libuv/src/ares/ares_parse_ns_reply.c +182 -0
  258. data/ext/noderb_extension/libuv/src/ares/ares_parse_ptr_reply.c +208 -0
  259. data/ext/noderb_extension/libuv/src/ares/ares_parse_srv_reply.c +179 -0
  260. data/ext/noderb_extension/libuv/src/ares/ares_parse_txt_reply.c +201 -0
  261. data/ext/noderb_extension/libuv/src/ares/ares_private.h +351 -0
  262. data/ext/noderb_extension/libuv/src/ares/ares_process.c +1296 -0
  263. data/ext/noderb_extension/libuv/src/ares/ares_query.c +183 -0
  264. data/ext/noderb_extension/libuv/src/ares/ares_rules.h +144 -0
  265. data/ext/noderb_extension/libuv/src/ares/ares_search.c +322 -0
  266. data/ext/noderb_extension/libuv/src/ares/ares_send.c +134 -0
  267. data/ext/noderb_extension/libuv/src/ares/ares_setup.h +191 -0
  268. data/ext/noderb_extension/libuv/src/ares/ares_strcasecmp.c +66 -0
  269. data/ext/noderb_extension/libuv/src/ares/ares_strcasecmp.h +30 -0
  270. data/ext/noderb_extension/libuv/src/ares/ares_strdup.c +42 -0
  271. data/ext/noderb_extension/libuv/src/ares/ares_strdup.h +26 -0
  272. data/ext/noderb_extension/libuv/src/ares/ares_strerror.c +56 -0
  273. data/ext/noderb_extension/libuv/src/ares/ares_timeout.c +80 -0
  274. data/ext/noderb_extension/libuv/src/ares/ares_version.c +11 -0
  275. data/ext/noderb_extension/libuv/src/ares/ares_writev.c +79 -0
  276. data/ext/noderb_extension/libuv/src/ares/ares_writev.h +36 -0
  277. data/ext/noderb_extension/libuv/src/ares/bitncmp.c +59 -0
  278. data/ext/noderb_extension/libuv/src/ares/bitncmp.h +26 -0
  279. data/ext/noderb_extension/libuv/src/ares/config_cygwin/ares_config.h +510 -0
  280. data/ext/noderb_extension/libuv/src/ares/config_darwin/ares_config.h +510 -0
  281. data/ext/noderb_extension/libuv/src/ares/config_freebsd/ares_config.h +510 -0
  282. data/ext/noderb_extension/libuv/src/ares/config_linux/ares_config.h +510 -0
  283. data/ext/noderb_extension/libuv/src/ares/config_openbsd/ares_config.h +510 -0
  284. data/ext/noderb_extension/libuv/src/ares/config_sunos/ares_config.h +510 -0
  285. data/ext/noderb_extension/libuv/src/ares/config_win32/ares_config.h +369 -0
  286. data/ext/noderb_extension/libuv/src/ares/get_ver.awk +35 -0
  287. data/ext/noderb_extension/libuv/src/ares/inet_net_pton.c +450 -0
  288. data/ext/noderb_extension/libuv/src/ares/inet_net_pton.h +31 -0
  289. data/ext/noderb_extension/libuv/src/ares/inet_ntop.c +232 -0
  290. data/ext/noderb_extension/libuv/src/ares/inet_ntop.h +27 -0
  291. data/ext/noderb_extension/libuv/src/ares/nameser.h +193 -0
  292. data/ext/noderb_extension/libuv/src/ares/setup_once.h +488 -0
  293. data/ext/noderb_extension/libuv/src/ares/windows_port.c +22 -0
  294. data/ext/noderb_extension/libuv/src/eio/Changes +63 -0
  295. data/ext/noderb_extension/libuv/src/eio/LICENSE +36 -0
  296. data/ext/noderb_extension/libuv/src/eio/Makefile.am +15 -0
  297. data/ext/noderb_extension/libuv/src/eio/aclocal.m4 +8957 -0
  298. data/ext/noderb_extension/libuv/src/eio/autogen.sh +3 -0
  299. data/ext/noderb_extension/libuv/src/eio/config.h.in +86 -0
  300. data/ext/noderb_extension/libuv/src/eio/config_cygwin.h +77 -0
  301. data/ext/noderb_extension/libuv/src/eio/config_darwin.h +137 -0
  302. data/ext/noderb_extension/libuv/src/eio/config_freebsd.h +78 -0
  303. data/ext/noderb_extension/libuv/src/eio/config_linux.h +101 -0
  304. data/ext/noderb_extension/libuv/src/eio/config_sunos.h +81 -0
  305. data/ext/noderb_extension/libuv/src/eio/configure.ac +22 -0
  306. data/ext/noderb_extension/libuv/src/eio/demo.c +194 -0
  307. data/ext/noderb_extension/libuv/src/eio/ecb.h +370 -0
  308. data/ext/noderb_extension/libuv/src/eio/eio.3 +3428 -0
  309. data/ext/noderb_extension/libuv/src/eio/eio.c +2562 -0
  310. data/ext/noderb_extension/libuv/src/eio/eio.pod +969 -0
  311. data/ext/noderb_extension/libuv/src/eio/libeio.m4 +195 -0
  312. data/ext/noderb_extension/libuv/src/eio/xthread.h +164 -0
  313. data/ext/noderb_extension/libuv/src/ev/Changes +388 -0
  314. data/ext/noderb_extension/libuv/src/ev/LICENSE +36 -0
  315. data/ext/noderb_extension/libuv/src/ev/Makefile.am +18 -0
  316. data/ext/noderb_extension/libuv/src/ev/Makefile.in +771 -0
  317. data/ext/noderb_extension/libuv/src/ev/README +58 -0
  318. data/ext/noderb_extension/libuv/src/ev/aclocal.m4 +8957 -0
  319. data/ext/noderb_extension/libuv/src/ev/autogen.sh +6 -0
  320. data/ext/noderb_extension/libuv/src/ev/config.guess +1526 -0
  321. data/ext/noderb_extension/libuv/src/ev/config.h.in +125 -0
  322. data/ext/noderb_extension/libuv/src/ev/config.sub +1658 -0
  323. data/ext/noderb_extension/libuv/src/ev/config_cygwin.h +123 -0
  324. data/ext/noderb_extension/libuv/src/ev/config_darwin.h +122 -0
  325. data/ext/noderb_extension/libuv/src/ev/config_freebsd.h +120 -0
  326. data/ext/noderb_extension/libuv/src/ev/config_linux.h +130 -0
  327. data/ext/noderb_extension/libuv/src/ev/config_sunos.h +122 -0
  328. data/ext/noderb_extension/libuv/src/ev/configure +13037 -0
  329. data/ext/noderb_extension/libuv/src/ev/configure.ac +18 -0
  330. data/ext/noderb_extension/libuv/src/ev/depcomp +630 -0
  331. data/ext/noderb_extension/libuv/src/ev/ev++.h +816 -0
  332. data/ext/noderb_extension/libuv/src/ev/ev.3 +5311 -0
  333. data/ext/noderb_extension/libuv/src/ev/ev.c +3913 -0
  334. data/ext/noderb_extension/libuv/src/ev/ev.pod +5243 -0
  335. data/ext/noderb_extension/libuv/src/ev/ev_epoll.c +266 -0
  336. data/ext/noderb_extension/libuv/src/ev/ev_kqueue.c +198 -0
  337. data/ext/noderb_extension/libuv/src/ev/ev_poll.c +148 -0
  338. data/ext/noderb_extension/libuv/src/ev/ev_port.c +179 -0
  339. data/ext/noderb_extension/libuv/src/ev/ev_select.c +310 -0
  340. data/ext/noderb_extension/libuv/src/ev/ev_vars.h +203 -0
  341. data/ext/noderb_extension/libuv/src/ev/ev_win32.c +153 -0
  342. data/ext/noderb_extension/libuv/src/ev/ev_wrap.h +196 -0
  343. data/ext/noderb_extension/libuv/src/ev/event.c +402 -0
  344. data/ext/noderb_extension/libuv/src/ev/event.h +170 -0
  345. data/ext/noderb_extension/libuv/src/ev/install-sh +294 -0
  346. data/ext/noderb_extension/libuv/src/ev/libev.m4 +39 -0
  347. data/ext/noderb_extension/libuv/src/ev/ltmain.sh +8413 -0
  348. data/ext/noderb_extension/libuv/src/ev/missing +336 -0
  349. data/ext/noderb_extension/libuv/src/ev/mkinstalldirs +111 -0
  350. data/ext/noderb_extension/libuv/src/uv-common.c +172 -0
  351. data/ext/noderb_extension/libuv/src/uv-common.h +53 -0
  352. data/ext/noderb_extension/libuv/src/uv-cygwin.c +52 -0
  353. data/ext/noderb_extension/libuv/src/uv-darwin.c +64 -0
  354. data/ext/noderb_extension/libuv/src/uv-eio.c +113 -0
  355. data/ext/noderb_extension/libuv/src/uv-eio.h +13 -0
  356. data/ext/noderb_extension/libuv/src/uv-freebsd.c +65 -0
  357. data/ext/noderb_extension/libuv/src/uv-linux.c +51 -0
  358. data/ext/noderb_extension/libuv/src/uv-sunos.c +60 -0
  359. data/ext/noderb_extension/libuv/src/uv-unix.c +2408 -0
  360. data/ext/noderb_extension/libuv/src/win/async.c +129 -0
  361. data/ext/noderb_extension/libuv/src/win/cares.c +304 -0
  362. data/ext/noderb_extension/libuv/src/win/core.c +155 -0
  363. data/ext/noderb_extension/libuv/src/win/error.c +140 -0
  364. data/ext/noderb_extension/libuv/src/win/getaddrinfo.c +341 -0
  365. data/ext/noderb_extension/libuv/src/win/handle.c +176 -0
  366. data/ext/noderb_extension/libuv/src/win/internal.h +237 -0
  367. data/ext/noderb_extension/libuv/src/win/loop-watcher.c +128 -0
  368. data/ext/noderb_extension/libuv/src/win/pipe.c +828 -0
  369. data/ext/noderb_extension/libuv/src/win/process.c +936 -0
  370. data/ext/noderb_extension/libuv/src/win/req.c +141 -0
  371. data/ext/noderb_extension/libuv/src/win/stdio.c +75 -0
  372. data/ext/noderb_extension/libuv/src/win/stream.c +149 -0
  373. data/ext/noderb_extension/libuv/src/win/tcp.c +895 -0
  374. data/ext/noderb_extension/libuv/src/win/timer.c +269 -0
  375. data/ext/noderb_extension/libuv/src/win/util.c +82 -0
  376. data/ext/noderb_extension/libuv/test/benchmark-ares.c +117 -0
  377. data/ext/noderb_extension/libuv/test/benchmark-getaddrinfo.c +90 -0
  378. data/ext/noderb_extension/libuv/test/benchmark-list.h +77 -0
  379. data/ext/noderb_extension/libuv/test/benchmark-ping-pongs.c +210 -0
  380. data/ext/noderb_extension/libuv/test/benchmark-pound.c +237 -0
  381. data/ext/noderb_extension/libuv/test/benchmark-pump.c +459 -0
  382. data/ext/noderb_extension/libuv/test/benchmark-sizes.c +39 -0
  383. data/ext/noderb_extension/libuv/test/benchmark-spawn.c +154 -0
  384. data/ext/noderb_extension/libuv/test/dns-server.c +323 -0
  385. data/ext/noderb_extension/libuv/test/echo-server.c +299 -0
  386. data/ext/noderb_extension/libuv/test/run-benchmarks.c +64 -0
  387. data/ext/noderb_extension/libuv/test/run-tests.c +82 -0
  388. data/ext/noderb_extension/libuv/test/runner-unix.c +335 -0
  389. data/ext/noderb_extension/libuv/test/runner-unix.h +36 -0
  390. data/ext/noderb_extension/libuv/test/runner-win.c +343 -0
  391. data/ext/noderb_extension/libuv/test/runner-win.h +42 -0
  392. data/ext/noderb_extension/libuv/test/runner.c +311 -0
  393. data/ext/noderb_extension/libuv/test/runner.h +155 -0
  394. data/ext/noderb_extension/libuv/test/task.h +111 -0
  395. data/ext/noderb_extension/libuv/test/test-async.c +218 -0
  396. data/ext/noderb_extension/libuv/test/test-callback-stack.c +205 -0
  397. data/ext/noderb_extension/libuv/test/test-connection-fail.c +149 -0
  398. data/ext/noderb_extension/libuv/test/test-delayed-accept.c +198 -0
  399. data/ext/noderb_extension/libuv/test/test-fail-always.c +29 -0
  400. data/ext/noderb_extension/libuv/test/test-get-currentexe.c +53 -0
  401. data/ext/noderb_extension/libuv/test/test-getaddrinfo.c +110 -0
  402. data/ext/noderb_extension/libuv/test/test-gethostbyname.c +192 -0
  403. data/ext/noderb_extension/libuv/test/test-getsockname.c +196 -0
  404. data/ext/noderb_extension/libuv/test/test-hrtime.c +51 -0
  405. data/ext/noderb_extension/libuv/test/test-idle.c +83 -0
  406. data/ext/noderb_extension/libuv/test/test-list.h +165 -0
  407. data/ext/noderb_extension/libuv/test/test-loop-handles.c +361 -0
  408. data/ext/noderb_extension/libuv/test/test-pass-always.c +28 -0
  409. data/ext/noderb_extension/libuv/test/test-ping-pong.c +256 -0
  410. data/ext/noderb_extension/libuv/test/test-pipe-bind-error.c +148 -0
  411. data/ext/noderb_extension/libuv/test/test-ref.c +91 -0
  412. data/ext/noderb_extension/libuv/test/test-shutdown-eof.c +183 -0
  413. data/ext/noderb_extension/libuv/test/test-spawn.c +345 -0
  414. data/ext/noderb_extension/libuv/test/test-tcp-bind-error.c +204 -0
  415. data/ext/noderb_extension/libuv/test/test-tcp-bind6-error.c +164 -0
  416. data/ext/noderb_extension/libuv/test/test-tcp-writealot.c +198 -0
  417. data/ext/noderb_extension/libuv/test/test-timer-again.c +141 -0
  418. data/ext/noderb_extension/libuv/test/test-timer.c +134 -0
  419. data/ext/noderb_extension/noderb.c +340 -0
  420. data/ext/noderb_extension/noderb.h +2 -0
  421. data/lib/noderb/connection.rb +21 -0
  422. data/lib/noderb/process.rb +17 -0
  423. data/lib/noderb.rb +25 -0
  424. metadata +470 -0
@@ -0,0 +1,1296 @@
1
+
2
+ /* Copyright 1998 by the Massachusetts Institute of Technology.
3
+ * Copyright (C) 2004-2010 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_SOCKET_H
21
+ # include <sys/socket.h>
22
+ #endif
23
+ #ifdef HAVE_SYS_UIO_H
24
+ # include <sys/uio.h>
25
+ #endif
26
+ #ifdef HAVE_NETINET_IN_H
27
+ # include <netinet/in.h>
28
+ #endif
29
+ #ifdef HAVE_NETINET_TCP_H
30
+ # include <netinet/tcp.h>
31
+ #endif
32
+ #ifdef HAVE_NETDB_H
33
+ # include <netdb.h>
34
+ #endif
35
+ #ifdef HAVE_ARPA_NAMESER_H
36
+ # include <arpa/nameser.h>
37
+ #else
38
+ # include "nameser.h"
39
+ #endif
40
+ #ifdef HAVE_ARPA_NAMESER_COMPAT_H
41
+ # include <arpa/nameser_compat.h>
42
+ #endif
43
+
44
+ #ifdef HAVE_SYS_TIME_H
45
+ # include <sys/time.h>
46
+ #endif
47
+
48
+ #ifdef HAVE_STRINGS_H
49
+ # include <strings.h>
50
+ #endif
51
+ #ifdef HAVE_UNISTD_H
52
+ # include <unistd.h>
53
+ #endif
54
+ #ifdef HAVE_SYS_IOCTL_H
55
+ # include <sys/ioctl.h>
56
+ #endif
57
+ #ifdef NETWARE
58
+ # include <sys/filio.h>
59
+ #endif
60
+
61
+ #include <assert.h>
62
+ #include <string.h>
63
+ #include <stdlib.h>
64
+ #include <fcntl.h>
65
+ #include <time.h>
66
+ #include <errno.h>
67
+
68
+ #include "ares.h"
69
+ #include "ares_dns.h"
70
+ #include "ares_private.h"
71
+
72
+
73
+ static int try_again(int errnum);
74
+ static void write_tcp_data(ares_channel channel, fd_set *write_fds,
75
+ ares_socket_t write_fd, struct timeval *now);
76
+ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
77
+ ares_socket_t read_fd, struct timeval *now);
78
+ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
79
+ ares_socket_t read_fd, struct timeval *now);
80
+ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
81
+ ssize_t num_bytes);
82
+ static void process_timeouts(ares_channel channel, struct timeval *now);
83
+ static void process_broken_connections(ares_channel channel,
84
+ struct timeval *now);
85
+ static void process_answer(ares_channel channel, unsigned char *abuf,
86
+ int alen, int whichserver, int tcp,
87
+ struct timeval *now);
88
+ static void handle_error(ares_channel channel, int whichserver,
89
+ struct timeval *now);
90
+ static void skip_server(ares_channel channel, struct query *query,
91
+ int whichserver);
92
+ static void next_server(ares_channel channel, struct query *query,
93
+ struct timeval *now);
94
+ static int open_tcp_socket(ares_channel channel, struct server_state *server);
95
+ static int open_udp_socket(ares_channel channel, struct server_state *server);
96
+ static int same_questions(const unsigned char *qbuf, int qlen,
97
+ const unsigned char *abuf, int alen);
98
+ static int same_address(struct sockaddr *sa, struct ares_addr *aa);
99
+ static void end_query(ares_channel channel, struct query *query, int status,
100
+ unsigned char *abuf, int alen);
101
+
102
+ /* return true if now is exactly check time or later */
103
+ int ares__timedout(struct timeval *now,
104
+ struct timeval *check)
105
+ {
106
+ long secs = (now->tv_sec - check->tv_sec);
107
+
108
+ if(secs > 0)
109
+ return 1; /* yes, timed out */
110
+ if(secs < 0)
111
+ return 0; /* nope, not timed out */
112
+
113
+ /* if the full seconds were identical, check the sub second parts */
114
+ return (now->tv_usec - check->tv_usec >= 0);
115
+ }
116
+
117
+ /* add the specific number of milliseconds to the time in the first argument */
118
+ int ares__timeadd(struct timeval *now,
119
+ int millisecs)
120
+ {
121
+ now->tv_sec += millisecs/1000;
122
+ now->tv_usec += (millisecs%1000)*1000;
123
+
124
+ if(now->tv_usec >= 1000000) {
125
+ ++(now->tv_sec);
126
+ now->tv_usec -= 1000000;
127
+ }
128
+
129
+ return 0;
130
+ }
131
+
132
+ /* return time offset between now and (future) check, in milliseconds */
133
+ long ares__timeoffset(struct timeval *now,
134
+ struct timeval *check)
135
+ {
136
+ return (check->tv_sec - now->tv_sec)*1000 +
137
+ (check->tv_usec - now->tv_usec)/1000;
138
+ }
139
+
140
+
141
+ /*
142
+ * generic process function
143
+ */
144
+ static void processfds(ares_channel channel,
145
+ fd_set *read_fds, ares_socket_t read_fd,
146
+ fd_set *write_fds, ares_socket_t write_fd)
147
+ {
148
+ struct timeval now = ares__tvnow();
149
+
150
+ write_tcp_data(channel, write_fds, write_fd, &now);
151
+ read_tcp_data(channel, read_fds, read_fd, &now);
152
+ read_udp_packets(channel, read_fds, read_fd, &now);
153
+ process_timeouts(channel, &now);
154
+ process_broken_connections(channel, &now);
155
+ }
156
+
157
+ /* Something interesting happened on the wire, or there was a timeout.
158
+ * See what's up and respond accordingly.
159
+ */
160
+ void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
161
+ {
162
+ processfds(channel, read_fds, ARES_SOCKET_BAD, write_fds, ARES_SOCKET_BAD);
163
+ }
164
+
165
+ /* Something interesting happened on the wire, or there was a timeout.
166
+ * See what's up and respond accordingly.
167
+ */
168
+ void ares_process_fd(ares_channel channel,
169
+ ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid
170
+ file descriptors */
171
+ ares_socket_t write_fd)
172
+ {
173
+ processfds(channel, NULL, read_fd, NULL, write_fd);
174
+ }
175
+
176
+
177
+ /* Return 1 if the specified error number describes a readiness error, or 0
178
+ * otherwise. This is mostly for HP-UX, which could return EAGAIN or
179
+ * EWOULDBLOCK. See this man page
180
+ *
181
+ * http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html?
182
+ * manpage=/usr/share/man/man2.Z/send.2
183
+ */
184
+ static int try_again(int errnum)
185
+ {
186
+ #if !defined EWOULDBLOCK && !defined EAGAIN
187
+ #error "Neither EWOULDBLOCK nor EAGAIN defined"
188
+ #endif
189
+ switch (errnum)
190
+ {
191
+ #ifdef EWOULDBLOCK
192
+ case EWOULDBLOCK:
193
+ return 1;
194
+ #endif
195
+ #if defined EAGAIN && EAGAIN != EWOULDBLOCK
196
+ case EAGAIN:
197
+ return 1;
198
+ #endif
199
+ }
200
+ return 0;
201
+ }
202
+
203
+ /* If any TCP sockets select true for writing, write out queued data
204
+ * we have for them.
205
+ */
206
+ static void write_tcp_data(ares_channel channel,
207
+ fd_set *write_fds,
208
+ ares_socket_t write_fd,
209
+ struct timeval *now)
210
+ {
211
+ struct server_state *server;
212
+ struct send_request *sendreq;
213
+ struct iovec *vec;
214
+ int i;
215
+ ssize_t scount;
216
+ ssize_t wcount;
217
+ size_t n;
218
+
219
+ if(!write_fds && (write_fd == ARES_SOCKET_BAD))
220
+ /* no possible action */
221
+ return;
222
+
223
+ for (i = 0; i < channel->nservers; i++)
224
+ {
225
+ /* Make sure server has data to send and is selected in write_fds or
226
+ write_fd. */
227
+ server = &channel->servers[i];
228
+ if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD ||
229
+ server->is_broken)
230
+ continue;
231
+
232
+ if(write_fds) {
233
+ if(!FD_ISSET(server->tcp_socket, write_fds))
234
+ continue;
235
+ }
236
+ else {
237
+ if(server->tcp_socket != write_fd)
238
+ continue;
239
+ }
240
+
241
+ if(write_fds)
242
+ /* If there's an error and we close this socket, then open
243
+ * another with the same fd to talk to another server, then we
244
+ * don't want to think that it was the new socket that was
245
+ * ready. This is not disastrous, but is likely to result in
246
+ * extra system calls and confusion. */
247
+ FD_CLR(server->tcp_socket, write_fds);
248
+
249
+ /* Count the number of send queue items. */
250
+ n = 0;
251
+ for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
252
+ n++;
253
+
254
+ /* Allocate iovecs so we can send all our data at once. */
255
+ vec = malloc(n * sizeof(struct iovec));
256
+ if (vec)
257
+ {
258
+ /* Fill in the iovecs and send. */
259
+ n = 0;
260
+ for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
261
+ {
262
+ vec[n].iov_base = (char *) sendreq->data;
263
+ vec[n].iov_len = sendreq->len;
264
+ n++;
265
+ }
266
+ wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n);
267
+ free(vec);
268
+ if (wcount < 0)
269
+ {
270
+ if (!try_again(SOCKERRNO))
271
+ handle_error(channel, i, now);
272
+ continue;
273
+ }
274
+
275
+ /* Advance the send queue by as many bytes as we sent. */
276
+ advance_tcp_send_queue(channel, i, wcount);
277
+ }
278
+ else
279
+ {
280
+ /* Can't allocate iovecs; just send the first request. */
281
+ sendreq = server->qhead;
282
+
283
+ scount = swrite(server->tcp_socket, sendreq->data, sendreq->len);
284
+ if (scount < 0)
285
+ {
286
+ if (!try_again(SOCKERRNO))
287
+ handle_error(channel, i, now);
288
+ continue;
289
+ }
290
+
291
+ /* Advance the send queue by as many bytes as we sent. */
292
+ advance_tcp_send_queue(channel, i, scount);
293
+ }
294
+ }
295
+ }
296
+
297
+ /* Consume the given number of bytes from the head of the TCP send queue. */
298
+ static void advance_tcp_send_queue(ares_channel channel, int whichserver,
299
+ ssize_t num_bytes)
300
+ {
301
+ struct send_request *sendreq;
302
+ struct server_state *server = &channel->servers[whichserver];
303
+ while (num_bytes > 0)
304
+ {
305
+ sendreq = server->qhead;
306
+ if ((size_t)num_bytes >= sendreq->len)
307
+ {
308
+ num_bytes -= sendreq->len;
309
+ server->qhead = sendreq->next;
310
+ if (server->qhead == NULL)
311
+ {
312
+ SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0);
313
+ server->qtail = NULL;
314
+ }
315
+ if (sendreq->data_storage != NULL)
316
+ free(sendreq->data_storage);
317
+ free(sendreq);
318
+ }
319
+ else
320
+ {
321
+ sendreq->data += num_bytes;
322
+ sendreq->len -= num_bytes;
323
+ num_bytes = 0;
324
+ }
325
+ }
326
+ }
327
+
328
+ /* If any TCP socket selects true for reading, read some data,
329
+ * allocate a buffer if we finish reading the length word, and process
330
+ * a packet if we finish reading one.
331
+ */
332
+ static void read_tcp_data(ares_channel channel, fd_set *read_fds,
333
+ ares_socket_t read_fd, struct timeval *now)
334
+ {
335
+ struct server_state *server;
336
+ int i;
337
+ ssize_t count;
338
+
339
+ if(!read_fds && (read_fd == ARES_SOCKET_BAD))
340
+ /* no possible action */
341
+ return;
342
+
343
+ for (i = 0; i < channel->nservers; i++)
344
+ {
345
+ /* Make sure the server has a socket and is selected in read_fds. */
346
+ server = &channel->servers[i];
347
+ if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken)
348
+ continue;
349
+
350
+ if(read_fds) {
351
+ if(!FD_ISSET(server->tcp_socket, read_fds))
352
+ continue;
353
+ }
354
+ else {
355
+ if(server->tcp_socket != read_fd)
356
+ continue;
357
+ }
358
+
359
+ if(read_fds)
360
+ /* If there's an error and we close this socket, then open
361
+ * another with the same fd to talk to another server, then we
362
+ * don't want to think that it was the new socket that was
363
+ * ready. This is not disastrous, but is likely to result in
364
+ * extra system calls and confusion. */
365
+ FD_CLR(server->tcp_socket, read_fds);
366
+
367
+ if (server->tcp_lenbuf_pos != 2)
368
+ {
369
+ /* We haven't yet read a length word, so read that (or
370
+ * what's left to read of it).
371
+ */
372
+ count = sread(server->tcp_socket,
373
+ server->tcp_lenbuf + server->tcp_lenbuf_pos,
374
+ 2 - server->tcp_lenbuf_pos);
375
+ if (count <= 0)
376
+ {
377
+ if (!(count == -1 && try_again(SOCKERRNO)))
378
+ handle_error(channel, i, now);
379
+ continue;
380
+ }
381
+
382
+ server->tcp_lenbuf_pos += (int)count;
383
+ if (server->tcp_lenbuf_pos == 2)
384
+ {
385
+ /* We finished reading the length word. Decode the
386
+ * length and allocate a buffer for the data.
387
+ */
388
+ server->tcp_length = server->tcp_lenbuf[0] << 8
389
+ | server->tcp_lenbuf[1];
390
+ server->tcp_buffer = malloc(server->tcp_length);
391
+ if (!server->tcp_buffer)
392
+ handle_error(channel, i, now);
393
+ server->tcp_buffer_pos = 0;
394
+ }
395
+ }
396
+ else
397
+ {
398
+ /* Read data into the allocated buffer. */
399
+ count = sread(server->tcp_socket,
400
+ server->tcp_buffer + server->tcp_buffer_pos,
401
+ server->tcp_length - server->tcp_buffer_pos);
402
+ if (count <= 0)
403
+ {
404
+ if (!(count == -1 && try_again(SOCKERRNO)))
405
+ handle_error(channel, i, now);
406
+ continue;
407
+ }
408
+
409
+ server->tcp_buffer_pos += (int)count;
410
+ if (server->tcp_buffer_pos == server->tcp_length)
411
+ {
412
+ /* We finished reading this answer; process it and
413
+ * prepare to read another length word.
414
+ */
415
+ process_answer(channel, server->tcp_buffer, server->tcp_length,
416
+ i, 1, now);
417
+ if (server->tcp_buffer)
418
+ free(server->tcp_buffer);
419
+ server->tcp_buffer = NULL;
420
+ server->tcp_lenbuf_pos = 0;
421
+ server->tcp_buffer_pos = 0;
422
+ }
423
+ }
424
+ }
425
+ }
426
+
427
+ /* If any UDP sockets select true for reading, process them. */
428
+ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
429
+ ares_socket_t read_fd, struct timeval *now)
430
+ {
431
+ struct server_state *server;
432
+ int i;
433
+ ssize_t count;
434
+ unsigned char buf[PACKETSZ + 1];
435
+ #ifdef HAVE_RECVFROM
436
+ ares_socklen_t fromlen;
437
+ union {
438
+ struct sockaddr sa;
439
+ struct sockaddr_in sa4;
440
+ struct sockaddr_in6 sa6;
441
+ } from;
442
+ #endif
443
+
444
+ if(!read_fds && (read_fd == ARES_SOCKET_BAD))
445
+ /* no possible action */
446
+ return;
447
+
448
+ for (i = 0; i < channel->nservers; i++)
449
+ {
450
+ /* Make sure the server has a socket and is selected in read_fds. */
451
+ server = &channel->servers[i];
452
+
453
+ if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken)
454
+ continue;
455
+
456
+ if(read_fds) {
457
+ if(!FD_ISSET(server->udp_socket, read_fds))
458
+ continue;
459
+ }
460
+ else {
461
+ if(server->udp_socket != read_fd)
462
+ continue;
463
+ }
464
+
465
+ if(read_fds)
466
+ /* If there's an error and we close this socket, then open
467
+ * another with the same fd to talk to another server, then we
468
+ * don't want to think that it was the new socket that was
469
+ * ready. This is not disastrous, but is likely to result in
470
+ * extra system calls and confusion. */
471
+ FD_CLR(server->udp_socket, read_fds);
472
+
473
+ /* To reduce event loop overhead, read and process as many
474
+ * packets as we can. */
475
+ do {
476
+ #ifdef HAVE_RECVFROM
477
+ if (server->addr.family == AF_INET)
478
+ fromlen = sizeof(from.sa4);
479
+ else
480
+ fromlen = sizeof(from.sa6);
481
+ count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf),
482
+ 0, &from.sa, &fromlen);
483
+ #else
484
+ count = sread(server->udp_socket, buf, sizeof(buf));
485
+ #endif
486
+ if (count == -1 && try_again(SOCKERRNO))
487
+ continue;
488
+ else if (count <= 0)
489
+ handle_error(channel, i, now);
490
+ #ifdef HAVE_RECVFROM
491
+ else if (!same_address(&from.sa, &server->addr))
492
+ /* The address the response comes from does not match
493
+ * the address we sent the request to. Someone may be
494
+ * attempting to perform a cache poisoning attack. */
495
+ break;
496
+ #endif
497
+ else
498
+ process_answer(channel, buf, (int)count, i, 0, now);
499
+ } while (count > 0);
500
+ }
501
+ }
502
+
503
+ /* If any queries have timed out, note the timeout and move them on. */
504
+ static void process_timeouts(ares_channel channel, struct timeval *now)
505
+ {
506
+ time_t t; /* the time of the timeouts we're processing */
507
+ struct query *query;
508
+ struct list_node* list_head;
509
+ struct list_node* list_node;
510
+
511
+ /* Process all the timeouts that have fired since the last time we
512
+ * processed timeouts. If things are going well, then we'll have
513
+ * hundreds/thousands of queries that fall into future buckets, and
514
+ * only a handful of requests that fall into the "now" bucket, so
515
+ * this should be quite quick.
516
+ */
517
+ for (t = channel->last_timeout_processed; t <= now->tv_sec; t++)
518
+ {
519
+ list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]);
520
+ for (list_node = list_head->next; list_node != list_head; )
521
+ {
522
+ query = list_node->data;
523
+ list_node = list_node->next; /* in case the query gets deleted */
524
+ if (query->timeout.tv_sec && ares__timedout(now, &query->timeout))
525
+ {
526
+ query->error_status = ARES_ETIMEOUT;
527
+ ++query->timeouts;
528
+ next_server(channel, query, now);
529
+ }
530
+ }
531
+ }
532
+ channel->last_timeout_processed = now->tv_sec;
533
+ }
534
+
535
+ /* Handle an answer from a server. */
536
+ static void process_answer(ares_channel channel, unsigned char *abuf,
537
+ int alen, int whichserver, int tcp,
538
+ struct timeval *now)
539
+ {
540
+ int tc, rcode;
541
+ unsigned short id;
542
+ struct query *query;
543
+ struct list_node* list_head;
544
+ struct list_node* list_node;
545
+
546
+ /* If there's no room in the answer for a header, we can't do much
547
+ * with it. */
548
+ if (alen < HFIXEDSZ)
549
+ return;
550
+
551
+ /* Grab the query ID, truncate bit, and response code from the packet. */
552
+ id = DNS_HEADER_QID(abuf);
553
+ tc = DNS_HEADER_TC(abuf);
554
+ rcode = DNS_HEADER_RCODE(abuf);
555
+
556
+ /* Find the query corresponding to this packet. The queries are
557
+ * hashed/bucketed by query id, so this lookup should be quick.
558
+ * Note that both the query id and the questions must be the same;
559
+ * when the query id wraps around we can have multiple outstanding
560
+ * queries with the same query id, so we need to check both the id and
561
+ * question.
562
+ */
563
+ query = NULL;
564
+ list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]);
565
+ for (list_node = list_head->next; list_node != list_head;
566
+ list_node = list_node->next)
567
+ {
568
+ struct query *q = list_node->data;
569
+ if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen))
570
+ {
571
+ query = q;
572
+ break;
573
+ }
574
+ }
575
+ if (!query)
576
+ return;
577
+
578
+ /* If we got a truncated UDP packet and are not ignoring truncation,
579
+ * don't accept the packet, and switch the query to TCP if we hadn't
580
+ * done so already.
581
+ */
582
+ if ((tc || alen > PACKETSZ) && !tcp && !(channel->flags & ARES_FLAG_IGNTC))
583
+ {
584
+ if (!query->using_tcp)
585
+ {
586
+ query->using_tcp = 1;
587
+ ares__send_query(channel, query, now);
588
+ }
589
+ return;
590
+ }
591
+
592
+ /* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we
593
+ * are ignoring truncation.
594
+ */
595
+ if (alen > PACKETSZ && !tcp)
596
+ alen = PACKETSZ;
597
+
598
+ /* If we aren't passing through all error packets, discard packets
599
+ * with SERVFAIL, NOTIMP, or REFUSED response codes.
600
+ */
601
+ if (!(channel->flags & ARES_FLAG_NOCHECKRESP))
602
+ {
603
+ if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED)
604
+ {
605
+ skip_server(channel, query, whichserver);
606
+ if (query->server == whichserver)
607
+ next_server(channel, query, now);
608
+ return;
609
+ }
610
+ }
611
+
612
+ end_query(channel, query, ARES_SUCCESS, abuf, alen);
613
+ }
614
+
615
+ /* Close all the connections that are no longer usable. */
616
+ static void process_broken_connections(ares_channel channel,
617
+ struct timeval *now)
618
+ {
619
+ int i;
620
+ for (i = 0; i < channel->nservers; i++)
621
+ {
622
+ struct server_state *server = &channel->servers[i];
623
+ if (server->is_broken)
624
+ {
625
+ handle_error(channel, i, now);
626
+ }
627
+ }
628
+ }
629
+
630
+ static void handle_error(ares_channel channel, int whichserver,
631
+ struct timeval *now)
632
+ {
633
+ struct server_state *server;
634
+ struct query *query;
635
+ struct list_node list_head;
636
+ struct list_node* list_node;
637
+
638
+ server = &channel->servers[whichserver];
639
+
640
+ /* Reset communications with this server. */
641
+ ares__close_sockets(channel, server);
642
+
643
+ /* Tell all queries talking to this server to move on and not try
644
+ * this server again. We steal the current list of queries that were
645
+ * in-flight to this server, since when we call next_server this can
646
+ * cause the queries to be re-sent to this server, which will
647
+ * re-insert these queries in that same server->queries_to_server
648
+ * list.
649
+ */
650
+ ares__init_list_head(&list_head);
651
+ ares__swap_lists(&list_head, &(server->queries_to_server));
652
+ for (list_node = list_head.next; list_node != &list_head; )
653
+ {
654
+ query = list_node->data;
655
+ list_node = list_node->next; /* in case the query gets deleted */
656
+ assert(query->server == whichserver);
657
+ skip_server(channel, query, whichserver);
658
+ next_server(channel, query, now);
659
+ }
660
+ /* Each query should have removed itself from our temporary list as
661
+ * it re-sent itself or finished up...
662
+ */
663
+ assert(ares__is_list_empty(&list_head));
664
+ }
665
+
666
+ static void skip_server(ares_channel channel, struct query *query,
667
+ int whichserver) {
668
+ /* The given server gave us problems with this query, so if we have
669
+ * the luxury of using other servers, then let's skip the
670
+ * potentially broken server and just use the others. If we only
671
+ * have one server and we need to retry then we should just go ahead
672
+ * and re-use that server, since it's our only hope; perhaps we
673
+ * just got unlucky, and retrying will work (eg, the server timed
674
+ * out our TCP connection just as we were sending another request).
675
+ */
676
+ if (channel->nservers > 1)
677
+ {
678
+ query->server_info[whichserver].skip_server = 1;
679
+ }
680
+ }
681
+
682
+ static void next_server(ares_channel channel, struct query *query,
683
+ struct timeval *now)
684
+ {
685
+ /* We need to try each server channel->tries times. We have channel->nservers
686
+ * servers to try. In total, we need to do channel->nservers * channel->tries
687
+ * attempts. Use query->try to remember how many times we already attempted
688
+ * this query. Use modular arithmetic to find the next server to try. */
689
+ while (++(query->try) < (channel->nservers * channel->tries))
690
+ {
691
+ struct server_state *server;
692
+
693
+ /* Move on to the next server. */
694
+ query->server = (query->server + 1) % channel->nservers;
695
+ server = &channel->servers[query->server];
696
+
697
+ /* We don't want to use this server if (1) we decided this
698
+ * connection is broken, and thus about to be closed, (2)
699
+ * we've decided to skip this server because of earlier
700
+ * errors we encountered, or (3) we already sent this query
701
+ * over this exact connection.
702
+ */
703
+ if (!server->is_broken &&
704
+ !query->server_info[query->server].skip_server &&
705
+ !(query->using_tcp &&
706
+ (query->server_info[query->server].tcp_connection_generation ==
707
+ server->tcp_connection_generation)))
708
+ {
709
+ ares__send_query(channel, query, now);
710
+ return;
711
+ }
712
+
713
+ /* You might think that with TCP we only need one try. However,
714
+ * even when using TCP, servers can time-out our connection just
715
+ * as we're sending a request, or close our connection because
716
+ * they die, or never send us a reply because they get wedged or
717
+ * tickle a bug that drops our request.
718
+ */
719
+ }
720
+
721
+ /* If we are here, all attempts to perform query failed. */
722
+ end_query(channel, query, query->error_status, NULL, 0);
723
+ }
724
+
725
+ void ares__send_query(ares_channel channel, struct query *query,
726
+ struct timeval *now)
727
+ {
728
+ struct send_request *sendreq;
729
+ struct server_state *server;
730
+ int timeplus;
731
+
732
+ server = &channel->servers[query->server];
733
+ if (query->using_tcp)
734
+ {
735
+ /* Make sure the TCP socket for this server is set up and queue
736
+ * a send request.
737
+ */
738
+ if (server->tcp_socket == ARES_SOCKET_BAD)
739
+ {
740
+ if (open_tcp_socket(channel, server) == -1)
741
+ {
742
+ skip_server(channel, query, query->server);
743
+ next_server(channel, query, now);
744
+ return;
745
+ }
746
+ }
747
+ sendreq = calloc(1, sizeof(struct send_request));
748
+ if (!sendreq)
749
+ {
750
+ end_query(channel, query, ARES_ENOMEM, NULL, 0);
751
+ return;
752
+ }
753
+ /* To make the common case fast, we avoid copies by using the
754
+ * query's tcpbuf for as long as the query is alive. In the rare
755
+ * case where the query ends while it's queued for transmission,
756
+ * then we give the sendreq its own copy of the request packet
757
+ * and put it in sendreq->data_storage.
758
+ */
759
+ sendreq->data_storage = NULL;
760
+ sendreq->data = query->tcpbuf;
761
+ sendreq->len = query->tcplen;
762
+ sendreq->owner_query = query;
763
+ sendreq->next = NULL;
764
+ if (server->qtail)
765
+ server->qtail->next = sendreq;
766
+ else
767
+ {
768
+ SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1);
769
+ server->qhead = sendreq;
770
+ }
771
+ server->qtail = sendreq;
772
+ query->server_info[query->server].tcp_connection_generation =
773
+ server->tcp_connection_generation;
774
+ }
775
+ else
776
+ {
777
+ if (server->udp_socket == ARES_SOCKET_BAD)
778
+ {
779
+ if (open_udp_socket(channel, server) == -1)
780
+ {
781
+ skip_server(channel, query, query->server);
782
+ next_server(channel, query, now);
783
+ return;
784
+ }
785
+ }
786
+ if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1)
787
+ {
788
+ /* FIXME: Handle EAGAIN here since it likely can happen. */
789
+ skip_server(channel, query, query->server);
790
+ next_server(channel, query, now);
791
+ return;
792
+ }
793
+ }
794
+ timeplus = channel->timeout << (query->try / channel->nservers);
795
+ timeplus = (timeplus * (9 + (rand () & 7))) / 16;
796
+ query->timeout = *now;
797
+ ares__timeadd(&query->timeout,
798
+ timeplus);
799
+ /* Keep track of queries bucketed by timeout, so we can process
800
+ * timeout events quickly.
801
+ */
802
+ ares__remove_from_list(&(query->queries_by_timeout));
803
+ ares__insert_in_list(
804
+ &(query->queries_by_timeout),
805
+ &(channel->queries_by_timeout[query->timeout.tv_sec %
806
+ ARES_TIMEOUT_TABLE_SIZE]));
807
+
808
+ /* Keep track of queries bucketed by server, so we can process server
809
+ * errors quickly.
810
+ */
811
+ ares__remove_from_list(&(query->queries_to_server));
812
+ ares__insert_in_list(&(query->queries_to_server),
813
+ &(server->queries_to_server));
814
+ }
815
+
816
+ /*
817
+ * setsocknonblock sets the given socket to either blocking or non-blocking
818
+ * mode based on the 'nonblock' boolean argument. This function is highly
819
+ * portable.
820
+ */
821
+ static int setsocknonblock(ares_socket_t sockfd, /* operate on this */
822
+ int nonblock /* TRUE or FALSE */)
823
+ {
824
+ #if defined(USE_BLOCKING_SOCKETS)
825
+
826
+ return 0; /* returns success */
827
+
828
+ #elif defined(HAVE_FCNTL_O_NONBLOCK)
829
+
830
+ /* most recent unix versions */
831
+ int flags;
832
+ flags = fcntl(sockfd, F_GETFL, 0);
833
+ if (FALSE != nonblock)
834
+ return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
835
+ else
836
+ return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
837
+
838
+ #elif defined(HAVE_IOCTL_FIONBIO)
839
+
840
+ /* older unix versions */
841
+ int flags;
842
+ flags = nonblock;
843
+ return ioctl(sockfd, FIONBIO, &flags);
844
+
845
+ #elif defined(HAVE_IOCTLSOCKET_FIONBIO)
846
+
847
+ #ifdef WATT32
848
+ char flags;
849
+ #else
850
+ /* Windows */
851
+ unsigned long flags;
852
+ #endif
853
+ flags = nonblock;
854
+ return ioctlsocket(sockfd, FIONBIO, &flags);
855
+
856
+ #elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
857
+
858
+ /* Amiga */
859
+ return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
860
+
861
+ #elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
862
+
863
+ /* BeOS */
864
+ long b = nonblock ? 1 : 0;
865
+ return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
866
+
867
+ #else
868
+ # error "no non-blocking method was found/used/set"
869
+ #endif
870
+ }
871
+
872
+ static int configure_socket(ares_socket_t s, int family, ares_channel channel)
873
+ {
874
+ union {
875
+ struct sockaddr sa;
876
+ struct sockaddr_in sa4;
877
+ struct sockaddr_in6 sa6;
878
+ } local;
879
+
880
+ setsocknonblock(s, TRUE);
881
+
882
+ #if defined(FD_CLOEXEC) && !defined(MSDOS)
883
+ /* Configure the socket fd as close-on-exec. */
884
+ if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
885
+ return -1;
886
+ #endif
887
+
888
+ /* Set the socket's send and receive buffer sizes. */
889
+ if ((channel->socket_send_buffer_size > 0) &&
890
+ setsockopt(s, SOL_SOCKET, SO_SNDBUF,
891
+ (void *)&channel->socket_send_buffer_size,
892
+ sizeof(channel->socket_send_buffer_size)) == -1)
893
+ return -1;
894
+
895
+ if ((channel->socket_receive_buffer_size > 0) &&
896
+ setsockopt(s, SOL_SOCKET, SO_RCVBUF,
897
+ (void *)&channel->socket_receive_buffer_size,
898
+ sizeof(channel->socket_receive_buffer_size)) == -1)
899
+ return -1;
900
+
901
+ #ifdef SO_BINDTODEVICE
902
+ if (channel->local_dev_name[0]) {
903
+ if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
904
+ channel->local_dev_name, sizeof(channel->local_dev_name))) {
905
+ /* Only root can do this, and usually not fatal if it doesn't work, so */
906
+ /* just continue on. */
907
+ }
908
+ }
909
+ #endif
910
+
911
+ if (family == AF_INET) {
912
+ if (channel->local_ip4) {
913
+ memset(&local.sa4, 0, sizeof(local.sa4));
914
+ local.sa4.sin_family = AF_INET;
915
+ local.sa4.sin_addr.s_addr = htonl(channel->local_ip4);
916
+ if (bind(s, &local.sa, sizeof(local.sa4)) < 0)
917
+ return -1;
918
+ }
919
+ }
920
+ else if (family == AF_INET6) {
921
+ if (memcmp(channel->local_ip6, &ares_in6addr_any, sizeof(channel->local_ip6)) != 0) {
922
+ memset(&local.sa6, 0, sizeof(local.sa6));
923
+ local.sa6.sin6_family = AF_INET6;
924
+ memcpy(&local.sa6.sin6_addr, channel->local_ip6, sizeof(channel->local_ip6));
925
+ if (bind(s, &local.sa, sizeof(local.sa6)) < 0)
926
+ return -1;
927
+ }
928
+ }
929
+
930
+ return 0;
931
+ }
932
+
933
+ static int open_tcp_socket(ares_channel channel, struct server_state *server)
934
+ {
935
+ ares_socket_t s;
936
+ int opt;
937
+ ares_socklen_t salen;
938
+ union {
939
+ struct sockaddr_in sa4;
940
+ struct sockaddr_in6 sa6;
941
+ } saddr;
942
+ struct sockaddr *sa;
943
+
944
+ switch (server->addr.family)
945
+ {
946
+ case AF_INET:
947
+ sa = (void *)&saddr.sa4;
948
+ salen = sizeof(saddr.sa4);
949
+ memset(sa, 0, salen);
950
+ saddr.sa4.sin_family = AF_INET;
951
+ saddr.sa4.sin_port = (unsigned short)(channel->tcp_port & 0xffff);
952
+ memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
953
+ sizeof(server->addr.addrV4));
954
+ break;
955
+ case AF_INET6:
956
+ sa = (void *)&saddr.sa6;
957
+ salen = sizeof(saddr.sa6);
958
+ memset(sa, 0, salen);
959
+ saddr.sa6.sin6_family = AF_INET6;
960
+ saddr.sa6.sin6_port = (unsigned short)(channel->tcp_port & 0xffff);
961
+ memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
962
+ sizeof(server->addr.addrV6));
963
+ break;
964
+ default:
965
+ return -1;
966
+ }
967
+
968
+ /* Acquire a socket. */
969
+ s = socket(server->addr.family, SOCK_STREAM, 0);
970
+ if (s == ARES_SOCKET_BAD)
971
+ return -1;
972
+
973
+ /* Configure it. */
974
+ if (configure_socket(s, server->addr.family, channel) < 0)
975
+ {
976
+ sclose(s);
977
+ return -1;
978
+ }
979
+
980
+ #ifdef TCP_NODELAY
981
+ /*
982
+ * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not
983
+ * in configure_socket). In general, in DNS lookups we're pretty much
984
+ * interested in firing off a single request and then waiting for a reply,
985
+ * so batching isn't very interesting.
986
+ */
987
+ opt = 1;
988
+ if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
989
+ (void *)&opt, sizeof(opt)) == -1)
990
+ {
991
+ sclose(s);
992
+ return -1;
993
+ }
994
+ #endif
995
+
996
+ /* Connect to the server. */
997
+ if (connect(s, sa, salen) == -1)
998
+ {
999
+ int err = SOCKERRNO;
1000
+
1001
+ if (err != EINPROGRESS && err != EWOULDBLOCK)
1002
+ {
1003
+ sclose(s);
1004
+ return -1;
1005
+ }
1006
+ }
1007
+
1008
+ if (channel->sock_create_cb)
1009
+ {
1010
+ int err = channel->sock_create_cb(s, SOCK_STREAM,
1011
+ channel->sock_create_cb_data);
1012
+ if (err < 0)
1013
+ {
1014
+ sclose(s);
1015
+ return err;
1016
+ }
1017
+ }
1018
+
1019
+ SOCK_STATE_CALLBACK(channel, s, 1, 0);
1020
+ server->tcp_buffer_pos = 0;
1021
+ server->tcp_socket = s;
1022
+ server->tcp_connection_generation = ++channel->tcp_connection_generation;
1023
+ return 0;
1024
+ }
1025
+
1026
+ static int open_udp_socket(ares_channel channel, struct server_state *server)
1027
+ {
1028
+ ares_socket_t s;
1029
+ ares_socklen_t salen;
1030
+ union {
1031
+ struct sockaddr_in sa4;
1032
+ struct sockaddr_in6 sa6;
1033
+ } saddr;
1034
+ struct sockaddr *sa;
1035
+
1036
+ switch (server->addr.family)
1037
+ {
1038
+ case AF_INET:
1039
+ sa = (void *)&saddr.sa4;
1040
+ salen = sizeof(saddr.sa4);
1041
+ memset(sa, 0, salen);
1042
+ saddr.sa4.sin_family = AF_INET;
1043
+ saddr.sa4.sin_port = (unsigned short)(channel->udp_port & 0xffff);
1044
+ memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4,
1045
+ sizeof(server->addr.addrV4));
1046
+ break;
1047
+ case AF_INET6:
1048
+ sa = (void *)&saddr.sa6;
1049
+ salen = sizeof(saddr.sa6);
1050
+ memset(sa, 0, salen);
1051
+ saddr.sa6.sin6_family = AF_INET6;
1052
+ saddr.sa6.sin6_port = (unsigned short)(channel->udp_port & 0xffff);
1053
+ memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6,
1054
+ sizeof(server->addr.addrV6));
1055
+ break;
1056
+ default:
1057
+ return -1;
1058
+ }
1059
+
1060
+ /* Acquire a socket. */
1061
+ s = socket(server->addr.family, SOCK_DGRAM, 0);
1062
+ if (s == ARES_SOCKET_BAD)
1063
+ return -1;
1064
+
1065
+ /* Set the socket non-blocking. */
1066
+ if (configure_socket(s, server->addr.family, channel) < 0)
1067
+ {
1068
+ sclose(s);
1069
+ return -1;
1070
+ }
1071
+
1072
+ /* Connect to the server. */
1073
+ if (connect(s, sa, salen) == -1)
1074
+ {
1075
+ int err = SOCKERRNO;
1076
+
1077
+ if (err != EINPROGRESS && err != EWOULDBLOCK)
1078
+ {
1079
+ sclose(s);
1080
+ return -1;
1081
+ }
1082
+ }
1083
+
1084
+ if (channel->sock_create_cb)
1085
+ {
1086
+ int err = channel->sock_create_cb(s, SOCK_DGRAM,
1087
+ channel->sock_create_cb_data);
1088
+ if (err < 0)
1089
+ {
1090
+ sclose(s);
1091
+ return err;
1092
+ }
1093
+ }
1094
+
1095
+ SOCK_STATE_CALLBACK(channel, s, 1, 0);
1096
+
1097
+ server->udp_socket = s;
1098
+ return 0;
1099
+ }
1100
+
1101
+ static int same_questions(const unsigned char *qbuf, int qlen,
1102
+ const unsigned char *abuf, int alen)
1103
+ {
1104
+ struct {
1105
+ const unsigned char *p;
1106
+ int qdcount;
1107
+ char *name;
1108
+ long namelen;
1109
+ int type;
1110
+ int dnsclass;
1111
+ } q, a;
1112
+ int i, j;
1113
+
1114
+ if (qlen < HFIXEDSZ || alen < HFIXEDSZ)
1115
+ return 0;
1116
+
1117
+ /* Extract qdcount from the request and reply buffers and compare them. */
1118
+ q.qdcount = DNS_HEADER_QDCOUNT(qbuf);
1119
+ a.qdcount = DNS_HEADER_QDCOUNT(abuf);
1120
+ if (q.qdcount != a.qdcount)
1121
+ return 0;
1122
+
1123
+ /* For each question in qbuf, find it in abuf. */
1124
+ q.p = qbuf + HFIXEDSZ;
1125
+ for (i = 0; i < q.qdcount; i++)
1126
+ {
1127
+ /* Decode the question in the query. */
1128
+ if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen)
1129
+ != ARES_SUCCESS)
1130
+ return 0;
1131
+ q.p += q.namelen;
1132
+ if (q.p + QFIXEDSZ > qbuf + qlen)
1133
+ {
1134
+ free(q.name);
1135
+ return 0;
1136
+ }
1137
+ q.type = DNS_QUESTION_TYPE(q.p);
1138
+ q.dnsclass = DNS_QUESTION_CLASS(q.p);
1139
+ q.p += QFIXEDSZ;
1140
+
1141
+ /* Search for this question in the answer. */
1142
+ a.p = abuf + HFIXEDSZ;
1143
+ for (j = 0; j < a.qdcount; j++)
1144
+ {
1145
+ /* Decode the question in the answer. */
1146
+ if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen)
1147
+ != ARES_SUCCESS)
1148
+ {
1149
+ free(q.name);
1150
+ return 0;
1151
+ }
1152
+ a.p += a.namelen;
1153
+ if (a.p + QFIXEDSZ > abuf + alen)
1154
+ {
1155
+ free(q.name);
1156
+ free(a.name);
1157
+ return 0;
1158
+ }
1159
+ a.type = DNS_QUESTION_TYPE(a.p);
1160
+ a.dnsclass = DNS_QUESTION_CLASS(a.p);
1161
+ a.p += QFIXEDSZ;
1162
+
1163
+ /* Compare the decoded questions. */
1164
+ if (strcasecmp(q.name, a.name) == 0 && q.type == a.type
1165
+ && q.dnsclass == a.dnsclass)
1166
+ {
1167
+ free(a.name);
1168
+ break;
1169
+ }
1170
+ free(a.name);
1171
+ }
1172
+
1173
+ free(q.name);
1174
+ if (j == a.qdcount)
1175
+ return 0;
1176
+ }
1177
+ return 1;
1178
+ }
1179
+
1180
+ static int same_address(struct sockaddr *sa, struct ares_addr *aa)
1181
+ {
1182
+ void *addr1;
1183
+ void *addr2;
1184
+
1185
+ if (sa->sa_family == aa->family)
1186
+ {
1187
+ switch (aa->family)
1188
+ {
1189
+ case AF_INET:
1190
+ addr1 = &aa->addrV4;
1191
+ addr2 = &((struct sockaddr_in *)sa)->sin_addr;
1192
+ if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0)
1193
+ return 1; /* match */
1194
+ break;
1195
+ case AF_INET6:
1196
+ addr1 = &aa->addrV6;
1197
+ addr2 = &((struct sockaddr_in6 *)sa)->sin6_addr;
1198
+ if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0)
1199
+ return 1; /* match */
1200
+ break;
1201
+ default:
1202
+ break;
1203
+ }
1204
+ }
1205
+ return 0; /* different */
1206
+ }
1207
+
1208
+ static void end_query (ares_channel channel, struct query *query, int status,
1209
+ unsigned char *abuf, int alen)
1210
+ {
1211
+ int i;
1212
+
1213
+ /* First we check to see if this query ended while one of our send
1214
+ * queues still has pointers to it.
1215
+ */
1216
+ for (i = 0; i < channel->nservers; i++)
1217
+ {
1218
+ struct server_state *server = &channel->servers[i];
1219
+ struct send_request *sendreq;
1220
+ for (sendreq = server->qhead; sendreq; sendreq = sendreq->next)
1221
+ if (sendreq->owner_query == query)
1222
+ {
1223
+ sendreq->owner_query = NULL;
1224
+ assert(sendreq->data_storage == NULL);
1225
+ if (status == ARES_SUCCESS)
1226
+ {
1227
+ /* We got a reply for this query, but this queued
1228
+ * sendreq points into this soon-to-be-gone query's
1229
+ * tcpbuf. Probably this means we timed out and queued
1230
+ * the query for retransmission, then received a
1231
+ * response before actually retransmitting. This is
1232
+ * perfectly fine, so we want to keep the connection
1233
+ * running smoothly if we can. But in the worst case
1234
+ * we may have sent only some prefix of the query,
1235
+ * with some suffix of the query left to send. Also,
1236
+ * the buffer may be queued on multiple queues. To
1237
+ * prevent dangling pointers to the query's tcpbuf and
1238
+ * handle these cases, we just give such sendreqs
1239
+ * their own copy of the query packet.
1240
+ */
1241
+ sendreq->data_storage = malloc(sendreq->len);
1242
+ if (sendreq->data_storage != NULL)
1243
+ {
1244
+ memcpy(sendreq->data_storage, sendreq->data, sendreq->len);
1245
+ sendreq->data = sendreq->data_storage;
1246
+ }
1247
+ }
1248
+ if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL))
1249
+ {
1250
+ /* We encountered an error (probably a timeout,
1251
+ * suggesting the DNS server we're talking to is
1252
+ * probably unreachable, wedged, or severely
1253
+ * overloaded) or we couldn't copy the request, so
1254
+ * mark the connection as broken. When we get to
1255
+ * process_broken_connections() we'll close the
1256
+ * connection and try to re-send requests to another
1257
+ * server.
1258
+ */
1259
+ server->is_broken = 1;
1260
+ /* Just to be paranoid, zero out this sendreq... */
1261
+ sendreq->data = NULL;
1262
+ sendreq->len = 0;
1263
+ }
1264
+ }
1265
+ }
1266
+
1267
+ /* Invoke the callback */
1268
+ query->callback(query->arg, status, query->timeouts, abuf, alen);
1269
+ ares__free_query(query);
1270
+
1271
+ /* Simple cleanup policy: if no queries are remaining, close all
1272
+ * network sockets unless STAYOPEN is set.
1273
+ */
1274
+ if (!(channel->flags & ARES_FLAG_STAYOPEN) &&
1275
+ ares__is_list_empty(&(channel->all_queries)))
1276
+ {
1277
+ for (i = 0; i < channel->nservers; i++)
1278
+ ares__close_sockets(channel, &channel->servers[i]);
1279
+ }
1280
+ }
1281
+
1282
+ void ares__free_query(struct query *query)
1283
+ {
1284
+ /* Remove the query from all the lists in which it is linked */
1285
+ ares__remove_from_list(&(query->queries_by_qid));
1286
+ ares__remove_from_list(&(query->queries_by_timeout));
1287
+ ares__remove_from_list(&(query->queries_to_server));
1288
+ ares__remove_from_list(&(query->all_queries));
1289
+ /* Zero out some important stuff, to help catch bugs */
1290
+ query->callback = NULL;
1291
+ query->arg = NULL;
1292
+ /* Deallocate the memory associated with the query */
1293
+ free(query->tcpbuf);
1294
+ free(query->server_info);
1295
+ free(query);
1296
+ }