grpc 1.2.5 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (327) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1434 -399
  3. data/etc/roots.pem +34 -150
  4. data/include/grpc/grpc.h +71 -0
  5. data/include/grpc/impl/codegen/atm.h +5 -0
  6. data/include/grpc/impl/codegen/atm_gcc_atomic.h +6 -0
  7. data/include/grpc/impl/codegen/atm_gcc_sync.h +2 -0
  8. data/include/grpc/impl/codegen/atm_windows.h +11 -0
  9. data/include/grpc/impl/codegen/grpc_types.h +54 -13
  10. data/include/grpc/impl/codegen/port_platform.h +15 -1
  11. data/include/grpc/support/alloc.h +2 -1
  12. data/include/grpc/support/sync.h +4 -0
  13. data/include/grpc/support/tls.h +1 -1
  14. data/src/core/ext/census/gen/trace_context.pb.h +1 -1
  15. data/src/core/ext/census/grpc_filter.c +14 -10
  16. data/src/core/ext/census/grpc_plugin.c +3 -1
  17. data/src/core/ext/census/trace_label.h +1 -1
  18. data/src/core/ext/census/trace_propagation.h +1 -1
  19. data/src/core/ext/census/trace_status.h +1 -1
  20. data/src/core/ext/census/trace_string.h +1 -1
  21. data/src/core/ext/census/tracing.h +1 -1
  22. data/src/core/ext/{client_channel → filters/client_channel}/channel_connectivity.c +56 -27
  23. data/src/core/ext/{client_channel → filters/client_channel}/client_channel.c +407 -202
  24. data/src/core/ext/{client_channel → filters/client_channel}/client_channel.h +10 -6
  25. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.c +1 -1
  26. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.h +4 -4
  27. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_plugin.c +12 -7
  28. data/src/core/ext/{client_channel → filters/client_channel}/connector.c +1 -1
  29. data/src/core/ext/{client_channel → filters/client_channel}/connector.h +3 -5
  30. data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.c +6 -6
  31. data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.h +3 -3
  32. data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.c +4 -4
  33. data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.h +3 -3
  34. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.c +1 -1
  35. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.h +4 -4
  36. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.c +22 -20
  37. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.h +4 -4
  38. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel.h +5 -4
  39. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel_secure.c +2 -2
  40. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.c +1 -1
  41. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.h +6 -5
  42. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +1 -1
  43. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +0 -0
  44. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/pick_first/pick_first.c +20 -15
  45. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/round_robin/round_robin.c +21 -16
  46. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.c +1 -1
  47. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.h +5 -5
  48. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.c +1 -1
  49. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.h +4 -4
  50. data/src/core/ext/{client_channel → filters/client_channel}/parse_address.c +1 -1
  51. data/src/core/ext/{client_channel → filters/client_channel}/parse_address.h +4 -4
  52. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.c +1 -1
  53. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.h +3 -3
  54. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.c +10 -4
  55. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.h +4 -4
  56. data/src/core/ext/{client_channel → filters/client_channel}/resolver.c +1 -1
  57. data/src/core/ext/{client_channel → filters/client_channel}/resolver.h +4 -4
  58. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +350 -0
  59. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +66 -0
  60. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +319 -0
  61. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +289 -0
  62. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +64 -0
  63. data/src/core/ext/{resolver → filters/client_channel/resolver}/dns/native/dns_resolver.c +21 -5
  64. data/src/core/ext/{resolver → filters/client_channel/resolver}/sockaddr/sockaddr_resolver.c +3 -3
  65. data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.c +1 -1
  66. data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.h +6 -6
  67. data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.c +1 -2
  68. data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.h +4 -4
  69. data/src/core/ext/filters/client_channel/retry_throttle.c +210 -0
  70. data/src/core/ext/filters/client_channel/retry_throttle.h +65 -0
  71. data/src/core/ext/{client_channel → filters/client_channel}/subchannel.c +49 -43
  72. data/src/core/ext/{client_channel → filters/client_channel}/subchannel.h +21 -7
  73. data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.c +1 -1
  74. data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.h +5 -5
  75. data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.c +1 -1
  76. data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.h +3 -3
  77. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.c +4 -2
  78. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.h +3 -3
  79. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.c +17 -14
  80. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.h +4 -4
  81. data/src/core/ext/filters/max_age/max_age_filter.c +439 -0
  82. data/src/core/ext/filters/max_age/max_age_filter.h +39 -0
  83. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +6 -41
  84. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +1 -1
  85. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +2 -2
  86. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +3 -3
  87. data/src/core/ext/transport/chttp2/server/chttp2_server.c +2 -2
  88. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +2 -5
  89. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +2 -2
  90. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +449 -204
  91. data/src/core/ext/transport/chttp2/transport/frame_data.c +10 -7
  92. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +3 -2
  93. data/src/core/ext/transport/chttp2/transport/frame_ping.c +37 -7
  94. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -0
  95. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +4 -3
  96. data/src/core/ext/transport/chttp2/transport/frame_settings.c +18 -38
  97. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -29
  98. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +2 -2
  99. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +64 -37
  100. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +11 -4
  101. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +60 -39
  102. data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
  103. data/src/core/ext/transport/chttp2/transport/http2_settings.c +75 -0
  104. data/src/core/ext/transport/chttp2/transport/http2_settings.h +74 -0
  105. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +22 -43
  106. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +8 -10
  107. data/src/core/ext/transport/chttp2/transport/internal.h +24 -2
  108. data/src/core/ext/transport/chttp2/transport/parsing.c +33 -15
  109. data/src/core/ext/transport/chttp2/transport/writing.c +56 -10
  110. data/src/core/lib/channel/channel_args.c +7 -0
  111. data/src/core/lib/channel/channel_args.h +2 -0
  112. data/src/core/lib/channel/channel_stack.c +20 -27
  113. data/src/core/lib/channel/channel_stack.h +18 -16
  114. data/src/core/lib/channel/compress_filter.c +20 -18
  115. data/src/core/lib/channel/connected_channel.c +9 -8
  116. data/src/core/lib/channel/deadline_filter.c +28 -24
  117. data/src/core/lib/channel/deadline_filter.h +3 -3
  118. data/src/core/lib/channel/handshaker.c +3 -2
  119. data/src/core/lib/channel/http_client_filter.c +119 -61
  120. data/src/core/lib/channel/http_server_filter.c +124 -69
  121. data/src/core/lib/channel/message_size_filter.c +23 -19
  122. data/src/core/lib/http/httpcli.c +8 -6
  123. data/src/core/lib/http/httpcli_security_connector.c +5 -5
  124. data/src/core/lib/http/parser.c +57 -31
  125. data/src/core/lib/iomgr/closure.c +15 -0
  126. data/src/core/lib/iomgr/closure.h +4 -0
  127. data/src/core/lib/iomgr/combiner.c +8 -0
  128. data/src/core/lib/iomgr/endpoint_pair.h +2 -3
  129. data/src/core/lib/iomgr/endpoint_pair_posix.c +10 -7
  130. data/src/core/lib/iomgr/endpoint_pair_uv.c +2 -3
  131. data/src/core/lib/iomgr/endpoint_pair_windows.c +9 -6
  132. data/src/core/lib/iomgr/error.c +360 -177
  133. data/src/core/lib/iomgr/error.h +31 -33
  134. data/src/core/lib/iomgr/error_internal.h +30 -9
  135. data/src/core/lib/iomgr/ev_epoll_linux.c +25 -239
  136. data/src/core/lib/iomgr/ev_poll_posix.c +11 -7
  137. data/src/core/lib/iomgr/ev_posix.c +6 -0
  138. data/src/core/lib/iomgr/ev_posix.h +3 -0
  139. data/src/core/lib/iomgr/exec_ctx.c +6 -0
  140. data/src/core/lib/iomgr/executor.c +8 -2
  141. data/src/core/lib/iomgr/load_file.c +6 -3
  142. data/src/core/lib/iomgr/lockfree_event.c +238 -0
  143. data/src/core/{ext/client_channel/initial_connect_string.h → lib/iomgr/lockfree_event.h} +17 -13
  144. data/src/core/lib/iomgr/pollset.h +4 -0
  145. data/src/core/lib/iomgr/pollset_windows.c +2 -2
  146. data/src/core/lib/iomgr/port.h +9 -0
  147. data/src/core/lib/iomgr/resolve_address_posix.c +15 -9
  148. data/src/core/lib/iomgr/resolve_address_uv.c +8 -6
  149. data/src/core/lib/iomgr/resolve_address_windows.c +2 -2
  150. data/src/core/lib/iomgr/resource_quota.c +19 -4
  151. data/src/core/lib/iomgr/resource_quota.h +2 -0
  152. data/src/core/lib/iomgr/sockaddr_utils.c +3 -1
  153. data/src/core/lib/iomgr/socket_factory_posix.c +110 -0
  154. data/src/core/lib/iomgr/socket_factory_posix.h +90 -0
  155. data/src/core/lib/iomgr/socket_utils_common_posix.c +25 -9
  156. data/src/core/lib/iomgr/socket_utils_posix.h +7 -0
  157. data/src/core/lib/iomgr/tcp_client.h +0 -4
  158. data/src/core/lib/iomgr/tcp_client_posix.c +15 -31
  159. data/src/core/lib/iomgr/tcp_client_uv.c +10 -6
  160. data/src/core/lib/iomgr/tcp_client_windows.c +9 -19
  161. data/src/core/lib/iomgr/tcp_posix.c +111 -22
  162. data/src/core/lib/iomgr/tcp_posix.h +3 -4
  163. data/src/core/lib/iomgr/tcp_server_posix.c +39 -417
  164. data/src/core/lib/iomgr/tcp_server_utils_posix.h +135 -0
  165. data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +221 -0
  166. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c +196 -0
  167. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c +49 -0
  168. data/src/core/lib/iomgr/tcp_server_uv.c +43 -16
  169. data/src/core/lib/iomgr/tcp_server_windows.c +10 -22
  170. data/src/core/lib/iomgr/tcp_uv.c +16 -13
  171. data/src/core/lib/iomgr/tcp_windows.c +24 -12
  172. data/src/core/lib/iomgr/tcp_windows.h +2 -2
  173. data/src/core/lib/iomgr/timer.h +3 -0
  174. data/src/core/lib/iomgr/timer_generic.c +257 -72
  175. data/src/core/lib/iomgr/timer_generic.h +1 -1
  176. data/src/core/lib/iomgr/timer_heap.c +8 -8
  177. data/src/core/lib/iomgr/udp_server.c +54 -24
  178. data/src/core/lib/iomgr/udp_server.h +7 -7
  179. data/src/core/lib/iomgr/unix_sockets_posix.c +1 -1
  180. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +2 -1
  181. data/src/core/lib/iomgr/wakeup_fd_posix.h +1 -1
  182. data/src/core/lib/profiling/basic_timers.c +1 -1
  183. data/src/core/lib/security/credentials/credentials.h +1 -1
  184. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +10 -9
  185. data/src/core/lib/security/credentials/jwt/json_token.c +1 -1
  186. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +2 -2
  187. data/src/core/lib/security/transport/client_auth_filter.c +33 -26
  188. data/src/core/lib/security/transport/secure_endpoint.c +8 -5
  189. data/src/core/lib/security/transport/security_connector.c +37 -37
  190. data/src/core/lib/security/transport/security_connector.h +1 -1
  191. data/src/core/lib/security/transport/security_handshaker.c +15 -12
  192. data/src/core/lib/security/transport/server_auth_filter.c +20 -18
  193. data/src/core/lib/security/transport/tsi_error.c +5 -3
  194. data/src/core/lib/security/transport/tsi_error.h +1 -1
  195. data/src/core/lib/{security/util → slice}/b64.c +21 -6
  196. data/src/core/lib/{security/util → slice}/b64.h +16 -4
  197. data/src/core/lib/slice/slice.c +4 -2
  198. data/src/core/lib/slice/slice_buffer.c +16 -14
  199. data/src/core/lib/support/arena.c +98 -0
  200. data/src/core/{ext/client_channel/initial_connect_string.c → lib/support/arena.h} +17 -15
  201. data/src/core/{ext/client_channel/default_initial_connect_string.c → lib/support/atm.c} +14 -5
  202. data/src/core/lib/support/cpu_linux.c +5 -0
  203. data/src/core/lib/support/sync.c +4 -0
  204. data/src/core/lib/support/time.c +4 -10
  205. data/src/core/lib/support/wrap_memcpy.c +3 -1
  206. data/src/core/lib/surface/call.c +252 -221
  207. data/src/core/lib/surface/channel.c +72 -21
  208. data/src/core/lib/surface/channel.h +8 -0
  209. data/src/core/lib/surface/completion_queue.c +2 -3
  210. data/src/core/lib/surface/completion_queue_factory.c +77 -0
  211. data/src/core/lib/surface/completion_queue_factory.h +51 -0
  212. data/src/core/lib/surface/init_secure.c +3 -1
  213. data/src/core/lib/surface/lame_client.c +18 -14
  214. data/src/core/lib/surface/server.c +43 -41
  215. data/src/core/lib/surface/validate_metadata.c +8 -4
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.h +1 -1
  218. data/src/core/lib/transport/connectivity_state.c +2 -1
  219. data/src/core/lib/transport/error_utils.c +17 -17
  220. data/src/core/lib/transport/error_utils.h +1 -1
  221. data/src/core/lib/transport/metadata_batch.c +6 -7
  222. data/src/core/lib/transport/pid_controller.c +1 -0
  223. data/src/core/lib/transport/service_config.c +12 -0
  224. data/src/core/lib/transport/service_config.h +6 -0
  225. data/src/core/lib/transport/transport.c +29 -17
  226. data/src/core/lib/transport/transport.h +85 -42
  227. data/src/core/lib/transport/transport_impl.h +5 -3
  228. data/src/core/lib/transport/transport_op_string.c +20 -14
  229. data/src/core/plugin_registry/grpc_plugin_registry.c +8 -0
  230. data/src/core/{lib/tsi → tsi}/fake_transport_security.c +2 -2
  231. data/src/core/{lib/tsi → tsi}/fake_transport_security.h +4 -4
  232. data/src/core/{lib/tsi → tsi}/ssl_transport_security.c +40 -79
  233. data/src/core/{lib/tsi → tsi}/ssl_transport_security.h +44 -21
  234. data/src/core/{lib/tsi → tsi}/ssl_types.h +3 -3
  235. data/src/core/{lib/tsi → tsi}/transport_security.c +2 -2
  236. data/src/core/{lib/tsi → tsi}/transport_security.h +4 -4
  237. data/src/core/{lib/tsi → tsi}/transport_security_interface.h +3 -3
  238. data/src/ruby/ext/grpc/extconf.rb +1 -0
  239. data/src/ruby/ext/grpc/rb_call_credentials.c +2 -2
  240. data/src/ruby/ext/grpc/rb_channel.c +520 -93
  241. data/src/ruby/ext/grpc/rb_channel.h +2 -0
  242. data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -0
  243. data/src/ruby/ext/grpc/rb_compression_options.c +5 -2
  244. data/src/ruby/ext/grpc/rb_event_thread.c +6 -6
  245. data/src/ruby/ext/grpc/rb_grpc.c +29 -7
  246. data/src/ruby/ext/grpc/rb_grpc.h +2 -0
  247. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +10 -0
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +15 -0
  249. data/src/ruby/ext/grpc/rb_server.c +5 -3
  250. data/src/ruby/lib/grpc/version.rb +1 -1
  251. data/src/ruby/spec/channel_connection_spec.rb +173 -0
  252. data/src/ruby/spec/channel_spec.rb +29 -0
  253. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +27 -17
  254. data/third_party/cares/ares_build.h +264 -0
  255. data/third_party/cares/cares/ares.h +636 -0
  256. data/third_party/cares/cares/ares__close_sockets.c +61 -0
  257. data/third_party/cares/cares/ares__get_hostent.c +261 -0
  258. data/third_party/cares/cares/ares__read_line.c +73 -0
  259. data/third_party/cares/cares/ares__timeval.c +111 -0
  260. data/third_party/cares/cares/ares_cancel.c +63 -0
  261. data/third_party/cares/cares/ares_create_query.c +202 -0
  262. data/third_party/cares/cares/ares_data.c +221 -0
  263. data/third_party/cares/cares/ares_data.h +72 -0
  264. data/third_party/cares/cares/ares_destroy.c +108 -0
  265. data/third_party/cares/cares/ares_dns.h +103 -0
  266. data/third_party/cares/cares/ares_expand_name.c +205 -0
  267. data/third_party/cares/cares/ares_expand_string.c +70 -0
  268. data/third_party/cares/cares/ares_fds.c +59 -0
  269. data/third_party/cares/cares/ares_free_hostent.c +41 -0
  270. data/third_party/cares/cares/ares_free_string.c +25 -0
  271. data/third_party/cares/cares/ares_getenv.c +30 -0
  272. data/third_party/cares/cares/ares_getenv.h +26 -0
  273. data/third_party/cares/cares/ares_gethostbyaddr.c +294 -0
  274. data/third_party/cares/cares/ares_gethostbyname.c +518 -0
  275. data/third_party/cares/cares/ares_getnameinfo.c +422 -0
  276. data/third_party/cares/cares/ares_getopt.c +122 -0
  277. data/third_party/cares/cares/ares_getopt.h +53 -0
  278. data/third_party/cares/cares/ares_getsock.c +66 -0
  279. data/third_party/cares/cares/ares_inet_net_pton.h +25 -0
  280. data/third_party/cares/cares/ares_init.c +2146 -0
  281. data/third_party/cares/cares/ares_iphlpapi.h +221 -0
  282. data/third_party/cares/cares/ares_ipv6.h +78 -0
  283. data/third_party/cares/cares/ares_library_init.c +167 -0
  284. data/third_party/cares/cares/ares_library_init.h +42 -0
  285. data/third_party/cares/cares/ares_llist.c +63 -0
  286. data/third_party/cares/cares/ares_llist.h +39 -0
  287. data/third_party/cares/cares/ares_mkquery.c +24 -0
  288. data/third_party/cares/cares/ares_nowarn.c +260 -0
  289. data/third_party/cares/cares/ares_nowarn.h +61 -0
  290. data/third_party/cares/cares/ares_options.c +402 -0
  291. data/third_party/cares/cares/ares_parse_a_reply.c +264 -0
  292. data/third_party/cares/cares/ares_parse_aaaa_reply.c +264 -0
  293. data/third_party/cares/cares/ares_parse_mx_reply.c +170 -0
  294. data/third_party/cares/cares/ares_parse_naptr_reply.c +188 -0
  295. data/third_party/cares/cares/ares_parse_ns_reply.c +183 -0
  296. data/third_party/cares/cares/ares_parse_ptr_reply.c +219 -0
  297. data/third_party/cares/cares/ares_parse_soa_reply.c +133 -0
  298. data/third_party/cares/cares/ares_parse_srv_reply.c +179 -0
  299. data/third_party/cares/cares/ares_parse_txt_reply.c +220 -0
  300. data/third_party/cares/cares/ares_platform.c +11035 -0
  301. data/third_party/cares/cares/ares_platform.h +43 -0
  302. data/third_party/cares/cares/ares_private.h +363 -0
  303. data/third_party/cares/cares/ares_process.c +1359 -0
  304. data/third_party/cares/cares/ares_query.c +186 -0
  305. data/third_party/cares/cares/ares_rules.h +125 -0
  306. data/third_party/cares/cares/ares_search.c +316 -0
  307. data/third_party/cares/cares/ares_send.c +131 -0
  308. data/third_party/cares/cares/ares_setup.h +217 -0
  309. data/third_party/cares/cares/ares_strcasecmp.c +66 -0
  310. data/third_party/cares/cares/ares_strcasecmp.h +30 -0
  311. data/third_party/cares/cares/ares_strdup.c +49 -0
  312. data/third_party/cares/cares/ares_strdup.h +24 -0
  313. data/third_party/cares/cares/ares_strerror.c +56 -0
  314. data/third_party/cares/cares/ares_timeout.c +88 -0
  315. data/third_party/cares/cares/ares_version.c +11 -0
  316. data/third_party/cares/cares/ares_version.h +24 -0
  317. data/third_party/cares/cares/ares_writev.c +79 -0
  318. data/third_party/cares/cares/bitncmp.c +59 -0
  319. data/third_party/cares/cares/bitncmp.h +26 -0
  320. data/third_party/cares/cares/config-win32.h +377 -0
  321. data/third_party/cares/cares/inet_net_pton.c +450 -0
  322. data/third_party/cares/cares/inet_ntop.c +208 -0
  323. data/third_party/cares/cares/setup_once.h +554 -0
  324. data/third_party/cares/cares/windows_port.c +22 -0
  325. data/third_party/cares/config_darwin/ares_config.h +523 -0
  326. data/third_party/cares/config_linux/ares_config.h +524 -0
  327. metadata +164 -68
@@ -0,0 +1,53 @@
1
+ #ifndef ARES_GETOPT_H
2
+ #define ARES_GETOPT_H
3
+
4
+ /*
5
+ * Copyright (c) 1987-2001 The Regents of the University of California.
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * A. Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * B. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ * C. Neither the names of the copyright holders nor the names of its
17
+ * contributors may be used to endorse or promote products derived from this
18
+ * software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
21
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ int ares_getopt(int nargc, char * const nargv[], const char *ostr);
35
+
36
+ #undef optarg
37
+ #undef optind
38
+ #undef opterr
39
+ #undef optopt
40
+ #undef optreset
41
+
42
+ #define optarg ares_optarg
43
+ #define optind ares_optind
44
+ #define opterr ares_opterr
45
+ #define optopt ares_optopt
46
+ #define optreset ares_optreset
47
+
48
+ extern char *optarg;
49
+ extern int optind;
50
+ extern int opterr;
51
+ extern int optopt;
52
+
53
+ #endif /* ARES_GETOPT_H */
@@ -0,0 +1,66 @@
1
+
2
+ /* Copyright (C) 2005 - 2010, Daniel Stenberg
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software and its
5
+ * documentation for any purpose and without fee is hereby granted, provided
6
+ * that the above copyright notice appear in all copies and that both that
7
+ * copyright notice and this permission notice appear in supporting
8
+ * documentation, and that the name of M.I.T. not be used in advertising or
9
+ * publicity pertaining to distribution of the software without specific,
10
+ * written prior permission. M.I.T. makes no representations about the
11
+ * suitability of this software for any purpose. It is provided "as is"
12
+ * without express or implied warranty.
13
+ */
14
+
15
+ #include "ares_setup.h"
16
+
17
+ #include "ares.h"
18
+ #include "ares_private.h"
19
+
20
+ int ares_getsock(ares_channel channel,
21
+ ares_socket_t *socks,
22
+ int numsocks) /* size of the 'socks' array */
23
+ {
24
+ struct server_state *server;
25
+ int i;
26
+ int sockindex=0;
27
+ int bitmap = 0;
28
+ unsigned int setbits = 0xffffffff;
29
+
30
+ /* Are there any active queries? */
31
+ int active_queries = !ares__is_list_empty(&(channel->all_queries));
32
+
33
+ for (i = 0; i < channel->nservers; i++)
34
+ {
35
+ server = &channel->servers[i];
36
+ /* We only need to register interest in UDP sockets if we have
37
+ * outstanding queries.
38
+ */
39
+ if (active_queries && server->udp_socket != ARES_SOCKET_BAD)
40
+ {
41
+ if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM)
42
+ break;
43
+ socks[sockindex] = server->udp_socket;
44
+ bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
45
+ sockindex++;
46
+ }
47
+ /* We always register for TCP events, because we want to know
48
+ * when the other side closes the connection, so we don't waste
49
+ * time trying to use a broken connection.
50
+ */
51
+ if (server->tcp_socket != ARES_SOCKET_BAD)
52
+ {
53
+ if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM)
54
+ break;
55
+ socks[sockindex] = server->tcp_socket;
56
+ bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
57
+
58
+ if (server->qhead && active_queries)
59
+ /* then the tcp socket is also writable! */
60
+ bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
61
+
62
+ sockindex++;
63
+ }
64
+ }
65
+ return bitmap;
66
+ }
@@ -0,0 +1,25 @@
1
+ #ifndef HEADER_CARES_INET_NET_PTON_H
2
+ #define HEADER_CARES_INET_NET_PTON_H
3
+
4
+ /* Copyright (C) 2005-2013 by Daniel Stenberg et al
5
+ *
6
+ * Permission to use, copy, modify, and distribute this
7
+ * software and its documentation for any purpose and without
8
+ * fee is hereby granted, provided that the above copyright
9
+ * notice appear in all copies and that both that copyright
10
+ * notice and this permission notice appear in supporting
11
+ * documentation, and that the name of M.I.T. not be used in
12
+ * advertising or publicity pertaining to distribution of the
13
+ * software without specific, written prior permission.
14
+ * M.I.T. makes no representations about the suitability of
15
+ * this software for any purpose. It is provided "as is"
16
+ * without express or implied warranty.
17
+ */
18
+
19
+ #ifdef HAVE_INET_NET_PTON
20
+ #define ares_inet_net_pton(w,x,y,z) inet_net_pton(w,x,y,z)
21
+ #else
22
+ int ares_inet_net_pton(int af, const char *src, void *dst, size_t size);
23
+ #endif
24
+
25
+ #endif /* HEADER_CARES_INET_NET_PTON_H */
@@ -0,0 +1,2146 @@
1
+
2
+ /* Copyright 1998 by the Massachusetts Institute of Technology.
3
+ * Copyright (C) 2007-2013 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_NETINET_IN_H
25
+ #include <netinet/in.h>
26
+ #endif
27
+
28
+ #ifdef HAVE_NETDB_H
29
+ #include <netdb.h>
30
+ #endif
31
+
32
+ #ifdef HAVE_ARPA_INET_H
33
+ #include <arpa/inet.h>
34
+ #endif
35
+
36
+ #ifdef HAVE_ARPA_NAMESER_H
37
+ # include <arpa/nameser.h>
38
+ #else
39
+ # include "nameser.h"
40
+ #endif
41
+ #ifdef HAVE_ARPA_NAMESER_COMPAT_H
42
+ # include <arpa/nameser_compat.h>
43
+ #endif
44
+
45
+ #if defined(ANDROID) || defined(__ANDROID__)
46
+ #include <sys/system_properties.h>
47
+ /* From the Bionic sources */
48
+ #define DNS_PROP_NAME_PREFIX "net.dns"
49
+ #define MAX_DNS_PROPERTIES 8
50
+ #endif
51
+
52
+ #if defined(CARES_USE_LIBRESOLV)
53
+ #include <resolv.h>
54
+ #endif
55
+
56
+ #include "ares.h"
57
+ #include "ares_inet_net_pton.h"
58
+ #include "ares_library_init.h"
59
+ #include "ares_nowarn.h"
60
+ #include "ares_platform.h"
61
+ #include "ares_private.h"
62
+
63
+ #ifdef WATT32
64
+ #undef WIN32 /* Redefined in MingW/MSVC headers */
65
+ #endif
66
+
67
+ static int init_by_options(ares_channel channel,
68
+ const struct ares_options *options,
69
+ int optmask);
70
+ static int init_by_environment(ares_channel channel);
71
+ static int init_by_resolv_conf(ares_channel channel);
72
+ static int init_by_defaults(ares_channel channel);
73
+
74
+ #ifndef WATT32
75
+ static int config_nameserver(struct server_state **servers, int *nservers,
76
+ char *str);
77
+ #endif
78
+ static int set_search(ares_channel channel, const char *str);
79
+ static int set_options(ares_channel channel, const char *str);
80
+ static const char *try_option(const char *p, const char *q, const char *opt);
81
+ static int init_id_key(rc4_key* key,int key_data_len);
82
+
83
+ static int config_sortlist(struct apattern **sortlist, int *nsort,
84
+ const char *str);
85
+ static int sortlist_alloc(struct apattern **sortlist, int *nsort,
86
+ struct apattern *pat);
87
+ static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
88
+ static void natural_mask(struct apattern *pat);
89
+ #if !defined(WIN32) && !defined(WATT32) && \
90
+ !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
91
+ static int config_domain(ares_channel channel, char *str);
92
+ static int config_lookup(ares_channel channel, const char *str,
93
+ const char *bindch, const char *altbindch,
94
+ const char *filech);
95
+ static char *try_config(char *s, const char *opt, char scc);
96
+ #endif
97
+
98
+ #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
99
+ x->nservers > -1 && \
100
+ x->ndomains > -1 && \
101
+ x->ndots > -1 && x->timeout > -1 && \
102
+ x->tries > -1)
103
+
104
+ int ares_init(ares_channel *channelptr)
105
+ {
106
+ return ares_init_options(channelptr, NULL, 0);
107
+ }
108
+
109
+ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
110
+ int optmask)
111
+ {
112
+ ares_channel channel;
113
+ int i;
114
+ int status = ARES_SUCCESS;
115
+ struct timeval now;
116
+
117
+ #ifdef CURLDEBUG
118
+ const char *env = getenv("CARES_MEMDEBUG");
119
+
120
+ if (env)
121
+ curl_memdebug(env);
122
+ env = getenv("CARES_MEMLIMIT");
123
+ if (env) {
124
+ char *endptr;
125
+ long num = strtol(env, &endptr, 10);
126
+ if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
127
+ curl_memlimit(num);
128
+ }
129
+ #endif
130
+
131
+ if (ares_library_initialized() != ARES_SUCCESS)
132
+ return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
133
+
134
+ channel = ares_malloc(sizeof(struct ares_channeldata));
135
+ if (!channel) {
136
+ *channelptr = NULL;
137
+ return ARES_ENOMEM;
138
+ }
139
+
140
+ now = ares__tvnow();
141
+
142
+ /* Set everything to distinguished values so we know they haven't
143
+ * been set yet.
144
+ */
145
+ channel->flags = -1;
146
+ channel->timeout = -1;
147
+ channel->tries = -1;
148
+ channel->ndots = -1;
149
+ channel->rotate = -1;
150
+ channel->udp_port = -1;
151
+ channel->tcp_port = -1;
152
+ channel->ednspsz = -1;
153
+ channel->socket_send_buffer_size = -1;
154
+ channel->socket_receive_buffer_size = -1;
155
+ channel->nservers = -1;
156
+ channel->ndomains = -1;
157
+ channel->nsort = -1;
158
+ channel->tcp_connection_generation = 0;
159
+ channel->lookups = NULL;
160
+ channel->domains = NULL;
161
+ channel->sortlist = NULL;
162
+ channel->servers = NULL;
163
+ channel->sock_state_cb = NULL;
164
+ channel->sock_state_cb_data = NULL;
165
+ channel->sock_create_cb = NULL;
166
+ channel->sock_create_cb_data = NULL;
167
+ channel->sock_config_cb = NULL;
168
+ channel->sock_config_cb_data = NULL;
169
+
170
+ channel->last_server = 0;
171
+ channel->last_timeout_processed = (time_t)now.tv_sec;
172
+
173
+ memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
174
+ channel->local_ip4 = 0;
175
+ memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
176
+
177
+ /* Initialize our lists of queries */
178
+ ares__init_list_head(&(channel->all_queries));
179
+ for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
180
+ {
181
+ ares__init_list_head(&(channel->queries_by_qid[i]));
182
+ }
183
+ for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
184
+ {
185
+ ares__init_list_head(&(channel->queries_by_timeout[i]));
186
+ }
187
+
188
+ /* Initialize configuration by each of the four sources, from highest
189
+ * precedence to lowest.
190
+ */
191
+
192
+ status = init_by_options(channel, options, optmask);
193
+ if (status != ARES_SUCCESS) {
194
+ DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
195
+ ares_strerror(status)));
196
+ /* If we fail to apply user-specified options, fail the whole init process */
197
+ goto done;
198
+ }
199
+ status = init_by_environment(channel);
200
+ if (status != ARES_SUCCESS)
201
+ DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
202
+ ares_strerror(status)));
203
+ if (status == ARES_SUCCESS) {
204
+ status = init_by_resolv_conf(channel);
205
+ if (status != ARES_SUCCESS)
206
+ DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
207
+ ares_strerror(status)));
208
+ }
209
+
210
+ /*
211
+ * No matter what failed or succeeded, seed defaults to provide
212
+ * useful behavior for things that we missed.
213
+ */
214
+ status = init_by_defaults(channel);
215
+ if (status != ARES_SUCCESS)
216
+ DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
217
+ ares_strerror(status)));
218
+
219
+ /* Generate random key */
220
+
221
+ if (status == ARES_SUCCESS) {
222
+ status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
223
+ if (status == ARES_SUCCESS)
224
+ channel->next_id = ares__generate_new_id(&channel->id_key);
225
+ else
226
+ DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
227
+ ares_strerror(status)));
228
+ }
229
+
230
+ done:
231
+ if (status != ARES_SUCCESS)
232
+ {
233
+ /* Something failed; clean up memory we may have allocated. */
234
+ if (channel->servers)
235
+ ares_free(channel->servers);
236
+ if (channel->domains)
237
+ {
238
+ for (i = 0; i < channel->ndomains; i++)
239
+ ares_free(channel->domains[i]);
240
+ ares_free(channel->domains);
241
+ }
242
+ if (channel->sortlist)
243
+ ares_free(channel->sortlist);
244
+ if(channel->lookups)
245
+ ares_free(channel->lookups);
246
+ ares_free(channel);
247
+ return status;
248
+ }
249
+
250
+ /* Trim to one server if ARES_FLAG_PRIMARY is set. */
251
+ if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
252
+ channel->nservers = 1;
253
+
254
+ ares__init_servers_state(channel);
255
+
256
+ *channelptr = channel;
257
+ return ARES_SUCCESS;
258
+ }
259
+
260
+ /* ares_dup() duplicates a channel handle with all its options and returns a
261
+ new channel handle */
262
+ int ares_dup(ares_channel *dest, ares_channel src)
263
+ {
264
+ struct ares_options opts;
265
+ struct ares_addr_port_node *servers;
266
+ int non_v4_default_port = 0;
267
+ int i, rc;
268
+ int optmask;
269
+
270
+ *dest = NULL; /* in case of failure return NULL explicitly */
271
+
272
+ /* First get the options supported by the old ares_save_options() function,
273
+ which is most of them */
274
+ rc = ares_save_options(src, &opts, &optmask);
275
+ if(rc)
276
+ {
277
+ ares_destroy_options(&opts);
278
+ return rc;
279
+ }
280
+
281
+ /* Then create the new channel with those options */
282
+ rc = ares_init_options(dest, &opts, optmask);
283
+
284
+ /* destroy the options copy to not leak any memory */
285
+ ares_destroy_options(&opts);
286
+
287
+ if(rc)
288
+ return rc;
289
+
290
+ /* Now clone the options that ares_save_options() doesn't support. */
291
+ (*dest)->sock_create_cb = src->sock_create_cb;
292
+ (*dest)->sock_create_cb_data = src->sock_create_cb_data;
293
+ (*dest)->sock_config_cb = src->sock_config_cb;
294
+ (*dest)->sock_config_cb_data = src->sock_config_cb_data;
295
+
296
+ strncpy((*dest)->local_dev_name, src->local_dev_name,
297
+ sizeof(src->local_dev_name));
298
+ (*dest)->local_ip4 = src->local_ip4;
299
+ memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
300
+
301
+ /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
302
+ for (i = 0; i < src->nservers; i++)
303
+ {
304
+ if ((src->servers[i].addr.family != AF_INET) ||
305
+ (src->servers[i].addr.udp_port != 0) ||
306
+ (src->servers[i].addr.tcp_port != 0)) {
307
+ non_v4_default_port++;
308
+ break;
309
+ }
310
+ }
311
+ if (non_v4_default_port) {
312
+ rc = ares_get_servers_ports(src, &servers);
313
+ if (rc != ARES_SUCCESS) {
314
+ ares_destroy(*dest);
315
+ *dest = NULL;
316
+ return rc;
317
+ }
318
+ rc = ares_set_servers_ports(*dest, servers);
319
+ ares_free_data(servers);
320
+ if (rc != ARES_SUCCESS) {
321
+ ares_destroy(*dest);
322
+ *dest = NULL;
323
+ return rc;
324
+ }
325
+ }
326
+
327
+ return ARES_SUCCESS; /* everything went fine */
328
+ }
329
+
330
+ /* Save options from initialized channel */
331
+ int ares_save_options(ares_channel channel, struct ares_options *options,
332
+ int *optmask)
333
+ {
334
+ int i, j;
335
+ int ipv4_nservers = 0;
336
+
337
+ /* Zero everything out */
338
+ memset(options, 0, sizeof(struct ares_options));
339
+
340
+ if (!ARES_CONFIG_CHECK(channel))
341
+ return ARES_ENODATA;
342
+
343
+ /* Traditionally the optmask wasn't saved in the channel struct so it was
344
+ recreated here. ROTATE is the first option that has no struct field of
345
+ its own in the public config struct */
346
+ (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
347
+ ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
348
+ ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
349
+ ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
350
+ (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
351
+
352
+ /* Copy easy stuff */
353
+ options->flags = channel->flags;
354
+
355
+ /* We return full millisecond resolution but that's only because we don't
356
+ set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
357
+ options->timeout = channel->timeout;
358
+ options->tries = channel->tries;
359
+ options->ndots = channel->ndots;
360
+ options->udp_port = ntohs(aresx_sitous(channel->udp_port));
361
+ options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
362
+ options->sock_state_cb = channel->sock_state_cb;
363
+ options->sock_state_cb_data = channel->sock_state_cb_data;
364
+
365
+ /* Copy IPv4 servers that use the default port */
366
+ if (channel->nservers) {
367
+ for (i = 0; i < channel->nservers; i++)
368
+ {
369
+ if ((channel->servers[i].addr.family == AF_INET) &&
370
+ (channel->servers[i].addr.udp_port == 0) &&
371
+ (channel->servers[i].addr.tcp_port == 0))
372
+ ipv4_nservers++;
373
+ }
374
+ if (ipv4_nservers) {
375
+ options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
376
+ if (!options->servers)
377
+ return ARES_ENOMEM;
378
+ for (i = j = 0; i < channel->nservers; i++)
379
+ {
380
+ if ((channel->servers[i].addr.family == AF_INET) &&
381
+ (channel->servers[i].addr.udp_port == 0) &&
382
+ (channel->servers[i].addr.tcp_port == 0))
383
+ memcpy(&options->servers[j++],
384
+ &channel->servers[i].addr.addrV4,
385
+ sizeof(channel->servers[i].addr.addrV4));
386
+ }
387
+ }
388
+ }
389
+ options->nservers = ipv4_nservers;
390
+
391
+ /* copy domains */
392
+ if (channel->ndomains) {
393
+ options->domains = ares_malloc(channel->ndomains * sizeof(char *));
394
+ if (!options->domains)
395
+ return ARES_ENOMEM;
396
+
397
+ for (i = 0; i < channel->ndomains; i++)
398
+ {
399
+ options->ndomains = i;
400
+ options->domains[i] = ares_strdup(channel->domains[i]);
401
+ if (!options->domains[i])
402
+ return ARES_ENOMEM;
403
+ }
404
+ }
405
+ options->ndomains = channel->ndomains;
406
+
407
+ /* copy lookups */
408
+ if (channel->lookups) {
409
+ options->lookups = ares_strdup(channel->lookups);
410
+ if (!options->lookups && channel->lookups)
411
+ return ARES_ENOMEM;
412
+ }
413
+
414
+ /* copy sortlist */
415
+ if (channel->nsort) {
416
+ options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
417
+ if (!options->sortlist)
418
+ return ARES_ENOMEM;
419
+ for (i = 0; i < channel->nsort; i++)
420
+ options->sortlist[i] = channel->sortlist[i];
421
+ }
422
+ options->nsort = channel->nsort;
423
+
424
+ return ARES_SUCCESS;
425
+ }
426
+
427
+ static int init_by_options(ares_channel channel,
428
+ const struct ares_options *options,
429
+ int optmask)
430
+ {
431
+ int i;
432
+
433
+ /* Easy stuff. */
434
+ if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
435
+ channel->flags = options->flags;
436
+ if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
437
+ channel->timeout = options->timeout;
438
+ else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
439
+ channel->timeout = options->timeout * 1000;
440
+ if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
441
+ channel->tries = options->tries;
442
+ if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
443
+ channel->ndots = options->ndots;
444
+ if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
445
+ channel->rotate = 1;
446
+ if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
447
+ channel->rotate = 0;
448
+ if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
449
+ channel->udp_port = htons(options->udp_port);
450
+ if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
451
+ channel->tcp_port = htons(options->tcp_port);
452
+ if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
453
+ {
454
+ channel->sock_state_cb = options->sock_state_cb;
455
+ channel->sock_state_cb_data = options->sock_state_cb_data;
456
+ }
457
+ if ((optmask & ARES_OPT_SOCK_SNDBUF)
458
+ && channel->socket_send_buffer_size == -1)
459
+ channel->socket_send_buffer_size = options->socket_send_buffer_size;
460
+ if ((optmask & ARES_OPT_SOCK_RCVBUF)
461
+ && channel->socket_receive_buffer_size == -1)
462
+ channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
463
+
464
+ if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
465
+ channel->ednspsz = options->ednspsz;
466
+
467
+ /* Copy the IPv4 servers, if given. */
468
+ if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
469
+ {
470
+ /* Avoid zero size allocations at any cost */
471
+ if (options->nservers > 0)
472
+ {
473
+ channel->servers =
474
+ ares_malloc(options->nservers * sizeof(struct server_state));
475
+ if (!channel->servers)
476
+ return ARES_ENOMEM;
477
+ for (i = 0; i < options->nservers; i++)
478
+ {
479
+ channel->servers[i].addr.family = AF_INET;
480
+ channel->servers[i].addr.udp_port = 0;
481
+ channel->servers[i].addr.tcp_port = 0;
482
+ memcpy(&channel->servers[i].addr.addrV4,
483
+ &options->servers[i],
484
+ sizeof(channel->servers[i].addr.addrV4));
485
+ }
486
+ }
487
+ channel->nservers = options->nservers;
488
+ }
489
+
490
+ /* Copy the domains, if given. Keep channel->ndomains consistent so
491
+ * we can clean up in case of error.
492
+ */
493
+ if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
494
+ {
495
+ /* Avoid zero size allocations at any cost */
496
+ if (options->ndomains > 0)
497
+ {
498
+ channel->domains = ares_malloc(options->ndomains * sizeof(char *));
499
+ if (!channel->domains)
500
+ return ARES_ENOMEM;
501
+ for (i = 0; i < options->ndomains; i++)
502
+ {
503
+ channel->ndomains = i;
504
+ channel->domains[i] = ares_strdup(options->domains[i]);
505
+ if (!channel->domains[i])
506
+ return ARES_ENOMEM;
507
+ }
508
+ }
509
+ channel->ndomains = options->ndomains;
510
+ }
511
+
512
+ /* Set lookups, if given. */
513
+ if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
514
+ {
515
+ channel->lookups = ares_strdup(options->lookups);
516
+ if (!channel->lookups)
517
+ return ARES_ENOMEM;
518
+ }
519
+
520
+ /* copy sortlist */
521
+ if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1)) {
522
+ if (options->nsort > 0) {
523
+ channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
524
+ if (!channel->sortlist)
525
+ return ARES_ENOMEM;
526
+ for (i = 0; i < options->nsort; i++)
527
+ channel->sortlist[i] = options->sortlist[i];
528
+ }
529
+ channel->nsort = options->nsort;
530
+ }
531
+
532
+ channel->optmask = optmask;
533
+
534
+ return ARES_SUCCESS;
535
+ }
536
+
537
+ static int init_by_environment(ares_channel channel)
538
+ {
539
+ const char *localdomain, *res_options;
540
+ int status;
541
+
542
+ localdomain = getenv("LOCALDOMAIN");
543
+ if (localdomain && channel->ndomains == -1)
544
+ {
545
+ status = set_search(channel, localdomain);
546
+ if (status != ARES_SUCCESS)
547
+ return status;
548
+ }
549
+
550
+ res_options = getenv("RES_OPTIONS");
551
+ if (res_options)
552
+ {
553
+ status = set_options(channel, res_options);
554
+ if (status != ARES_SUCCESS)
555
+ return status; /* LCOV_EXCL_LINE: set_options() never fails */
556
+ }
557
+
558
+ return ARES_SUCCESS;
559
+ }
560
+
561
+ #ifdef WIN32
562
+ /*
563
+ * get_REG_SZ()
564
+ *
565
+ * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
566
+ * to the name of the registry leaf key to be queried, fetch it's string
567
+ * value and return a pointer in *outptr to a newly allocated memory area
568
+ * holding it as a null-terminated string.
569
+ *
570
+ * Returns 0 and nullifies *outptr upon inability to return a string value.
571
+ *
572
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
573
+ *
574
+ * Supported on Windows NT 3.5 and newer.
575
+ */
576
+ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
577
+ {
578
+ DWORD size = 0;
579
+ int res;
580
+
581
+ *outptr = NULL;
582
+
583
+ /* Find out size of string stored in registry */
584
+ res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size);
585
+ if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
586
+ return 0;
587
+
588
+ /* Allocate buffer of indicated size plus one given that string
589
+ might have been stored without null termination */
590
+ *outptr = ares_malloc(size+1);
591
+ if (!*outptr)
592
+ return 0;
593
+
594
+ /* Get the value for real */
595
+ res = RegQueryValueEx(hKey, leafKeyName, 0, NULL,
596
+ (unsigned char *)*outptr, &size);
597
+ if ((res != ERROR_SUCCESS) || (size == 1))
598
+ {
599
+ ares_free(*outptr);
600
+ *outptr = NULL;
601
+ return 0;
602
+ }
603
+
604
+ /* Null terminate buffer allways */
605
+ *(*outptr + size) = '\0';
606
+
607
+ return 1;
608
+ }
609
+
610
+ /*
611
+ * get_REG_SZ_9X()
612
+ *
613
+ * Functionally identical to get_REG_SZ()
614
+ *
615
+ * Supported on Windows 95, 98 and ME.
616
+ */
617
+ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
618
+ {
619
+ DWORD dataType = 0;
620
+ DWORD size = 0;
621
+ int res;
622
+
623
+ *outptr = NULL;
624
+
625
+ /* Find out size of string stored in registry */
626
+ res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size);
627
+ if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
628
+ return 0;
629
+
630
+ /* Allocate buffer of indicated size plus one given that string
631
+ might have been stored without null termination */
632
+ *outptr = ares_malloc(size+1);
633
+ if (!*outptr)
634
+ return 0;
635
+
636
+ /* Get the value for real */
637
+ res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType,
638
+ (unsigned char *)*outptr, &size);
639
+ if ((res != ERROR_SUCCESS) || (size == 1))
640
+ {
641
+ ares_free(*outptr);
642
+ *outptr = NULL;
643
+ return 0;
644
+ }
645
+
646
+ /* Null terminate buffer allways */
647
+ *(*outptr + size) = '\0';
648
+
649
+ return 1;
650
+ }
651
+
652
+ /*
653
+ * get_enum_REG_SZ()
654
+ *
655
+ * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
656
+ * pointer to the name of the registry leaf key to be queried, parent key
657
+ * is enumerated searching in child keys for given leaf key name and its
658
+ * associated string value. When located, this returns a pointer in *outptr
659
+ * to a newly allocated memory area holding it as a null-terminated string.
660
+ *
661
+ * Returns 0 and nullifies *outptr upon inability to return a string value.
662
+ *
663
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
664
+ *
665
+ * Supported on Windows NT 3.5 and newer.
666
+ */
667
+ static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
668
+ char **outptr)
669
+ {
670
+ char enumKeyName[256];
671
+ DWORD enumKeyNameBuffSize;
672
+ DWORD enumKeyIdx = 0;
673
+ HKEY hKeyEnum;
674
+ int gotString;
675
+ int res;
676
+
677
+ *outptr = NULL;
678
+
679
+ for(;;)
680
+ {
681
+ enumKeyNameBuffSize = sizeof(enumKeyName);
682
+ res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName,
683
+ &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
684
+ if (res != ERROR_SUCCESS)
685
+ break;
686
+ res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
687
+ &hKeyEnum);
688
+ if (res != ERROR_SUCCESS)
689
+ continue;
690
+ gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
691
+ RegCloseKey(hKeyEnum);
692
+ if (gotString)
693
+ break;
694
+ }
695
+
696
+ if (!*outptr)
697
+ return 0;
698
+
699
+ return 1;
700
+ }
701
+
702
+ /*
703
+ * get_DNS_Registry_9X()
704
+ *
705
+ * Functionally identical to get_DNS_Registry()
706
+ *
707
+ * Implementation supports Windows 95, 98 and ME.
708
+ */
709
+ static int get_DNS_Registry_9X(char **outptr)
710
+ {
711
+ HKEY hKey_VxD_MStcp;
712
+ int gotString;
713
+ int res;
714
+
715
+ *outptr = NULL;
716
+
717
+ res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
718
+ &hKey_VxD_MStcp);
719
+ if (res != ERROR_SUCCESS)
720
+ return 0;
721
+
722
+ gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
723
+ RegCloseKey(hKey_VxD_MStcp);
724
+
725
+ if (!gotString || !*outptr)
726
+ return 0;
727
+
728
+ return 1;
729
+ }
730
+
731
+ /*
732
+ * get_DNS_Registry_NT()
733
+ *
734
+ * Functionally identical to get_DNS_Registry()
735
+ *
736
+ * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
737
+ *
738
+ * Implementation supports Windows NT 3.5 and newer.
739
+ */
740
+ static int get_DNS_Registry_NT(char **outptr)
741
+ {
742
+ HKEY hKey_Interfaces = NULL;
743
+ HKEY hKey_Tcpip_Parameters;
744
+ int gotString;
745
+ int res;
746
+
747
+ *outptr = NULL;
748
+
749
+ res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
750
+ &hKey_Tcpip_Parameters);
751
+ if (res != ERROR_SUCCESS)
752
+ return 0;
753
+
754
+ /*
755
+ ** Global DNS settings override adapter specific parameters when both
756
+ ** are set. Additionally static DNS settings override DHCP-configured
757
+ ** parameters when both are set.
758
+ */
759
+
760
+ /* Global DNS static parameters */
761
+ gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
762
+ if (gotString)
763
+ goto done;
764
+
765
+ /* Global DNS DHCP-configured parameters */
766
+ gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
767
+ if (gotString)
768
+ goto done;
769
+
770
+ /* Try adapter specific parameters */
771
+ res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0,
772
+ KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
773
+ &hKey_Interfaces);
774
+ if (res != ERROR_SUCCESS)
775
+ {
776
+ hKey_Interfaces = NULL;
777
+ goto done;
778
+ }
779
+
780
+ /* Adapter specific DNS static parameters */
781
+ gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
782
+ if (gotString)
783
+ goto done;
784
+
785
+ /* Adapter specific DNS DHCP-configured parameters */
786
+ gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
787
+
788
+ done:
789
+ if (hKey_Interfaces)
790
+ RegCloseKey(hKey_Interfaces);
791
+
792
+ RegCloseKey(hKey_Tcpip_Parameters);
793
+
794
+ if (!gotString || !*outptr)
795
+ return 0;
796
+
797
+ return 1;
798
+ }
799
+
800
+ /*
801
+ * get_DNS_Registry()
802
+ *
803
+ * Locates DNS info in the registry. When located, this returns a pointer
804
+ * in *outptr to a newly allocated memory area holding a null-terminated
805
+ * string with a space or comma seperated list of DNS IP addresses.
806
+ *
807
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
808
+ *
809
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
810
+ */
811
+ static int get_DNS_Registry(char **outptr)
812
+ {
813
+ win_platform platform;
814
+ int gotString = 0;
815
+
816
+ *outptr = NULL;
817
+
818
+ platform = ares__getplatform();
819
+
820
+ if (platform == WIN_NT)
821
+ gotString = get_DNS_Registry_NT(outptr);
822
+ else if (platform == WIN_9X)
823
+ gotString = get_DNS_Registry_9X(outptr);
824
+
825
+ if (!gotString)
826
+ return 0;
827
+
828
+ return 1;
829
+ }
830
+
831
+ /*
832
+ * commajoin()
833
+ *
834
+ * RTF code.
835
+ */
836
+ static void commajoin(char **dst, const char *src)
837
+ {
838
+ char *tmp;
839
+
840
+ if (*dst)
841
+ {
842
+ tmp = ares_malloc(strlen(*dst) + strlen(src) + 2);
843
+ if (!tmp)
844
+ return;
845
+ sprintf(tmp, "%s,%s", *dst, src);
846
+ ares_free(*dst);
847
+ *dst = tmp;
848
+ }
849
+ else
850
+ {
851
+ *dst = ares_malloc(strlen(src) + 1);
852
+ if (!*dst)
853
+ return;
854
+ strcpy(*dst, src);
855
+ }
856
+ }
857
+
858
+ /*
859
+ * get_DNS_NetworkParams()
860
+ *
861
+ * Locates DNS info using GetNetworkParams() function from the Internet
862
+ * Protocol Helper (IP Helper) API. When located, this returns a pointer
863
+ * in *outptr to a newly allocated memory area holding a null-terminated
864
+ * string with a space or comma seperated list of DNS IP addresses.
865
+ *
866
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
867
+ *
868
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
869
+ *
870
+ * Implementation supports Windows 98 and newer.
871
+ *
872
+ * Note: Ancient PSDK required in order to build a W98 target.
873
+ */
874
+ static int get_DNS_NetworkParams(char **outptr)
875
+ {
876
+ FIXED_INFO *fi, *newfi;
877
+ struct ares_addr namesrvr;
878
+ char *txtaddr;
879
+ IP_ADDR_STRING *ipAddr;
880
+ int res;
881
+ DWORD size = sizeof (*fi);
882
+
883
+ *outptr = NULL;
884
+
885
+ /* Verify run-time availability of GetNetworkParams() */
886
+ if (ares_fpGetNetworkParams == ZERO_NULL)
887
+ return 0;
888
+
889
+ fi = ares_malloc(size);
890
+ if (!fi)
891
+ return 0;
892
+
893
+ res = (*ares_fpGetNetworkParams) (fi, &size);
894
+ if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
895
+ goto done;
896
+
897
+ newfi = ares_realloc(fi, size);
898
+ if (!newfi)
899
+ goto done;
900
+
901
+ fi = newfi;
902
+ res = (*ares_fpGetNetworkParams) (fi, &size);
903
+ if (res != ERROR_SUCCESS)
904
+ goto done;
905
+
906
+ for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
907
+ {
908
+ txtaddr = &ipAddr->IpAddress.String[0];
909
+
910
+ /* Validate converting textual address to binary format. */
911
+ if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
912
+ {
913
+ if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
914
+ (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
915
+ continue;
916
+ }
917
+ else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
918
+ {
919
+ if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
920
+ sizeof(namesrvr.addrV6)) == 0)
921
+ continue;
922
+ }
923
+ else
924
+ continue;
925
+
926
+ commajoin(outptr, txtaddr);
927
+
928
+ if (!*outptr)
929
+ break;
930
+ }
931
+
932
+ done:
933
+ if (fi)
934
+ ares_free(fi);
935
+
936
+ if (!*outptr)
937
+ return 0;
938
+
939
+ return 1;
940
+ }
941
+
942
+ /*
943
+ * get_DNS_AdaptersAddresses()
944
+ *
945
+ * Locates DNS info using GetAdaptersAddresses() function from the Internet
946
+ * Protocol Helper (IP Helper) API. When located, this returns a pointer
947
+ * in *outptr to a newly allocated memory area holding a null-terminated
948
+ * string with a space or comma seperated list of DNS IP addresses.
949
+ *
950
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
951
+ *
952
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
953
+ *
954
+ * Implementation supports Windows XP and newer.
955
+ */
956
+ #define IPAA_INITIAL_BUF_SZ 15 * 1024
957
+ #define IPAA_MAX_TRIES 3
958
+ static int get_DNS_AdaptersAddresses(char **outptr)
959
+ {
960
+ IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
961
+ IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
962
+ ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
963
+ ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
964
+ ULONG AddrFlags = 0;
965
+ int trying = IPAA_MAX_TRIES;
966
+ int res;
967
+
968
+ union {
969
+ struct sockaddr *sa;
970
+ struct sockaddr_in *sa4;
971
+ struct sockaddr_in6 *sa6;
972
+ } namesrvr;
973
+
974
+ char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
975
+
976
+ *outptr = NULL;
977
+
978
+ /* Verify run-time availability of GetAdaptersAddresses() */
979
+ if (ares_fpGetAdaptersAddresses == ZERO_NULL)
980
+ return 0;
981
+
982
+ ipaa = ares_malloc(Bufsz);
983
+ if (!ipaa)
984
+ return 0;
985
+
986
+ /* Usually this call suceeds with initial buffer size */
987
+ res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
988
+ ipaa, &ReqBufsz);
989
+ if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
990
+ goto done;
991
+
992
+ while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
993
+ {
994
+ if (Bufsz < ReqBufsz)
995
+ {
996
+ newipaa = ares_realloc(ipaa, ReqBufsz);
997
+ if (!newipaa)
998
+ goto done;
999
+ Bufsz = ReqBufsz;
1000
+ ipaa = newipaa;
1001
+ }
1002
+ res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1003
+ ipaa, &ReqBufsz);
1004
+ if (res == ERROR_SUCCESS)
1005
+ break;
1006
+ }
1007
+ if (res != ERROR_SUCCESS)
1008
+ goto done;
1009
+
1010
+ for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1011
+ {
1012
+ if(ipaaEntry->OperStatus != IfOperStatusUp)
1013
+ continue;
1014
+
1015
+ for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1016
+ ipaDNSAddr;
1017
+ ipaDNSAddr = ipaDNSAddr->Next)
1018
+ {
1019
+ namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1020
+
1021
+ if (namesrvr.sa->sa_family == AF_INET)
1022
+ {
1023
+ if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1024
+ (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
1025
+ continue;
1026
+ if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1027
+ txtaddr, sizeof(txtaddr)))
1028
+ continue;
1029
+ }
1030
+ else if (namesrvr.sa->sa_family == AF_INET6)
1031
+ {
1032
+ if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1033
+ sizeof(namesrvr.sa6->sin6_addr)) == 0)
1034
+ continue;
1035
+ if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1036
+ txtaddr, sizeof(txtaddr)))
1037
+ continue;
1038
+ }
1039
+ else
1040
+ continue;
1041
+
1042
+ commajoin(outptr, txtaddr);
1043
+
1044
+ if (!*outptr)
1045
+ goto done;
1046
+ }
1047
+ }
1048
+
1049
+ done:
1050
+ if (ipaa)
1051
+ ares_free(ipaa);
1052
+
1053
+ if (!*outptr)
1054
+ return 0;
1055
+
1056
+ return 1;
1057
+ }
1058
+
1059
+ /*
1060
+ * get_DNS_Windows()
1061
+ *
1062
+ * Locates DNS info from Windows employing most suitable methods available at
1063
+ * run-time no matter which Windows version it is. When located, this returns
1064
+ * a pointer in *outptr to a newly allocated memory area holding a string with
1065
+ * a space or comma seperated list of DNS IP addresses, null-terminated.
1066
+ *
1067
+ * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1068
+ *
1069
+ * Returns 1 and sets *outptr when returning a dynamically allocated string.
1070
+ *
1071
+ * Implementation supports Windows 95 and newer.
1072
+ */
1073
+ static int get_DNS_Windows(char **outptr)
1074
+ {
1075
+ /*
1076
+ Use GetNetworkParams First in case of
1077
+ multiple adapter is enabled on this machine.
1078
+ GetAdaptersAddresses will retrive dummy dns servers.
1079
+ That will slowing DNS lookup.
1080
+ */
1081
+ /* Try using IP helper API GetNetworkParams() */
1082
+ if (get_DNS_NetworkParams(outptr))
1083
+ return 1;
1084
+
1085
+ /* Try using IP helper API GetAdaptersAddresses() */
1086
+ if (get_DNS_AdaptersAddresses(outptr))
1087
+ return 1;
1088
+
1089
+ /* Fall-back to registry information */
1090
+ return get_DNS_Registry(outptr);
1091
+ }
1092
+ #endif
1093
+
1094
+ static int init_by_resolv_conf(ares_channel channel)
1095
+ {
1096
+ #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1097
+ !defined(CARES_USE_LIBRESOLV)
1098
+ char *line = NULL;
1099
+ #endif
1100
+ int status = -1, nservers = 0, nsort = 0;
1101
+ struct server_state *servers = NULL;
1102
+ struct apattern *sortlist = NULL;
1103
+
1104
+ #ifdef WIN32
1105
+
1106
+ if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1107
+ return ARES_SUCCESS;
1108
+
1109
+ if (get_DNS_Windows(&line))
1110
+ {
1111
+ status = config_nameserver(&servers, &nservers, line);
1112
+ ares_free(line);
1113
+ }
1114
+
1115
+ if (status == ARES_SUCCESS)
1116
+ status = ARES_EOF;
1117
+ else
1118
+ /* Catch the case when all the above checks fail (which happens when there
1119
+ is no network card or the cable is unplugged) */
1120
+ status = ARES_EFILE;
1121
+
1122
+ #elif defined(__riscos__)
1123
+
1124
+ /* Under RISC OS, name servers are listed in the
1125
+ system variable Inet$Resolvers, space separated. */
1126
+
1127
+ line = getenv("Inet$Resolvers");
1128
+ status = ARES_EOF;
1129
+ if (line) {
1130
+ char *resolvers = ares_strdup(line), *pos, *space;
1131
+
1132
+ if (!resolvers)
1133
+ return ARES_ENOMEM;
1134
+
1135
+ pos = resolvers;
1136
+ do {
1137
+ space = strchr(pos, ' ');
1138
+ if (space)
1139
+ *space = '\0';
1140
+ status = config_nameserver(&servers, &nservers, pos);
1141
+ if (status != ARES_SUCCESS)
1142
+ break;
1143
+ pos = space + 1;
1144
+ } while (space);
1145
+
1146
+ if (status == ARES_SUCCESS)
1147
+ status = ARES_EOF;
1148
+
1149
+ ares_free(resolvers);
1150
+ }
1151
+
1152
+ #elif defined(WATT32)
1153
+ int i;
1154
+
1155
+ sock_init();
1156
+ for (i = 0; def_nameservers[i]; i++)
1157
+ ;
1158
+ if (i == 0)
1159
+ return ARES_SUCCESS; /* use localhost DNS server */
1160
+
1161
+ nservers = i;
1162
+ servers = ares_malloc(sizeof(struct server_state));
1163
+ if (!servers)
1164
+ return ARES_ENOMEM;
1165
+ memset(servers, 0, sizeof(struct server_state));
1166
+
1167
+ for (i = 0; def_nameservers[i]; i++)
1168
+ {
1169
+ servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1170
+ servers[i].addr.family = AF_INET;
1171
+ servers[i].addr.udp_port = 0;
1172
+ servers[i].addr.tcp_port = 0;
1173
+ }
1174
+ status = ARES_EOF;
1175
+
1176
+ #elif defined(ANDROID) || defined(__ANDROID__)
1177
+ unsigned int i;
1178
+ char propname[PROP_NAME_MAX];
1179
+ char propvalue[PROP_VALUE_MAX]="";
1180
+
1181
+ for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1182
+ snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1183
+ if (__system_property_get(propname, propvalue) < 1) {
1184
+ status = ARES_EOF;
1185
+ break;
1186
+ }
1187
+ status = config_nameserver(&servers, &nservers, propvalue);
1188
+ if (status != ARES_SUCCESS)
1189
+ break;
1190
+ status = ARES_EOF;
1191
+ }
1192
+ #elif defined(CARES_USE_LIBRESOLV)
1193
+ struct __res_state res;
1194
+ memset(&res, 0, sizeof(res));
1195
+ int result = res_ninit(&res);
1196
+ if (result == 0 && (res.options & RES_INIT)) {
1197
+ status = ARES_EOF;
1198
+
1199
+ if (channel->nservers == -1) {
1200
+ union res_sockaddr_union addr[MAXNS];
1201
+ int nscount = res_getservers(&res, addr, MAXNS);
1202
+ for (int i = 0; i < nscount; ++i) {
1203
+ char str[INET6_ADDRSTRLEN];
1204
+ int config_status;
1205
+ sa_family_t family = addr[i].sin.sin_family;
1206
+ if (family == AF_INET) {
1207
+ ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
1208
+ } else if (family == AF_INET6) {
1209
+ ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
1210
+ } else {
1211
+ continue;
1212
+ }
1213
+
1214
+ config_status = config_nameserver(&servers, &nservers, str);
1215
+ if (config_status != ARES_SUCCESS) {
1216
+ status = config_status;
1217
+ break;
1218
+ }
1219
+ }
1220
+ }
1221
+ if (channel->ndomains == -1) {
1222
+ int entries = 0;
1223
+ while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1224
+ entries++;
1225
+
1226
+ channel->domains = ares_malloc(entries * sizeof(char *));
1227
+ if (!channel->domains) {
1228
+ status = ARES_ENOMEM;
1229
+ } else {
1230
+ channel->ndomains = entries;
1231
+ for (int i = 0; i < channel->ndomains; ++i) {
1232
+ channel->domains[i] = ares_strdup(res.dnsrch[i]);
1233
+ if (!channel->domains[i])
1234
+ status = ARES_ENOMEM;
1235
+ }
1236
+ }
1237
+ }
1238
+ if (channel->ndots == -1)
1239
+ channel->ndots = res.ndots;
1240
+ if (channel->tries == -1)
1241
+ channel->tries = res.retry;
1242
+ if (channel->rotate == -1)
1243
+ channel->rotate = res.options & RES_ROTATE;
1244
+ if (channel->timeout == -1)
1245
+ channel->timeout = res.retrans * 1000;
1246
+
1247
+ res_ndestroy(&res);
1248
+ }
1249
+ #else
1250
+ {
1251
+ char *p;
1252
+ FILE *fp;
1253
+ size_t linesize;
1254
+ int error;
1255
+ int update_domains;
1256
+
1257
+ /* Don't read resolv.conf and friends if we don't have to */
1258
+ if (ARES_CONFIG_CHECK(channel))
1259
+ return ARES_SUCCESS;
1260
+
1261
+ /* Only update search domains if they're not already specified */
1262
+ update_domains = (channel->ndomains == -1);
1263
+
1264
+ fp = fopen(PATH_RESOLV_CONF, "r");
1265
+ if (fp) {
1266
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1267
+ {
1268
+ if ((p = try_config(line, "domain", ';')) && update_domains)
1269
+ status = config_domain(channel, p);
1270
+ else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1271
+ status = config_lookup(channel, p, "bind", NULL, "file");
1272
+ else if ((p = try_config(line, "search", ';')) && update_domains)
1273
+ status = set_search(channel, p);
1274
+ else if ((p = try_config(line, "nameserver", ';')) &&
1275
+ channel->nservers == -1)
1276
+ status = config_nameserver(&servers, &nservers, p);
1277
+ else if ((p = try_config(line, "sortlist", ';')) &&
1278
+ channel->nsort == -1)
1279
+ status = config_sortlist(&sortlist, &nsort, p);
1280
+ else if ((p = try_config(line, "options", ';')))
1281
+ status = set_options(channel, p);
1282
+ else
1283
+ status = ARES_SUCCESS;
1284
+ if (status != ARES_SUCCESS)
1285
+ break;
1286
+ }
1287
+ fclose(fp);
1288
+ }
1289
+ else {
1290
+ error = ERRNO;
1291
+ switch(error) {
1292
+ case ENOENT:
1293
+ case ESRCH:
1294
+ status = ARES_EOF;
1295
+ break;
1296
+ default:
1297
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1298
+ error, strerror(error)));
1299
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1300
+ status = ARES_EFILE;
1301
+ }
1302
+ }
1303
+
1304
+ if ((status == ARES_EOF) && (!channel->lookups)) {
1305
+ /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1306
+ fp = fopen("/etc/nsswitch.conf", "r");
1307
+ if (fp) {
1308
+ while ((status = ares__read_line(fp, &line, &linesize)) ==
1309
+ ARES_SUCCESS)
1310
+ {
1311
+ if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1312
+ (void)config_lookup(channel, p, "dns", "resolve", "files");
1313
+ }
1314
+ fclose(fp);
1315
+ }
1316
+ else {
1317
+ error = ERRNO;
1318
+ switch(error) {
1319
+ case ENOENT:
1320
+ case ESRCH:
1321
+ break;
1322
+ default:
1323
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1324
+ error, strerror(error)));
1325
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1326
+ "/etc/nsswitch.conf"));
1327
+ }
1328
+
1329
+ /* ignore error, maybe we will get luck in next if clause */
1330
+ status = ARES_EOF;
1331
+ }
1332
+ }
1333
+
1334
+ if ((status == ARES_EOF) && (!channel->lookups)) {
1335
+ /* Linux / GNU libc 2.x and possibly others have host.conf */
1336
+ fp = fopen("/etc/host.conf", "r");
1337
+ if (fp) {
1338
+ while ((status = ares__read_line(fp, &line, &linesize)) ==
1339
+ ARES_SUCCESS)
1340
+ {
1341
+ if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1342
+ /* ignore errors */
1343
+ (void)config_lookup(channel, p, "bind", NULL, "hosts");
1344
+ }
1345
+ fclose(fp);
1346
+ }
1347
+ else {
1348
+ error = ERRNO;
1349
+ switch(error) {
1350
+ case ENOENT:
1351
+ case ESRCH:
1352
+ break;
1353
+ default:
1354
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1355
+ error, strerror(error)));
1356
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1357
+ "/etc/host.conf"));
1358
+ }
1359
+
1360
+ /* ignore error, maybe we will get luck in next if clause */
1361
+ status = ARES_EOF;
1362
+ }
1363
+ }
1364
+
1365
+ if ((status == ARES_EOF) && (!channel->lookups)) {
1366
+ /* Tru64 uses /etc/svc.conf */
1367
+ fp = fopen("/etc/svc.conf", "r");
1368
+ if (fp) {
1369
+ while ((status = ares__read_line(fp, &line, &linesize)) ==
1370
+ ARES_SUCCESS)
1371
+ {
1372
+ if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1373
+ /* ignore errors */
1374
+ (void)config_lookup(channel, p, "bind", NULL, "local");
1375
+ }
1376
+ fclose(fp);
1377
+ }
1378
+ else {
1379
+ error = ERRNO;
1380
+ switch(error) {
1381
+ case ENOENT:
1382
+ case ESRCH:
1383
+ break;
1384
+ default:
1385
+ DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1386
+ error, strerror(error)));
1387
+ DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1388
+ }
1389
+
1390
+ /* ignore error, default value will be chosen for `channel->lookups` */
1391
+ status = ARES_EOF;
1392
+ }
1393
+ }
1394
+
1395
+ if(line)
1396
+ ares_free(line);
1397
+ }
1398
+
1399
+ #endif
1400
+
1401
+ /* Handle errors. */
1402
+ if (status != ARES_EOF)
1403
+ {
1404
+ if (servers != NULL)
1405
+ ares_free(servers);
1406
+ if (sortlist != NULL)
1407
+ ares_free(sortlist);
1408
+ return status;
1409
+ }
1410
+
1411
+ /* If we got any name server entries, fill them in. */
1412
+ if (servers)
1413
+ {
1414
+ channel->servers = servers;
1415
+ channel->nservers = nservers;
1416
+ }
1417
+
1418
+ /* If we got any sortlist entries, fill them in. */
1419
+ if (sortlist)
1420
+ {
1421
+ channel->sortlist = sortlist;
1422
+ channel->nsort = nsort;
1423
+ }
1424
+
1425
+ return ARES_SUCCESS;
1426
+ }
1427
+
1428
+ static int init_by_defaults(ares_channel channel)
1429
+ {
1430
+ char *hostname = NULL;
1431
+ int rc = ARES_SUCCESS;
1432
+ #ifdef HAVE_GETHOSTNAME
1433
+ char *dot;
1434
+ #endif
1435
+
1436
+ if (channel->flags == -1)
1437
+ channel->flags = 0;
1438
+ if (channel->timeout == -1)
1439
+ channel->timeout = DEFAULT_TIMEOUT;
1440
+ if (channel->tries == -1)
1441
+ channel->tries = DEFAULT_TRIES;
1442
+ if (channel->ndots == -1)
1443
+ channel->ndots = 1;
1444
+ if (channel->rotate == -1)
1445
+ channel->rotate = 0;
1446
+ if (channel->udp_port == -1)
1447
+ channel->udp_port = htons(NAMESERVER_PORT);
1448
+ if (channel->tcp_port == -1)
1449
+ channel->tcp_port = htons(NAMESERVER_PORT);
1450
+
1451
+ if (channel->ednspsz == -1)
1452
+ channel->ednspsz = EDNSPACKETSZ;
1453
+
1454
+ if (channel->nservers == -1) {
1455
+ /* If nobody specified servers, try a local named. */
1456
+ channel->servers = ares_malloc(sizeof(struct server_state));
1457
+ if (!channel->servers) {
1458
+ rc = ARES_ENOMEM;
1459
+ goto error;
1460
+ }
1461
+ channel->servers[0].addr.family = AF_INET;
1462
+ channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1463
+ channel->servers[0].addr.udp_port = 0;
1464
+ channel->servers[0].addr.tcp_port = 0;
1465
+ channel->nservers = 1;
1466
+ }
1467
+
1468
+ #if defined(USE_WINSOCK)
1469
+ #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1470
+ #elif defined(ENAMETOOLONG)
1471
+ #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1472
+ (SOCKERRNO == EINVAL))
1473
+ #else
1474
+ #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1475
+ #endif
1476
+
1477
+ if (channel->ndomains == -1) {
1478
+ /* Derive a default domain search list from the kernel hostname,
1479
+ * or set it to empty if the hostname isn't helpful.
1480
+ */
1481
+ #ifndef HAVE_GETHOSTNAME
1482
+ channel->ndomains = 0; /* default to none */
1483
+ #else
1484
+ GETHOSTNAME_TYPE_ARG2 lenv = 64;
1485
+ size_t len = 64;
1486
+ int res;
1487
+ channel->ndomains = 0; /* default to none */
1488
+
1489
+ hostname = ares_malloc(len);
1490
+ if(!hostname) {
1491
+ rc = ARES_ENOMEM;
1492
+ goto error;
1493
+ }
1494
+
1495
+ do {
1496
+ res = gethostname(hostname, lenv);
1497
+
1498
+ if(toolong(res)) {
1499
+ char *p;
1500
+ len *= 2;
1501
+ lenv *= 2;
1502
+ p = ares_realloc(hostname, len);
1503
+ if(!p) {
1504
+ rc = ARES_ENOMEM;
1505
+ goto error;
1506
+ }
1507
+ hostname = p;
1508
+ continue;
1509
+ }
1510
+ else if(res) {
1511
+ rc = ARES_EBADNAME;
1512
+ goto error;
1513
+ }
1514
+
1515
+ } while (res != 0);
1516
+
1517
+ dot = strchr(hostname, '.');
1518
+ if (dot) {
1519
+ /* a dot was found */
1520
+ channel->domains = ares_malloc(sizeof(char *));
1521
+ if (!channel->domains) {
1522
+ rc = ARES_ENOMEM;
1523
+ goto error;
1524
+ }
1525
+ channel->domains[0] = ares_strdup(dot + 1);
1526
+ if (!channel->domains[0]) {
1527
+ rc = ARES_ENOMEM;
1528
+ goto error;
1529
+ }
1530
+ channel->ndomains = 1;
1531
+ }
1532
+ #endif
1533
+ }
1534
+
1535
+ if (channel->nsort == -1) {
1536
+ channel->sortlist = NULL;
1537
+ channel->nsort = 0;
1538
+ }
1539
+
1540
+ if (!channel->lookups) {
1541
+ channel->lookups = ares_strdup("fb");
1542
+ if (!channel->lookups)
1543
+ rc = ARES_ENOMEM;
1544
+ }
1545
+
1546
+ error:
1547
+ if(rc) {
1548
+ if(channel->servers) {
1549
+ ares_free(channel->servers);
1550
+ channel->servers = NULL;
1551
+ }
1552
+
1553
+ if(channel->domains && channel->domains[0])
1554
+ ares_free(channel->domains[0]);
1555
+ if(channel->domains) {
1556
+ ares_free(channel->domains);
1557
+ channel->domains = NULL;
1558
+ }
1559
+
1560
+ if(channel->lookups) {
1561
+ ares_free(channel->lookups);
1562
+ channel->lookups = NULL;
1563
+ }
1564
+ }
1565
+
1566
+ if(hostname)
1567
+ ares_free(hostname);
1568
+
1569
+ return rc;
1570
+ }
1571
+
1572
+ #if !defined(WIN32) && !defined(WATT32) && \
1573
+ !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1574
+ static int config_domain(ares_channel channel, char *str)
1575
+ {
1576
+ char *q;
1577
+
1578
+ /* Set a single search domain. */
1579
+ q = str;
1580
+ while (*q && !ISSPACE(*q))
1581
+ q++;
1582
+ *q = '\0';
1583
+ return set_search(channel, str);
1584
+ }
1585
+
1586
+ #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1587
+ defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1588
+ /* workaround icc 9.1 optimizer issue */
1589
+ # define vqualifier volatile
1590
+ #else
1591
+ # define vqualifier
1592
+ #endif
1593
+
1594
+ static int config_lookup(ares_channel channel, const char *str,
1595
+ const char *bindch, const char *altbindch,
1596
+ const char *filech)
1597
+ {
1598
+ char lookups[3], *l;
1599
+ const char *vqualifier p;
1600
+
1601
+ if (altbindch == NULL)
1602
+ altbindch = bindch;
1603
+
1604
+ /* Set the lookup order. Only the first letter of each work
1605
+ * is relevant, and it has to be "b" for DNS or "f" for the
1606
+ * host file. Ignore everything else.
1607
+ */
1608
+ l = lookups;
1609
+ p = str;
1610
+ while (*p)
1611
+ {
1612
+ if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
1613
+ if (*p == *bindch || *p == *altbindch) *l++ = 'b';
1614
+ else *l++ = 'f';
1615
+ }
1616
+ while (*p && !ISSPACE(*p) && (*p != ','))
1617
+ p++;
1618
+ while (*p && (ISSPACE(*p) || (*p == ',')))
1619
+ p++;
1620
+ }
1621
+ *l = '\0';
1622
+ channel->lookups = ares_strdup(lookups);
1623
+ return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1624
+ }
1625
+ #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
1626
+
1627
+ #ifndef WATT32
1628
+ static int config_nameserver(struct server_state **servers, int *nservers,
1629
+ char *str)
1630
+ {
1631
+ struct ares_addr host;
1632
+ struct server_state *newserv;
1633
+ char *p, *txtaddr;
1634
+ /* On Windows, there may be more than one nameserver specified in the same
1635
+ * registry key, so we parse input as a space or comma seperated list.
1636
+ */
1637
+ for (p = str; p;)
1638
+ {
1639
+ /* Skip whitespace and commas. */
1640
+ while (*p && (ISSPACE(*p) || (*p == ',')))
1641
+ p++;
1642
+ if (!*p)
1643
+ /* No more input, done. */
1644
+ break;
1645
+
1646
+ /* Pointer to start of IPv4 or IPv6 address part. */
1647
+ txtaddr = p;
1648
+
1649
+ /* Advance past this address. */
1650
+ while (*p && !ISSPACE(*p) && (*p != ','))
1651
+ p++;
1652
+ if (*p)
1653
+ /* Null terminate this address. */
1654
+ *p++ = '\0';
1655
+ else
1656
+ /* Reached end of input, done when this address is processed. */
1657
+ p = NULL;
1658
+
1659
+ /* Convert textual address to binary format. */
1660
+ if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1661
+ host.family = AF_INET;
1662
+ else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1663
+ host.family = AF_INET6;
1664
+ else
1665
+ continue;
1666
+
1667
+ /* Resize servers state array. */
1668
+ newserv = ares_realloc(*servers, (*nservers + 1) *
1669
+ sizeof(struct server_state));
1670
+ if (!newserv)
1671
+ return ARES_ENOMEM;
1672
+
1673
+ /* Store address data. */
1674
+ newserv[*nservers].addr.family = host.family;
1675
+ newserv[*nservers].addr.udp_port = 0;
1676
+ newserv[*nservers].addr.tcp_port = 0;
1677
+ if (host.family == AF_INET)
1678
+ memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1679
+ sizeof(host.addrV4));
1680
+ else
1681
+ memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1682
+ sizeof(host.addrV6));
1683
+
1684
+ /* Update arguments. */
1685
+ *servers = newserv;
1686
+ *nservers += 1;
1687
+ }
1688
+
1689
+ return ARES_SUCCESS;
1690
+ }
1691
+ #endif /* !WATT32 */
1692
+
1693
+ static int config_sortlist(struct apattern **sortlist, int *nsort,
1694
+ const char *str)
1695
+ {
1696
+ struct apattern pat;
1697
+ const char *q;
1698
+
1699
+ /* Add sortlist entries. */
1700
+ while (*str && *str != ';')
1701
+ {
1702
+ int bits;
1703
+ char ipbuf[16], ipbufpfx[32];
1704
+ /* Find just the IP */
1705
+ q = str;
1706
+ while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1707
+ q++;
1708
+ memcpy(ipbuf, str, q-str);
1709
+ ipbuf[q-str] = '\0';
1710
+ /* Find the prefix */
1711
+ if (*q == '/')
1712
+ {
1713
+ const char *str2 = q+1;
1714
+ while (*q && *q != ';' && !ISSPACE(*q))
1715
+ q++;
1716
+ memcpy(ipbufpfx, str, q-str);
1717
+ ipbufpfx[q-str] = '\0';
1718
+ str = str2;
1719
+ }
1720
+ else
1721
+ ipbufpfx[0] = '\0';
1722
+ /* Lets see if it is CIDR */
1723
+ /* First we'll try IPv6 */
1724
+ if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1725
+ &pat.addrV6,
1726
+ sizeof(pat.addrV6))) > 0)
1727
+ {
1728
+ pat.type = PATTERN_CIDR;
1729
+ pat.mask.bits = (unsigned short)bits;
1730
+ pat.family = AF_INET6;
1731
+ if (!sortlist_alloc(sortlist, nsort, &pat)) {
1732
+ ares_free(*sortlist);
1733
+ *sortlist = NULL;
1734
+ return ARES_ENOMEM;
1735
+ }
1736
+ }
1737
+ else if (ipbufpfx[0] &&
1738
+ (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1739
+ sizeof(pat.addrV4))) > 0)
1740
+ {
1741
+ pat.type = PATTERN_CIDR;
1742
+ pat.mask.bits = (unsigned short)bits;
1743
+ pat.family = AF_INET;
1744
+ if (!sortlist_alloc(sortlist, nsort, &pat)) {
1745
+ ares_free(*sortlist);
1746
+ *sortlist = NULL;
1747
+ return ARES_ENOMEM;
1748
+ }
1749
+ }
1750
+ /* See if it is just a regular IP */
1751
+ else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1752
+ {
1753
+ if (ipbufpfx[0])
1754
+ {
1755
+ memcpy(ipbuf, str, q-str);
1756
+ ipbuf[q-str] = '\0';
1757
+ if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1758
+ natural_mask(&pat);
1759
+ }
1760
+ else
1761
+ natural_mask(&pat);
1762
+ pat.family = AF_INET;
1763
+ pat.type = PATTERN_MASK;
1764
+ if (!sortlist_alloc(sortlist, nsort, &pat)) {
1765
+ ares_free(*sortlist);
1766
+ *sortlist = NULL;
1767
+ return ARES_ENOMEM;
1768
+ }
1769
+ }
1770
+ else
1771
+ {
1772
+ while (*q && *q != ';' && !ISSPACE(*q))
1773
+ q++;
1774
+ }
1775
+ str = q;
1776
+ while (ISSPACE(*str))
1777
+ str++;
1778
+ }
1779
+
1780
+ return ARES_SUCCESS;
1781
+ }
1782
+
1783
+ static int set_search(ares_channel channel, const char *str)
1784
+ {
1785
+ int n;
1786
+ const char *p, *q;
1787
+
1788
+ if(channel->ndomains != -1) {
1789
+ /* LCOV_EXCL_START: all callers check ndomains == -1 */
1790
+ /* if we already have some domains present, free them first */
1791
+ for(n=0; n < channel->ndomains; n++)
1792
+ ares_free(channel->domains[n]);
1793
+ ares_free(channel->domains);
1794
+ channel->domains = NULL;
1795
+ channel->ndomains = -1;
1796
+ } /* LCOV_EXCL_STOP */
1797
+
1798
+ /* Count the domains given. */
1799
+ n = 0;
1800
+ p = str;
1801
+ while (*p)
1802
+ {
1803
+ while (*p && !ISSPACE(*p))
1804
+ p++;
1805
+ while (ISSPACE(*p))
1806
+ p++;
1807
+ n++;
1808
+ }
1809
+
1810
+ if (!n)
1811
+ {
1812
+ channel->ndomains = 0;
1813
+ return ARES_SUCCESS;
1814
+ }
1815
+
1816
+ channel->domains = ares_malloc(n * sizeof(char *));
1817
+ if (!channel->domains)
1818
+ return ARES_ENOMEM;
1819
+
1820
+ /* Now copy the domains. */
1821
+ n = 0;
1822
+ p = str;
1823
+ while (*p)
1824
+ {
1825
+ channel->ndomains = n;
1826
+ q = p;
1827
+ while (*q && !ISSPACE(*q))
1828
+ q++;
1829
+ channel->domains[n] = ares_malloc(q - p + 1);
1830
+ if (!channel->domains[n])
1831
+ return ARES_ENOMEM;
1832
+ memcpy(channel->domains[n], p, q - p);
1833
+ channel->domains[n][q - p] = 0;
1834
+ p = q;
1835
+ while (ISSPACE(*p))
1836
+ p++;
1837
+ n++;
1838
+ }
1839
+ channel->ndomains = n;
1840
+
1841
+ return ARES_SUCCESS;
1842
+ }
1843
+
1844
+ static int set_options(ares_channel channel, const char *str)
1845
+ {
1846
+ const char *p, *q, *val;
1847
+
1848
+ p = str;
1849
+ while (*p)
1850
+ {
1851
+ q = p;
1852
+ while (*q && !ISSPACE(*q))
1853
+ q++;
1854
+ val = try_option(p, q, "ndots:");
1855
+ if (val && channel->ndots == -1)
1856
+ channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1857
+ val = try_option(p, q, "retrans:");
1858
+ if (val && channel->timeout == -1)
1859
+ channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1860
+ val = try_option(p, q, "retry:");
1861
+ if (val && channel->tries == -1)
1862
+ channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1863
+ val = try_option(p, q, "rotate");
1864
+ if (val && channel->rotate == -1)
1865
+ channel->rotate = 1;
1866
+ p = q;
1867
+ while (ISSPACE(*p))
1868
+ p++;
1869
+ }
1870
+
1871
+ return ARES_SUCCESS;
1872
+ }
1873
+
1874
+ static const char *try_option(const char *p, const char *q, const char *opt)
1875
+ {
1876
+ size_t len = strlen(opt);
1877
+ return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1878
+ }
1879
+
1880
+ #if !defined(WIN32) && !defined(WATT32) && \
1881
+ !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1882
+ static char *try_config(char *s, const char *opt, char scc)
1883
+ {
1884
+ size_t len;
1885
+ char *p;
1886
+ char *q;
1887
+
1888
+ if (!s || !opt)
1889
+ /* no line or no option */
1890
+ return NULL; /* LCOV_EXCL_LINE */
1891
+
1892
+ /* Hash '#' character is always used as primary comment char, additionally
1893
+ a not-NUL secondary comment char will be considered when specified. */
1894
+
1895
+ /* trim line comment */
1896
+ p = s;
1897
+ if(scc)
1898
+ while (*p && (*p != '#') && (*p != scc))
1899
+ p++;
1900
+ else
1901
+ while (*p && (*p != '#'))
1902
+ p++;
1903
+ *p = '\0';
1904
+
1905
+ /* trim trailing whitespace */
1906
+ q = p - 1;
1907
+ while ((q >= s) && ISSPACE(*q))
1908
+ q--;
1909
+ *++q = '\0';
1910
+
1911
+ /* skip leading whitespace */
1912
+ p = s;
1913
+ while (*p && ISSPACE(*p))
1914
+ p++;
1915
+
1916
+ if (!*p)
1917
+ /* empty line */
1918
+ return NULL;
1919
+
1920
+ if ((len = strlen(opt)) == 0)
1921
+ /* empty option */
1922
+ return NULL; /* LCOV_EXCL_LINE */
1923
+
1924
+ if (strncmp(p, opt, len) != 0)
1925
+ /* line and option do not match */
1926
+ return NULL;
1927
+
1928
+ /* skip over given option name */
1929
+ p += len;
1930
+
1931
+ if (!*p)
1932
+ /* no option value */
1933
+ return NULL; /* LCOV_EXCL_LINE */
1934
+
1935
+ if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1936
+ /* whitespace between option name and value is mandatory
1937
+ for given option names which do not end with ':' or '=' */
1938
+ return NULL;
1939
+
1940
+ /* skip over whitespace */
1941
+ while (*p && ISSPACE(*p))
1942
+ p++;
1943
+
1944
+ if (!*p)
1945
+ /* no option value */
1946
+ return NULL;
1947
+
1948
+ /* return pointer to option value */
1949
+ return p;
1950
+ }
1951
+ #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1952
+
1953
+ static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1954
+ {
1955
+
1956
+ /* Four octets and three periods yields at most 15 characters. */
1957
+ if (len > 15)
1958
+ return -1;
1959
+
1960
+ addr->s_addr = inet_addr(ipbuf);
1961
+ if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1962
+ return -1;
1963
+ return 0;
1964
+ }
1965
+
1966
+ static void natural_mask(struct apattern *pat)
1967
+ {
1968
+ struct in_addr addr;
1969
+
1970
+ /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1971
+ * but portable.
1972
+ */
1973
+ addr.s_addr = ntohl(pat->addrV4.s_addr);
1974
+
1975
+ /* This is out of date in the CIDR world, but some people might
1976
+ * still rely on it.
1977
+ */
1978
+ if (IN_CLASSA(addr.s_addr))
1979
+ pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1980
+ else if (IN_CLASSB(addr.s_addr))
1981
+ pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1982
+ else
1983
+ pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1984
+ }
1985
+
1986
+ static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1987
+ struct apattern *pat)
1988
+ {
1989
+ struct apattern *newsort;
1990
+ newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1991
+ if (!newsort)
1992
+ return 0;
1993
+ newsort[*nsort] = *pat;
1994
+ *sortlist = newsort;
1995
+ (*nsort)++;
1996
+ return 1;
1997
+ }
1998
+
1999
+ /* initialize an rc4 key. If possible a cryptographically secure random key
2000
+ is generated using a suitable function (for example win32's RtlGenRandom as
2001
+ described in
2002
+ http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
2003
+ otherwise the code defaults to cross-platform albeit less secure mechanism
2004
+ using rand
2005
+ */
2006
+ static void randomize_key(unsigned char* key,int key_data_len)
2007
+ {
2008
+ int randomized = 0;
2009
+ int counter=0;
2010
+ #ifdef WIN32
2011
+ BOOLEAN res;
2012
+ if (ares_fpSystemFunction036)
2013
+ {
2014
+ res = (*ares_fpSystemFunction036) (key, key_data_len);
2015
+ if (res)
2016
+ randomized = 1;
2017
+ }
2018
+ #else /* !WIN32 */
2019
+ #ifdef RANDOM_FILE
2020
+ FILE *f = fopen(RANDOM_FILE, "rb");
2021
+ if(f) {
2022
+ counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2023
+ fclose(f);
2024
+ }
2025
+ #endif
2026
+ #endif /* WIN32 */
2027
+
2028
+ if (!randomized) {
2029
+ for (;counter<key_data_len;counter++)
2030
+ key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2031
+ }
2032
+ }
2033
+
2034
+ static int init_id_key(rc4_key* key,int key_data_len)
2035
+ {
2036
+ unsigned char index1;
2037
+ unsigned char index2;
2038
+ unsigned char* state;
2039
+ short counter;
2040
+ unsigned char *key_data_ptr = 0;
2041
+
2042
+ key_data_ptr = ares_malloc(key_data_len);
2043
+ if (!key_data_ptr)
2044
+ return ARES_ENOMEM;
2045
+ memset(key_data_ptr, 0, key_data_len);
2046
+
2047
+ state = &key->state[0];
2048
+ for(counter = 0; counter < 256; counter++)
2049
+ /* unnecessary AND but it keeps some compilers happier */
2050
+ state[counter] = (unsigned char)(counter & 0xff);
2051
+ randomize_key(key->state,key_data_len);
2052
+ key->x = 0;
2053
+ key->y = 0;
2054
+ index1 = 0;
2055
+ index2 = 0;
2056
+ for(counter = 0; counter < 256; counter++)
2057
+ {
2058
+ index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2059
+ index2) % 256);
2060
+ ARES_SWAP_BYTE(&state[counter], &state[index2]);
2061
+
2062
+ index1 = (unsigned char)((index1 + 1) % key_data_len);
2063
+ }
2064
+ ares_free(key_data_ptr);
2065
+ return ARES_SUCCESS;
2066
+ }
2067
+
2068
+ void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2069
+ {
2070
+ channel->local_ip4 = local_ip;
2071
+ }
2072
+
2073
+ /* local_ip6 should be 16 bytes in length */
2074
+ void ares_set_local_ip6(ares_channel channel,
2075
+ const unsigned char* local_ip6)
2076
+ {
2077
+ memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2078
+ }
2079
+
2080
+ /* local_dev_name should be null terminated. */
2081
+ void ares_set_local_dev(ares_channel channel,
2082
+ const char* local_dev_name)
2083
+ {
2084
+ strncpy(channel->local_dev_name, local_dev_name,
2085
+ sizeof(channel->local_dev_name));
2086
+ channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
2087
+ }
2088
+
2089
+
2090
+ void ares_set_socket_callback(ares_channel channel,
2091
+ ares_sock_create_callback cb,
2092
+ void *data)
2093
+ {
2094
+ channel->sock_create_cb = cb;
2095
+ channel->sock_create_cb_data = data;
2096
+ }
2097
+
2098
+ void ares_set_socket_configure_callback(ares_channel channel,
2099
+ ares_sock_config_callback cb,
2100
+ void *data)
2101
+ {
2102
+ channel->sock_config_cb = cb;
2103
+ channel->sock_config_cb_data = data;
2104
+ }
2105
+
2106
+ int ares_set_sortlist(ares_channel channel, const char *sortstr)
2107
+ {
2108
+ int nsort = 0;
2109
+ struct apattern *sortlist = NULL;
2110
+ int status;
2111
+
2112
+ if (!channel)
2113
+ return ARES_ENODATA;
2114
+
2115
+ status = config_sortlist(&sortlist, &nsort, sortstr);
2116
+ if (status == ARES_SUCCESS && sortlist) {
2117
+ if (channel->sortlist)
2118
+ ares_free(channel->sortlist);
2119
+ channel->sortlist = sortlist;
2120
+ channel->nsort = nsort;
2121
+ }
2122
+ return status;
2123
+ }
2124
+
2125
+ void ares__init_servers_state(ares_channel channel)
2126
+ {
2127
+ struct server_state *server;
2128
+ int i;
2129
+
2130
+ for (i = 0; i < channel->nservers; i++)
2131
+ {
2132
+ server = &channel->servers[i];
2133
+ server->udp_socket = ARES_SOCKET_BAD;
2134
+ server->tcp_socket = ARES_SOCKET_BAD;
2135
+ server->tcp_connection_generation = ++channel->tcp_connection_generation;
2136
+ server->tcp_lenbuf_pos = 0;
2137
+ server->tcp_buffer_pos = 0;
2138
+ server->tcp_buffer = NULL;
2139
+ server->tcp_length = 0;
2140
+ server->qhead = NULL;
2141
+ server->qtail = NULL;
2142
+ ares__init_list_head(&server->queries_to_server);
2143
+ server->channel = channel;
2144
+ server->is_broken = 0;
2145
+ }
2146
+ }