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
@@ -0,0 +1,1362 @@
1
+ /* MIT License
2
+ *
3
+ * Copyright (c) 1998 Massachusetts Institute of Technology
4
+ * Copyright (c) 2008 Daniel Stenberg
5
+ * Copyright (c) 2023 Brad House
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice (including the next
15
+ * paragraph) shall be included in all copies or substantial portions of the
16
+ * Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *
26
+ * SPDX-License-Identifier: MIT
27
+ */
28
+ #include "ares_private.h"
29
+
30
+ #ifdef HAVE_ARPA_INET_H
31
+ # include <arpa/inet.h>
32
+ #endif
33
+ #ifdef HAVE_SYS_TYPES_H
34
+ # include <sys/types.h>
35
+ #endif
36
+ #ifdef HAVE_SYS_SOCKET_H
37
+ # include <sys/socket.h>
38
+ #endif
39
+ #ifdef HAVE_NET_IF_H
40
+ # include <net/if.h>
41
+ #endif
42
+ #ifdef HAVE_STDINT_H
43
+ # include <stdint.h>
44
+ #endif
45
+
46
+ #if defined(USE_WINSOCK)
47
+ # if defined(HAVE_IPHLPAPI_H)
48
+ # include <iphlpapi.h>
49
+ # endif
50
+ # if defined(HAVE_NETIOAPI_H)
51
+ # include <netioapi.h>
52
+ # endif
53
+ #endif
54
+
55
+ #include "ares_data.h"
56
+ #include "ares_inet_net_pton.h"
57
+
58
+ typedef struct {
59
+ struct ares_addr addr;
60
+ unsigned short tcp_port;
61
+ unsigned short udp_port;
62
+
63
+ char ll_iface[IF_NAMESIZE];
64
+ unsigned int ll_scope;
65
+ } ares_sconfig_t;
66
+
67
+ static ares_bool_t ares_addr_match(const struct ares_addr *addr1,
68
+ const struct ares_addr *addr2)
69
+ {
70
+ if (addr1 == NULL && addr2 == NULL) {
71
+ return ARES_TRUE; /* LCOV_EXCL_LINE: DefensiveCoding */
72
+ }
73
+
74
+ if (addr1 == NULL || addr2 == NULL) {
75
+ return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
76
+ }
77
+
78
+ if (addr1->family != addr2->family) {
79
+ return ARES_FALSE;
80
+ }
81
+
82
+ if (addr1->family == AF_INET && memcmp(&addr1->addr.addr4, &addr2->addr.addr4,
83
+ sizeof(addr1->addr.addr4)) == 0) {
84
+ return ARES_TRUE;
85
+ }
86
+
87
+ if (addr1->family == AF_INET6 &&
88
+ memcmp(&addr1->addr.addr6._S6_un._S6_u8, &addr2->addr.addr6._S6_un._S6_u8,
89
+ sizeof(addr1->addr.addr6._S6_un._S6_u8)) == 0) {
90
+ return ARES_TRUE;
91
+ }
92
+
93
+ return ARES_FALSE;
94
+ }
95
+
96
+ ares_bool_t ares_subnet_match(const struct ares_addr *addr,
97
+ const struct ares_addr *subnet,
98
+ unsigned char netmask)
99
+ {
100
+ const unsigned char *addr_ptr;
101
+ const unsigned char *subnet_ptr;
102
+ size_t len;
103
+ size_t i;
104
+
105
+ if (addr == NULL || subnet == NULL) {
106
+ return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
107
+ }
108
+
109
+ if (addr->family != subnet->family) {
110
+ return ARES_FALSE;
111
+ }
112
+
113
+ if (addr->family == AF_INET) {
114
+ addr_ptr = (const unsigned char *)&addr->addr.addr4;
115
+ subnet_ptr = (const unsigned char *)&subnet->addr.addr4;
116
+ len = 4;
117
+
118
+ if (netmask > 32) {
119
+ return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
120
+ }
121
+ } else if (addr->family == AF_INET6) {
122
+ addr_ptr = (const unsigned char *)&addr->addr.addr6;
123
+ subnet_ptr = (const unsigned char *)&subnet->addr.addr6;
124
+ len = 16;
125
+
126
+ if (netmask > 128) {
127
+ return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
128
+ }
129
+ } else {
130
+ return ARES_FALSE; /* LCOV_EXCL_LINE: DefensiveCoding */
131
+ }
132
+
133
+ for (i = 0; i < len && netmask > 0; i++) {
134
+ unsigned char mask = 0xff;
135
+ if (netmask < 8) {
136
+ mask <<= (8 - netmask);
137
+ netmask = 0;
138
+ } else {
139
+ netmask -= 8;
140
+ }
141
+
142
+ if ((addr_ptr[i] & mask) != (subnet_ptr[i] & mask)) {
143
+ return ARES_FALSE;
144
+ }
145
+ }
146
+
147
+ return ARES_TRUE;
148
+ }
149
+
150
+ ares_bool_t ares_addr_is_linklocal(const struct ares_addr *addr)
151
+ {
152
+ struct ares_addr subnet;
153
+ const unsigned char subnetaddr[16] = { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00,
154
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155
+ 0x00, 0x00, 0x00, 0x00 };
156
+
157
+ /* fe80::/10 */
158
+ subnet.family = AF_INET6;
159
+ memcpy(&subnet.addr.addr6, subnetaddr, 16);
160
+
161
+ return ares_subnet_match(addr, &subnet, 10);
162
+ }
163
+
164
+ static ares_bool_t ares_server_blacklisted(const struct ares_addr *addr)
165
+ {
166
+ /* A list of blacklisted IPv6 subnets. */
167
+ const struct {
168
+ const unsigned char netbase[16];
169
+ unsigned char netmask;
170
+ } blacklist_v6[] = {
171
+ /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
172
+ * Site-Local scoped address prefix. These are never valid DNS servers,
173
+ * but are known to be returned at least sometimes on Windows and Android.
174
+ */
175
+ { { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176
+ 0x00, 0x00, 0x00, 0x00 },
177
+ 10 }
178
+ };
179
+
180
+ size_t i;
181
+
182
+ if (addr->family != AF_INET6) {
183
+ return ARES_FALSE;
184
+ }
185
+
186
+ /* See if ipaddr matches any of the entries in the blacklist. */
187
+ for (i = 0; i < sizeof(blacklist_v6) / sizeof(*blacklist_v6); i++) {
188
+ struct ares_addr subnet;
189
+ subnet.family = AF_INET6;
190
+ memcpy(&subnet.addr.addr6, blacklist_v6[i].netbase, 16);
191
+ if (ares_subnet_match(addr, &subnet, blacklist_v6[i].netmask)) {
192
+ return ARES_TRUE;
193
+ }
194
+ }
195
+ return ARES_FALSE;
196
+ }
197
+
198
+ static ares_status_t parse_nameserver_uri(ares_buf_t *buf,
199
+ ares_sconfig_t *sconfig)
200
+ {
201
+ ares_uri_t *uri = NULL;
202
+ ares_status_t status = ARES_SUCCESS;
203
+ const char *port;
204
+ char *ll_scope;
205
+ char hoststr[256];
206
+ size_t addrlen;
207
+
208
+ status = ares_uri_parse_buf(&uri, buf);
209
+ if (status != ARES_SUCCESS) {
210
+ return status;
211
+ }
212
+
213
+ if (!ares_streq("dns", ares_uri_get_scheme(uri))) {
214
+ status = ARES_EBADSTR;
215
+ goto done;
216
+ }
217
+
218
+ ares_strcpy(hoststr, ares_uri_get_host(uri), sizeof(hoststr));
219
+ ll_scope = strchr(hoststr, '%');
220
+ if (ll_scope != NULL) {
221
+ *ll_scope = 0;
222
+ ll_scope++;
223
+ ares_strcpy(sconfig->ll_iface, ll_scope, sizeof(sconfig->ll_iface));
224
+ }
225
+
226
+ /* Convert ip address from string to network byte order */
227
+ sconfig->addr.family = AF_UNSPEC;
228
+ if (ares_dns_pton(hoststr, &sconfig->addr, &addrlen) == NULL) {
229
+ status = ARES_EBADSTR;
230
+ goto done;
231
+ }
232
+
233
+ sconfig->udp_port = ares_uri_get_port(uri);
234
+ sconfig->tcp_port = sconfig->udp_port;
235
+ port = ares_uri_get_query_key(uri, "tcpport");
236
+ if (port != NULL) {
237
+ sconfig->tcp_port = (unsigned short)atoi(port);
238
+ }
239
+
240
+ done:
241
+ ares_uri_destroy(uri);
242
+ return status;
243
+ }
244
+
245
+ /* Parse address and port in these formats, either ipv4 or ipv6 addresses
246
+ * are allowed:
247
+ * ipaddr
248
+ * ipv4addr:port
249
+ * [ipaddr]
250
+ * [ipaddr]:port
251
+ *
252
+ * Modifiers: %iface
253
+ *
254
+ * TODO: #domain modifier
255
+ *
256
+ * If a port is not specified, will set port to 0.
257
+ *
258
+ * Will fail if an IPv6 nameserver as detected by
259
+ * ares_ipv6_server_blacklisted()
260
+ *
261
+ * Returns an error code on failure, else ARES_SUCCESS
262
+ */
263
+
264
+ static ares_status_t parse_nameserver(ares_buf_t *buf, ares_sconfig_t *sconfig)
265
+ {
266
+ ares_status_t status;
267
+ char ipaddr[INET6_ADDRSTRLEN] = "";
268
+ size_t addrlen;
269
+
270
+ memset(sconfig, 0, sizeof(*sconfig));
271
+
272
+ /* Consume any leading whitespace */
273
+ ares_buf_consume_whitespace(buf, ARES_TRUE);
274
+
275
+ /* pop off IP address. If it is in [ ] then it can be ipv4 or ipv6. If
276
+ * not, ipv4 only */
277
+ if (ares_buf_begins_with(buf, (const unsigned char *)"[", 1)) {
278
+ /* Consume [ */
279
+ ares_buf_consume(buf, 1);
280
+
281
+ ares_buf_tag(buf);
282
+
283
+ /* Consume until ] */
284
+ if (ares_buf_consume_until_charset(buf, (const unsigned char *)"]", 1,
285
+ ARES_TRUE) == SIZE_MAX) {
286
+ return ARES_EBADSTR;
287
+ }
288
+
289
+ status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr));
290
+ if (status != ARES_SUCCESS) {
291
+ return status;
292
+ }
293
+
294
+ /* Skip over ] */
295
+ ares_buf_consume(buf, 1);
296
+ } else {
297
+ size_t offset;
298
+
299
+ /* Not in [ ], see if '.' is in first 4 characters, if it is, then its ipv4,
300
+ * otherwise treat as ipv6 */
301
+ ares_buf_tag(buf);
302
+
303
+ offset = ares_buf_consume_until_charset(buf, (const unsigned char *)".", 1,
304
+ ARES_TRUE);
305
+ ares_buf_tag_rollback(buf);
306
+ ares_buf_tag(buf);
307
+
308
+ if (offset > 0 && offset < 4) {
309
+ /* IPv4 */
310
+ if (ares_buf_consume_charset(buf, (const unsigned char *)"0123456789.",
311
+ 11) == 0) {
312
+ return ARES_EBADSTR;
313
+ }
314
+ } else {
315
+ /* IPv6 */
316
+ const unsigned char ipv6_charset[] = "ABCDEFabcdef0123456789.:";
317
+ if (ares_buf_consume_charset(buf, ipv6_charset,
318
+ sizeof(ipv6_charset) - 1) == 0) {
319
+ return ARES_EBADSTR;
320
+ }
321
+ }
322
+
323
+ status = ares_buf_tag_fetch_string(buf, ipaddr, sizeof(ipaddr));
324
+ if (status != ARES_SUCCESS) {
325
+ return status;
326
+ }
327
+ }
328
+
329
+ /* Convert ip address from string to network byte order */
330
+ sconfig->addr.family = AF_UNSPEC;
331
+ if (ares_dns_pton(ipaddr, &sconfig->addr, &addrlen) == NULL) {
332
+ return ARES_EBADSTR;
333
+ }
334
+
335
+ /* Pull off port */
336
+ if (ares_buf_begins_with(buf, (const unsigned char *)":", 1)) {
337
+ char portstr[6];
338
+
339
+ /* Consume : */
340
+ ares_buf_consume(buf, 1);
341
+
342
+ ares_buf_tag(buf);
343
+
344
+ /* Read numbers */
345
+ if (ares_buf_consume_charset(buf, (const unsigned char *)"0123456789",
346
+ 10) == 0) {
347
+ return ARES_EBADSTR;
348
+ }
349
+
350
+ status = ares_buf_tag_fetch_string(buf, portstr, sizeof(portstr));
351
+ if (status != ARES_SUCCESS) {
352
+ return status;
353
+ }
354
+
355
+ sconfig->udp_port = (unsigned short)atoi(portstr);
356
+ sconfig->tcp_port = sconfig->udp_port;
357
+ }
358
+
359
+ /* Pull off interface modifier */
360
+ if (ares_buf_begins_with(buf, (const unsigned char *)"%", 1)) {
361
+ const unsigned char iface_charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
362
+ "abcdefghijklmnopqrstuvwxyz"
363
+ "0123456789.-_\\:{}";
364
+ /* Consume % */
365
+ ares_buf_consume(buf, 1);
366
+
367
+ ares_buf_tag(buf);
368
+
369
+ if (ares_buf_consume_charset(buf, iface_charset,
370
+ sizeof(iface_charset) - 1) == 0) {
371
+ return ARES_EBADSTR;
372
+ }
373
+
374
+ status = ares_buf_tag_fetch_string(buf, sconfig->ll_iface,
375
+ sizeof(sconfig->ll_iface));
376
+ if (status != ARES_SUCCESS) {
377
+ return status;
378
+ }
379
+ }
380
+
381
+ /* Consume any trailing whitespace so we can bail out if there is something
382
+ * after we didn't read */
383
+ ares_buf_consume_whitespace(buf, ARES_TRUE);
384
+
385
+ if (ares_buf_len(buf) != 0) {
386
+ return ARES_EBADSTR;
387
+ }
388
+
389
+ return ARES_SUCCESS;
390
+ }
391
+
392
+ static ares_status_t ares_sconfig_linklocal(const ares_channel_t *channel,
393
+ ares_sconfig_t *s,
394
+ const char *ll_iface)
395
+ {
396
+ unsigned int ll_scope = 0;
397
+
398
+
399
+ if (ares_str_isnum(ll_iface)) {
400
+ char ifname[IF_NAMESIZE] = "";
401
+ ll_scope = (unsigned int)atoi(ll_iface);
402
+ if (channel->sock_funcs.aif_indextoname == NULL ||
403
+ channel->sock_funcs.aif_indextoname(ll_scope, ifname, sizeof(ifname),
404
+ channel->sock_func_cb_data) ==
405
+ NULL) {
406
+ DEBUGF(fprintf(stderr, "Interface %s for ipv6 Link Local not found\n",
407
+ ll_iface));
408
+ return ARES_ENOTFOUND;
409
+ }
410
+ ares_strcpy(s->ll_iface, ifname, sizeof(s->ll_iface));
411
+ s->ll_scope = ll_scope;
412
+ return ARES_SUCCESS;
413
+ }
414
+
415
+ if (channel->sock_funcs.aif_nametoindex != NULL) {
416
+ ll_scope =
417
+ channel->sock_funcs.aif_nametoindex(ll_iface, channel->sock_func_cb_data);
418
+ }
419
+ if (ll_scope == 0) {
420
+ DEBUGF(fprintf(stderr, "Interface %s for ipv6 Link Local not found\n",
421
+ ll_iface));
422
+ return ARES_ENOTFOUND;
423
+ }
424
+ ares_strcpy(s->ll_iface, ll_iface, sizeof(s->ll_iface));
425
+ s->ll_scope = ll_scope;
426
+ return ARES_SUCCESS;
427
+ }
428
+
429
+ ares_status_t ares_sconfig_append(const ares_channel_t *channel,
430
+ ares_llist_t **sconfig,
431
+ const struct ares_addr *addr,
432
+ unsigned short udp_port,
433
+ unsigned short tcp_port, const char *ll_iface)
434
+ {
435
+ ares_sconfig_t *s;
436
+ ares_status_t status;
437
+
438
+ if (sconfig == NULL || addr == NULL) {
439
+ return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */
440
+ }
441
+
442
+ /* Silently skip blacklisted IPv6 servers. */
443
+ if (ares_server_blacklisted(addr)) {
444
+ return ARES_SUCCESS;
445
+ }
446
+
447
+ s = ares_malloc_zero(sizeof(*s));
448
+ if (s == NULL) {
449
+ return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
450
+ }
451
+
452
+ if (*sconfig == NULL) {
453
+ *sconfig = ares_llist_create(ares_free);
454
+ if (*sconfig == NULL) {
455
+ status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
456
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
457
+ }
458
+ }
459
+
460
+ memcpy(&s->addr, addr, sizeof(s->addr));
461
+ s->udp_port = udp_port;
462
+ s->tcp_port = tcp_port;
463
+
464
+ /* Handle link-local enumeration. If an interface is specified on a
465
+ * non-link-local address, we'll simply end up ignoring that */
466
+ if (ares_addr_is_linklocal(&s->addr)) {
467
+ if (ares_strlen(ll_iface) == 0) {
468
+ /* Silently ignore this entry, we require an interface */
469
+ status = ARES_SUCCESS;
470
+ goto fail;
471
+ }
472
+ status = ares_sconfig_linklocal(channel, s, ll_iface);
473
+ /* Silently ignore this entry, we can't validate the interface */
474
+ if (status != ARES_SUCCESS) {
475
+ status = ARES_SUCCESS;
476
+ goto fail;
477
+ }
478
+ }
479
+
480
+ if (ares_llist_insert_last(*sconfig, s) == NULL) {
481
+ status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
482
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
483
+ }
484
+
485
+ return ARES_SUCCESS;
486
+
487
+ fail:
488
+ ares_free(s);
489
+
490
+ return status;
491
+ }
492
+
493
+ /* Add the IPv4 or IPv6 nameservers in str (separated by commas or spaces) to
494
+ * the servers list, updating servers and nservers as required.
495
+ *
496
+ * If a nameserver is encapsulated in [ ] it may optionally include a port
497
+ * suffix, e.g.:
498
+ * [127.0.0.1]:59591
499
+ *
500
+ * The extended format is required to support OpenBSD's resolv.conf format:
501
+ * https://man.openbsd.org/OpenBSD-5.1/resolv.conf.5
502
+ * As well as MacOS libresolv that may include a non-default port number.
503
+ *
504
+ * This will silently ignore blacklisted IPv6 nameservers as detected by
505
+ * ares_ipv6_server_blacklisted().
506
+ *
507
+ * Returns an error code on failure, else ARES_SUCCESS.
508
+ */
509
+ ares_status_t ares_sconfig_append_fromstr(const ares_channel_t *channel,
510
+ ares_llist_t **sconfig,
511
+ const char *str,
512
+ ares_bool_t ignore_invalid)
513
+ {
514
+ ares_status_t status = ARES_SUCCESS;
515
+ ares_buf_t *buf = NULL;
516
+ ares_array_t *list = NULL;
517
+ size_t num;
518
+ size_t i;
519
+
520
+ /* On Windows, there may be more than one nameserver specified in the same
521
+ * registry key, so we parse input as a space or comma separated list.
522
+ */
523
+ buf = ares_buf_create_const((const unsigned char *)str, ares_strlen(str));
524
+ if (buf == NULL) {
525
+ status = ARES_ENOMEM;
526
+ goto done;
527
+ }
528
+
529
+ status = ares_buf_split(buf, (const unsigned char *)" ,", 2,
530
+ ARES_BUF_SPLIT_NONE, 0, &list);
531
+ if (status != ARES_SUCCESS) {
532
+ goto done;
533
+ }
534
+
535
+ num = ares_array_len(list);
536
+ for (i = 0; i < num; i++) {
537
+ ares_buf_t **bufptr = ares_array_at(list, i);
538
+ ares_buf_t *entry = *bufptr;
539
+ ares_sconfig_t s;
540
+
541
+ status = parse_nameserver_uri(entry, &s);
542
+ if (status != ARES_SUCCESS) {
543
+ status = parse_nameserver(entry, &s);
544
+ }
545
+
546
+ if (status != ARES_SUCCESS) {
547
+ if (ignore_invalid) {
548
+ continue;
549
+ } else {
550
+ goto done;
551
+ }
552
+ }
553
+
554
+ status = ares_sconfig_append(channel, sconfig, &s.addr, s.udp_port,
555
+ s.tcp_port, s.ll_iface);
556
+ if (status != ARES_SUCCESS) {
557
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
558
+ }
559
+ }
560
+
561
+ status = ARES_SUCCESS;
562
+
563
+ done:
564
+ ares_array_destroy(list);
565
+ ares_buf_destroy(buf);
566
+ return status;
567
+ }
568
+
569
+ static unsigned short ares_sconfig_get_port(const ares_channel_t *channel,
570
+ const ares_sconfig_t *s,
571
+ ares_bool_t is_tcp)
572
+ {
573
+ unsigned short port = is_tcp ? s->tcp_port : s->udp_port;
574
+
575
+ if (port == 0) {
576
+ port = is_tcp ? channel->tcp_port : channel->udp_port;
577
+ }
578
+
579
+ if (port == 0) {
580
+ port = 53;
581
+ }
582
+
583
+ return port;
584
+ }
585
+
586
+ static ares_slist_node_t *ares_server_find(const ares_channel_t *channel,
587
+ const ares_sconfig_t *s)
588
+ {
589
+ ares_slist_node_t *node;
590
+
591
+ for (node = ares_slist_node_first(channel->servers); node != NULL;
592
+ node = ares_slist_node_next(node)) {
593
+ const ares_server_t *server = ares_slist_node_val(node);
594
+
595
+ if (!ares_addr_match(&server->addr, &s->addr)) {
596
+ continue;
597
+ }
598
+
599
+ if (server->tcp_port != ares_sconfig_get_port(channel, s, ARES_TRUE)) {
600
+ continue;
601
+ }
602
+
603
+ if (server->udp_port != ares_sconfig_get_port(channel, s, ARES_FALSE)) {
604
+ continue;
605
+ }
606
+
607
+ return node;
608
+ }
609
+ return NULL;
610
+ }
611
+
612
+ static ares_bool_t ares_server_isdup(const ares_channel_t *channel,
613
+ ares_llist_node_t *s)
614
+ {
615
+ /* Scan backwards to see if this is a duplicate */
616
+ ares_llist_node_t *prev;
617
+ const ares_sconfig_t *server = ares_llist_node_val(s);
618
+
619
+ for (prev = ares_llist_node_prev(s); prev != NULL;
620
+ prev = ares_llist_node_prev(prev)) {
621
+ const ares_sconfig_t *p = ares_llist_node_val(prev);
622
+
623
+ if (!ares_addr_match(&server->addr, &p->addr)) {
624
+ continue;
625
+ }
626
+
627
+ if (ares_sconfig_get_port(channel, server, ARES_TRUE) !=
628
+ ares_sconfig_get_port(channel, p, ARES_TRUE)) {
629
+ continue;
630
+ }
631
+
632
+ if (ares_sconfig_get_port(channel, server, ARES_FALSE) !=
633
+ ares_sconfig_get_port(channel, p, ARES_FALSE)) {
634
+ continue;
635
+ }
636
+
637
+ return ARES_TRUE;
638
+ }
639
+
640
+ return ARES_FALSE;
641
+ }
642
+
643
+ static ares_status_t ares_server_create(ares_channel_t *channel,
644
+ const ares_sconfig_t *sconfig,
645
+ size_t idx)
646
+ {
647
+ ares_status_t status;
648
+ ares_server_t *server = ares_malloc_zero(sizeof(*server));
649
+
650
+ if (server == NULL) {
651
+ return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
652
+ }
653
+
654
+ server->idx = idx;
655
+ server->channel = channel;
656
+ server->udp_port = ares_sconfig_get_port(channel, sconfig, ARES_FALSE);
657
+ server->tcp_port = ares_sconfig_get_port(channel, sconfig, ARES_TRUE);
658
+ server->addr.family = sconfig->addr.family;
659
+ server->next_retry_time.sec = 0;
660
+ server->next_retry_time.usec = 0;
661
+
662
+ if (sconfig->addr.family == AF_INET) {
663
+ memcpy(&server->addr.addr.addr4, &sconfig->addr.addr.addr4,
664
+ sizeof(server->addr.addr.addr4));
665
+ } else if (sconfig->addr.family == AF_INET6) {
666
+ memcpy(&server->addr.addr.addr6, &sconfig->addr.addr.addr6,
667
+ sizeof(server->addr.addr.addr6));
668
+ }
669
+
670
+ /* Copy over link-local settings */
671
+ if (ares_strlen(sconfig->ll_iface)) {
672
+ ares_strcpy(server->ll_iface, sconfig->ll_iface, sizeof(server->ll_iface));
673
+ server->ll_scope = sconfig->ll_scope;
674
+ }
675
+
676
+ server->connections = ares_llist_create(NULL);
677
+ if (server->connections == NULL) {
678
+ status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
679
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
680
+ }
681
+
682
+ if (ares_slist_insert(channel->servers, server) == NULL) {
683
+ status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
684
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
685
+ }
686
+
687
+ status = ARES_SUCCESS;
688
+
689
+ done:
690
+ if (status != ARES_SUCCESS) {
691
+ ares_destroy_server(server); /* LCOV_EXCL_LINE: OutOfMemory */
692
+ }
693
+
694
+ return status;
695
+ }
696
+
697
+ static ares_bool_t ares_server_in_newconfig(const ares_server_t *server,
698
+ ares_llist_t *srvlist)
699
+ {
700
+ ares_llist_node_t *node;
701
+ const ares_channel_t *channel = server->channel;
702
+
703
+ for (node = ares_llist_node_first(srvlist); node != NULL;
704
+ node = ares_llist_node_next(node)) {
705
+ const ares_sconfig_t *s = ares_llist_node_val(node);
706
+
707
+ if (!ares_addr_match(&server->addr, &s->addr)) {
708
+ continue;
709
+ }
710
+
711
+ if (server->tcp_port != ares_sconfig_get_port(channel, s, ARES_TRUE)) {
712
+ continue;
713
+ }
714
+
715
+ if (server->udp_port != ares_sconfig_get_port(channel, s, ARES_FALSE)) {
716
+ continue;
717
+ }
718
+
719
+ return ARES_TRUE;
720
+ }
721
+
722
+ return ARES_FALSE;
723
+ }
724
+
725
+ static ares_bool_t ares_servers_remove_stale(ares_channel_t *channel,
726
+ ares_llist_t *srvlist)
727
+ {
728
+ ares_bool_t stale_removed = ARES_FALSE;
729
+ ares_slist_node_t *snode = ares_slist_node_first(channel->servers);
730
+
731
+ while (snode != NULL) {
732
+ ares_slist_node_t *snext = ares_slist_node_next(snode);
733
+ const ares_server_t *server = ares_slist_node_val(snode);
734
+ if (!ares_server_in_newconfig(server, srvlist)) {
735
+ /* This will clean up all server state via the destruction callback and
736
+ * move any queries to new servers */
737
+ ares_slist_node_destroy(snode);
738
+ stale_removed = ARES_TRUE;
739
+ }
740
+ snode = snext;
741
+ }
742
+ return stale_removed;
743
+ }
744
+
745
+ static void ares_servers_trim_single(ares_channel_t *channel)
746
+ {
747
+ while (ares_slist_len(channel->servers) > 1) {
748
+ ares_slist_node_destroy(ares_slist_node_last(channel->servers));
749
+ }
750
+ }
751
+
752
+ ares_status_t ares_servers_update(ares_channel_t *channel,
753
+ ares_llist_t *server_list,
754
+ ares_bool_t user_specified)
755
+ {
756
+ ares_llist_node_t *node;
757
+ size_t idx = 0;
758
+ ares_status_t status;
759
+ ares_bool_t list_changed = ARES_FALSE;
760
+
761
+ if (channel == NULL) {
762
+ return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */
763
+ }
764
+
765
+ /* NOTE: a NULL or zero entry server list is considered valid due to
766
+ * real-world people needing support for this for their test harnesses
767
+ */
768
+
769
+ /* Add new entries */
770
+ for (node = ares_llist_node_first(server_list); node != NULL;
771
+ node = ares_llist_node_next(node)) {
772
+ const ares_sconfig_t *sconfig = ares_llist_node_val(node);
773
+ ares_slist_node_t *snode;
774
+
775
+ /* If a server has already appeared in the list of new servers, skip it. */
776
+ if (ares_server_isdup(channel, node)) {
777
+ continue;
778
+ }
779
+
780
+ snode = ares_server_find(channel, sconfig);
781
+ if (snode != NULL) {
782
+ ares_server_t *server = ares_slist_node_val(snode);
783
+
784
+ /* Copy over link-local settings. Its possible some of this data has
785
+ * changed, maybe ... */
786
+ if (ares_strlen(sconfig->ll_iface)) {
787
+ ares_strcpy(server->ll_iface, sconfig->ll_iface,
788
+ sizeof(server->ll_iface));
789
+ server->ll_scope = sconfig->ll_scope;
790
+ }
791
+
792
+ if (server->idx != idx) {
793
+ server->idx = idx;
794
+ /* Index changed, reinsert node, doesn't require any memory
795
+ * allocations so can't fail. */
796
+ ares_slist_node_reinsert(snode);
797
+ }
798
+ } else {
799
+ status = ares_server_create(channel, sconfig, idx);
800
+ if (status != ARES_SUCCESS) {
801
+ goto done;
802
+ }
803
+
804
+ list_changed = ARES_TRUE;
805
+ }
806
+
807
+ idx++;
808
+ }
809
+
810
+ /* Remove any servers that don't exist in the current configuration */
811
+ if (ares_servers_remove_stale(channel, server_list)) {
812
+ list_changed = ARES_TRUE;
813
+ }
814
+
815
+ /* Trim to one server if ARES_FLAG_PRIMARY is set. */
816
+ if (channel->flags & ARES_FLAG_PRIMARY) {
817
+ ares_servers_trim_single(channel);
818
+ }
819
+
820
+ if (user_specified) {
821
+ /* Save servers as if they were passed in as an option */
822
+ channel->optmask |= ARES_OPT_SERVERS;
823
+ }
824
+
825
+ /* Clear any cached query results only if the server list changed */
826
+ if (list_changed) {
827
+ ares_qcache_flush(channel->qcache);
828
+ }
829
+
830
+ status = ARES_SUCCESS;
831
+
832
+ done:
833
+ return status;
834
+ }
835
+
836
+ static ares_status_t
837
+ ares_addr_node_to_sconfig_llist(const struct ares_addr_node *servers,
838
+ ares_llist_t **llist)
839
+ {
840
+ const struct ares_addr_node *node;
841
+ ares_llist_t *s;
842
+
843
+ *llist = NULL;
844
+
845
+ s = ares_llist_create(ares_free);
846
+ if (s == NULL) {
847
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
848
+ }
849
+
850
+ for (node = servers; node != NULL; node = node->next) {
851
+ ares_sconfig_t *sconfig;
852
+
853
+ /* Invalid entry */
854
+ if (node->family != AF_INET && node->family != AF_INET6) {
855
+ continue;
856
+ }
857
+
858
+ sconfig = ares_malloc_zero(sizeof(*sconfig));
859
+ if (sconfig == NULL) {
860
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
861
+ }
862
+
863
+ sconfig->addr.family = node->family;
864
+ if (node->family == AF_INET) {
865
+ memcpy(&sconfig->addr.addr.addr4, &node->addr.addr4,
866
+ sizeof(sconfig->addr.addr.addr4));
867
+ } else if (sconfig->addr.family == AF_INET6) {
868
+ memcpy(&sconfig->addr.addr.addr6, &node->addr.addr6,
869
+ sizeof(sconfig->addr.addr.addr6));
870
+ }
871
+
872
+ if (ares_llist_insert_last(s, sconfig) == NULL) {
873
+ ares_free(sconfig); /* LCOV_EXCL_LINE: OutOfMemory */
874
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
875
+ }
876
+ }
877
+
878
+ *llist = s;
879
+ return ARES_SUCCESS;
880
+
881
+ /* LCOV_EXCL_START: OutOfMemory */
882
+ fail:
883
+ ares_llist_destroy(s);
884
+ return ARES_ENOMEM;
885
+ /* LCOV_EXCL_STOP */
886
+ }
887
+
888
+ static ares_status_t
889
+ ares_addrpnode_to_sconfig_llist(const struct ares_addr_port_node *servers,
890
+ ares_llist_t **llist)
891
+ {
892
+ const struct ares_addr_port_node *node;
893
+ ares_llist_t *s;
894
+
895
+ *llist = NULL;
896
+
897
+ s = ares_llist_create(ares_free);
898
+ if (s == NULL) {
899
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
900
+ }
901
+
902
+ for (node = servers; node != NULL; node = node->next) {
903
+ ares_sconfig_t *sconfig;
904
+
905
+ /* Invalid entry */
906
+ if (node->family != AF_INET && node->family != AF_INET6) {
907
+ continue;
908
+ }
909
+
910
+ sconfig = ares_malloc_zero(sizeof(*sconfig));
911
+ if (sconfig == NULL) {
912
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
913
+ }
914
+
915
+ sconfig->addr.family = node->family;
916
+ if (node->family == AF_INET) {
917
+ memcpy(&sconfig->addr.addr.addr4, &node->addr.addr4,
918
+ sizeof(sconfig->addr.addr.addr4));
919
+ } else if (sconfig->addr.family == AF_INET6) {
920
+ memcpy(&sconfig->addr.addr.addr6, &node->addr.addr6,
921
+ sizeof(sconfig->addr.addr.addr6));
922
+ }
923
+
924
+ sconfig->tcp_port = (unsigned short)node->tcp_port;
925
+ sconfig->udp_port = (unsigned short)node->udp_port;
926
+
927
+ if (ares_llist_insert_last(s, sconfig) == NULL) {
928
+ ares_free(sconfig); /* LCOV_EXCL_LINE: OutOfMemory */
929
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
930
+ }
931
+ }
932
+
933
+ *llist = s;
934
+ return ARES_SUCCESS;
935
+
936
+ /* LCOV_EXCL_START: OutOfMemory */
937
+ fail:
938
+ ares_llist_destroy(s);
939
+ return ARES_ENOMEM;
940
+ /* LCOV_EXCL_STOP */
941
+ }
942
+
943
+ ares_status_t ares_in_addr_to_sconfig_llist(const struct in_addr *servers,
944
+ size_t nservers,
945
+ ares_llist_t **llist)
946
+ {
947
+ size_t i;
948
+ ares_llist_t *s;
949
+
950
+ *llist = NULL;
951
+
952
+ s = ares_llist_create(ares_free);
953
+ if (s == NULL) {
954
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
955
+ }
956
+
957
+ for (i = 0; servers != NULL && i < nservers; i++) {
958
+ ares_sconfig_t *sconfig;
959
+
960
+ sconfig = ares_malloc_zero(sizeof(*sconfig));
961
+ if (sconfig == NULL) {
962
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
963
+ }
964
+
965
+ sconfig->addr.family = AF_INET;
966
+ memcpy(&sconfig->addr.addr.addr4, &servers[i],
967
+ sizeof(sconfig->addr.addr.addr4));
968
+
969
+ if (ares_llist_insert_last(s, sconfig) == NULL) {
970
+ goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
971
+ }
972
+ }
973
+
974
+ *llist = s;
975
+ return ARES_SUCCESS;
976
+
977
+ /* LCOV_EXCL_START: OutOfMemory */
978
+ fail:
979
+ ares_llist_destroy(s);
980
+ return ARES_ENOMEM;
981
+ /* LCOV_EXCL_STOP */
982
+ }
983
+
984
+ static ares_bool_t ares_server_use_uri(const ares_server_t *server)
985
+ {
986
+ /* Currently only reason to use new format is if the ports for udp and tcp
987
+ * are different */
988
+ if (server->tcp_port != server->udp_port) {
989
+ return ARES_TRUE;
990
+ }
991
+ return ARES_FALSE;
992
+ }
993
+
994
+ static ares_status_t ares_get_server_addr_uri(const ares_server_t *server,
995
+ ares_buf_t *buf)
996
+ {
997
+ ares_uri_t *uri = NULL;
998
+ ares_status_t status;
999
+ char addr[INET6_ADDRSTRLEN];
1000
+
1001
+ uri = ares_uri_create();
1002
+ if (uri == NULL) {
1003
+ return ARES_ENOMEM;
1004
+ }
1005
+
1006
+ status = ares_uri_set_scheme(uri, "dns");
1007
+ if (status != ARES_SUCCESS) {
1008
+ goto done;
1009
+ }
1010
+
1011
+ ares_inet_ntop(server->addr.family, &server->addr.addr, addr, sizeof(addr));
1012
+
1013
+ if (ares_strlen(server->ll_iface)) {
1014
+ char addr_iface[256];
1015
+
1016
+ snprintf(addr_iface, sizeof(addr_iface), "%s%%%s", addr, server->ll_iface);
1017
+ status = ares_uri_set_host(uri, addr_iface);
1018
+ } else {
1019
+ status = ares_uri_set_host(uri, addr);
1020
+ }
1021
+
1022
+ if (status != ARES_SUCCESS) {
1023
+ goto done;
1024
+ }
1025
+
1026
+ status = ares_uri_set_port(uri, server->udp_port);
1027
+ if (status != ARES_SUCCESS) {
1028
+ goto done;
1029
+ }
1030
+
1031
+ if (server->udp_port != server->tcp_port) {
1032
+ char port[6];
1033
+ snprintf(port, sizeof(port), "%d", server->tcp_port);
1034
+ status = ares_uri_set_query_key(uri, "tcpport", port);
1035
+ if (status != ARES_SUCCESS) {
1036
+ goto done;
1037
+ }
1038
+ }
1039
+
1040
+ status = ares_uri_write_buf(uri, buf);
1041
+ if (status != ARES_SUCCESS) {
1042
+ goto done;
1043
+ }
1044
+
1045
+ done:
1046
+ ares_uri_destroy(uri);
1047
+ return status;
1048
+ }
1049
+
1050
+ /* Write out the details of a server to a buffer */
1051
+ ares_status_t ares_get_server_addr(const ares_server_t *server, ares_buf_t *buf)
1052
+ {
1053
+ ares_status_t status;
1054
+ char addr[INET6_ADDRSTRLEN];
1055
+
1056
+ if (ares_server_use_uri(server)) {
1057
+ return ares_get_server_addr_uri(server, buf);
1058
+ }
1059
+
1060
+ /* ipv4addr or [ipv6addr] */
1061
+ if (server->addr.family == AF_INET6) {
1062
+ status = ares_buf_append_byte(buf, '[');
1063
+ if (status != ARES_SUCCESS) {
1064
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1065
+ }
1066
+ }
1067
+
1068
+ ares_inet_ntop(server->addr.family, &server->addr.addr, addr, sizeof(addr));
1069
+
1070
+ status = ares_buf_append_str(buf, addr);
1071
+ if (status != ARES_SUCCESS) {
1072
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1073
+ }
1074
+
1075
+ if (server->addr.family == AF_INET6) {
1076
+ status = ares_buf_append_byte(buf, ']');
1077
+ if (status != ARES_SUCCESS) {
1078
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1079
+ }
1080
+ }
1081
+
1082
+ /* :port */
1083
+ status = ares_buf_append_byte(buf, ':');
1084
+ if (status != ARES_SUCCESS) {
1085
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1086
+ }
1087
+
1088
+ status = ares_buf_append_num_dec(buf, server->udp_port, 0);
1089
+ if (status != ARES_SUCCESS) {
1090
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1091
+ }
1092
+
1093
+ /* %iface */
1094
+ if (ares_strlen(server->ll_iface)) {
1095
+ status = ares_buf_append_byte(buf, '%');
1096
+ if (status != ARES_SUCCESS) {
1097
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1098
+ }
1099
+
1100
+ status = ares_buf_append_str(buf, server->ll_iface);
1101
+ if (status != ARES_SUCCESS) {
1102
+ return status; /* LCOV_EXCL_LINE: OutOfMemory */
1103
+ }
1104
+ }
1105
+
1106
+ return ARES_SUCCESS;
1107
+ }
1108
+
1109
+ int ares_get_servers(const ares_channel_t *channel,
1110
+ struct ares_addr_node **servers)
1111
+ {
1112
+ struct ares_addr_node *srvr_head = NULL;
1113
+ struct ares_addr_node *srvr_last = NULL;
1114
+ struct ares_addr_node *srvr_curr;
1115
+ ares_status_t status = ARES_SUCCESS;
1116
+ ares_slist_node_t *node;
1117
+
1118
+ if (channel == NULL) {
1119
+ return ARES_ENODATA;
1120
+ }
1121
+
1122
+ ares_channel_lock(channel);
1123
+
1124
+ for (node = ares_slist_node_first(channel->servers); node != NULL;
1125
+ node = ares_slist_node_next(node)) {
1126
+ const ares_server_t *server = ares_slist_node_val(node);
1127
+
1128
+ /* Allocate storage for this server node appending it to the list */
1129
+ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_NODE);
1130
+ if (!srvr_curr) {
1131
+ status = ARES_ENOMEM;
1132
+ break;
1133
+ }
1134
+ if (srvr_last) {
1135
+ srvr_last->next = srvr_curr;
1136
+ } else {
1137
+ srvr_head = srvr_curr;
1138
+ }
1139
+ srvr_last = srvr_curr;
1140
+
1141
+ /* Fill this server node data */
1142
+ srvr_curr->family = server->addr.family;
1143
+ if (srvr_curr->family == AF_INET) {
1144
+ memcpy(&srvr_curr->addr.addr4, &server->addr.addr.addr4,
1145
+ sizeof(srvr_curr->addr.addr4));
1146
+ } else {
1147
+ memcpy(&srvr_curr->addr.addr6, &server->addr.addr.addr6,
1148
+ sizeof(srvr_curr->addr.addr6));
1149
+ }
1150
+ }
1151
+
1152
+ if (status != ARES_SUCCESS) {
1153
+ ares_free_data(srvr_head);
1154
+ srvr_head = NULL;
1155
+ }
1156
+
1157
+ *servers = srvr_head;
1158
+
1159
+ ares_channel_unlock(channel);
1160
+
1161
+ return (int)status;
1162
+ }
1163
+
1164
+ int ares_get_servers_ports(const ares_channel_t *channel,
1165
+ struct ares_addr_port_node **servers)
1166
+ {
1167
+ struct ares_addr_port_node *srvr_head = NULL;
1168
+ struct ares_addr_port_node *srvr_last = NULL;
1169
+ struct ares_addr_port_node *srvr_curr;
1170
+ ares_status_t status = ARES_SUCCESS;
1171
+ ares_slist_node_t *node;
1172
+
1173
+ if (channel == NULL) {
1174
+ return ARES_ENODATA;
1175
+ }
1176
+
1177
+ ares_channel_lock(channel);
1178
+
1179
+ for (node = ares_slist_node_first(channel->servers); node != NULL;
1180
+ node = ares_slist_node_next(node)) {
1181
+ const ares_server_t *server = ares_slist_node_val(node);
1182
+
1183
+ /* Allocate storage for this server node appending it to the list */
1184
+ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_PORT_NODE);
1185
+ if (!srvr_curr) {
1186
+ status = ARES_ENOMEM;
1187
+ break;
1188
+ }
1189
+ if (srvr_last) {
1190
+ srvr_last->next = srvr_curr;
1191
+ } else {
1192
+ srvr_head = srvr_curr;
1193
+ }
1194
+ srvr_last = srvr_curr;
1195
+
1196
+ /* Fill this server node data */
1197
+ srvr_curr->family = server->addr.family;
1198
+ srvr_curr->udp_port = server->udp_port;
1199
+ srvr_curr->tcp_port = server->tcp_port;
1200
+
1201
+ if (srvr_curr->family == AF_INET) {
1202
+ memcpy(&srvr_curr->addr.addr4, &server->addr.addr.addr4,
1203
+ sizeof(srvr_curr->addr.addr4));
1204
+ } else {
1205
+ memcpy(&srvr_curr->addr.addr6, &server->addr.addr.addr6,
1206
+ sizeof(srvr_curr->addr.addr6));
1207
+ }
1208
+ }
1209
+
1210
+ if (status != ARES_SUCCESS) {
1211
+ ares_free_data(srvr_head);
1212
+ srvr_head = NULL;
1213
+ }
1214
+
1215
+ *servers = srvr_head;
1216
+
1217
+ ares_channel_unlock(channel);
1218
+ return (int)status;
1219
+ }
1220
+
1221
+ int ares_set_servers(ares_channel_t *channel,
1222
+ const struct ares_addr_node *servers)
1223
+ {
1224
+ ares_llist_t *slist;
1225
+ ares_status_t status;
1226
+
1227
+ if (channel == NULL) {
1228
+ return ARES_ENODATA;
1229
+ }
1230
+
1231
+ status = ares_addr_node_to_sconfig_llist(servers, &slist);
1232
+ if (status != ARES_SUCCESS) {
1233
+ return (int)status;
1234
+ }
1235
+
1236
+ ares_channel_lock(channel);
1237
+ status = ares_servers_update(channel, slist, ARES_TRUE);
1238
+ ares_channel_unlock(channel);
1239
+
1240
+ ares_llist_destroy(slist);
1241
+
1242
+ return (int)status;
1243
+ }
1244
+
1245
+ int ares_set_servers_ports(ares_channel_t *channel,
1246
+ const struct ares_addr_port_node *servers)
1247
+ {
1248
+ ares_llist_t *slist;
1249
+ ares_status_t status;
1250
+
1251
+ if (channel == NULL) {
1252
+ return ARES_ENODATA;
1253
+ }
1254
+
1255
+ status = ares_addrpnode_to_sconfig_llist(servers, &slist);
1256
+ if (status != ARES_SUCCESS) {
1257
+ return (int)status;
1258
+ }
1259
+
1260
+ ares_channel_lock(channel);
1261
+ status = ares_servers_update(channel, slist, ARES_TRUE);
1262
+ ares_channel_unlock(channel);
1263
+
1264
+ ares_llist_destroy(slist);
1265
+
1266
+ return (int)status;
1267
+ }
1268
+
1269
+ /* Incoming string format: host[:port][,host[:port]]... */
1270
+ /* IPv6 addresses with ports require square brackets [fe80::1]:53 */
1271
+ static ares_status_t set_servers_csv(ares_channel_t *channel, const char *_csv)
1272
+ {
1273
+ ares_status_t status;
1274
+ ares_llist_t *slist = NULL;
1275
+
1276
+ if (channel == NULL) {
1277
+ return ARES_ENODATA;
1278
+ }
1279
+
1280
+ if (ares_strlen(_csv) == 0) {
1281
+ /* blank all servers */
1282
+ ares_channel_lock(channel);
1283
+ status = ares_servers_update(channel, NULL, ARES_TRUE);
1284
+ ares_channel_unlock(channel);
1285
+ return status;
1286
+ }
1287
+
1288
+ status = ares_sconfig_append_fromstr(channel, &slist, _csv, ARES_FALSE);
1289
+ if (status != ARES_SUCCESS) {
1290
+ ares_llist_destroy(slist);
1291
+ return status;
1292
+ }
1293
+
1294
+ ares_channel_lock(channel);
1295
+ status = ares_servers_update(channel, slist, ARES_TRUE);
1296
+ ares_channel_unlock(channel);
1297
+
1298
+ ares_llist_destroy(slist);
1299
+
1300
+ return status;
1301
+ }
1302
+
1303
+ /* We'll go ahead and honor ports anyhow */
1304
+ int ares_set_servers_csv(ares_channel_t *channel, const char *_csv)
1305
+ {
1306
+ return (int)set_servers_csv(channel, _csv);
1307
+ }
1308
+
1309
+ int ares_set_servers_ports_csv(ares_channel_t *channel, const char *_csv)
1310
+ {
1311
+ return (int)set_servers_csv(channel, _csv);
1312
+ }
1313
+
1314
+ char *ares_get_servers_csv(const ares_channel_t *channel)
1315
+ {
1316
+ ares_buf_t *buf = NULL;
1317
+ char *out = NULL;
1318
+ ares_slist_node_t *node;
1319
+
1320
+ ares_channel_lock(channel);
1321
+
1322
+ buf = ares_buf_create();
1323
+ if (buf == NULL) {
1324
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
1325
+ }
1326
+
1327
+ for (node = ares_slist_node_first(channel->servers); node != NULL;
1328
+ node = ares_slist_node_next(node)) {
1329
+ ares_status_t status;
1330
+ const ares_server_t *server = ares_slist_node_val(node);
1331
+
1332
+ if (ares_buf_len(buf)) {
1333
+ status = ares_buf_append_byte(buf, ',');
1334
+ if (status != ARES_SUCCESS) {
1335
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
1336
+ }
1337
+ }
1338
+
1339
+ status = ares_get_server_addr(server, buf);
1340
+ if (status != ARES_SUCCESS) {
1341
+ goto done; /* LCOV_EXCL_LINE: OutOfMemory */
1342
+ }
1343
+ }
1344
+
1345
+ out = ares_buf_finish_str(buf, NULL);
1346
+ buf = NULL;
1347
+
1348
+ done:
1349
+ ares_channel_unlock(channel);
1350
+ ares_buf_destroy(buf);
1351
+ return out;
1352
+ }
1353
+
1354
+ void ares_set_server_state_callback(ares_channel_t *channel,
1355
+ ares_server_state_callback cb, void *data)
1356
+ {
1357
+ if (channel == NULL) {
1358
+ return; /* LCOV_EXCL_LINE: DefensiveCoding */
1359
+ }
1360
+ channel->server_state_cb = cb;
1361
+ channel->server_state_cb_data = data;
1362
+ }