blob: 50e470d14916a23d5e2b5ac2f7c16d8b74c78a4b [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
murgatroid9954070892016-08-08 17:01:18 -070034#include "src/core/lib/iomgr/port.h"
murgatroid99623dd4f2016-08-08 17:31:27 -070035#ifdef GRPC_POSIX_SOCKET
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036
Craig Tiller9533d042016-03-25 17:11:06 -070037#include "src/core/lib/iomgr/sockaddr.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080038
murgatroid997871f732016-09-23 13:49:05 -070039#include "src/core/lib/iomgr/resolve_address.h"
40
Craig Tillere1e45592016-03-11 08:01:58 -080041#include <string.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080042#include <sys/types.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080043
44#include <grpc/support/alloc.h>
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080045#include <grpc/support/host_port.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070047#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080048#include <grpc/support/thd.h>
nnoble0c475f02014-12-05 15:37:39 -080049#include <grpc/support/time.h>
Craig Tillerb9d35962015-09-11 13:31:16 -070050#include <grpc/support/useful.h>
Craig Tiller9533d042016-03-25 17:11:06 -070051#include "src/core/lib/iomgr/executor.h"
52#include "src/core/lib/iomgr/iomgr_internal.h"
Craig Tiller9533d042016-03-25 17:11:06 -070053#include "src/core/lib/iomgr/unix_sockets_posix.h"
54#include "src/core/lib/support/block_annotate.h"
55#include "src/core/lib/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080056
Craig Tiller5b15afd2016-05-04 15:00:14 -070057static grpc_error *blocking_resolve_address_impl(
58 const char *name, const char *default_port,
59 grpc_resolved_addresses **addresses) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080060 struct addrinfo hints;
61 struct addrinfo *result = NULL, *resp;
62 char *host;
63 char *port;
64 int s;
65 size_t i;
Craig Tiller5b15afd2016-05-04 15:00:14 -070066 grpc_error *err;
Craig Tillerae7fe922015-02-13 23:16:32 -080067
Craig Tillera82950e2015-09-22 12:33:20 -070068 if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
69 name[4] == ':' && name[5] != 0) {
Craig Tiller5b15afd2016-05-04 15:00:14 -070070 return grpc_resolve_unix_domain_address(name + 5, addresses);
Craig Tillera82950e2015-09-22 12:33:20 -070071 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080072
73 /* parse name, splitting it into host and port parts */
Craig Tillera82950e2015-09-22 12:33:20 -070074 gpr_split_host_port(name, &host, &port);
75 if (host == NULL) {
Craig Tiller5b15afd2016-05-04 15:00:14 -070076 err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
77 GRPC_ERROR_STR_TARGET_ADDRESS, name);
Craig Tillera82950e2015-09-22 12:33:20 -070078 goto done;
79 }
80 if (port == NULL) {
81 if (default_port == NULL) {
Craig Tiller5b15afd2016-05-04 15:00:14 -070082 err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
83 GRPC_ERROR_STR_TARGET_ADDRESS, name);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080084 goto done;
85 }
Craig Tillera82950e2015-09-22 12:33:20 -070086 port = gpr_strdup(default_port);
87 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080088
89 /* Call getaddrinfo */
Craig Tillera82950e2015-09-22 12:33:20 -070090 memset(&hints, 0, sizeof(hints));
91 hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */
92 hints.ai_socktype = SOCK_STREAM; /* stream socket */
93 hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080094
vjpai9839d282015-09-24 17:55:18 -070095 GRPC_SCHEDULING_START_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -070096 s = getaddrinfo(host, port, &hints, &result);
vjpai9839d282015-09-24 17:55:18 -070097 GRPC_SCHEDULING_END_BLOCKING_REGION;
Vijay Paiba130552015-09-24 13:43:01 -070098
Craig Tillera82950e2015-09-22 12:33:20 -070099 if (s != 0) {
100 /* Retry if well-known service name is recognized */
101 char *svc[][2] = {{"http", "80"}, {"https", "443"}};
Craig Tillerb9d35962015-09-11 13:31:16 -0700102 for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
Craig Tillera82950e2015-09-22 12:33:20 -0700103 if (strcmp(port, svc[i][0]) == 0) {
vjpai9839d282015-09-24 17:55:18 -0700104 GRPC_SCHEDULING_START_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700105 s = getaddrinfo(host, svc[i][1], &hints, &result);
vjpai9839d282015-09-24 17:55:18 -0700106 GRPC_SCHEDULING_END_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700107 break;
108 }
Raul Silvera659be5a2015-03-04 11:51:11 -0800109 }
Craig Tillera82950e2015-09-22 12:33:20 -0700110 }
Raul Silvera659be5a2015-03-04 11:51:11 -0800111
Craig Tillera82950e2015-09-22 12:33:20 -0700112 if (s != 0) {
Craig Tiller5b15afd2016-05-04 15:00:14 -0700113 err = grpc_error_set_str(
114 grpc_error_set_str(
115 grpc_error_set_str(grpc_error_set_int(GRPC_ERROR_CREATE("OS Error"),
116 GRPC_ERROR_INT_ERRNO, s),
117 GRPC_ERROR_STR_OS_ERROR, gai_strerror(s)),
118 GRPC_ERROR_STR_SYSCALL, "getaddrinfo"),
119 GRPC_ERROR_STR_TARGET_ADDRESS, name);
Craig Tillera82950e2015-09-22 12:33:20 -0700120 goto done;
121 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800122
123 /* Success path: set addrs non-NULL, fill it in */
Craig Tiller5b15afd2016-05-04 15:00:14 -0700124 *addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
125 (*addresses)->naddrs = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700126 for (resp = result; resp != NULL; resp = resp->ai_next) {
Craig Tiller5b15afd2016-05-04 15:00:14 -0700127 (*addresses)->naddrs++;
Craig Tillera82950e2015-09-22 12:33:20 -0700128 }
Craig Tiller5b15afd2016-05-04 15:00:14 -0700129 (*addresses)->addrs =
130 gpr_malloc(sizeof(grpc_resolved_address) * (*addresses)->naddrs);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800131 i = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700132 for (resp = result; resp != NULL; resp = resp->ai_next) {
Craig Tiller5b15afd2016-05-04 15:00:14 -0700133 memcpy(&(*addresses)->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
134 (*addresses)->addrs[i].len = resp->ai_addrlen;
Craig Tillera82950e2015-09-22 12:33:20 -0700135 i++;
136 }
Craig Tiller5b15afd2016-05-04 15:00:14 -0700137 err = GRPC_ERROR_NONE;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800138
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800139done:
Craig Tillera82950e2015-09-22 12:33:20 -0700140 gpr_free(host);
141 gpr_free(port);
142 if (result) {
143 freeaddrinfo(result);
144 }
Craig Tiller5b15afd2016-05-04 15:00:14 -0700145 return err;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800146}
147
Craig Tiller5b15afd2016-05-04 15:00:14 -0700148grpc_error *(*grpc_blocking_resolve_address)(
149 const char *name, const char *default_port,
150 grpc_resolved_addresses **addresses) = blocking_resolve_address_impl;
151
152typedef struct {
153 char *name;
154 char *default_port;
155 grpc_closure *on_done;
156 grpc_resolved_addresses **addrs_out;
157 grpc_closure request_closure;
158 void *arg;
159} request;
Craig Tillere1e45592016-03-11 08:01:58 -0800160
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700161/* Callback to be passed to grpc_executor to asynch-ify
162 * grpc_blocking_resolve_address */
Craig Tillerc027e772016-05-03 16:27:00 -0700163static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp,
164 grpc_error *error) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800165 request *r = rp;
Craig Tiller91031da2016-12-28 15:44:25 -0800166 grpc_closure_sched(
Craig Tiller5b15afd2016-05-04 15:00:14 -0700167 exec_ctx, r->on_done,
Craig Tiller91031da2016-12-28 15:44:25 -0800168 grpc_blocking_resolve_address(r->name, r->default_port, r->addrs_out));
Craig Tillera82950e2015-09-22 12:33:20 -0700169 gpr_free(r->name);
170 gpr_free(r->default_port);
Craig Tillera82950e2015-09-22 12:33:20 -0700171 gpr_free(r);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800172}
173
Craig Tillera82950e2015-09-22 12:33:20 -0700174void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
David Garcia Quintasd5520c12016-05-10 16:03:12 -0700175 if (addrs != NULL) {
176 gpr_free(addrs->addrs);
177 }
Craig Tillera82950e2015-09-22 12:33:20 -0700178 gpr_free(addrs);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800179}
180
Craig Tiller24d687e2016-04-13 19:47:27 -0700181static void resolve_address_impl(grpc_exec_ctx *exec_ctx, const char *name,
Craig Tiller5b15afd2016-05-04 15:00:14 -0700182 const char *default_port,
Yuchen Zeng15521de2016-11-17 20:39:27 -0800183 grpc_pollset_set *interested_parties,
Craig Tiller5b15afd2016-05-04 15:00:14 -0700184 grpc_closure *on_done,
185 grpc_resolved_addresses **addrs) {
Craig Tillera82950e2015-09-22 12:33:20 -0700186 request *r = gpr_malloc(sizeof(request));
Craig Tiller91031da2016-12-28 15:44:25 -0800187 grpc_closure_init(&r->request_closure, do_request_thread, r,
188 grpc_executor_scheduler);
Craig Tillera82950e2015-09-22 12:33:20 -0700189 r->name = gpr_strdup(name);
190 r->default_port = gpr_strdup(default_port);
Craig Tiller5b15afd2016-05-04 15:00:14 -0700191 r->on_done = on_done;
192 r->addrs_out = addrs;
Craig Tiller91031da2016-12-28 15:44:25 -0800193 grpc_closure_sched(exec_ctx, &r->request_closure, GRPC_ERROR_NONE);
Craig Tiller190d3602015-02-18 09:23:38 -0800194}
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +0100195
Yuchen Zeng15521de2016-11-17 20:39:27 -0800196void (*grpc_resolve_address)(
197 grpc_exec_ctx *exec_ctx, const char *name, const char *default_port,
198 grpc_pollset_set *interested_parties, grpc_closure *on_done,
199 grpc_resolved_addresses **addrs) = resolve_address_impl;
Craig Tiller24d687e2016-04-13 19:47:27 -0700200
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +0100201#endif