| 
					
				 | 
			
			
				@@ -0,0 +1,83 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright 2019 gRPC authors. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Licensed under the Apache License, Version 2.0 (the "License"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * you may not use this file except in compliance with the License. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * You may obtain a copy of the License at 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *     http://www.apache.org/licenses/LICENSE-2.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Unless required by applicable law or agreed to in writing, software 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * distributed under the License is distributed on an "AS IS" BASIS, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * See the License for the specific language governing permissions and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * limitations under the License. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <grpc/support/port_platform.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/lib/iomgr/port.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <grpc/support/string_util.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/ext/filters/client_channel/parse_address.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/ext/filters/client_channel/server_address.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/lib/gpr/host_port.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/lib/gpr/string.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool inner_maybe_resolve_localhost_manually_locked( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const char* name, const char* default_port, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char** port) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_split_host_port(name, host, port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (*host == nullptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_log(GPR_ERROR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "Failed to parse %s into host:port during manual localhost " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "resolution check.", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (*port == nullptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (default_port == nullptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_log(GPR_ERROR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "No port or default port for %s during manual localhost " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "resolution check.", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    *port = gpr_strdup(default_port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (gpr_stricmp(*host, "localhost") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(*addrs == nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    *addrs = grpc_core::MakeUnique<grpc_core::ServerAddressList>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint16_t numeric_port = grpc_strhtons(*port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Append the ipv6 loopback address. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct sockaddr_in6 ipv6_loopback_addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ipv6_loopback_addr.sin6_family = AF_INET6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ipv6_loopback_addr.sin6_port = numeric_port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           nullptr /* args */); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Append the ipv4 loopback address. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct sockaddr_in ipv4_loopback_addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ipv4_loopback_addr.sin_family = AF_INET; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ipv4_loopback_addr.sin_port = numeric_port; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           nullptr /* args */); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Let the address sorter figure out which one should be tried first. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_cares_wrapper_address_sorting_sort(addrs->get()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ 
			 |