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.
- checksums.yaml +4 -4
- data/Makefile +83 -41
- data/include/grpc/credentials.h +7 -1
- data/src/core/call/client_call.cc +4 -4
- data/src/core/call/filter_fusion.h +1230 -0
- data/src/core/call/metadata.cc +22 -0
- data/src/core/call/metadata.h +24 -2
- data/src/core/channelz/channelz.cc +10 -17
- data/src/core/channelz/channelz.h +58 -19
- data/src/core/channelz/channelz_registry.cc +0 -162
- data/src/core/channelz/channelz_registry.h +14 -7
- data/src/core/channelz/property_list.cc +19 -23
- data/src/core/channelz/property_list.h +3 -1
- data/src/core/channelz/v2tov1/convert.cc +683 -0
- data/src/core/channelz/v2tov1/convert.h +58 -0
- data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
- data/src/core/channelz/v2tov1/legacy_api.h +32 -0
- data/src/core/channelz/v2tov1/property_list.cc +118 -0
- data/src/core/channelz/v2tov1/property_list.h +52 -0
- data/src/core/client_channel/client_channel_filter.cc +5 -4
- data/src/core/client_channel/client_channel_filter.h +2 -2
- data/src/core/client_channel/client_channel_internal.h +2 -1
- data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
- data/src/core/client_channel/subchannel.cc +14 -6
- data/src/core/client_channel/subchannel.h +2 -0
- data/src/core/config/core_configuration.cc +3 -1
- data/src/core/config/core_configuration.h +12 -0
- data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
- data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
- data/src/core/credentials/transport/channel_creds_registry_init.cc +3 -1
- data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
- data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
- data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
- data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
- data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
- data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
- data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
- data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
- data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
- data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
- data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
- data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
- data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
- data/src/core/ext/filters/http/client_authority_filter.cc +1 -2
- data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
- data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
- data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
- data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
- data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -0
- data/src/core/ext/transport/chttp2/transport/frame.cc +89 -6
- data/src/core/ext/transport/chttp2/transport/frame.h +38 -0
- data/src/core/ext/transport/chttp2/transport/header_assembler.h +5 -14
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +294 -78
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +128 -9
- data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +52 -35
- data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +81 -3
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +12 -1
- data/src/core/ext/transport/chttp2/transport/message_assembler.h +2 -2
- data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -1
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +2 -1
- data/src/core/ext/transport/chttp2/transport/ping_promise.h +22 -5
- data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
- data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +6 -4
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +142 -54
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +18 -14
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +2 -2
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +86 -88
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +2 -2
- data/src/core/filter/auth/auth_filters.h +2 -2
- data/src/core/filter/fused_filters.cc +154 -0
- data/src/core/handshaker/security/legacy_secure_endpoint.cc +1 -1
- data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
- data/src/core/handshaker/security/secure_endpoint.cc +28 -13
- data/src/core/handshaker/security/secure_endpoint.h +8 -0
- data/src/core/lib/channel/promise_based_filter.cc +15 -25
- data/src/core/lib/channel/promise_based_filter.h +6 -5
- data/src/core/lib/event_engine/ares_resolver.h +3 -1
- data/src/core/lib/event_engine/cf_engine/cf_engine.cc +9 -5
- data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -1
- data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
- data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +12 -0
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +12 -10
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +6 -4
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +15 -14
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -5
- data/src/core/lib/event_engine/posix_engine/event_poller.h +0 -8
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -5
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
- data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +1 -0
- data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
- data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +2 -2
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +188 -199
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +30 -45
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -1
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +2 -1
- data/src/core/lib/experiments/experiments.cc +120 -6
- data/src/core/lib/experiments/experiments.h +46 -3
- data/src/core/lib/iomgr/combiner.cc +1 -1
- data/src/core/lib/iomgr/exec_ctx.h +3 -9
- data/src/core/lib/iomgr/socket_mutator.cc +1 -1
- data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
- data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
- data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
- data/src/core/lib/iomgr/tcp_posix.cc +3 -3
- data/src/core/lib/promise/activity.h +2 -2
- data/src/core/lib/promise/mpsc.cc +8 -8
- data/src/core/lib/promise/party.cc +7 -7
- data/src/core/lib/promise/party.h +4 -4
- data/src/core/lib/promise/poll.h +10 -0
- data/src/core/lib/resource_quota/memory_quota.cc +90 -3
- data/src/core/lib/resource_quota/memory_quota.h +20 -9
- data/src/core/lib/resource_quota/periodic_update.cc +14 -0
- data/src/core/lib/resource_quota/periodic_update.h +8 -0
- data/src/core/lib/resource_quota/resource_quota.cc +15 -4
- data/src/core/lib/resource_quota/resource_quota.h +3 -0
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
- data/src/core/lib/surface/call.cc +5 -5
- data/src/core/lib/surface/call.h +6 -5
- data/src/core/lib/surface/completion_queue.cc +2 -4
- data/src/core/lib/surface/filter_stack_call.cc +1 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.h +3 -3
- data/src/core/load_balancing/endpoint_list.cc +29 -2
- data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
- data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
- data/src/core/load_balancing/pick_first/pick_first.cc +12 -5
- data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
- data/src/core/net/socket_mutator.cc +19 -0
- data/src/core/net/socket_mutator.h +25 -0
- data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
- data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
- data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
- data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
- data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
- data/src/core/resolver/xds/xds_dependency_manager.cc +1 -1
- data/src/core/server/server.cc +1 -1
- data/src/core/server/server_call_tracer_filter.cc +0 -66
- data/src/core/server/server_call_tracer_filter.h +64 -0
- data/src/core/server/server_config_selector_filter.cc +1 -1
- data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
- data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
- data/src/core/telemetry/call_tracer.cc +20 -14
- data/src/core/telemetry/call_tracer.h +22 -17
- data/src/core/telemetry/metrics.h +8 -8
- data/src/core/telemetry/stats_data.cc +151 -151
- data/src/core/telemetry/stats_data.h +87 -87
- data/src/core/transport/auth_context.cc +20 -0
- data/src/core/transport/auth_context.h +4 -0
- data/src/core/transport/auth_context_comparator_registry.h +69 -0
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
- data/src/core/tsi/ssl_transport_security.cc +202 -32
- data/src/core/tsi/ssl_transport_security.h +19 -10
- data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
- data/src/core/tsi/ssl_transport_security_utils.h +4 -0
- data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
- data/src/core/util/latent_see.cc +178 -146
- data/src/core/util/latent_see.h +245 -188
- data/src/core/util/single_set_ptr.h +5 -2
- data/src/core/util/useful.h +91 -0
- data/src/core/util/windows/directory_reader.cc +1 -0
- data/src/core/util/windows/thd.cc +1 -3
- data/src/core/util/work_serializer.cc +1 -1
- data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
- data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
- data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/cares/cares/include/ares.h +925 -460
- data/third_party/cares/cares/include/ares_dns.h +86 -71
- data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
- data/third_party/cares/cares/include/ares_nameser.h +215 -189
- data/third_party/cares/cares/include/ares_version.h +37 -14
- data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
- data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
- data/third_party/cares/cares/src/lib/ares_android.c +216 -164
- data/third_party/cares/cares/src/lib/ares_android.h +25 -14
- data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
- data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
- data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
- data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
- data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
- data/third_party/cares/cares/src/lib/ares_data.c +93 -181
- data/third_party/cares/cares/src/lib/ares_data.h +50 -39
- data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
- data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
- data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
- data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
- data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
- data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
- data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
- data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
- data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
- data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
- data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
- data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
- data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
- data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
- data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
- data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
- data/third_party/cares/cares/src/lib/ares_options.c +418 -332
- data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
- data/third_party/cares/cares/src/lib/ares_private.h +558 -356
- data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
- data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
- data/third_party/cares/cares/src/lib/ares_query.c +126 -121
- data/third_party/cares/cares/src/lib/ares_search.c +564 -262
- data/third_party/cares/cares/src/lib/ares_send.c +264 -93
- data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
- data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
- data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
- data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
- data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
- data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
- data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
- data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
- data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
- data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
- data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
- data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
- data/third_party/cares/cares/src/lib/ares_version.c +29 -4
- data/third_party/cares/cares/src/lib/config-dos.h +88 -89
- data/third_party/cares/cares/src/lib/config-win32.h +122 -77
- data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
- data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
- data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
- data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
- data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
- data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
- data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
- data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
- data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
- data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
- data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
- data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
- data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
- data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
- data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
- data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
- data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
- data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
- data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
- data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
- data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
- data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
- data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
- data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
- data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
- data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
- data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
- data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
- data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
- data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
- data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
- data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
- data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
- data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
- data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
- data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
- data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
- data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
- data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
- data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
- data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
- data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
- data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
- data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
- data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
- data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
- data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
- data/third_party/cares/cares/src/lib/windows_port.c +16 -9
- metadata +121 -49
- data/src/core/util/ring_buffer.h +0 -122
- data/third_party/cares/cares/include/ares_rules.h +0 -125
- data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
- data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
- data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
- data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
- data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
- data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
- data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
- data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
- data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
- data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
- data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
- data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
- data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
- data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
- data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
- data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
- data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
- data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
- data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
- data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
- data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
- data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
- data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
- data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
- data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
- data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
- data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
- data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
- data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
- data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
- data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
- data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
- data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
- data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
- data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
- data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
- data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
- data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
- data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
- data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
- data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
- data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
- data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
- data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
- data/third_party/cares/cares/src/lib/setup_once.h +0 -554
- 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
|
+
}
|