blob: 82763d11f4fb1635707350c4d3a40a9161078e31 [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
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +010034#include <grpc/support/port_platform.h>
35#ifdef GPR_WINSOCK_SOCKET
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036
Craig Tiller9533d042016-03-25 17:11:06 -070037#include "src/core/lib/iomgr/resolve_address.h"
38#include "src/core/lib/iomgr/sockaddr.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080040#include <string.h>
Craig Tillere1e45592016-03-11 08:01:58 -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>
David Garcia Quintas661ad7f2015-10-13 15:51:31 -070046#include <grpc/support/log_win32.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 Tiller9533d042016-03-25 17:11:06 -070050#include "src/core/lib/iomgr/executor.h"
51#include "src/core/lib/iomgr/iomgr_internal.h"
52#include "src/core/lib/iomgr/sockaddr_utils.h"
53#include "src/core/lib/support/block_annotate.h"
54#include "src/core/lib/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080055
56typedef struct {
57 char *name;
58 char *default_port;
59 grpc_resolve_cb cb;
David Garcia Quintas706b70f2015-10-13 11:19:49 -070060 grpc_closure request_closure;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061 void *arg;
62} request;
63
Craig Tillere1e45592016-03-11 08:01:58 -080064static grpc_resolved_addresses *blocking_resolve_address_impl(
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065 const char *name, const char *default_port) {
66 struct addrinfo hints;
67 struct addrinfo *result = NULL, *resp;
68 char *host;
69 char *port;
70 int s;
71 size_t i;
72 grpc_resolved_addresses *addrs = NULL;
73
74 /* parse name, splitting it into host and port parts */
Nicolas "Pixel" Noble589cba22015-02-20 22:58:54 -080075 gpr_split_host_port(name, &host, &port);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080076 if (host == NULL) {
77 gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name);
78 goto done;
79 }
80 if (port == NULL) {
81 if (default_port == NULL) {
82 gpr_log(GPR_ERROR, "no port in name '%s'", name);
83 goto done;
84 }
85 port = gpr_strdup(default_port);
86 }
87
88 /* Call getaddrinfo */
89 memset(&hints, 0, sizeof(hints));
90 hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */
91 hints.ai_socktype = SOCK_STREAM; /* stream socket */
92 hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
93
vjpai9839d282015-09-24 17:55:18 -070094 GRPC_SCHEDULING_START_BLOCKING_REGION;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080095 s = getaddrinfo(host, port, &hints, &result);
vjpai9839d282015-09-24 17:55:18 -070096 GRPC_SCHEDULING_END_BLOCKING_REGION;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080097 if (s != 0) {
David Garcia Quintas661ad7f2015-10-13 15:51:31 -070098 char *error_message = gpr_format_message(s);
99 gpr_log(GPR_ERROR, "getaddrinfo: %s", error_message);
100 gpr_free(error_message);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800101 goto done;
102 }
103
104 /* Success path: set addrs non-NULL, fill it in */
105 addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
106 addrs->naddrs = 0;
107 for (resp = result; resp != NULL; resp = resp->ai_next) {
108 addrs->naddrs++;
109 }
110 addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs);
111 i = 0;
112 for (resp = result; resp != NULL; resp = resp->ai_next) {
113 memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen);
114 addrs->addrs[i].len = resp->ai_addrlen;
115 i++;
116 }
117
nnoble0c475f02014-12-05 15:37:39 -0800118 {
nnoble0c475f02014-12-05 15:37:39 -0800119 for (i = 0; i < addrs->naddrs; i++) {
120 char *buf;
121 grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr,
122 0);
nnoble0c475f02014-12-05 15:37:39 -0800123 gpr_free(buf);
124 }
125 }
126
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800127done:
128 gpr_free(host);
129 gpr_free(port);
130 if (result) {
131 freeaddrinfo(result);
132 }
133 return addrs;
134}
135
Craig Tillere1e45592016-03-11 08:01:58 -0800136grpc_resolved_addresses *(*grpc_blocking_resolve_address)(
137 const char *name, const char *default_port) = blocking_resolve_address_impl;
138
David Garcia Quintas706b70f2015-10-13 11:19:49 -0700139/* Callback to be passed to grpc_executor to asynch-ify
140 * grpc_blocking_resolve_address */
Craig Tillereced8ae2016-01-28 14:13:20 -0800141static void do_request_thread(grpc_exec_ctx *exec_ctx, void *rp, bool success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142 request *r = rp;
ctillerccd27fd2014-12-11 09:12:02 -0800143 grpc_resolved_addresses *resolved =
144 grpc_blocking_resolve_address(r->name, r->default_port);
145 void *arg = r->arg;
146 grpc_resolve_cb cb = r->cb;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800147 gpr_free(r->name);
148 gpr_free(r->default_port);
David Garcia Quintas706b70f2015-10-13 11:19:49 -0700149 cb(exec_ctx, arg, resolved);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800150 gpr_free(r);
151}
152
153void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) {
154 gpr_free(addrs->addrs);
155 gpr_free(addrs);
156}
157
158void grpc_resolve_address(const char *name, const char *default_port,
159 grpc_resolve_cb cb, void *arg) {
160 request *r = gpr_malloc(sizeof(request));
David Garcia Quintas706b70f2015-10-13 11:19:49 -0700161 grpc_closure_init(&r->request_closure, do_request_thread, r);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800162 r->name = gpr_strdup(name);
163 r->default_port = gpr_strdup(default_port);
164 r->cb = cb;
165 r->arg = arg;
David Garcia Quintas706b70f2015-10-13 11:19:49 -0700166 grpc_executor_enqueue(&r->request_closure, 1);
Craig Tiller190d3602015-02-18 09:23:38 -0800167}
Nicolas "Pixel" Noble94964fd2015-02-21 07:19:19 +0100168
169#endif