3 * Copyright 2016 gRPC authors.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #include <grpc/support/port_platform.h>
21 #include "src/core/lib/iomgr/port.h"
22 #if GRPC_ARES == 1 && defined(GPR_WINDOWS)
24 #include <grpc/support/string_util.h>
26 #include "src/core/ext/filters/client_channel/parse_address.h"
27 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
28 #include "src/core/ext/filters/client_channel/server_address.h"
29 #include "src/core/lib/gpr/host_port.h"
30 #include "src/core/lib/gpr/string.h"
31 #include "src/core/lib/iomgr/socket_windows.h"
33 bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
35 static bool inner_maybe_resolve_localhost_manually_locked(
36 const char* name, const char* default_port,
37 grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
39 gpr_split_host_port(name, host, port);
40 if (*host == nullptr) {
42 "Failed to parse %s into host:port during Windows localhost "
47 if (*port == nullptr) {
48 if (default_port == nullptr) {
50 "No port or default port for %s during Windows localhost "
55 *port = gpr_strdup(default_port);
57 if (gpr_stricmp(*host, "localhost") == 0) {
58 GPR_ASSERT(*addrs == nullptr);
59 *addrs = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
60 uint16_t numeric_port = grpc_strhtons(*port);
61 // Append the ipv6 loopback address.
62 struct sockaddr_in6 ipv6_loopback_addr;
63 memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr));
64 ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1;
65 ipv6_loopback_addr.sin6_family = AF_INET6;
66 ipv6_loopback_addr.sin6_port = numeric_port;
67 (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr),
69 // Append the ipv4 loopback address.
70 struct sockaddr_in ipv4_loopback_addr;
71 memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr));
72 ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f;
73 ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01;
74 ipv4_loopback_addr.sin_family = AF_INET;
75 ipv4_loopback_addr.sin_port = numeric_port;
76 (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr),
78 // Let the address sorter figure out which one should be tried first.
79 grpc_cares_wrapper_address_sorting_sort(addrs->get());
85 bool grpc_ares_maybe_resolve_localhost_manually_locked(
86 const char* name, const char* default_port,
87 grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
90 bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port,
97 #endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */