grpc 1.74.1 → 1.75.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +83 -41
  3. data/include/grpc/credentials.h +7 -1
  4. data/src/core/call/client_call.cc +4 -4
  5. data/src/core/call/filter_fusion.h +1230 -0
  6. data/src/core/call/metadata.cc +22 -0
  7. data/src/core/call/metadata.h +24 -2
  8. data/src/core/channelz/channelz.cc +10 -17
  9. data/src/core/channelz/channelz.h +58 -19
  10. data/src/core/channelz/channelz_registry.cc +0 -162
  11. data/src/core/channelz/channelz_registry.h +14 -7
  12. data/src/core/channelz/property_list.cc +19 -23
  13. data/src/core/channelz/property_list.h +3 -1
  14. data/src/core/channelz/v2tov1/convert.cc +683 -0
  15. data/src/core/channelz/v2tov1/convert.h +58 -0
  16. data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
  17. data/src/core/channelz/v2tov1/legacy_api.h +32 -0
  18. data/src/core/channelz/v2tov1/property_list.cc +118 -0
  19. data/src/core/channelz/v2tov1/property_list.h +52 -0
  20. data/src/core/client_channel/client_channel_filter.cc +5 -4
  21. data/src/core/client_channel/client_channel_filter.h +2 -2
  22. data/src/core/client_channel/client_channel_internal.h +2 -1
  23. data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
  24. data/src/core/client_channel/subchannel.cc +14 -6
  25. data/src/core/client_channel/subchannel.h +2 -0
  26. data/src/core/config/core_configuration.cc +3 -1
  27. data/src/core/config/core_configuration.h +12 -0
  28. data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
  29. data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
  30. data/src/core/credentials/transport/channel_creds_registry_init.cc +3 -1
  31. data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
  32. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
  33. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
  34. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
  35. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
  36. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
  37. data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
  38. data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
  39. data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
  40. data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
  41. data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
  42. data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
  43. data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
  44. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
  45. data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
  46. data/src/core/ext/filters/http/client_authority_filter.cc +1 -2
  47. data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
  48. data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
  49. data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
  50. data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
  51. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
  52. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3 -2
  53. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -0
  55. data/src/core/ext/transport/chttp2/transport/frame.cc +89 -6
  56. data/src/core/ext/transport/chttp2/transport/frame.h +38 -0
  57. data/src/core/ext/transport/chttp2/transport/header_assembler.h +5 -14
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
  59. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +294 -78
  60. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +128 -9
  61. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
  62. data/src/core/ext/transport/chttp2/transport/http2_settings.h +52 -35
  63. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
  64. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
  65. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +81 -3
  66. data/src/core/ext/transport/chttp2/transport/http2_transport.h +12 -1
  67. data/src/core/ext/transport/chttp2/transport/message_assembler.h +2 -2
  68. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -1
  69. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +2 -1
  70. data/src/core/ext/transport/chttp2/transport/ping_promise.h +22 -5
  71. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
  72. data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
  73. data/src/core/ext/transport/chttp2/transport/writing.cc +6 -4
  74. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
  75. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
  76. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
  77. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +142 -54
  78. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +18 -14
  79. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +2 -2
  80. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
  81. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
  82. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +86 -88
  83. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +2 -2
  84. data/src/core/filter/auth/auth_filters.h +2 -2
  85. data/src/core/filter/fused_filters.cc +154 -0
  86. data/src/core/handshaker/security/legacy_secure_endpoint.cc +1 -1
  87. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
  88. data/src/core/handshaker/security/secure_endpoint.cc +28 -13
  89. data/src/core/handshaker/security/secure_endpoint.h +8 -0
  90. data/src/core/lib/channel/promise_based_filter.cc +15 -25
  91. data/src/core/lib/channel/promise_based_filter.h +6 -5
  92. data/src/core/lib/event_engine/ares_resolver.h +3 -1
  93. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +9 -5
  94. data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -1
  95. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
  96. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
  97. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
  98. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +12 -0
  99. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +12 -10
  100. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +6 -4
  101. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +15 -14
  102. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -5
  103. data/src/core/lib/event_engine/posix_engine/event_poller.h +0 -8
  104. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -5
  105. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
  106. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +1 -0
  107. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
  108. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
  109. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +2 -2
  110. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +188 -199
  111. data/src/core/lib/event_engine/posix_engine/posix_engine.h +30 -45
  112. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -1
  113. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
  114. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +2 -1
  115. data/src/core/lib/experiments/experiments.cc +120 -6
  116. data/src/core/lib/experiments/experiments.h +46 -3
  117. data/src/core/lib/iomgr/combiner.cc +1 -1
  118. data/src/core/lib/iomgr/exec_ctx.h +3 -9
  119. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  120. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
  121. data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
  122. data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
  123. data/src/core/lib/iomgr/tcp_posix.cc +3 -3
  124. data/src/core/lib/promise/activity.h +2 -2
  125. data/src/core/lib/promise/mpsc.cc +8 -8
  126. data/src/core/lib/promise/party.cc +7 -7
  127. data/src/core/lib/promise/party.h +4 -4
  128. data/src/core/lib/promise/poll.h +10 -0
  129. data/src/core/lib/resource_quota/memory_quota.cc +90 -3
  130. data/src/core/lib/resource_quota/memory_quota.h +20 -9
  131. data/src/core/lib/resource_quota/periodic_update.cc +14 -0
  132. data/src/core/lib/resource_quota/periodic_update.h +8 -0
  133. data/src/core/lib/resource_quota/resource_quota.cc +15 -4
  134. data/src/core/lib/resource_quota/resource_quota.h +3 -0
  135. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
  136. data/src/core/lib/surface/call.cc +5 -5
  137. data/src/core/lib/surface/call.h +6 -5
  138. data/src/core/lib/surface/completion_queue.cc +2 -4
  139. data/src/core/lib/surface/filter_stack_call.cc +1 -1
  140. data/src/core/lib/surface/version.cc +2 -2
  141. data/src/core/lib/transport/promise_endpoint.cc +2 -2
  142. data/src/core/lib/transport/promise_endpoint.h +3 -3
  143. data/src/core/load_balancing/endpoint_list.cc +29 -2
  144. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
  145. data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
  146. data/src/core/load_balancing/pick_first/pick_first.cc +12 -5
  147. data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
  148. data/src/core/net/socket_mutator.cc +19 -0
  149. data/src/core/net/socket_mutator.h +25 -0
  150. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
  151. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
  152. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
  153. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
  154. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
  155. data/src/core/resolver/xds/xds_dependency_manager.cc +1 -1
  156. data/src/core/server/server.cc +1 -1
  157. data/src/core/server/server_call_tracer_filter.cc +0 -66
  158. data/src/core/server/server_call_tracer_filter.h +64 -0
  159. data/src/core/server/server_config_selector_filter.cc +1 -1
  160. data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
  161. data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
  162. data/src/core/telemetry/call_tracer.cc +20 -14
  163. data/src/core/telemetry/call_tracer.h +22 -17
  164. data/src/core/telemetry/metrics.h +8 -8
  165. data/src/core/telemetry/stats_data.cc +151 -151
  166. data/src/core/telemetry/stats_data.h +87 -87
  167. data/src/core/transport/auth_context.cc +20 -0
  168. data/src/core/transport/auth_context.h +4 -0
  169. data/src/core/transport/auth_context_comparator_registry.h +69 -0
  170. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
  171. data/src/core/tsi/ssl_transport_security.cc +202 -32
  172. data/src/core/tsi/ssl_transport_security.h +19 -10
  173. data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
  174. data/src/core/tsi/ssl_transport_security_utils.h +4 -0
  175. data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
  176. data/src/core/util/latent_see.cc +178 -146
  177. data/src/core/util/latent_see.h +245 -188
  178. data/src/core/util/single_set_ptr.h +5 -2
  179. data/src/core/util/useful.h +91 -0
  180. data/src/core/util/windows/directory_reader.cc +1 -0
  181. data/src/core/util/windows/thd.cc +1 -3
  182. data/src/core/util/work_serializer.cc +1 -1
  183. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
  184. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
  185. data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
  186. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  187. data/src/ruby/lib/grpc/version.rb +1 -1
  188. data/third_party/cares/cares/include/ares.h +925 -460
  189. data/third_party/cares/cares/include/ares_dns.h +86 -71
  190. data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
  191. data/third_party/cares/cares/include/ares_nameser.h +215 -189
  192. data/third_party/cares/cares/include/ares_version.h +37 -14
  193. data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
  194. data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
  195. data/third_party/cares/cares/src/lib/ares_android.c +216 -164
  196. data/third_party/cares/cares/src/lib/ares_android.h +25 -14
  197. data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
  198. data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
  199. data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
  200. data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
  201. data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
  202. data/third_party/cares/cares/src/lib/ares_data.c +93 -181
  203. data/third_party/cares/cares/src/lib/ares_data.h +50 -39
  204. data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
  205. data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
  206. data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
  207. data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
  208. data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
  209. data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
  210. data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
  211. data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
  212. data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
  213. data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
  214. data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
  215. data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
  216. data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
  217. data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
  218. data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
  219. data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
  220. data/third_party/cares/cares/src/lib/ares_options.c +418 -332
  221. data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
  222. data/third_party/cares/cares/src/lib/ares_private.h +558 -356
  223. data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
  224. data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
  225. data/third_party/cares/cares/src/lib/ares_query.c +126 -121
  226. data/third_party/cares/cares/src/lib/ares_search.c +564 -262
  227. data/third_party/cares/cares/src/lib/ares_send.c +264 -93
  228. data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
  229. data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
  230. data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
  231. data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
  232. data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
  233. data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
  234. data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
  235. data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
  236. data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
  237. data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
  238. data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
  239. data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
  240. data/third_party/cares/cares/src/lib/ares_version.c +29 -4
  241. data/third_party/cares/cares/src/lib/config-dos.h +88 -89
  242. data/third_party/cares/cares/src/lib/config-win32.h +122 -77
  243. data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
  244. data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
  245. data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
  246. data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
  247. data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
  248. data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
  249. data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
  250. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  251. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  252. data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
  253. data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
  254. data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
  255. data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
  256. data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
  257. data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
  258. data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
  259. data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
  260. data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
  261. data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
  262. data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
  263. data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
  264. data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
  265. data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
  266. data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
  267. data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
  268. data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
  269. data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
  270. data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
  271. data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
  272. data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
  273. data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
  274. data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
  275. data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
  276. data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
  277. data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
  278. data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
  279. data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
  280. data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
  281. data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
  282. data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
  283. data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  284. data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  285. data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  286. data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  287. data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  288. data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  289. data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  290. data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  291. data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  292. data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  293. data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  294. data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
  295. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
  296. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
  297. data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
  298. data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
  299. data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
  300. data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
  301. data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
  302. data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
  303. data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
  304. data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
  305. data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
  306. data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  307. data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
  308. data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
  309. data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
  310. data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
  311. data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
  312. data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
  313. data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
  314. data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
  315. data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
  316. data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
  317. data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
  318. data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
  319. data/third_party/cares/cares/src/lib/windows_port.c +16 -9
  320. metadata +121 -49
  321. data/src/core/util/ring_buffer.h +0 -122
  322. data/third_party/cares/cares/include/ares_rules.h +0 -125
  323. data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
  324. data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
  325. data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
  326. data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
  327. data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
  328. data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
  329. data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
  330. data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
  331. data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
  332. data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
  333. data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
  334. data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
  335. data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
  336. data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
  337. data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
  338. data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
  339. data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
  340. data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
  341. data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
  342. data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
  343. data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
  344. data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
  345. data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
  346. data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
  347. data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
  348. data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
  349. data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
  350. data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
  351. data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
  352. data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
  353. data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
  354. data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
  355. data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
  356. data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
  357. data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
  358. data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
  359. data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
  360. data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
  361. data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
  362. data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
  363. data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
  364. data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
  365. data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
  366. data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
  367. data/third_party/cares/cares/src/lib/setup_once.h +0 -554
  368. data/third_party/cares/cares/src/tools/ares_getopt.h +0 -53
@@ -1,2266 +1,600 @@
1
-
2
- /* Copyright 1998 by the Massachusetts Institute of Technology.
3
- * Copyright (C) 2007-2013 by Daniel Stenberg
1
+ /* MIT License
2
+ *
3
+ * Copyright (c) 1998 Massachusetts Institute of Technology
4
+ * Copyright (c) 2007 Daniel Stenberg
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice (including the next
14
+ * paragraph) shall be included in all copies or substantial portions of the
15
+ * Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ * SOFTWARE.
4
24
  *
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.
25
+ * SPDX-License-Identifier: MIT
16
26
  */
17
27
 
18
- #include "ares_setup.h"
28
+ #include "ares_private.h"
19
29
 
20
30
  #ifdef HAVE_SYS_PARAM_H
21
- #include <sys/param.h>
31
+ # include <sys/param.h>
22
32
  #endif
23
33
 
24
34
  #ifdef HAVE_NETINET_IN_H
25
- #include <netinet/in.h>
35
+ # include <netinet/in.h>
26
36
  #endif
27
37
 
28
38
  #ifdef HAVE_NETDB_H
29
- #include <netdb.h>
39
+ # include <netdb.h>
30
40
  #endif
31
41
 
32
42
  #ifdef HAVE_ARPA_INET_H
33
- #include <arpa/inet.h>
43
+ # include <arpa/inet.h>
34
44
  #endif
35
45
 
36
46
  #include "ares_nameser.h"
37
47
 
38
48
  #if defined(ANDROID) || defined(__ANDROID__)
39
- #include <sys/system_properties.h>
40
- #include "ares_android.h"
49
+ # include <sys/system_properties.h>
50
+ # include "ares_android.h"
41
51
  /* From the Bionic sources */
42
- #define DNS_PROP_NAME_PREFIX "net.dns"
43
- #define MAX_DNS_PROPERTIES 8
52
+ # define DNS_PROP_NAME_PREFIX "net.dns"
53
+ # define MAX_DNS_PROPERTIES 8
44
54
  #endif
45
55
 
46
56
  #if defined(CARES_USE_LIBRESOLV)
47
- #include <resolv.h>
57
+ # include <resolv.h>
48
58
  #endif
49
59
 
50
- #if defined(USE_WINSOCK)
60
+ #if defined(USE_WINSOCK) && defined(HAVE_IPHLPAPI_H)
51
61
  # include <iphlpapi.h>
52
62
  #endif
53
63
 
54
- #include "ares.h"
55
64
  #include "ares_inet_net_pton.h"
56
- #include "ares_nowarn.h"
57
- #include "ares_platform.h"
58
- #include "ares_private.h"
59
-
60
- #ifdef WATT32
61
- #undef WIN32 /* Redefined in MingW/MSVC headers */
62
- #endif
63
-
65
+ #include "event/ares_event.h"
64
66
 
65
- static int init_by_options(ares_channel channel,
66
- const struct ares_options *options,
67
- int optmask);
68
- static int init_by_environment(ares_channel channel);
69
- static int init_by_resolv_conf(ares_channel channel);
70
- static int init_by_defaults(ares_channel channel);
71
-
72
- #ifndef WATT32
73
- static int config_nameserver(struct server_state **servers, int *nservers,
74
- char *str);
75
- #endif
76
- static int set_search(ares_channel channel, const char *str);
77
- static int set_options(ares_channel channel, const char *str);
78
- static const char *try_option(const char *p, const char *q, const char *opt);
79
-
80
- static int config_sortlist(struct apattern **sortlist, int *nsort,
81
- const char *str);
82
- static int sortlist_alloc(struct apattern **sortlist, int *nsort,
83
- struct apattern *pat);
84
- static int ip_addr(const char *s, ares_ssize_t len, struct in_addr *addr);
85
- static void natural_mask(struct apattern *pat);
86
- #if !defined(WIN32) && !defined(WATT32) && \
87
- !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
88
- static int config_domain(ares_channel channel, char *str);
89
- static int config_lookup(ares_channel channel, const char *str,
90
- const char *bindch, const char *altbindch,
91
- const char *filech);
92
- static char *try_config(char *s, const char *opt, char scc);
93
- #endif
94
-
95
- #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
96
- x->nservers > -1 && \
97
- x->ndomains > -1 && \
98
- x->ndots > -1 && x->timeout > -1 && \
99
- x->tries > -1)
100
-
101
- int ares_init(ares_channel *channelptr)
67
+ int ares_init(ares_channel_t **channelptr)
102
68
  {
103
69
  return ares_init_options(channelptr, NULL, 0);
104
70
  }
105
71
 
106
- int ares_init_options(ares_channel *channelptr, struct ares_options *options,
107
- int optmask)
108
- {
109
- ares_channel channel;
110
- int i;
111
- int status = ARES_SUCCESS;
112
- struct timeval now;
113
-
114
- if (ares_library_initialized() != ARES_SUCCESS)
115
- return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
116
-
117
- channel = ares_malloc(sizeof(struct ares_channeldata));
118
- if (!channel) {
119
- *channelptr = NULL;
120
- return ARES_ENOMEM;
121
- }
122
-
123
- now = ares__tvnow();
124
-
125
- /* Set everything to distinguished values so we know they haven't
126
- * been set yet.
127
- */
128
- channel->flags = -1;
129
- channel->timeout = -1;
130
- channel->tries = -1;
131
- channel->ndots = -1;
132
- channel->rotate = -1;
133
- channel->udp_port = -1;
134
- channel->tcp_port = -1;
135
- channel->ednspsz = -1;
136
- channel->socket_send_buffer_size = -1;
137
- channel->socket_receive_buffer_size = -1;
138
- channel->nservers = -1;
139
- channel->ndomains = -1;
140
- channel->nsort = -1;
141
- channel->tcp_connection_generation = 0;
142
- channel->lookups = NULL;
143
- channel->domains = NULL;
144
- channel->sortlist = NULL;
145
- channel->servers = NULL;
146
- channel->sock_state_cb = NULL;
147
- channel->sock_state_cb_data = NULL;
148
- channel->sock_create_cb = NULL;
149
- channel->sock_create_cb_data = NULL;
150
- channel->sock_config_cb = NULL;
151
- channel->sock_config_cb_data = NULL;
152
- channel->sock_funcs = NULL;
153
- channel->sock_func_cb_data = NULL;
154
- channel->resolvconf_path = NULL;
155
- channel->hosts_path = NULL;
156
- channel->rand_state = NULL;
157
-
158
- channel->last_server = 0;
159
- channel->last_timeout_processed = (time_t)now.tv_sec;
160
-
161
- memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
162
- channel->local_ip4 = 0;
163
- memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
164
-
165
- /* Initialize our lists of queries */
166
- ares__init_list_head(&(channel->all_queries));
167
- for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
168
- {
169
- ares__init_list_head(&(channel->queries_by_qid[i]));
170
- }
171
- for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
172
- {
173
- ares__init_list_head(&(channel->queries_by_timeout[i]));
174
- }
175
-
176
- /* Initialize configuration by each of the four sources, from highest
177
- * precedence to lowest.
178
- */
179
-
180
- status = init_by_options(channel, options, optmask);
181
- if (status != ARES_SUCCESS) {
182
- DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
183
- ares_strerror(status)));
184
- /* If we fail to apply user-specified options, fail the whole init process */
185
- goto done;
186
- }
187
- status = init_by_environment(channel);
188
- if (status != ARES_SUCCESS)
189
- DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
190
- ares_strerror(status)));
191
- if (status == ARES_SUCCESS) {
192
- status = init_by_resolv_conf(channel);
193
- if (status != ARES_SUCCESS)
194
- DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
195
- ares_strerror(status)));
196
- }
197
-
198
- /*
199
- * No matter what failed or succeeded, seed defaults to provide
200
- * useful behavior for things that we missed.
201
- */
202
- status = init_by_defaults(channel);
203
- if (status != ARES_SUCCESS)
204
- DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
205
- ares_strerror(status)));
206
-
207
- /* Generate random key */
208
-
209
- if (status == ARES_SUCCESS) {
210
- channel->rand_state = ares__init_rand_state();
211
- if (channel->rand_state == NULL) {
212
- status = ARES_ENOMEM;
213
- }
214
-
215
- if (status == ARES_SUCCESS)
216
- channel->next_id = ares__generate_new_id(channel->rand_state);
217
- else
218
- DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
219
- ares_strerror(status)));
220
- }
221
-
222
- done:
223
- if (status != ARES_SUCCESS)
224
- {
225
- /* Something failed; clean up memory we may have allocated. */
226
- if (channel->servers)
227
- ares_free(channel->servers);
228
- if (channel->ndomains != -1)
229
- ares__strsplit_free(channel->domains, channel->ndomains);
230
- if (channel->sortlist)
231
- ares_free(channel->sortlist);
232
- if(channel->lookups)
233
- ares_free(channel->lookups);
234
- if(channel->resolvconf_path)
235
- ares_free(channel->resolvconf_path);
236
- if(channel->hosts_path)
237
- ares_free(channel->hosts_path);
238
- if (channel->rand_state)
239
- ares__destroy_rand_state(channel->rand_state);
240
- ares_free(channel);
241
- return status;
242
- }
243
-
244
- /* Trim to one server if ARES_FLAG_PRIMARY is set. */
245
- if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
246
- channel->nservers = 1;
247
-
248
- ares__init_servers_state(channel);
249
-
250
- *channelptr = channel;
251
- return ARES_SUCCESS;
252
- }
253
-
254
- /* ares_dup() duplicates a channel handle with all its options and returns a
255
- new channel handle */
256
- int ares_dup(ares_channel *dest, ares_channel src)
257
- {
258
- struct ares_options opts;
259
- struct ares_addr_port_node *servers;
260
- int non_v4_default_port = 0;
261
- int i, rc;
262
- int optmask;
263
-
264
- *dest = NULL; /* in case of failure return NULL explicitly */
265
-
266
- /* First get the options supported by the old ares_save_options() function,
267
- which is most of them */
268
- rc = ares_save_options(src, &opts, &optmask);
269
- if(rc)
270
- {
271
- ares_destroy_options(&opts);
272
- return rc;
273
- }
274
-
275
- /* Then create the new channel with those options */
276
- rc = ares_init_options(dest, &opts, optmask);
277
-
278
- /* destroy the options copy to not leak any memory */
279
- ares_destroy_options(&opts);
280
-
281
- if(rc)
282
- return rc;
283
-
284
- /* Now clone the options that ares_save_options() doesn't support. */
285
- (*dest)->sock_create_cb = src->sock_create_cb;
286
- (*dest)->sock_create_cb_data = src->sock_create_cb_data;
287
- (*dest)->sock_config_cb = src->sock_config_cb;
288
- (*dest)->sock_config_cb_data = src->sock_config_cb_data;
289
- (*dest)->sock_funcs = src->sock_funcs;
290
- (*dest)->sock_func_cb_data = src->sock_func_cb_data;
291
-
292
- strncpy((*dest)->local_dev_name, src->local_dev_name,
293
- sizeof((*dest)->local_dev_name));
294
- (*dest)->local_ip4 = src->local_ip4;
295
- memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
296
-
297
- /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
298
- for (i = 0; i < src->nservers; i++)
299
- {
300
- if ((src->servers[i].addr.family != AF_INET) ||
301
- (src->servers[i].addr.udp_port != 0) ||
302
- (src->servers[i].addr.tcp_port != 0)) {
303
- non_v4_default_port++;
304
- break;
305
- }
306
- }
307
- if (non_v4_default_port) {
308
- rc = ares_get_servers_ports(src, &servers);
309
- if (rc != ARES_SUCCESS) {
310
- ares_destroy(*dest);
311
- *dest = NULL;
312
- return rc;
313
- }
314
- rc = ares_set_servers_ports(*dest, servers);
315
- ares_free_data(servers);
316
- if (rc != ARES_SUCCESS) {
317
- ares_destroy(*dest);
318
- *dest = NULL;
319
- return rc;
320
- }
321
- }
322
-
323
- return ARES_SUCCESS; /* everything went fine */
324
- }
325
-
326
- /* Save options from initialized channel */
327
- int ares_save_options(ares_channel channel, struct ares_options *options,
328
- int *optmask)
329
- {
330
- int i, j;
331
- int ipv4_nservers = 0;
332
-
333
- /* Zero everything out */
334
- memset(options, 0, sizeof(struct ares_options));
335
-
336
- if (!ARES_CONFIG_CHECK(channel))
337
- return ARES_ENODATA;
338
-
339
- /* Traditionally the optmask wasn't saved in the channel struct so it was
340
- recreated here. ROTATE is the first option that has no struct field of
341
- its own in the public config struct */
342
- (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
343
- ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
344
- ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
345
- ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
346
- (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
347
-
348
- if (channel->resolvconf_path)
349
- (*optmask) |= ARES_OPT_RESOLVCONF;
350
-
351
- if (channel->hosts_path)
352
- (*optmask) |= ARES_OPT_HOSTS_FILE;
353
-
354
- /* Copy easy stuff */
355
- options->flags = channel->flags;
356
-
357
- /* We return full millisecond resolution but that's only because we don't
358
- set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
359
- options->timeout = channel->timeout;
360
- options->tries = channel->tries;
361
- options->ndots = channel->ndots;
362
- options->udp_port = ntohs(aresx_sitous(channel->udp_port));
363
- options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
364
- options->sock_state_cb = channel->sock_state_cb;
365
- options->sock_state_cb_data = channel->sock_state_cb_data;
366
-
367
- /* Copy IPv4 servers that use the default port */
368
- if (channel->nservers) {
369
- for (i = 0; i < channel->nservers; i++)
370
- {
371
- if ((channel->servers[i].addr.family == AF_INET) &&
372
- (channel->servers[i].addr.udp_port == 0) &&
373
- (channel->servers[i].addr.tcp_port == 0))
374
- ipv4_nservers++;
375
- }
376
- if (ipv4_nservers) {
377
- options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
378
- if (!options->servers)
379
- return ARES_ENOMEM;
380
- for (i = j = 0; i < channel->nservers; i++)
381
- {
382
- if ((channel->servers[i].addr.family == AF_INET) &&
383
- (channel->servers[i].addr.udp_port == 0) &&
384
- (channel->servers[i].addr.tcp_port == 0))
385
- memcpy(&options->servers[j++],
386
- &channel->servers[i].addr.addrV4,
387
- sizeof(channel->servers[i].addr.addrV4));
388
- }
389
- }
390
- }
391
- options->nservers = ipv4_nservers;
392
-
393
- /* copy domains */
394
- if (channel->ndomains) {
395
- options->domains = ares_malloc(channel->ndomains * sizeof(char *));
396
- if (!options->domains)
397
- return ARES_ENOMEM;
398
-
399
- for (i = 0; i < channel->ndomains; i++)
400
- {
401
- options->ndomains = i;
402
- options->domains[i] = ares_strdup(channel->domains[i]);
403
- if (!options->domains[i])
404
- return ARES_ENOMEM;
405
- }
406
- }
407
- options->ndomains = channel->ndomains;
408
-
409
- /* copy lookups */
410
- if (channel->lookups) {
411
- options->lookups = ares_strdup(channel->lookups);
412
- if (!options->lookups && channel->lookups)
413
- return ARES_ENOMEM;
414
- }
415
-
416
- /* copy sortlist */
417
- if (channel->nsort) {
418
- options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
419
- if (!options->sortlist)
420
- return ARES_ENOMEM;
421
- for (i = 0; i < channel->nsort; i++)
422
- options->sortlist[i] = channel->sortlist[i];
423
- }
424
- options->nsort = channel->nsort;
425
-
426
- /* copy path for resolv.conf file */
427
- if (channel->resolvconf_path) {
428
- options->resolvconf_path = ares_strdup(channel->resolvconf_path);
429
- if (!options->resolvconf_path)
430
- return ARES_ENOMEM;
431
- }
432
-
433
- /* copy path for hosts file */
434
- if (channel->hosts_path) {
435
- options->hosts_path = ares_strdup(channel->hosts_path);
436
- if (!options->hosts_path)
437
- return ARES_ENOMEM;
438
- }
439
-
440
- return ARES_SUCCESS;
441
- }
442
-
443
- static int init_by_options(ares_channel channel,
444
- const struct ares_options *options,
445
- int optmask)
446
- {
447
- int i;
448
-
449
- /* Easy stuff. */
450
- if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
451
- channel->flags = options->flags;
452
- if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
453
- channel->timeout = options->timeout;
454
- else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
455
- channel->timeout = options->timeout * 1000;
456
- if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
457
- channel->tries = options->tries;
458
- if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
459
- channel->ndots = options->ndots;
460
- if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
461
- channel->rotate = 1;
462
- if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
463
- channel->rotate = 0;
464
- if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
465
- channel->udp_port = htons(options->udp_port);
466
- if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
467
- channel->tcp_port = htons(options->tcp_port);
468
- if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
469
- {
470
- channel->sock_state_cb = options->sock_state_cb;
471
- channel->sock_state_cb_data = options->sock_state_cb_data;
472
- }
473
- if ((optmask & ARES_OPT_SOCK_SNDBUF)
474
- && channel->socket_send_buffer_size == -1)
475
- channel->socket_send_buffer_size = options->socket_send_buffer_size;
476
- if ((optmask & ARES_OPT_SOCK_RCVBUF)
477
- && channel->socket_receive_buffer_size == -1)
478
- channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
479
-
480
- if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
481
- channel->ednspsz = options->ednspsz;
482
-
483
- /* Copy the IPv4 servers, if given. */
484
- if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
485
- {
486
- /* Avoid zero size allocations at any cost */
487
- if (options->nservers > 0)
488
- {
489
- channel->servers =
490
- ares_malloc(options->nservers * sizeof(struct server_state));
491
- if (!channel->servers)
492
- return ARES_ENOMEM;
493
- for (i = 0; i < options->nservers; i++)
494
- {
495
- channel->servers[i].addr.family = AF_INET;
496
- channel->servers[i].addr.udp_port = 0;
497
- channel->servers[i].addr.tcp_port = 0;
498
- memcpy(&channel->servers[i].addr.addrV4,
499
- &options->servers[i],
500
- sizeof(channel->servers[i].addr.addrV4));
501
- }
502
- }
503
- channel->nservers = options->nservers;
504
- }
505
-
506
- /* Copy the domains, if given. Keep channel->ndomains consistent so
507
- * we can clean up in case of error.
508
- */
509
- if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
510
- {
511
- /* Avoid zero size allocations at any cost */
512
- if (options->ndomains > 0)
513
- {
514
- channel->domains = ares_malloc(options->ndomains * sizeof(char *));
515
- if (!channel->domains)
516
- return ARES_ENOMEM;
517
- for (i = 0; i < options->ndomains; i++)
518
- {
519
- channel->ndomains = i;
520
- channel->domains[i] = ares_strdup(options->domains[i]);
521
- if (!channel->domains[i])
522
- return ARES_ENOMEM;
523
- }
524
- }
525
- channel->ndomains = options->ndomains;
526
- }
527
-
528
- /* Set lookups, if given. */
529
- if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
530
- {
531
- channel->lookups = ares_strdup(options->lookups);
532
- if (!channel->lookups)
533
- return ARES_ENOMEM;
534
- }
535
-
536
- /* copy sortlist */
537
- if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1)) {
538
- if (options->nsort > 0) {
539
- channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
540
- if (!channel->sortlist)
541
- return ARES_ENOMEM;
542
- for (i = 0; i < options->nsort; i++)
543
- channel->sortlist[i] = options->sortlist[i];
544
- }
545
- channel->nsort = options->nsort;
546
- }
547
-
548
- /* Set path for resolv.conf file, if given. */
549
- if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
550
- {
551
- channel->resolvconf_path = ares_strdup(options->resolvconf_path);
552
- if (!channel->resolvconf_path && options->resolvconf_path)
553
- return ARES_ENOMEM;
554
- }
555
-
556
- /* Set path for hosts file, if given. */
557
- if ((optmask & ARES_OPT_HOSTS_FILE) && !channel->hosts_path)
558
- {
559
- channel->hosts_path = ares_strdup(options->hosts_path);
560
- if (!channel->hosts_path && options->hosts_path)
561
- return ARES_ENOMEM;
562
- }
563
-
564
- channel->optmask = optmask;
565
-
566
- return ARES_SUCCESS;
567
- }
568
-
569
- static int init_by_environment(ares_channel channel)
570
- {
571
- const char *localdomain, *res_options;
572
- int status;
573
-
574
- localdomain = getenv("LOCALDOMAIN");
575
- if (localdomain && channel->ndomains == -1)
576
- {
577
- status = set_search(channel, localdomain);
578
- if (status != ARES_SUCCESS)
579
- return status;
580
- }
581
-
582
- res_options = getenv("RES_OPTIONS");
583
- if (res_options)
584
- {
585
- status = set_options(channel, res_options);
586
- if (status != ARES_SUCCESS)
587
- return status; /* LCOV_EXCL_LINE: set_options() never fails */
588
- }
589
-
590
- return ARES_SUCCESS;
591
- }
592
-
593
- #ifdef WIN32
594
- /*
595
- * get_REG_SZ()
596
- *
597
- * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
598
- * to the name of the registry leaf key to be queried, fetch it's string
599
- * value and return a pointer in *outptr to a newly allocated memory area
600
- * holding it as a null-terminated string.
601
- *
602
- * Returns 0 and nullifies *outptr upon inability to return a string value.
603
- *
604
- * Returns 1 and sets *outptr when returning a dynamically allocated string.
605
- *
606
- * Supported on Windows NT 3.5 and newer.
607
- */
608
- static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
609
- {
610
- DWORD size = 0;
611
- int res;
612
-
613
- *outptr = NULL;
614
-
615
- /* Find out size of string stored in registry */
616
- res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size);
617
- if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
618
- return 0;
619
-
620
- /* Allocate buffer of indicated size plus one given that string
621
- might have been stored without null termination */
622
- *outptr = ares_malloc(size+1);
623
- if (!*outptr)
624
- return 0;
625
-
626
- /* Get the value for real */
627
- res = RegQueryValueExA(hKey, leafKeyName, 0, NULL,
628
- (unsigned char *)*outptr, &size);
629
- if ((res != ERROR_SUCCESS) || (size == 1))
630
- {
631
- ares_free(*outptr);
632
- *outptr = NULL;
633
- return 0;
634
- }
635
-
636
- /* Null terminate buffer allways */
637
- *(*outptr + size) = '\0';
638
-
639
- return 1;
640
- }
641
-
642
- static void commanjoin(char** dst, const char* const src, const size_t len)
643
- {
644
- char *newbuf;
645
- size_t newsize;
646
-
647
- /* 1 for terminating 0 and 2 for , and terminating 0 */
648
- newsize = len + (*dst ? (strlen(*dst) + 2) : 1);
649
- newbuf = ares_realloc(*dst, newsize);
650
- if (!newbuf)
651
- return;
652
- if (*dst == NULL)
653
- *newbuf = '\0';
654
- *dst = newbuf;
655
- if (strlen(*dst) != 0)
656
- strcat(*dst, ",");
657
- strncat(*dst, src, len);
658
- }
659
-
660
- /*
661
- * commajoin()
662
- *
663
- * RTF code.
664
- */
665
- static void commajoin(char **dst, const char *src)
666
- {
667
- commanjoin(dst, src, strlen(src));
668
- }
669
-
670
-
671
- /* A structure to hold the string form of IPv4 and IPv6 addresses so we can
672
- * sort them by a metric.
673
- */
674
- typedef struct
675
- {
676
- /* The metric we sort them by. */
677
- ULONG metric;
678
-
679
- /* Original index of the item, used as a secondary sort parameter to make
680
- * qsort() stable if the metrics are equal */
681
- size_t orig_idx;
682
-
683
- /* Room enough for the string form of any IPv4 or IPv6 address that
684
- * ares_inet_ntop() will create. Based on the existing c-ares practice.
685
- */
686
- char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
687
- } Address;
688
-
689
- /* Sort Address values \a left and \a right by metric, returning the usual
690
- * indicators for qsort().
691
- */
692
- static int compareAddresses(const void *arg1,
693
- const void *arg2)
694
- {
695
- const Address * const left = arg1;
696
- const Address * const right = arg2;
697
- /* Lower metric the more preferred */
698
- if(left->metric < right->metric) return -1;
699
- if(left->metric > right->metric) return 1;
700
- /* If metrics are equal, lower original index more preferred */
701
- if(left->orig_idx < right->orig_idx) return -1;
702
- if(left->orig_idx > right->orig_idx) return 1;
703
- return 0;
704
- }
705
-
706
- /* There can be multiple routes to "the Internet". And there can be different
707
- * DNS servers associated with each of the interfaces that offer those routes.
708
- * We have to assume that any DNS server can serve any request. But, some DNS
709
- * servers may only respond if requested over their associated interface. But
710
- * we also want to use "the preferred route to the Internet" whenever possible
711
- * (and not use DNS servers on a non-preferred route even by forcing request
712
- * to go out on the associated non-preferred interface). i.e. We want to use
713
- * the DNS servers associated with the same interface that we would use to
714
- * make a general request to anything else.
715
- *
716
- * But, Windows won't sort the DNS servers by the metrics associated with the
717
- * routes and interfaces _even_ though it obviously sends IP packets based on
718
- * those same routes and metrics. So, we must do it ourselves.
719
- *
720
- * So, we sort the DNS servers by the same metric values used to determine how
721
- * an outgoing IP packet will go, thus effectively using the DNS servers
722
- * associated with the interface that the DNS requests themselves will
723
- * travel. This gives us optimal routing and avoids issues where DNS servers
724
- * won't respond to requests that don't arrive via some specific subnetwork
725
- * (and thus some specific interface).
726
- *
727
- * This function computes the metric we use to sort. On the interface
728
- * identified by \a luid, it determines the best route to \a dest and combines
729
- * that route's metric with \a interfaceMetric to compute a metric for the
730
- * destination address on that interface. This metric can be used as a weight
731
- * to sort the DNS server addresses associated with each interface (lower is
732
- * better).
733
- *
734
- * Note that by restricting the route search to the specific interface with
735
- * which the DNS servers are associated, this function asks the question "What
736
- * is the metric for sending IP packets to this DNS server?" which allows us
737
- * to sort the DNS servers correctly.
738
- */
739
- static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
740
- const SOCKADDR_INET * const dest,
741
- const ULONG interfaceMetric)
742
- {
743
- /* On this interface, get the best route to that destination. */
744
- #if defined(__WATCOMC__)
745
- /* OpenWatcom's builtin Windows SDK does not have a definition for
746
- * MIB_IPFORWARD_ROW2, and also does not allow the usage of SOCKADDR_INET
747
- * as a variable. Let's work around this by returning the worst possible
748
- * metric, but only when using the OpenWatcom compiler.
749
- * It may be worth investigating using a different version of the Windows
750
- * SDK with OpenWatcom in the future, though this may be fixed in OpenWatcom
751
- * 2.0.
752
- */
753
- return (ULONG)-1;
754
- #else
755
- MIB_IPFORWARD_ROW2 row;
756
- SOCKADDR_INET ignored;
757
- if(GetBestRoute2(/* The interface to use. The index is ignored since we are
758
- * passing a LUID.
759
- */
760
- luid, 0,
761
- /* No specific source address. */
762
- NULL,
763
- /* Our destination address. */
764
- dest,
765
- /* No options. */
766
- 0,
767
- /* The route row. */
768
- &row,
769
- /* The best source address, which we don't need. */
770
- &ignored) != NO_ERROR
771
- /* If the metric is "unused" (-1) or too large for us to add the two
772
- * metrics, use the worst possible, thus sorting this last.
773
- */
774
- || row.Metric == (ULONG)-1
775
- || row.Metric > ((ULONG)-1) - interfaceMetric) {
776
- /* Return the worst possible metric. */
777
- return (ULONG)-1;
778
- }
779
-
780
- /* Return the metric value from that row, plus the interface metric.
781
- *
782
- * See
783
- * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
784
- * which describes the combination as a "sum".
785
- */
786
- return row.Metric + interfaceMetric;
787
- #endif /* __WATCOMC__ */
788
- }
789
-
790
- /*
791
- * get_DNS_Windows()
792
- *
793
- * Locates DNS info using GetAdaptersAddresses() function from the Internet
794
- * Protocol Helper (IP Helper) API. When located, this returns a pointer
795
- * in *outptr to a newly allocated memory area holding a null-terminated
796
- * string with a space or comma seperated list of DNS IP addresses.
797
- *
798
- * Returns 0 and nullifies *outptr upon inability to return DNSes string.
799
- *
800
- * Returns 1 and sets *outptr when returning a dynamically allocated string.
801
- *
802
- * Implementation supports Windows XP and newer.
803
- */
804
- #define IPAA_INITIAL_BUF_SZ 15 * 1024
805
- #define IPAA_MAX_TRIES 3
806
- static int get_DNS_Windows(char **outptr)
807
- {
808
- IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
809
- IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
810
- ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
811
- ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
812
- ULONG AddrFlags = 0;
813
- int trying = IPAA_MAX_TRIES;
814
- int res;
815
-
816
- /* The capacity of addresses, in elements. */
817
- size_t addressesSize;
818
- /* The number of elements in addresses. */
819
- size_t addressesIndex = 0;
820
- /* The addresses we will sort. */
821
- Address *addresses;
822
-
823
- union {
824
- struct sockaddr *sa;
825
- struct sockaddr_in *sa4;
826
- struct sockaddr_in6 *sa6;
827
- } namesrvr;
828
-
829
- *outptr = NULL;
830
-
831
- ipaa = ares_malloc(Bufsz);
832
- if (!ipaa)
833
- return 0;
834
-
835
- /* Start with enough room for a few DNS server addresses and we'll grow it
836
- * as we encounter more.
837
- */
838
- addressesSize = 4;
839
- addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
840
- if(addresses == NULL) {
841
- /* We need room for at least some addresses to function. */
842
- ares_free(ipaa);
843
- return 0;
844
- }
845
-
846
- /* Usually this call suceeds with initial buffer size */
847
- res = GetAdaptersAddresses(AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz);
848
- if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
849
- goto done;
850
-
851
- while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
852
- {
853
- if (Bufsz < ReqBufsz)
854
- {
855
- newipaa = ares_realloc(ipaa, ReqBufsz);
856
- if (!newipaa)
857
- goto done;
858
- Bufsz = ReqBufsz;
859
- ipaa = newipaa;
860
- }
861
- res = GetAdaptersAddresses(AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz);
862
- if (res == ERROR_SUCCESS)
863
- break;
864
- }
865
- if (res != ERROR_SUCCESS)
866
- goto done;
867
-
868
- for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
869
- {
870
- if(ipaaEntry->OperStatus != IfOperStatusUp)
871
- continue;
872
-
873
- /* For each interface, find any associated DNS servers as IPv4 or IPv6
874
- * addresses. For each found address, find the best route to that DNS
875
- * server address _on_ _that_ _interface_ (at this moment in time) and
876
- * compute the resulting total metric, just as Windows routing will do.
877
- * Then, sort all the addresses found by the metric.
878
- */
879
- for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
880
- ipaDNSAddr;
881
- ipaDNSAddr = ipaDNSAddr->Next)
882
- {
883
- namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
884
-
885
- if (namesrvr.sa->sa_family == AF_INET)
886
- {
887
- if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
888
- (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
889
- continue;
890
-
891
- /* Allocate room for another address, if necessary, else skip. */
892
- if(addressesIndex == addressesSize) {
893
- const size_t newSize = addressesSize + 4;
894
- Address * const newMem =
895
- (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
896
- if(newMem == NULL) {
897
- continue;
898
- }
899
- addresses = newMem;
900
- addressesSize = newSize;
901
- }
902
-
903
- addresses[addressesIndex].metric =
904
- getBestRouteMetric(&ipaaEntry->Luid,
905
- (SOCKADDR_INET*)(namesrvr.sa),
906
- ipaaEntry->Ipv4Metric);
907
-
908
- /* Record insertion index to make qsort stable */
909
- addresses[addressesIndex].orig_idx = addressesIndex;
910
-
911
- if (!ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
912
- addresses[addressesIndex].text,
913
- sizeof(addresses[0].text))) {
914
- continue;
915
- }
916
- ++addressesIndex;
917
- }
918
- else if (namesrvr.sa->sa_family == AF_INET6)
919
- {
920
- if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
921
- sizeof(namesrvr.sa6->sin6_addr)) == 0)
922
- continue;
923
-
924
- /* Allocate room for another address, if necessary, else skip. */
925
- if(addressesIndex == addressesSize) {
926
- const size_t newSize = addressesSize + 4;
927
- Address * const newMem =
928
- (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
929
- if(newMem == NULL) {
930
- continue;
931
- }
932
- addresses = newMem;
933
- addressesSize = newSize;
934
- }
935
-
936
- addresses[addressesIndex].metric =
937
- getBestRouteMetric(&ipaaEntry->Luid,
938
- (SOCKADDR_INET*)(namesrvr.sa),
939
- ipaaEntry->Ipv6Metric);
940
-
941
- /* Record insertion index to make qsort stable */
942
- addresses[addressesIndex].orig_idx = addressesIndex;
943
-
944
- if (!ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
945
- addresses[addressesIndex].text,
946
- sizeof(addresses[0].text))) {
947
- continue;
948
- }
949
- ++addressesIndex;
950
- }
951
- else {
952
- /* Skip non-IPv4/IPv6 addresses completely. */
953
- continue;
954
- }
955
- }
956
- }
957
-
958
- /* Sort all of the textual addresses by their metric (and original index if
959
- * metrics are equal). */
960
- qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses);
961
-
962
- /* Join them all into a single string, removing duplicates. */
963
- {
964
- size_t i;
965
- for(i = 0; i < addressesIndex; ++i) {
966
- size_t j;
967
- /* Look for this address text appearing previously in the results. */
968
- for(j = 0; j < i; ++j) {
969
- if(strcmp(addresses[j].text, addresses[i].text) == 0) {
970
- break;
971
- }
972
- }
973
- /* Iff we didn't emit this address already, emit it now. */
974
- if(j == i) {
975
- /* Add that to outptr (if we can). */
976
- commajoin(outptr, addresses[i].text);
977
- }
978
- }
979
- }
980
-
981
- done:
982
- ares_free(addresses);
983
-
984
- if (ipaa)
985
- ares_free(ipaa);
986
-
987
- if (!*outptr) {
988
- return 0;
989
- }
990
-
991
- return 1;
992
- }
993
-
994
- /*
995
- * get_SuffixList_Windows()
996
- *
997
- * Reads the "DNS Suffix Search List" from registry and writes the list items
998
- * whitespace separated to outptr. If the Search List is empty, the
999
- * "Primary Dns Suffix" is written to outptr.
1000
- *
1001
- * Returns 0 and nullifies *outptr upon inability to return the suffix list.
1002
- *
1003
- * Returns 1 and sets *outptr when returning a dynamically allocated string.
1004
- *
1005
- * Implementation supports Windows Server 2003 and newer
1006
- */
1007
- static int get_SuffixList_Windows(char **outptr)
1008
- {
1009
- HKEY hKey, hKeyEnum;
1010
- char keyName[256];
1011
- DWORD keyNameBuffSize;
1012
- DWORD keyIdx = 0;
1013
- char *p = NULL;
1014
-
1015
- *outptr = NULL;
1016
-
1017
- if (ares__getplatform() != WIN_NT)
1018
- return 0;
1019
-
1020
- /* 1. Global DNS Suffix Search List */
1021
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
1022
- KEY_READ, &hKey) == ERROR_SUCCESS)
1023
- {
1024
- get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
1025
- if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
1026
- {
1027
- commajoin(outptr, p);
1028
- ares_free(p);
1029
- p = NULL;
1030
- }
1031
- RegCloseKey(hKey);
1032
- }
1033
-
1034
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
1035
- KEY_READ, &hKey) == ERROR_SUCCESS)
1036
- {
1037
- if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
1038
- {
1039
- commajoin(outptr, p);
1040
- ares_free(p);
1041
- p = NULL;
1042
- }
1043
- RegCloseKey(hKey);
1044
- }
1045
-
1046
- /* 2. Connection Specific Search List composed of:
1047
- * a. Primary DNS Suffix */
1048
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
1049
- KEY_READ, &hKey) == ERROR_SUCCESS)
1050
- {
1051
- if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
1052
- {
1053
- commajoin(outptr, p);
1054
- ares_free(p);
1055
- p = NULL;
1056
- }
1057
- RegCloseKey(hKey);
1058
- }
1059
-
1060
- /* b. Interface SearchList, Domain, DhcpDomain */
1061
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
1062
- KEY_READ, &hKey) == ERROR_SUCCESS)
1063
- {
1064
- for(;;)
1065
- {
1066
- keyNameBuffSize = sizeof(keyName);
1067
- if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
1068
- 0, NULL, NULL, NULL)
1069
- != ERROR_SUCCESS)
1070
- break;
1071
- if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
1072
- != ERROR_SUCCESS)
1073
- continue;
1074
- /* p can be comma separated (SearchList) */
1075
- if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
1076
- {
1077
- commajoin(outptr, p);
1078
- ares_free(p);
1079
- p = NULL;
1080
- }
1081
- if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
1082
- {
1083
- commajoin(outptr, p);
1084
- ares_free(p);
1085
- p = NULL;
1086
- }
1087
- if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
1088
- {
1089
- commajoin(outptr, p);
1090
- ares_free(p);
1091
- p = NULL;
1092
- }
1093
- RegCloseKey(hKeyEnum);
1094
- }
1095
- RegCloseKey(hKey);
1096
- }
1097
-
1098
- return *outptr != NULL;
1099
- }
1100
-
1101
- #endif
1102
-
1103
- static int init_by_resolv_conf(ares_channel channel)
1104
- {
1105
- #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1106
- !defined(CARES_USE_LIBRESOLV)
1107
- char *line = NULL;
1108
- #endif
1109
- int status = -1, nservers = 0, nsort = 0;
1110
- struct server_state *servers = NULL;
1111
- struct apattern *sortlist = NULL;
1112
-
1113
- #ifdef WIN32
1114
-
1115
- if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1116
- return ARES_SUCCESS;
1117
-
1118
- if (get_DNS_Windows(&line))
1119
- {
1120
- status = config_nameserver(&servers, &nservers, line);
1121
- ares_free(line);
1122
- }
1123
-
1124
- if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
1125
- {
1126
- status = set_search(channel, line);
1127
- ares_free(line);
1128
- }
1129
-
1130
- if (status == ARES_SUCCESS)
1131
- status = ARES_EOF;
1132
- else
1133
- /* Catch the case when all the above checks fail (which happens when there
1134
- is no network card or the cable is unplugged) */
1135
- status = ARES_EFILE;
1136
- #elif defined(__MVS__)
1137
-
1138
- struct __res_state *res = 0;
1139
- int count4, count6;
1140
- __STATEEXTIPV6 *v6;
1141
- struct server_state *pserver;
1142
- if (0 == res) {
1143
- int rc = res_init();
1144
- while (rc == -1 && h_errno == TRY_AGAIN) {
1145
- rc = res_init();
1146
- }
1147
- if (rc == -1) {
1148
- return ARES_ENOMEM;
1149
- }
1150
- res = __res();
1151
- }
1152
-
1153
- v6 = res->__res_extIPv6;
1154
- count4 = res->nscount;
1155
- if (v6) {
1156
- count6 = v6->__stat_nscount;
1157
- } else {
1158
- count6 = 0;
1159
- }
1160
-
1161
- nservers = count4 + count6;
1162
- servers = ares_malloc(nservers * sizeof(struct server_state));
1163
- if (!servers)
1164
- return ARES_ENOMEM;
1165
-
1166
- memset(servers, 0, nservers * sizeof(struct server_state));
1167
-
1168
- pserver = servers;
1169
- for (int i = 0; i < count4; ++i, ++pserver) {
1170
- struct sockaddr_in *addr_in = &(res->nsaddr_list[i]);
1171
- pserver->addr.addrV4.s_addr = addr_in->sin_addr.s_addr;
1172
- pserver->addr.family = AF_INET;
1173
- pserver->addr.udp_port = addr_in->sin_port;
1174
- pserver->addr.tcp_port = addr_in->sin_port;
1175
- }
1176
-
1177
- for (int j = 0; j < count6; ++j, ++pserver) {
1178
- struct sockaddr_in6 *addr_in = &(v6->__stat_nsaddr_list[j]);
1179
- memcpy(&(pserver->addr.addr.addr6), &(addr_in->sin6_addr),
1180
- sizeof(addr_in->sin6_addr));
1181
- pserver->addr.family = AF_INET6;
1182
- pserver->addr.udp_port = addr_in->sin6_port;
1183
- pserver->addr.tcp_port = addr_in->sin6_port;
1184
- }
1185
-
1186
- status = ARES_EOF;
1187
-
1188
- #elif defined(__riscos__)
1189
-
1190
- /* Under RISC OS, name servers are listed in the
1191
- system variable Inet$Resolvers, space separated. */
72
+ static int ares_query_timeout_cmp_cb(const void *arg1, const void *arg2)
73
+ {
74
+ const ares_query_t *q1 = arg1;
75
+ const ares_query_t *q2 = arg2;
1192
76
 
1193
- line = getenv("Inet$Resolvers");
1194
- status = ARES_EOF;
1195
- if (line) {
1196
- char *resolvers = ares_strdup(line), *pos, *space;
77
+ if (q1->timeout.sec > q2->timeout.sec) {
78
+ return 1;
79
+ }
80
+ if (q1->timeout.sec < q2->timeout.sec) {
81
+ return -1;
82
+ }
1197
83
 
1198
- if (!resolvers)
1199
- return ARES_ENOMEM;
84
+ if (q1->timeout.usec > q2->timeout.usec) {
85
+ return 1;
86
+ }
87
+ if (q1->timeout.usec < q2->timeout.usec) {
88
+ return -1;
89
+ }
1200
90
 
1201
- pos = resolvers;
1202
- do {
1203
- space = strchr(pos, ' ');
1204
- if (space)
1205
- *space = '\0';
1206
- status = config_nameserver(&servers, &nservers, pos);
1207
- if (status != ARES_SUCCESS)
1208
- break;
1209
- pos = space + 1;
1210
- } while (space);
91
+ return 0;
92
+ }
1211
93
 
1212
- if (status == ARES_SUCCESS)
1213
- status = ARES_EOF;
94
+ static int server_sort_cb(const void *data1, const void *data2)
95
+ {
96
+ const ares_server_t *s1 = data1;
97
+ const ares_server_t *s2 = data2;
1214
98
 
1215
- ares_free(resolvers);
99
+ if (s1->consec_failures < s2->consec_failures) {
100
+ return -1;
1216
101
  }
1217
-
1218
- #elif defined(WATT32)
1219
- int i;
1220
-
1221
- sock_init();
1222
- for (i = 0; def_nameservers[i]; i++)
1223
- ;
1224
- if (i == 0)
1225
- return ARES_SUCCESS; /* use localhost DNS server */
1226
-
1227
- nservers = i;
1228
- servers = ares_malloc(sizeof(struct server_state));
1229
- if (!servers)
1230
- return ARES_ENOMEM;
1231
- memset(servers, 0, sizeof(struct server_state));
1232
-
1233
- for (i = 0; def_nameservers[i]; i++)
1234
- {
1235
- servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1236
- servers[i].addr.family = AF_INET;
1237
- servers[i].addr.udp_port = 0;
1238
- servers[i].addr.tcp_port = 0;
102
+ if (s1->consec_failures > s2->consec_failures) {
103
+ return 1;
1239
104
  }
1240
- status = ARES_EOF;
1241
-
1242
- #elif defined(ANDROID) || defined(__ANDROID__)
1243
- unsigned int i;
1244
- char **dns_servers;
1245
- char *domains;
1246
- size_t num_servers;
1247
-
1248
- /* Use the Android connectivity manager to get a list
1249
- * of DNS servers. As of Android 8 (Oreo) net.dns#
1250
- * system properties are no longer available. Google claims this
1251
- * improves privacy. Apps now need the ACCESS_NETWORK_STATE
1252
- * permission and must use the ConnectivityManager which
1253
- * is Java only. */
1254
- dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers);
1255
- if (dns_servers != NULL)
1256
- {
1257
- for (i = 0; i < num_servers; i++)
1258
- {
1259
- status = config_nameserver(&servers, &nservers, dns_servers[i]);
1260
- if (status != ARES_SUCCESS)
1261
- break;
1262
- status = ARES_EOF;
1263
- }
1264
- for (i = 0; i < num_servers; i++)
1265
- {
1266
- ares_free(dns_servers[i]);
1267
- }
1268
- ares_free(dns_servers);
105
+ if (s1->idx < s2->idx) {
106
+ return -1;
1269
107
  }
1270
- if (channel->ndomains == -1)
1271
- {
1272
- domains = ares_get_android_search_domains_list();
1273
- set_search(channel, domains);
1274
- ares_free(domains);
108
+ if (s1->idx > s2->idx) {
109
+ return 1;
1275
110
  }
111
+ return 0;
112
+ }
1276
113
 
1277
- # ifdef HAVE___SYSTEM_PROPERTY_GET
1278
- /* Old way using the system property still in place as
1279
- * a fallback. Older android versions can still use this.
1280
- * it's possible for older apps not not have added the new
1281
- * permission and we want to try to avoid breaking those.
1282
- *
1283
- * We'll only run this if we don't have any dns servers
1284
- * because this will get the same ones (if it works). */
1285
- if (status != ARES_EOF) {
1286
- char propname[PROP_NAME_MAX];
1287
- char propvalue[PROP_VALUE_MAX]="";
1288
- for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1289
- snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1290
- if (__system_property_get(propname, propvalue) < 1) {
1291
- status = ARES_EOF;
1292
- break;
1293
- }
1294
-
1295
- status = config_nameserver(&servers, &nservers, propvalue);
1296
- if (status != ARES_SUCCESS)
1297
- break;
1298
- status = ARES_EOF;
1299
- }
114
+ static void server_destroy_cb(void *data)
115
+ {
116
+ if (data == NULL) {
117
+ return; /* LCOV_EXCL_LINE: DefensiveCoding */
1300
118
  }
1301
- # endif /* HAVE___SYSTEM_PROPERTY_GET */
1302
- #elif defined(CARES_USE_LIBRESOLV)
1303
- struct __res_state res;
1304
- memset(&res, 0, sizeof(res));
1305
- int result = res_ninit(&res);
1306
- if (result == 0 && (res.options & RES_INIT)) {
1307
- status = ARES_EOF;
1308
-
1309
- if (channel->nservers == -1) {
1310
- union res_sockaddr_union addr[MAXNS];
1311
- int nscount = res_getservers(&res, addr, MAXNS);
1312
- int i;
1313
- for (i = 0; i < nscount; ++i) {
1314
- char str[INET6_ADDRSTRLEN];
1315
- int config_status;
1316
- sa_family_t family = addr[i].sin.sin_family;
1317
- if (family == AF_INET) {
1318
- ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
1319
- } else if (family == AF_INET6) {
1320
- ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
1321
- } else {
1322
- continue;
1323
- }
1324
-
1325
- config_status = config_nameserver(&servers, &nservers, str);
1326
- if (config_status != ARES_SUCCESS) {
1327
- status = config_status;
1328
- break;
1329
- }
1330
- }
1331
- }
1332
- if (channel->ndomains == -1) {
1333
- int entries = 0;
1334
- while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1335
- entries++;
1336
- if(entries) {
1337
- channel->domains = ares_malloc(entries * sizeof(char *));
1338
- if (!channel->domains) {
1339
- status = ARES_ENOMEM;
1340
- } else {
1341
- int i;
1342
- channel->ndomains = entries;
1343
- for (i = 0; i < channel->ndomains; ++i) {
1344
- channel->domains[i] = ares_strdup(res.dnsrch[i]);
1345
- if (!channel->domains[i])
1346
- status = ARES_ENOMEM;
1347
- }
1348
- }
1349
- }
1350
- }
1351
- if (channel->ndots == -1)
1352
- channel->ndots = res.ndots;
1353
- if (channel->tries == -1)
1354
- channel->tries = res.retry;
1355
- if (channel->rotate == -1)
1356
- channel->rotate = res.options & RES_ROTATE;
1357
- if (channel->timeout == -1) {
1358
- channel->timeout = res.retrans * 1000;
1359
- #ifdef __APPLE__
1360
- channel->timeout /= (res.retry + 1) * (res.nscount > 0 ? res.nscount : 1);
119
+ ares_destroy_server(data);
120
+ }
121
+
122
+ static ares_status_t init_by_defaults(ares_channel_t *channel)
123
+ {
124
+ char *hostname = NULL;
125
+ ares_status_t rc = ARES_SUCCESS;
126
+ #ifdef HAVE_GETHOSTNAME
127
+ const char *dot;
1361
128
  #endif
1362
- }
129
+ struct ares_addr addr;
130
+ ares_llist_t *sconfig = NULL;
1363
131
 
1364
- res_ndestroy(&res);
132
+ /* Enable EDNS by default */
133
+ if (!(channel->optmask & ARES_OPT_FLAGS)) {
134
+ channel->flags = ARES_FLAG_EDNS;
135
+ }
136
+ if (channel->ednspsz == 0) {
137
+ channel->ednspsz = EDNSPACKETSZ;
1365
138
  }
1366
- #else
1367
- {
1368
- char *p;
1369
- FILE *fp;
1370
- size_t linesize;
1371
- int error;
1372
- int update_domains;
1373
- const char *resolvconf_path;
1374
-
1375
- /* Don't read resolv.conf and friends if we don't have to */
1376
- if (ARES_CONFIG_CHECK(channel))
1377
- return ARES_SUCCESS;
1378
-
1379
- /* Only update search domains if they're not already specified */
1380
- update_domains = (channel->ndomains == -1);
1381
-
1382
- /* Support path for resolvconf filename set by ares_init_options */
1383
- if(channel->resolvconf_path) {
1384
- resolvconf_path = channel->resolvconf_path;
1385
- } else {
1386
- resolvconf_path = PATH_RESOLV_CONF;
1387
- }
1388
-
1389
- fp = fopen(resolvconf_path, "r");
1390
- if (fp) {
1391
- while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1392
- {
1393
- if ((p = try_config(line, "domain", ';')) && update_domains)
1394
- status = config_domain(channel, p);
1395
- else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1396
- status = config_lookup(channel, p, "bind", NULL, "file");
1397
- else if ((p = try_config(line, "search", ';')) && update_domains)
1398
- status = set_search(channel, p);
1399
- else if ((p = try_config(line, "nameserver", ';')) &&
1400
- channel->nservers == -1)
1401
- status = config_nameserver(&servers, &nservers, p);
1402
- else if ((p = try_config(line, "sortlist", ';')) &&
1403
- channel->nsort == -1)
1404
- status = config_sortlist(&sortlist, &nsort, p);
1405
- else if ((p = try_config(line, "options", ';')))
1406
- status = set_options(channel, p);
1407
- else
1408
- status = ARES_SUCCESS;
1409
- if (status != ARES_SUCCESS)
1410
- break;
1411
- }
1412
- fclose(fp);
1413
- }
1414
- else {
1415
- error = ERRNO;
1416
- switch(error) {
1417
- case ENOENT:
1418
- case ESRCH:
1419
- status = ARES_EOF;
1420
- break;
1421
- default:
1422
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1423
- error, strerror(error)));
1424
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1425
- status = ARES_EFILE;
1426
- }
1427
- }
1428
-
1429
- if ((status == ARES_EOF) && (!channel->lookups)) {
1430
- /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1431
- fp = fopen("/etc/nsswitch.conf", "r");
1432
- if (fp) {
1433
- while ((status = ares__read_line(fp, &line, &linesize)) ==
1434
- ARES_SUCCESS)
1435
- {
1436
- if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1437
- (void)config_lookup(channel, p, "dns", "resolve", "files");
1438
- }
1439
- fclose(fp);
1440
- }
1441
- else {
1442
- error = ERRNO;
1443
- switch(error) {
1444
- case ENOENT:
1445
- case ESRCH:
1446
- break;
1447
- default:
1448
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1449
- error, strerror(error)));
1450
- DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1451
- "/etc/nsswitch.conf"));
1452
- }
1453
-
1454
- /* ignore error, maybe we will get luck in next if clause */
1455
- status = ARES_EOF;
1456
- }
1457
- }
1458
-
1459
- if ((status == ARES_EOF) && (!channel->lookups)) {
1460
- /* Linux / GNU libc 2.x and possibly others have host.conf */
1461
- fp = fopen("/etc/host.conf", "r");
1462
- if (fp) {
1463
- while ((status = ares__read_line(fp, &line, &linesize)) ==
1464
- ARES_SUCCESS)
1465
- {
1466
- if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1467
- /* ignore errors */
1468
- (void)config_lookup(channel, p, "bind", NULL, "hosts");
1469
- }
1470
- fclose(fp);
1471
- }
1472
- else {
1473
- error = ERRNO;
1474
- switch(error) {
1475
- case ENOENT:
1476
- case ESRCH:
1477
- break;
1478
- default:
1479
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1480
- error, strerror(error)));
1481
- DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1482
- "/etc/host.conf"));
1483
- }
1484
-
1485
- /* ignore error, maybe we will get luck in next if clause */
1486
- status = ARES_EOF;
1487
- }
1488
- }
1489
-
1490
- if ((status == ARES_EOF) && (!channel->lookups)) {
1491
- /* Tru64 uses /etc/svc.conf */
1492
- fp = fopen("/etc/svc.conf", "r");
1493
- if (fp) {
1494
- while ((status = ares__read_line(fp, &line, &linesize)) ==
1495
- ARES_SUCCESS)
1496
- {
1497
- if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1498
- /* ignore errors */
1499
- (void)config_lookup(channel, p, "bind", NULL, "local");
1500
- }
1501
- fclose(fp);
1502
- }
1503
- else {
1504
- error = ERRNO;
1505
- switch(error) {
1506
- case ENOENT:
1507
- case ESRCH:
1508
- break;
1509
- default:
1510
- DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1511
- error, strerror(error)));
1512
- DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1513
- }
1514
-
1515
- /* ignore error, default value will be chosen for `channel->lookups` */
1516
- status = ARES_EOF;
1517
- }
1518
- }
1519
139
 
1520
- if(line)
1521
- ares_free(line);
140
+ if (channel->timeout == 0) {
141
+ channel->timeout = DEFAULT_TIMEOUT;
1522
142
  }
1523
143
 
1524
- #endif
144
+ if (channel->tries == 0) {
145
+ channel->tries = DEFAULT_TRIES;
146
+ }
1525
147
 
1526
- /* Handle errors. */
1527
- if (status != ARES_EOF)
1528
- {
1529
- if (servers != NULL)
1530
- ares_free(servers);
1531
- if (sortlist != NULL)
1532
- ares_free(sortlist);
1533
- return status;
148
+ if (ares_slist_len(channel->servers) == 0) {
149
+ /* Add a default local named server to the channel unless configured not
150
+ * to (in which case return an error).
151
+ */
152
+ if (channel->flags & ARES_FLAG_NO_DFLT_SVR) {
153
+ rc = ARES_ENOSERVER;
154
+ goto error;
1534
155
  }
1535
156
 
1536
- /* If we got any name server entries, fill them in. */
1537
- if (servers)
1538
- {
1539
- channel->servers = servers;
1540
- channel->nservers = nservers;
1541
- }
157
+ addr.family = AF_INET;
158
+ addr.addr.addr4.s_addr = htonl(INADDR_LOOPBACK);
1542
159
 
1543
- /* If we got any sortlist entries, fill them in. */
1544
- if (sortlist)
1545
- {
1546
- channel->sortlist = sortlist;
1547
- channel->nsort = nsort;
160
+ rc = ares_sconfig_append(channel, &sconfig, &addr, 0, 0, NULL);
161
+ if (rc != ARES_SUCCESS) {
162
+ goto error; /* LCOV_EXCL_LINE: OutOfMemory */
1548
163
  }
1549
164
 
1550
- return ARES_SUCCESS;
1551
- }
1552
-
1553
- static int init_by_defaults(ares_channel channel)
1554
- {
1555
- char *hostname = NULL;
1556
- int rc = ARES_SUCCESS;
1557
- #ifdef HAVE_GETHOSTNAME
1558
- char *dot;
1559
- #endif
1560
-
1561
- if (channel->flags == -1)
1562
- channel->flags = 0;
1563
- if (channel->timeout == -1)
1564
- channel->timeout = DEFAULT_TIMEOUT;
1565
- if (channel->tries == -1)
1566
- channel->tries = DEFAULT_TRIES;
1567
- if (channel->ndots == -1)
1568
- channel->ndots = 1;
1569
- if (channel->rotate == -1)
1570
- channel->rotate = 0;
1571
- if (channel->udp_port == -1)
1572
- channel->udp_port = htons(NAMESERVER_PORT);
1573
- if (channel->tcp_port == -1)
1574
- channel->tcp_port = htons(NAMESERVER_PORT);
1575
-
1576
- if (channel->ednspsz == -1)
1577
- channel->ednspsz = EDNSPACKETSZ;
165
+ rc = ares_servers_update(channel, sconfig, ARES_FALSE);
166
+ ares_llist_destroy(sconfig);
1578
167
 
1579
- if (channel->nservers == -1) {
1580
- /* If nobody specified servers, try a local named. */
1581
- channel->servers = ares_malloc(sizeof(struct server_state));
1582
- if (!channel->servers) {
1583
- rc = ARES_ENOMEM;
168
+ if (rc != ARES_SUCCESS) {
1584
169
  goto error;
1585
170
  }
1586
- channel->servers[0].addr.family = AF_INET;
1587
- channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1588
- channel->servers[0].addr.udp_port = 0;
1589
- channel->servers[0].addr.tcp_port = 0;
1590
- channel->nservers = 1;
1591
171
  }
1592
172
 
1593
- #if defined(USE_WINSOCK)
1594
- #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1595
- #elif defined(ENAMETOOLONG)
1596
- #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1597
- (SOCKERRNO == EINVAL))
1598
- #else
1599
- #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1600
- #endif
1601
-
1602
- if (channel->ndomains == -1) {
173
+ if (channel->ndomains == 0) {
1603
174
  /* Derive a default domain search list from the kernel hostname,
1604
175
  * or set it to empty if the hostname isn't helpful.
1605
176
  */
1606
177
  #ifndef HAVE_GETHOSTNAME
1607
178
  channel->ndomains = 0; /* default to none */
1608
179
  #else
1609
- GETHOSTNAME_TYPE_ARG2 lenv = 64;
1610
- size_t len = 64;
1611
- int res;
180
+ size_t len = 256;
1612
181
  channel->ndomains = 0; /* default to none */
1613
182
 
1614
183
  hostname = ares_malloc(len);
1615
- if(!hostname) {
1616
- rc = ARES_ENOMEM;
1617
- goto error;
184
+ if (!hostname) {
185
+ rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
186
+ goto error; /* LCOV_EXCL_LINE: OutOfMemory */
1618
187
  }
1619
188
 
1620
- do {
1621
- res = gethostname(hostname, lenv);
1622
-
1623
- if(toolong(res)) {
1624
- char *p;
1625
- len *= 2;
1626
- lenv *= 2;
1627
- p = ares_realloc(hostname, len);
1628
- if(!p) {
1629
- rc = ARES_ENOMEM;
1630
- goto error;
1631
- }
1632
- hostname = p;
1633
- continue;
1634
- }
1635
- else if(res) {
1636
- /* Lets not treat a gethostname failure as critical, since we
1637
- * are ok if gethostname doesn't even exist */
1638
- *hostname = '\0';
1639
- break;
1640
- }
1641
-
1642
- } while (res != 0);
189
+ if (gethostname(hostname, (GETHOSTNAME_TYPE_ARG2)len) != 0) {
190
+ /* Lets not treat a gethostname failure as critical, since we
191
+ * are ok if gethostname doesn't even exist */
192
+ *hostname = '\0';
193
+ }
1643
194
 
1644
195
  dot = strchr(hostname, '.');
1645
196
  if (dot) {
1646
197
  /* a dot was found */
1647
198
  channel->domains = ares_malloc(sizeof(char *));
1648
199
  if (!channel->domains) {
1649
- rc = ARES_ENOMEM;
1650
- goto error;
200
+ rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
201
+ goto error; /* LCOV_EXCL_LINE: OutOfMemory */
1651
202
  }
1652
203
  channel->domains[0] = ares_strdup(dot + 1);
1653
204
  if (!channel->domains[0]) {
1654
- rc = ARES_ENOMEM;
1655
- goto error;
205
+ rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
206
+ goto error; /* LCOV_EXCL_LINE: OutOfMemory */
1656
207
  }
1657
208
  channel->ndomains = 1;
1658
209
  }
1659
210
  #endif
1660
211
  }
1661
212
 
1662
- if (channel->nsort == -1) {
213
+ if (channel->nsort == 0) {
1663
214
  channel->sortlist = NULL;
1664
- channel->nsort = 0;
1665
215
  }
1666
216
 
1667
217
  if (!channel->lookups) {
1668
218
  channel->lookups = ares_strdup("fb");
1669
- if (!channel->lookups)
1670
- rc = ARES_ENOMEM;
1671
- }
1672
-
1673
- error:
1674
- if(rc) {
1675
- if(channel->servers) {
1676
- ares_free(channel->servers);
1677
- channel->servers = NULL;
1678
- }
1679
-
1680
- if(channel->domains && channel->domains[0])
1681
- ares_free(channel->domains[0]);
1682
- if(channel->domains) {
1683
- ares_free(channel->domains);
1684
- channel->domains = NULL;
1685
- }
1686
-
1687
- if(channel->lookups) {
1688
- ares_free(channel->lookups);
1689
- channel->lookups = NULL;
1690
- }
1691
-
1692
- if(channel->resolvconf_path) {
1693
- ares_free(channel->resolvconf_path);
1694
- channel->resolvconf_path = NULL;
219
+ if (!channel->lookups) {
220
+ rc = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
1695
221
  }
222
+ }
1696
223
 
1697
- if(channel->hosts_path) {
1698
- ares_free(channel->hosts_path);
1699
- channel->hosts_path = NULL;
1700
- }
224
+ /* Set default fields for server failover behavior */
225
+ if (!(channel->optmask & ARES_OPT_SERVER_FAILOVER)) {
226
+ channel->server_retry_chance = DEFAULT_SERVER_RETRY_CHANCE;
227
+ channel->server_retry_delay = DEFAULT_SERVER_RETRY_DELAY;
1701
228
  }
1702
229
 
1703
- if(hostname)
230
+ error:
231
+ if (hostname) {
1704
232
  ares_free(hostname);
233
+ }
1705
234
 
1706
235
  return rc;
1707
236
  }
1708
237
 
1709
- #if !defined(WIN32) && !defined(WATT32) && \
1710
- !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1711
- static int config_domain(ares_channel channel, char *str)
238
+ int ares_init_options(ares_channel_t **channelptr,
239
+ const struct ares_options *options, int optmask)
1712
240
  {
1713
- char *q;
1714
-
1715
- /* Set a single search domain. */
1716
- q = str;
1717
- while (*q && !ISSPACE(*q))
1718
- q++;
1719
- *q = '\0';
1720
- return set_search(channel, str);
1721
- }
241
+ ares_channel_t *channel;
242
+ ares_status_t status = ARES_SUCCESS;
1722
243
 
1723
- #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1724
- defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1725
- /* workaround icc 9.1 optimizer issue */
1726
- # define vqualifier volatile
1727
- #else
1728
- # define vqualifier
1729
- #endif
244
+ if (ares_library_initialized() != ARES_SUCCESS) {
245
+ return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
246
+ }
1730
247
 
1731
- static int config_lookup(ares_channel channel, const char *str,
1732
- const char *bindch, const char *altbindch,
1733
- const char *filech)
1734
- {
1735
- char lookups[3], *l;
1736
- const char *vqualifier p;
1737
- int found;
248
+ channel = ares_malloc_zero(sizeof(*channel));
249
+ if (!channel) {
250
+ *channelptr = NULL;
251
+ return ARES_ENOMEM;
252
+ }
1738
253
 
1739
- if (altbindch == NULL)
1740
- altbindch = bindch;
254
+ /* We are in a good state */
255
+ channel->sys_up = ARES_TRUE;
1741
256
 
1742
- /* Set the lookup order. Only the first letter of each work
1743
- * is relevant, and it has to be "b" for DNS or "f" for the
1744
- * host file. Ignore everything else.
1745
- */
1746
- l = lookups;
1747
- p = str;
1748
- found = 0;
1749
- while (*p)
1750
- {
1751
- if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
1752
- if (*p == *bindch || *p == *altbindch) *l++ = 'b';
1753
- else *l++ = 'f';
1754
- found = 1;
1755
- }
1756
- while (*p && !ISSPACE(*p) && (*p != ','))
1757
- p++;
1758
- while (*p && (ISSPACE(*p) || (*p == ',')))
1759
- p++;
1760
- }
1761
- if (!found)
1762
- return ARES_ENOTINITIALIZED;
1763
- *l = '\0';
1764
- channel->lookups = ares_strdup(lookups);
1765
- return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1766
- }
1767
- #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
257
+ /* One option where zero is valid, so set default value here */
258
+ channel->ndots = 1;
1768
259
 
1769
- #ifndef WATT32
1770
- /* Validate that the ip address matches the subnet (network base and network
1771
- * mask) specified. Addresses are specified in standard Network Byte Order as
1772
- * 16 bytes, and the netmask is 0 to 128 (bits).
1773
- */
1774
- static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
1775
- unsigned char netmask,
1776
- const unsigned char ipaddr[16])
1777
- {
1778
- unsigned char mask[16] = { 0 };
1779
- unsigned char i;
260
+ status = ares_channel_threading_init(channel);
261
+ if (status != ARES_SUCCESS) {
262
+ goto done;
263
+ }
264
+
265
+ /* Generate random key */
266
+ channel->rand_state = ares_init_rand_state();
267
+ if (channel->rand_state == NULL) {
268
+ status = ARES_ENOMEM;
269
+ DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
270
+ ares_strerror(status)));
271
+ goto done;
272
+ }
273
+
274
+ /* Initialize Server List */
275
+ channel->servers =
276
+ ares_slist_create(channel->rand_state, server_sort_cb, server_destroy_cb);
277
+ if (channel->servers == NULL) {
278
+ status = ARES_ENOMEM;
279
+ goto done;
280
+ }
1780
281
 
1781
- /* Misuse */
1782
- if (netmask > 128)
1783
- return 0;
282
+ /* Initialize our lists of queries */
283
+ channel->all_queries = ares_llist_create(NULL);
284
+ if (channel->all_queries == NULL) {
285
+ status = ARES_ENOMEM;
286
+ goto done;
287
+ }
1784
288
 
1785
- /* Quickly set whole bytes */
1786
- memset(mask, 0xFF, netmask / 8);
289
+ channel->queries_by_qid = ares_htable_szvp_create(NULL);
290
+ if (channel->queries_by_qid == NULL) {
291
+ status = ARES_ENOMEM;
292
+ goto done;
293
+ }
1787
294
 
1788
- /* Set remaining bits */
1789
- if(netmask % 8) {
1790
- mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
295
+ channel->queries_by_timeout =
296
+ ares_slist_create(channel->rand_state, ares_query_timeout_cmp_cb, NULL);
297
+ if (channel->queries_by_timeout == NULL) {
298
+ status = ARES_ENOMEM;
299
+ goto done;
1791
300
  }
1792
301
 
1793
- for (i=0; i<16; i++) {
1794
- if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
1795
- return 0;
302
+ channel->connnode_by_socket = ares_htable_asvp_create(NULL);
303
+ if (channel->connnode_by_socket == NULL) {
304
+ status = ARES_ENOMEM;
305
+ goto done;
1796
306
  }
1797
307
 
1798
- return 1;
1799
- }
308
+ /* Initialize configuration by each of the four sources, from highest
309
+ * precedence to lowest.
310
+ */
1800
311
 
1801
- /* Return true iff the IPv6 ipaddr is blacklisted. */
1802
- static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
1803
- {
1804
- /* A list of blacklisted IPv6 subnets. */
1805
- const struct {
1806
- const unsigned char netbase[16];
1807
- unsigned char netmask;
1808
- } blacklist[] = {
1809
- /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
1810
- * Site-Local scoped address prefix. These are never valid DNS servers,
1811
- * but are known to be returned at least sometimes on Windows and Android.
312
+ status = ares_init_by_options(channel, options, optmask);
313
+ if (status != ARES_SUCCESS) {
314
+ DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
315
+ ares_strerror(status)));
316
+ /* If we fail to apply user-specified options, fail the whole init process
1812
317
  */
1813
- {
1814
- {
1815
- 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1816
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1817
- },
1818
- 10
318
+ goto done;
319
+ }
320
+
321
+ /* Go ahead and let it initialize the query cache even if the ttl is 0 and
322
+ * completely unused. This reduces the number of different code paths that
323
+ * might be followed even if there is a minor performance hit. */
324
+ status = ares_qcache_create(channel->rand_state, channel->qcache_max_ttl,
325
+ &channel->qcache);
326
+ if (status != ARES_SUCCESS) {
327
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
328
+ }
329
+
330
+ if (status == ARES_SUCCESS) {
331
+ status = ares_init_by_sysconfig(channel);
332
+ if (status != ARES_SUCCESS) {
333
+ DEBUGF(fprintf(stderr, "Error: init_by_sysconfig failed: %s\n",
334
+ ares_strerror(status)));
1819
335
  }
1820
- };
1821
- size_t i;
1822
-
1823
- /* See if ipaddr matches any of the entries in the blacklist. */
1824
- for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
1825
- if (ares_ipv6_subnet_matches(
1826
- blacklist[i].netbase, blacklist[i].netmask, ipaddr))
1827
- return 1;
1828
336
  }
1829
- return 0;
1830
- }
1831
337
 
1832
- /* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
1833
- * servers list, updating servers and nservers as required.
1834
- *
1835
- * This will silently ignore blacklisted IPv6 nameservers as detected by
1836
- * ares_ipv6_server_blacklisted().
1837
- *
1838
- * Returns an error code on failure, else ARES_SUCCESS.
1839
- */
1840
- static int config_nameserver(struct server_state **servers, int *nservers,
1841
- char *str)
1842
- {
1843
- struct ares_addr host;
1844
- struct server_state *newserv;
1845
- char *p, *txtaddr;
1846
- /* On Windows, there may be more than one nameserver specified in the same
1847
- * registry key, so we parse input as a space or comma seperated list.
338
+ /*
339
+ * No matter what failed or succeeded, seed defaults to provide
340
+ * useful behavior for things that we missed.
1848
341
  */
1849
- for (p = str; p;)
1850
- {
1851
- /* Skip whitespace and commas. */
1852
- while (*p && (ISSPACE(*p) || (*p == ',')))
1853
- p++;
1854
- if (!*p)
1855
- /* No more input, done. */
1856
- break;
1857
-
1858
- /* Pointer to start of IPv4 or IPv6 address part. */
1859
- txtaddr = p;
1860
-
1861
- /* Advance past this address. */
1862
- while (*p && !ISSPACE(*p) && (*p != ','))
1863
- p++;
1864
- if (*p)
1865
- /* Null terminate this address. */
1866
- *p++ = '\0';
1867
- else
1868
- /* Reached end of input, done when this address is processed. */
1869
- p = NULL;
1870
-
1871
- /* Convert textual address to binary format. */
1872
- if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1873
- host.family = AF_INET;
1874
- else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1
1875
- /* Silently skip blacklisted IPv6 servers. */
1876
- && !ares_ipv6_server_blacklisted(
1877
- (const unsigned char *)&host.addrV6))
1878
- host.family = AF_INET6;
1879
- else
1880
- continue;
1881
-
1882
- /* Resize servers state array. */
1883
- newserv = ares_realloc(*servers, (*nservers + 1) *
1884
- sizeof(struct server_state));
1885
- if (!newserv)
1886
- return ARES_ENOMEM;
1887
-
1888
- /* Store address data. */
1889
- newserv[*nservers].addr.family = host.family;
1890
- newserv[*nservers].addr.udp_port = 0;
1891
- newserv[*nservers].addr.tcp_port = 0;
1892
- if (host.family == AF_INET)
1893
- memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1894
- sizeof(host.addrV4));
1895
- else
1896
- memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1897
- sizeof(host.addrV6));
1898
-
1899
- /* Update arguments. */
1900
- *servers = newserv;
1901
- *nservers += 1;
1902
- }
342
+ status = init_by_defaults(channel);
343
+ if (status != ARES_SUCCESS) {
344
+ DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
345
+ ares_strerror(status)));
346
+ goto done;
347
+ }
1903
348
 
1904
- return ARES_SUCCESS;
1905
- }
1906
- #endif /* !WATT32 */
349
+ ares_set_socket_functions_def(channel);
1907
350
 
1908
- static int config_sortlist(struct apattern **sortlist, int *nsort,
1909
- const char *str)
1910
- {
1911
- struct apattern pat;
1912
- const char *q;
1913
-
1914
- /* Add sortlist entries. */
1915
- while (*str && *str != ';')
1916
- {
1917
- int bits;
1918
- char ipbuf[16], ipbufpfx[32];
1919
- /* Find just the IP */
1920
- q = str;
1921
- while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1922
- q++;
1923
- if (q-str >= 16)
1924
- return ARES_EBADSTR;
1925
- memcpy(ipbuf, str, q-str);
1926
- ipbuf[q-str] = '\0';
1927
- /* Find the prefix */
1928
- if (*q == '/')
1929
- {
1930
- const char *str2 = q+1;
1931
- while (*q && *q != ';' && !ISSPACE(*q))
1932
- q++;
1933
- if (q-str >= 32)
1934
- return ARES_EBADSTR;
1935
- memcpy(ipbufpfx, str, q-str);
1936
- ipbufpfx[q-str] = '\0';
1937
- str = str2;
1938
- }
1939
- else
1940
- ipbufpfx[0] = '\0';
1941
- /* Lets see if it is CIDR */
1942
- /* First we'll try IPv6 */
1943
- if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1944
- &pat.addrV6,
1945
- sizeof(pat.addrV6))) > 0)
1946
- {
1947
- pat.type = PATTERN_CIDR;
1948
- pat.mask.bits = (unsigned short)bits;
1949
- pat.family = AF_INET6;
1950
- if (!sortlist_alloc(sortlist, nsort, &pat)) {
1951
- ares_free(*sortlist);
1952
- *sortlist = NULL;
1953
- return ARES_ENOMEM;
1954
- }
1955
- }
1956
- else if (ipbufpfx[0] &&
1957
- (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1958
- sizeof(pat.addrV4))) > 0)
1959
- {
1960
- pat.type = PATTERN_CIDR;
1961
- pat.mask.bits = (unsigned short)bits;
1962
- pat.family = AF_INET;
1963
- if (!sortlist_alloc(sortlist, nsort, &pat)) {
1964
- ares_free(*sortlist);
1965
- *sortlist = NULL;
1966
- return ARES_ENOMEM;
1967
- }
1968
- }
1969
- /* See if it is just a regular IP */
1970
- else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1971
- {
1972
- if (ipbufpfx[0])
1973
- {
1974
- memcpy(ipbuf, str, q-str);
1975
- ipbuf[q-str] = '\0';
1976
- if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1977
- natural_mask(&pat);
1978
- }
1979
- else
1980
- natural_mask(&pat);
1981
- pat.family = AF_INET;
1982
- pat.type = PATTERN_MASK;
1983
- if (!sortlist_alloc(sortlist, nsort, &pat)) {
1984
- ares_free(*sortlist);
1985
- *sortlist = NULL;
1986
- return ARES_ENOMEM;
1987
- }
1988
- }
1989
- else
1990
- {
1991
- while (*q && *q != ';' && !ISSPACE(*q))
1992
- q++;
1993
- }
1994
- str = q;
1995
- while (ISSPACE(*str))
1996
- str++;
351
+ /* Initialize the event thread */
352
+ if (channel->optmask & ARES_OPT_EVENT_THREAD) {
353
+ ares_event_thread_t *e = NULL;
354
+
355
+ status = ares_event_thread_init(channel);
356
+ if (status != ARES_SUCCESS) {
357
+ goto done; /* LCOV_EXCL_LINE: UntestablePath */
358
+ }
359
+
360
+ /* Initialize monitor for configuration changes. In some rare cases,
361
+ * ARES_ENOTIMP may occur (OpenWatcom), ignore this. */
362
+ e = channel->sock_state_cb_data;
363
+ status = ares_event_configchg_init(&e->configchg, e);
364
+ if (status != ARES_SUCCESS && status != ARES_ENOTIMP) {
365
+ goto done; /* LCOV_EXCL_LINE: UntestablePath */
1997
366
  }
367
+ status = ARES_SUCCESS;
368
+ }
369
+
370
+ done:
371
+ if (status != ARES_SUCCESS) {
372
+ ares_destroy(channel);
373
+ return (int)status;
374
+ }
1998
375
 
376
+ *channelptr = channel;
1999
377
  return ARES_SUCCESS;
2000
378
  }
2001
379
 
2002
- static int set_search(ares_channel channel, const char *str)
380
+ static void *ares_reinit_thread(void *arg)
2003
381
  {
2004
- size_t cnt;
2005
-
2006
- if(channel->ndomains != -1) {
2007
- /* LCOV_EXCL_START: all callers check ndomains == -1 */
2008
- /* if we already have some domains present, free them first */
2009
- ares__strsplit_free(channel->domains, channel->ndomains);
2010
- channel->domains = NULL;
2011
- channel->ndomains = -1;
2012
- } /* LCOV_EXCL_STOP */
2013
-
2014
- channel->domains = ares__strsplit(str, ", ", &cnt);
2015
- channel->ndomains = (int)cnt;
2016
- if (channel->domains == NULL || channel->ndomains == 0) {
2017
- channel->domains = NULL;
2018
- channel->ndomains = -1;
382
+ ares_channel_t *channel = arg;
383
+ ares_status_t status;
384
+
385
+ /* ares_init_by_sysconfig() will lock when applying the config, but not
386
+ * when retrieving. */
387
+ status = ares_init_by_sysconfig(channel);
388
+ if (status != ARES_SUCCESS) {
389
+ DEBUGF(fprintf(stderr, "Error: init_by_sysconfig failed: %s\n",
390
+ ares_strerror(status)));
2019
391
  }
2020
392
 
2021
- return ARES_SUCCESS;
393
+ ares_channel_lock(channel);
394
+
395
+ /* Flush cached queries on reinit */
396
+ if (status == ARES_SUCCESS && channel->qcache) {
397
+ ares_qcache_flush(channel->qcache);
398
+ }
399
+
400
+ channel->reinit_pending = ARES_FALSE;
401
+ ares_channel_unlock(channel);
402
+
403
+ return NULL;
2022
404
  }
2023
405
 
2024
- static int set_options(ares_channel channel, const char *str)
406
+ ares_status_t ares_reinit(ares_channel_t *channel)
2025
407
  {
2026
- const char *p, *q, *val;
2027
-
2028
- p = str;
2029
- while (*p)
2030
- {
2031
- q = p;
2032
- while (*q && !ISSPACE(*q))
2033
- q++;
2034
- val = try_option(p, q, "ndots:");
2035
- if (val && channel->ndots == -1)
2036
- channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
2037
- val = try_option(p, q, "retrans:");
2038
- if (val && channel->timeout == -1)
2039
- channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
2040
- val = try_option(p, q, "retry:");
2041
- if (val && channel->tries == -1)
2042
- channel->tries = aresx_sltosi(strtol(val, NULL, 10));
2043
- val = try_option(p, q, "rotate");
2044
- if (val && channel->rotate == -1)
2045
- channel->rotate = 1;
2046
- p = q;
2047
- while (ISSPACE(*p))
2048
- p++;
408
+ ares_status_t status = ARES_SUCCESS;
409
+
410
+ if (channel == NULL) {
411
+ return ARES_EFORMERR;
412
+ }
413
+
414
+ ares_channel_lock(channel);
415
+
416
+ /* If a reinit is already in process, lets not do it again. Or if we are
417
+ * shutting down, skip. */
418
+ if (!channel->sys_up || channel->reinit_pending) {
419
+ ares_channel_unlock(channel);
420
+ return ARES_SUCCESS;
421
+ }
422
+ channel->reinit_pending = ARES_TRUE;
423
+ ares_channel_unlock(channel);
424
+
425
+ if (ares_threadsafety()) {
426
+ /* clean up the prior reinit process's thread. We know the thread isn't
427
+ * running since reinit_pending was false */
428
+ if (channel->reinit_thread != NULL) {
429
+ void *rv;
430
+ ares_thread_join(channel->reinit_thread, &rv);
431
+ channel->reinit_thread = NULL;
2049
432
  }
2050
433
 
2051
- return ARES_SUCCESS;
2052
- }
434
+ /* Spawn a new thread */
435
+ status =
436
+ ares_thread_create(&channel->reinit_thread, ares_reinit_thread, channel);
437
+ if (status != ARES_SUCCESS) {
438
+ /* LCOV_EXCL_START: UntestablePath */
439
+ ares_channel_lock(channel);
440
+ channel->reinit_pending = ARES_FALSE;
441
+ ares_channel_unlock(channel);
442
+ /* LCOV_EXCL_STOP */
443
+ }
444
+ } else {
445
+ /* Threading support not available, call directly */
446
+ ares_reinit_thread(channel);
447
+ }
2053
448
 
2054
- static const char *try_option(const char *p, const char *q, const char *opt)
2055
- {
2056
- size_t len = strlen(opt);
2057
- return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
449
+ return status;
2058
450
  }
2059
451
 
2060
- #if !defined(WIN32) && !defined(WATT32) && \
2061
- !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
2062
- static char *try_config(char *s, const char *opt, char scc)
452
+ /* ares_dup() duplicates a channel handle with all its options and returns a
453
+ new channel handle */
454
+ int ares_dup(ares_channel_t **dest, const ares_channel_t *src)
2063
455
  {
2064
- size_t len;
2065
- char *p;
2066
- char *q;
2067
-
2068
- if (!s || !opt)
2069
- /* no line or no option */
2070
- return NULL; /* LCOV_EXCL_LINE */
2071
-
2072
- /* Hash '#' character is always used as primary comment char, additionally
2073
- a not-NUL secondary comment char will be considered when specified. */
2074
-
2075
- /* trim line comment */
2076
- p = s;
2077
- if(scc)
2078
- while (*p && (*p != '#') && (*p != scc))
2079
- p++;
2080
- else
2081
- while (*p && (*p != '#'))
2082
- p++;
2083
- *p = '\0';
2084
-
2085
- /* trim trailing whitespace */
2086
- q = p - 1;
2087
- while ((q >= s) && ISSPACE(*q))
2088
- q--;
2089
- *++q = '\0';
2090
-
2091
- /* skip leading whitespace */
2092
- p = s;
2093
- while (*p && ISSPACE(*p))
2094
- p++;
2095
-
2096
- if (!*p)
2097
- /* empty line */
2098
- return NULL;
2099
-
2100
- if ((len = strlen(opt)) == 0)
2101
- /* empty option */
2102
- return NULL; /* LCOV_EXCL_LINE */
2103
-
2104
- if (strncmp(p, opt, len) != 0)
2105
- /* line and option do not match */
2106
- return NULL;
2107
-
2108
- /* skip over given option name */
2109
- p += len;
2110
-
2111
- if (!*p)
2112
- /* no option value */
2113
- return NULL; /* LCOV_EXCL_LINE */
2114
-
2115
- if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
2116
- /* whitespace between option name and value is mandatory
2117
- for given option names which do not end with ':' or '=' */
2118
- return NULL;
2119
-
2120
- /* skip over whitespace */
2121
- while (*p && ISSPACE(*p))
2122
- p++;
2123
-
2124
- if (!*p)
2125
- /* no option value */
2126
- return NULL;
2127
-
2128
- /* return pointer to option value */
2129
- return p;
2130
- }
2131
- #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
456
+ struct ares_options opts;
457
+ ares_status_t rc;
458
+ int optmask;
2132
459
 
2133
- static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
2134
- {
460
+ if (dest == NULL || src == NULL) {
461
+ return ARES_EFORMERR;
462
+ }
2135
463
 
2136
- /* Four octets and three periods yields at most 15 characters. */
2137
- if (len > 15)
2138
- return -1;
464
+ *dest = NULL; /* in case of failure return NULL explicitly */
2139
465
 
2140
- if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
2141
- return -1;
466
+ /* First get the options supported by the old ares_save_options() function,
467
+ which is most of them */
468
+ rc = (ares_status_t)ares_save_options(src, &opts, &optmask);
469
+ if (rc != ARES_SUCCESS) {
470
+ ares_destroy_options(&opts);
471
+ goto done;
472
+ }
2142
473
 
2143
- return 0;
2144
- }
474
+ /* Then create the new channel with those options */
475
+ rc = (ares_status_t)ares_init_options(dest, &opts, optmask);
2145
476
 
2146
- static void natural_mask(struct apattern *pat)
2147
- {
2148
- struct in_addr addr;
477
+ /* destroy the options copy to not leak any memory */
478
+ ares_destroy_options(&opts);
2149
479
 
2150
- /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
2151
- * but portable.
2152
- */
2153
- addr.s_addr = ntohl(pat->addrV4.s_addr);
480
+ if (rc != ARES_SUCCESS) {
481
+ goto done;
482
+ }
483
+
484
+ ares_channel_lock(src);
485
+ /* Now clone the options that ares_save_options() doesn't support, but are
486
+ * user-provided */
487
+ (*dest)->sock_create_cb = src->sock_create_cb;
488
+ (*dest)->sock_create_cb_data = src->sock_create_cb_data;
489
+ (*dest)->sock_config_cb = src->sock_config_cb;
490
+ (*dest)->sock_config_cb_data = src->sock_config_cb_data;
491
+ memcpy(&(*dest)->sock_funcs, &(src->sock_funcs), sizeof((*dest)->sock_funcs));
492
+ (*dest)->sock_func_cb_data = src->sock_func_cb_data;
493
+ (*dest)->legacy_sock_funcs = src->legacy_sock_funcs;
494
+ (*dest)->legacy_sock_funcs_cb_data = src->legacy_sock_funcs_cb_data;
495
+ (*dest)->server_state_cb = src->server_state_cb;
496
+ (*dest)->server_state_cb_data = src->server_state_cb_data;
497
+
498
+ ares_strcpy((*dest)->local_dev_name, src->local_dev_name,
499
+ sizeof((*dest)->local_dev_name));
500
+ (*dest)->local_ip4 = src->local_ip4;
501
+ memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
502
+ ares_channel_unlock(src);
2154
503
 
2155
- /* This is out of date in the CIDR world, but some people might
2156
- * still rely on it.
504
+ /* Servers are a bit unique as ares_init_options() only allows ipv4 servers
505
+ * and not a port per server, but there are other user specified ways, that
506
+ * too will toggle the optmask ARES_OPT_SERVERS to let us know. If that's
507
+ * the case, pull them in.
508
+ *
509
+ * We don't want to clone system-configuration servers though.
510
+ *
511
+ * We must use the "csv" format to get things like link-local address support
2157
512
  */
2158
- if (IN_CLASSA(addr.s_addr))
2159
- pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
2160
- else if (IN_CLASSB(addr.s_addr))
2161
- pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
2162
- else
2163
- pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
2164
- }
2165
513
 
2166
- static int sortlist_alloc(struct apattern **sortlist, int *nsort,
2167
- struct apattern *pat)
2168
- {
2169
- struct apattern *newsort;
2170
- newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
2171
- if (!newsort)
2172
- return 0;
2173
- newsort[*nsort] = *pat;
2174
- *sortlist = newsort;
2175
- (*nsort)++;
2176
- return 1;
2177
- }
514
+ if (optmask & ARES_OPT_SERVERS) {
515
+ char *csv = ares_get_servers_csv(src);
516
+ if (csv == NULL) {
517
+ /* LCOV_EXCL_START: OutOfMemory */
518
+ ares_destroy(*dest);
519
+ *dest = NULL;
520
+ rc = ARES_ENOMEM;
521
+ goto done;
522
+ /* LCOV_EXCL_STOP */
523
+ }
524
+
525
+ rc = (ares_status_t)ares_set_servers_ports_csv(*dest, csv);
526
+ ares_free_string(csv);
527
+ if (rc != ARES_SUCCESS) {
528
+ /* LCOV_EXCL_START: OutOfMemory */
529
+ ares_destroy(*dest);
530
+ *dest = NULL;
531
+ goto done;
532
+ /* LCOV_EXCL_STOP */
533
+ }
534
+ }
2178
535
 
536
+ rc = ARES_SUCCESS;
537
+ done:
538
+ return (int)rc; /* everything went fine */
539
+ }
2179
540
 
2180
- void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
541
+ void ares_set_local_ip4(ares_channel_t *channel, unsigned int local_ip)
2181
542
  {
543
+ if (channel == NULL) {
544
+ return;
545
+ }
546
+ ares_channel_lock(channel);
2182
547
  channel->local_ip4 = local_ip;
548
+ ares_channel_unlock(channel);
2183
549
  }
2184
550
 
2185
551
  /* local_ip6 should be 16 bytes in length */
2186
- void ares_set_local_ip6(ares_channel channel,
2187
- const unsigned char* local_ip6)
552
+ void ares_set_local_ip6(ares_channel_t *channel, const unsigned char *local_ip6)
2188
553
  {
554
+ if (channel == NULL) {
555
+ return;
556
+ }
557
+ ares_channel_lock(channel);
2189
558
  memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
559
+ ares_channel_unlock(channel);
2190
560
  }
2191
561
 
2192
562
  /* local_dev_name should be null terminated. */
2193
- void ares_set_local_dev(ares_channel channel,
2194
- const char* local_dev_name)
2195
- {
2196
- strncpy(channel->local_dev_name, local_dev_name,
2197
- sizeof(channel->local_dev_name));
2198
- channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
2199
- }
2200
-
2201
-
2202
- void ares_set_socket_callback(ares_channel channel,
2203
- ares_sock_create_callback cb,
2204
- void *data)
2205
- {
2206
- channel->sock_create_cb = cb;
2207
- channel->sock_create_cb_data = data;
2208
- }
2209
-
2210
- void ares_set_socket_configure_callback(ares_channel channel,
2211
- ares_sock_config_callback cb,
2212
- void *data)
563
+ void ares_set_local_dev(ares_channel_t *channel, const char *local_dev_name)
2213
564
  {
2214
- channel->sock_config_cb = cb;
2215
- channel->sock_config_cb_data = data;
2216
- }
565
+ if (channel == NULL) {
566
+ return;
567
+ }
2217
568
 
2218
- void ares_set_socket_functions(ares_channel channel,
2219
- const struct ares_socket_functions * funcs,
2220
- void *data)
2221
- {
2222
- channel->sock_funcs = funcs;
2223
- channel->sock_func_cb_data = data;
569
+ ares_channel_lock(channel);
570
+ ares_strcpy(channel->local_dev_name, local_dev_name,
571
+ sizeof(channel->local_dev_name));
572
+ channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
573
+ ares_channel_unlock(channel);
2224
574
  }
2225
575
 
2226
- int ares_set_sortlist(ares_channel channel, const char *sortstr)
576
+ int ares_set_sortlist(ares_channel_t *channel, const char *sortstr)
2227
577
  {
2228
- int nsort = 0;
578
+ size_t nsort = 0;
2229
579
  struct apattern *sortlist = NULL;
2230
- int status;
580
+ ares_status_t status;
2231
581
 
2232
- if (!channel)
582
+ if (!channel) {
2233
583
  return ARES_ENODATA;
584
+ }
585
+ ares_channel_lock(channel);
2234
586
 
2235
- status = config_sortlist(&sortlist, &nsort, sortstr);
587
+ status = ares_parse_sortlist(&sortlist, &nsort, sortstr);
2236
588
  if (status == ARES_SUCCESS && sortlist) {
2237
- if (channel->sortlist)
589
+ if (channel->sortlist) {
2238
590
  ares_free(channel->sortlist);
591
+ }
2239
592
  channel->sortlist = sortlist;
2240
- channel->nsort = nsort;
2241
- }
2242
- return status;
2243
- }
593
+ channel->nsort = nsort;
2244
594
 
2245
- void ares__init_servers_state(ares_channel channel)
2246
- {
2247
- struct server_state *server;
2248
- int i;
2249
-
2250
- for (i = 0; i < channel->nservers; i++)
2251
- {
2252
- server = &channel->servers[i];
2253
- server->udp_socket = ARES_SOCKET_BAD;
2254
- server->tcp_socket = ARES_SOCKET_BAD;
2255
- server->tcp_connection_generation = ++channel->tcp_connection_generation;
2256
- server->tcp_lenbuf_pos = 0;
2257
- server->tcp_buffer_pos = 0;
2258
- server->tcp_buffer = NULL;
2259
- server->tcp_length = 0;
2260
- server->qhead = NULL;
2261
- server->qtail = NULL;
2262
- ares__init_list_head(&server->queries_to_server);
2263
- server->channel = channel;
2264
- server->is_broken = 0;
2265
- }
595
+ /* Save sortlist as if it was passed in as an option */
596
+ channel->optmask |= ARES_OPT_SORTLIST;
597
+ }
598
+ ares_channel_unlock(channel);
599
+ return (int)status;
2266
600
  }