blob: 26b3aa8189c938f3340e92bdc68b11fdd766238b [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tillera93a25f2016-01-28 13:55:49 -08003 * Copyright 2015-2016, 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
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +010034#include <grpc/support/port_platform.h>
35#ifdef GPR_POSIX_SOCKET
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036
ctiller18b49ab2014-12-09 14:39:16 -080037#include "src/core/iomgr/resolve_address.h"
Craig Tillere1e45592016-03-11 08:01:58 -080038#include "src/core/iomgr/sockaddr.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039
Craig Tillere1e45592016-03-11 08:01:58 -080040#include <string.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080041#include <sys/types.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080042
43#include <grpc/support/alloc.h>
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080044#include <grpc/support/host_port.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070046#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080047#include <grpc/support/thd.h>
nnoble0c475f02014-12-05 15:37:39 -080048#include <grpc/support/time.h>
Craig Tillerb9d35962015-09-11 13:31:16 -070049#include <grpc/support/useful.h>
Craig Tillere1e45592016-03-11 08:01:58 -080050#include "src/core/iomgr/executor.h"
51#include "src/core/iomgr/iomgr_internal.h"
52#include "src/core/iomgr/sockaddr_utils.h"
ahedberg43df2952016-03-18 10:46:38 -040053#include "src/core/iomgr/unix_sockets_posix.h"
Craig Tillere1e45592016-03-11 08:01:58 -080054#include "src/core/support/block_annotate.h"
55#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080056
Craig Tillera82950e2015-09-22 12:33:20 -070057typedef struct {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080058 char *name;
59 char *default_port;
60 grpc_resolve_cb cb;
David Garcia Quintas4bc34632015-10-07 16:12:35 -070061 grpc_closure request_closure;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080062 void *arg;
63} request;
64
Craig Tillere1e45592016-03-11 08:01:58 -080065static grpc_resolved_addresses *blocking_resolve_address_impl(
Craig Tillera82950e2015-09-22 12:33:20 -070066 const char *name, const char *default_port) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080067 struct addrinfo hints;
68 struct addrinfo *result = NULL, *resp;
69 char *host;
70 char *port;
71 int s;
72 size_t i;
73 grpc_resolved_addresses *addrs = NULL;
Craig Tillerae7fe922015-02-13 23:16:32 -080074
Craig Tillera82950e2015-09-22 12:33:20 -070075 if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
76 name[4] == ':' && name[5] != 0) {
ahedberg80d6b122016-03-17 17:37:35 -040077 return grpc_resolve_unix_domain_address(name + 5);
Craig Tillera82950e2015-09-22 12:33:20 -070078 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080079
80 /* parse name, splitting it into host and port parts */
Craig Tillera82950e2015-09-22 12:33:20 -070081 gpr_split_host_port(name, &host, &port);
82 if (host == NULL) {
83 gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name);
84 goto done;
85 }
86 if (port == NULL) {
87 if (default_port == NULL) {
88 gpr_log(GPR_ERROR, "no port in name '%s'", name);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080089 goto done;
90 }
Craig Tillera82950e2015-09-22 12:33:20 -070091 port = gpr_strdup(default_port);
92 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080093
94 /* Call getaddrinfo */
Craig Tillera82950e2015-09-22 12:33:20 -070095 memset(&hints, 0, sizeof(hints));
96 hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */
97 hints.ai_socktype = SOCK_STREAM; /* stream socket */
98 hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080099
vjpai9839d282015-09-24 17:55:18 -0700100 GRPC_SCHEDULING_START_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700101 s = getaddrinfo(host, port, &hints, &result);
vjpai9839d282015-09-24 17:55:18 -0700102 GRPC_SCHEDULING_END_BLOCKING_REGION;
Vijay Paiba130552015-09-24 13:43:01 -0700103
Craig Tillera82950e2015-09-22 12:33:20 -0700104 if (s != 0) {
105 /* Retry if well-known service name is recognized */
106 char *svc[][2] = {{"http", "80"}, {"https", "443"}};
Craig Tillerb9d35962015-09-11 13:31:16 -0700107 for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
Craig Tillera82950e2015-09-22 12:33:20 -0700108 if (strcmp(port, svc[i][0]) == 0) {
vjpai9839d282015-09-24 17:55:18 -0700109 GRPC_SCHEDULING_START_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700110 s = getaddrinfo(host, svc[i][1], &hints, &result);
vjpai9839d282015-09-24 17:55:18 -0700111 GRPC_SCHEDULING_END_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700112 break;
113 }
Raul Silvera659be5a2015-03-04 11:51:11 -0800114 }
Craig Tillera82950e2015-09-22 12:33:20 -0700115 }
Raul Silvera659be5a2015-03-04 11:51:11 -0800116
Craig Tillera82950e2015-09-22 12:33:20 -0700117 if (s != 0) {
118 gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s));
119 goto done;
120 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800121
122 /* Success path: set addrs non-NULL, fill it in */
Craig Tillera82950e2015-09-22 12:33:20 -0700123 addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800124 addrs->naddrs = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700125 for (resp = result; resp != NULL; resp = resp->ai_next) {
126 addrs->naddrs++;
127 }
128 addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800129 i = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700130 for (resp = result; resp != NULL; resp = resp->ai_next) {
131 memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
132 addrs->addrs[i].len = resp->ai_addrlen;
133 i++;
134 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800135
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800136done:
Craig Tillera82950e2015-09-22 12:33:20 -0700137 gpr_free(host);
138 gpr_free(port);
139 if (result) {
140 freeaddrinfo(result);
141 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142 return addrs;
143}
144
Craig Tillere1e45592016-03-11 08:01:58 -0800145grpc_resolved_addresses *(*grpc_blocking_resolve_address)(
146 const char *name, const char *default_port) = blocking_resolve_address_impl;
147
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700148/* Callback to be passed to grpc_executor to asynch-ify
149 * grpc_blocking_resolve_address */
Craig Tiller6c396862016-01-28 13:53:40 -0800150static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800151 request *r = rp;
Craig Tillera82950e2015-09-22 12:33:20 -0700152 grpc_resolved_addresses *resolved =
153 grpc_blocking_resolve_address(r->name, r->default_port);
ctillerccd27fd2014-12-11 09:12:02 -0800154 void *arg = r->arg;
155 grpc_resolve_cb cb = r->cb;
Craig Tillera82950e2015-09-22 12:33:20 -0700156 gpr_free(r->name);
157 gpr_free(r->default_port);
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700158 cb(exec_ctx, arg, resolved);
Craig Tillera82950e2015-09-22 12:33:20 -0700159 gpr_free(r);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800160}
161
Craig Tillera82950e2015-09-22 12:33:20 -0700162void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
163 gpr_free(addrs->addrs);
164 gpr_free(addrs);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800165}
166
Craig Tillera82950e2015-09-22 12:33:20 -0700167void grpc_resolve_address(const char *name, const char *default_port,
168 grpc_resolve_cb cb, void *arg) {
169 request *r = gpr_malloc(sizeof(request));
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700170 grpc_closure_init(&r->request_closure, do_request_thread, r);
Craig Tillera82950e2015-09-22 12:33:20 -0700171 r->name = gpr_strdup(name);
172 r->default_port = gpr_strdup(default_port);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800173 r->cb = cb;
174 r->arg = arg;
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700175 grpc_executor_enqueue(&r->request_closure, 1);
Craig Tiller190d3602015-02-18 09:23:38 -0800176}
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +0100177
178#endif