blob: 16bdb20c82edfedb1916b4d274e1957e31e7c0b7 [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>
ahedberg803931d2016-03-11 17:24:12 -050042#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillerae7fe922015-02-13 23:16:32 -080043#include <sys/un.h>
ahedberg803931d2016-03-11 17:24:12 -050044#endif
45#include <string.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046
47#include <grpc/support/alloc.h>
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080048#include <grpc/support/host_port.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080049#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070050#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080051#include <grpc/support/thd.h>
nnoble0c475f02014-12-05 15:37:39 -080052#include <grpc/support/time.h>
Craig Tillerb9d35962015-09-11 13:31:16 -070053#include <grpc/support/useful.h>
Craig Tillere1e45592016-03-11 08:01:58 -080054#include "src/core/iomgr/executor.h"
55#include "src/core/iomgr/iomgr_internal.h"
56#include "src/core/iomgr/sockaddr_utils.h"
57#include "src/core/support/block_annotate.h"
58#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080059
Craig Tillera82950e2015-09-22 12:33:20 -070060typedef struct {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061 char *name;
62 char *default_port;
63 grpc_resolve_cb cb;
David Garcia Quintas4bc34632015-10-07 16:12:35 -070064 grpc_closure request_closure;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065 void *arg;
66} request;
67
Craig Tillere1e45592016-03-11 08:01:58 -080068static grpc_resolved_addresses *blocking_resolve_address_impl(
Craig Tillera82950e2015-09-22 12:33:20 -070069 const char *name, const char *default_port) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080070 struct addrinfo hints;
71 struct addrinfo *result = NULL, *resp;
72 char *host;
73 char *port;
74 int s;
75 size_t i;
76 grpc_resolved_addresses *addrs = NULL;
ahedberg803931d2016-03-11 17:24:12 -050077#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillerae7fe922015-02-13 23:16:32 -080078 struct sockaddr_un *un;
79
Craig Tillera82950e2015-09-22 12:33:20 -070080 if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
81 name[4] == ':' && name[5] != 0) {
82 addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
83 addrs->naddrs = 1;
84 addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address));
85 un = (struct sockaddr_un *)addrs->addrs->addr;
86 un->sun_family = AF_UNIX;
87 strcpy(un->sun_path, name + 5);
88 addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family) + 1;
89 return addrs;
90 }
ahedberg803931d2016-03-11 17:24:12 -050091#endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080092
93 /* parse name, splitting it into host and port parts */
Craig Tillera82950e2015-09-22 12:33:20 -070094 gpr_split_host_port(name, &host, &port);
95 if (host == NULL) {
96 gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name);
97 goto done;
98 }
99 if (port == NULL) {
100 if (default_port == NULL) {
101 gpr_log(GPR_ERROR, "no port in name '%s'", name);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800102 goto done;
103 }
Craig Tillera82950e2015-09-22 12:33:20 -0700104 port = gpr_strdup(default_port);
105 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800106
107 /* Call getaddrinfo */
Craig Tillera82950e2015-09-22 12:33:20 -0700108 memset(&hints, 0, sizeof(hints));
109 hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */
110 hints.ai_socktype = SOCK_STREAM; /* stream socket */
111 hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800112
vjpai9839d282015-09-24 17:55:18 -0700113 GRPC_SCHEDULING_START_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700114 s = getaddrinfo(host, port, &hints, &result);
vjpai9839d282015-09-24 17:55:18 -0700115 GRPC_SCHEDULING_END_BLOCKING_REGION;
Vijay Paiba130552015-09-24 13:43:01 -0700116
Craig Tillera82950e2015-09-22 12:33:20 -0700117 if (s != 0) {
118 /* Retry if well-known service name is recognized */
119 char *svc[][2] = {{"http", "80"}, {"https", "443"}};
Craig Tillerb9d35962015-09-11 13:31:16 -0700120 for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
Craig Tillera82950e2015-09-22 12:33:20 -0700121 if (strcmp(port, svc[i][0]) == 0) {
vjpai9839d282015-09-24 17:55:18 -0700122 GRPC_SCHEDULING_START_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700123 s = getaddrinfo(host, svc[i][1], &hints, &result);
vjpai9839d282015-09-24 17:55:18 -0700124 GRPC_SCHEDULING_END_BLOCKING_REGION;
Craig Tillera82950e2015-09-22 12:33:20 -0700125 break;
126 }
Raul Silvera659be5a2015-03-04 11:51:11 -0800127 }
Craig Tillera82950e2015-09-22 12:33:20 -0700128 }
Raul Silvera659be5a2015-03-04 11:51:11 -0800129
Craig Tillera82950e2015-09-22 12:33:20 -0700130 if (s != 0) {
131 gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s));
132 goto done;
133 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800134
135 /* Success path: set addrs non-NULL, fill it in */
Craig Tillera82950e2015-09-22 12:33:20 -0700136 addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800137 addrs->naddrs = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700138 for (resp = result; resp != NULL; resp = resp->ai_next) {
139 addrs->naddrs++;
140 }
141 addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142 i = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700143 for (resp = result; resp != NULL; resp = resp->ai_next) {
144 memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
145 addrs->addrs[i].len = resp->ai_addrlen;
146 i++;
147 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800148
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800149done:
Craig Tillera82950e2015-09-22 12:33:20 -0700150 gpr_free(host);
151 gpr_free(port);
152 if (result) {
153 freeaddrinfo(result);
154 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800155 return addrs;
156}
157
Craig Tillere1e45592016-03-11 08:01:58 -0800158grpc_resolved_addresses *(*grpc_blocking_resolve_address)(
159 const char *name, const char *default_port) = blocking_resolve_address_impl;
160
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 Tiller6c396862016-01-28 13:53:40 -0800163static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800164 request *r = rp;
Craig Tillera82950e2015-09-22 12:33:20 -0700165 grpc_resolved_addresses *resolved =
166 grpc_blocking_resolve_address(r->name, r->default_port);
ctillerccd27fd2014-12-11 09:12:02 -0800167 void *arg = r->arg;
168 grpc_resolve_cb cb = r->cb;
Craig Tillera82950e2015-09-22 12:33:20 -0700169 gpr_free(r->name);
170 gpr_free(r->default_port);
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700171 cb(exec_ctx, arg, resolved);
Craig Tillera82950e2015-09-22 12:33:20 -0700172 gpr_free(r);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800173}
174
Craig Tillera82950e2015-09-22 12:33:20 -0700175void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
176 gpr_free(addrs->addrs);
177 gpr_free(addrs);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800178}
179
Craig Tillera82950e2015-09-22 12:33:20 -0700180void grpc_resolve_address(const char *name, const char *default_port,
181 grpc_resolve_cb cb, void *arg) {
182 request *r = gpr_malloc(sizeof(request));
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700183 grpc_closure_init(&r->request_closure, do_request_thread, r);
Craig Tillera82950e2015-09-22 12:33:20 -0700184 r->name = gpr_strdup(name);
185 r->default_port = gpr_strdup(default_port);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800186 r->cb = cb;
187 r->arg = arg;
David Garcia Quintas4bc34632015-10-07 16:12:35 -0700188 grpc_executor_enqueue(&r->request_closure, 1);
Craig Tiller190d3602015-02-18 09:23:38 -0800189}
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +0100190
191#endif