blob: e37da136af5c89be3785670015914aebbde20e64 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * 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
David Klempner78b79922015-02-04 10:18:59 -080034/* FIXME: "posix" files shouldn't be depending on _GNU_SOURCE */
35#ifndef _GNU_SOURCE
36#define _GNU_SOURCE
37#endif
38
Craig Tiller0c0b60c2015-01-21 15:49:28 -080039#include <grpc/support/port_platform.h>
40
Craig Tillera172ad72015-01-21 15:51:47 -080041#ifdef GPR_POSIX_SOCKET
Craig Tiller0c0b60c2015-01-21 15:49:28 -080042
ctiller18b49ab2014-12-09 14:39:16 -080043#include "src/core/iomgr/tcp_server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080044
Craig Tilleraa31da42015-02-17 16:33:35 -080045#include <errno.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046#include <fcntl.h>
Craig Tilleraa31da42015-02-17 16:33:35 -080047#include <limits.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080048#include <netinet/in.h>
49#include <netinet/tcp.h>
50#include <stdio.h>
Craig Tilleraa31da42015-02-17 16:33:35 -080051#include <string.h>
52#include <sys/socket.h>
53#include <sys/stat.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080054#include <sys/types.h>
Craig Tillerae7fe922015-02-13 23:16:32 -080055#include <sys/un.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080056#include <unistd.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080057
ctiller58393c22015-01-07 14:03:30 -080058#include "src/core/iomgr/pollset_posix.h"
Craig Tillerae7fe922015-02-13 23:16:32 -080059#include "src/core/iomgr/resolve_address.h"
ctiller18b49ab2014-12-09 14:39:16 -080060#include "src/core/iomgr/sockaddr_utils.h"
61#include "src/core/iomgr/socket_utils_posix.h"
62#include "src/core/iomgr/tcp_posix.h"
Craig Tillerfa275a92015-06-01 13:55:54 -070063#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080064#include <grpc/support/alloc.h>
65#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070066#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080067#include <grpc/support/sync.h>
68#include <grpc/support/time.h>
69
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080070#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
71
72static gpr_once s_init_max_accept_queue_size;
73static int s_max_accept_queue_size;
74
75/* one listening port */
Dan Bornfa6b6062016-01-08 21:01:59 -080076typedef struct grpc_tcp_listener grpc_tcp_listener;
Nicolas Noble8f714622015-11-19 11:16:54 -080077struct grpc_tcp_listener {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080078 int fd;
ctiller18b49ab2014-12-09 14:39:16 -080079 grpc_fd *emfd;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080080 grpc_tcp_server *server;
Craig Tillera82950e2015-09-22 12:33:20 -070081 union {
Craig Tiller7536af02015-12-22 13:49:30 -080082 uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE];
Craig Tiller772c97b2015-02-17 08:07:34 -080083 struct sockaddr sockaddr;
84 struct sockaddr_un un;
85 } addr;
Craig Tillerf96dfc32015-09-10 14:43:18 -070086 size_t addr_len;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -080087 int port;
Dan Bornfa6b6062016-01-08 21:01:59 -080088 unsigned port_index;
89 unsigned fd_index;
Craig Tiller33825112015-09-18 07:44:19 -070090 grpc_closure read_closure;
91 grpc_closure destroyed_closure;
Nicolas Noble8f714622015-11-19 11:16:54 -080092 struct grpc_tcp_listener *next;
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +010093 /* When we add a listener, more than one can be created, mainly because of
94 IPv6. A sibling will still be in the normal list, but will be flagged
95 as such. Any action, such as ref or unref, will affect all of the
96 siblings in the list. */
97 struct grpc_tcp_listener *sibling;
98 int is_sibling;
Nicolas Noble8f714622015-11-19 11:16:54 -080099};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800100
Craig Tillera82950e2015-09-22 12:33:20 -0700101static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) {
Craig Tilleraa31da42015-02-17 16:33:35 -0800102 struct stat st;
103
Craig Tillera82950e2015-09-22 12:33:20 -0700104 if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) {
105 unlink(un->sun_path);
106 }
Craig Tilleraa31da42015-02-17 16:33:35 -0800107}
108
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800109/* the overall server */
Craig Tillera82950e2015-09-22 12:33:20 -0700110struct grpc_tcp_server {
Dan Bornfa6b6062016-01-08 21:01:59 -0800111 gpr_refcount refs;
Robbie Shade3cd2d182015-08-28 14:30:35 -0400112 /* Called whenever accept() succeeds on a server port. */
113 grpc_tcp_server_cb on_accept_cb;
114 void *on_accept_cb_arg;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800115
116 gpr_mu mu;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800117
118 /* active port count: how many ports are actually still listening */
Craig Tilleraec96aa2015-04-07 14:32:15 -0700119 size_t active_ports;
120 /* destroyed port count: how many ports are completely destroyed */
121 size_t destroyed_ports;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800122
Craig Tiller6174b9a2015-06-18 08:13:05 -0700123 /* is this server shutting down? (boolean) */
Craig Tiller6f051402015-05-13 11:42:42 -0700124 int shutdown;
125
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800126 /* linked list of server ports */
Nicolas Noble8f714622015-11-19 11:16:54 -0800127 grpc_tcp_listener *head;
Dan Bornfa6b6062016-01-08 21:01:59 -0800128 grpc_tcp_listener *tail;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800129 unsigned nports;
Craig Tilleraec96aa2015-04-07 14:32:15 -0700130
131 /* shutdown callback */
Craig Tillerd1bec032015-09-18 17:29:00 -0700132 grpc_closure *shutdown_complete;
Craig Tiller0189ac02015-05-11 14:59:19 -0700133
Craig Tiller6174b9a2015-06-18 08:13:05 -0700134 /* all pollsets interested in new connections */
Craig Tiller0189ac02015-05-11 14:59:19 -0700135 grpc_pollset **pollsets;
Craig Tiller6174b9a2015-06-18 08:13:05 -0700136 /* number of pollsets in the pollsets array */
Craig Tiller0189ac02015-05-11 14:59:19 -0700137 size_t pollset_count;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800138};
139
Dan Bornfa6b6062016-01-08 21:01:59 -0800140grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
Craig Tillera82950e2015-09-22 12:33:20 -0700141 grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
Dan Bornfa6b6062016-01-08 21:01:59 -0800142 gpr_ref_init(&s->refs, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700143 gpr_mu_init(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800144 s->active_ports = 0;
Craig Tilleraec96aa2015-04-07 14:32:15 -0700145 s->destroyed_ports = 0;
Craig Tiller6f051402015-05-13 11:42:42 -0700146 s->shutdown = 0;
Dan Bornfa6b6062016-01-08 21:01:59 -0800147 s->shutdown_complete = shutdown_complete;
Robbie Shade3cd2d182015-08-28 14:30:35 -0400148 s->on_accept_cb = NULL;
149 s->on_accept_cb_arg = NULL;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800150 s->head = NULL;
Dan Bornfa6b6062016-01-08 21:01:59 -0800151 s->tail = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800152 s->nports = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800153 return s;
154}
155
Craig Tillera82950e2015-09-22 12:33:20 -0700156static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800157 if (s->shutdown_complete != NULL) {
158 grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
159 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700160
Craig Tillera82950e2015-09-22 12:33:20 -0700161 gpr_mu_destroy(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700162
Nicolas "Pixel" Noblec6a7c6e2015-11-19 21:55:44 +0100163 while (s->head) {
164 grpc_tcp_listener *sp = s->head;
165 s->head = sp->next;
Dan Bornfa6b6062016-01-08 21:01:59 -0800166 gpr_free(sp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800167 }
168
Craig Tillera82950e2015-09-22 12:33:20 -0700169 gpr_free(s);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700170}
171
Craig Tillera82950e2015-09-22 12:33:20 -0700172static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, int success) {
Craig Tilleraec96aa2015-04-07 14:32:15 -0700173 grpc_tcp_server *s = server;
Craig Tillera82950e2015-09-22 12:33:20 -0700174 gpr_mu_lock(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700175 s->destroyed_ports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700176 if (s->destroyed_ports == s->nports) {
177 gpr_mu_unlock(&s->mu);
178 finish_shutdown(exec_ctx, s);
179 } else {
180 GPR_ASSERT(s->destroyed_ports < s->nports);
181 gpr_mu_unlock(&s->mu);
182 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700183}
184
Craig Tiller6174b9a2015-06-18 08:13:05 -0700185/* called when all listening endpoints have been shutdown, so no further
186 events will be received on them - at this point it's safe to destroy
187 things */
Craig Tillera82950e2015-09-22 12:33:20 -0700188static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800189 /* delete ALL the things */
Craig Tillera82950e2015-09-22 12:33:20 -0700190 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700191
Craig Tillera82950e2015-09-22 12:33:20 -0700192 if (!s->shutdown) {
193 gpr_mu_unlock(&s->mu);
194 return;
195 }
Craig Tiller45724b32015-09-22 10:42:19 -0700196
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800197 if (s->head) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800198 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800199 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700200 if (sp->addr.sockaddr.sa_family == AF_UNIX) {
201 unlink_if_unix_domain_socket(&sp->addr.un);
202 }
203 sp->destroyed_closure.cb = destroyed_port;
204 sp->destroyed_closure.cb_arg = s;
yang-g5d850372015-12-01 10:32:28 -0800205 grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
Craig Tillera82950e2015-09-22 12:33:20 -0700206 "tcp_listener_shutdown");
Craig Tiller45724b32015-09-22 10:42:19 -0700207 }
Craig Tillera82950e2015-09-22 12:33:20 -0700208 gpr_mu_unlock(&s->mu);
209 } else {
210 gpr_mu_unlock(&s->mu);
211 finish_shutdown(exec_ctx, s);
212 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800213}
214
Dan Born5d81d152016-01-12 20:29:29 -0800215static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Craig Tillera82950e2015-09-22 12:33:20 -0700216 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700217
Craig Tillera82950e2015-09-22 12:33:20 -0700218 GPR_ASSERT(!s->shutdown);
Craig Tiller6f051402015-05-13 11:42:42 -0700219 s->shutdown = 1;
220
Craig Tiller6f051402015-05-13 11:42:42 -0700221 /* shutdown all fd's */
Craig Tillera82950e2015-09-22 12:33:20 -0700222 if (s->active_ports) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800223 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800224 for (sp = s->head; sp; sp = sp->next) {
225 grpc_fd_shutdown(exec_ctx, sp->emfd);
Craig Tiller6f051402015-05-13 11:42:42 -0700226 }
Craig Tillera82950e2015-09-22 12:33:20 -0700227 gpr_mu_unlock(&s->mu);
228 } else {
229 gpr_mu_unlock(&s->mu);
230 deactivated_all_ports(exec_ctx, s);
231 }
Craig Tiller6f051402015-05-13 11:42:42 -0700232}
233
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800234/* get max listen queue size on linux */
Craig Tillera82950e2015-09-22 12:33:20 -0700235static void init_max_accept_queue_size(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800236 int n = SOMAXCONN;
237 char buf[64];
Craig Tillera82950e2015-09-22 12:33:20 -0700238 FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
239 if (fp == NULL) {
240 /* 2.4 kernel. */
241 s_max_accept_queue_size = SOMAXCONN;
242 return;
243 }
244 if (fgets(buf, sizeof buf, fp)) {
245 char *end;
246 long i = strtol(buf, &end, 10);
247 if (i > 0 && i <= INT_MAX && end && *end == 0) {
248 n = (int)i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800249 }
Craig Tillera82950e2015-09-22 12:33:20 -0700250 }
251 fclose(fp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800252 s_max_accept_queue_size = n;
253
Craig Tillera82950e2015-09-22 12:33:20 -0700254 if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
255 gpr_log(GPR_INFO,
256 "Suspiciously small accept queue (%d) will probably lead to "
257 "connection drops",
258 s_max_accept_queue_size);
259 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800260}
261
Craig Tillera82950e2015-09-22 12:33:20 -0700262static int get_max_accept_queue_size(void) {
263 gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800264 return s_max_accept_queue_size;
265}
266
nnoble0c475f02014-12-05 15:37:39 -0800267/* Prepare a recently-created socket for listening. */
Craig Tillera82950e2015-09-22 12:33:20 -0700268static int prepare_socket(int fd, const struct sockaddr *addr,
269 size_t addr_len) {
ctiller570d1f42015-01-12 16:29:52 -0800270 struct sockaddr_storage sockname_temp;
271 socklen_t sockname_len;
272
Craig Tillera82950e2015-09-22 12:33:20 -0700273 if (fd < 0) {
274 goto error;
275 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800276
Craig Tillera82950e2015-09-22 12:33:20 -0700277 if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
278 (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) ||
279 !grpc_set_socket_reuse_addr(fd, 1))) ||
280 !grpc_set_socket_no_sigpipe_if_possible(fd)) {
281 gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
282 strerror(errno));
283 goto error;
284 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800285
Craig Tillera82950e2015-09-22 12:33:20 -0700286 GPR_ASSERT(addr_len < ~(socklen_t)0);
287 if (bind(fd, addr, (socklen_t)addr_len) < 0) {
288 char *addr_str;
289 grpc_sockaddr_to_string(&addr_str, addr, 0);
290 gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
291 gpr_free(addr_str);
292 goto error;
293 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800294
Craig Tillera82950e2015-09-22 12:33:20 -0700295 if (listen(fd, get_max_accept_queue_size()) < 0) {
296 gpr_log(GPR_ERROR, "listen: %s", strerror(errno));
297 goto error;
298 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800299
Craig Tillera82950e2015-09-22 12:33:20 -0700300 sockname_len = sizeof(sockname_temp);
301 if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
302 goto error;
303 }
ctiller570d1f42015-01-12 16:29:52 -0800304
Craig Tillera82950e2015-09-22 12:33:20 -0700305 return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800306
307error:
Craig Tillera82950e2015-09-22 12:33:20 -0700308 if (fd >= 0) {
309 close(fd);
310 }
ctiller570d1f42015-01-12 16:29:52 -0800311 return -1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800312}
313
314/* event manager callback when reads are ready */
Craig Tillera82950e2015-09-22 12:33:20 -0700315static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800316 grpc_tcp_listener *sp = arg;
Dan Born5d81d152016-01-12 20:29:29 -0800317 grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
318 sp->fd_index};
Craig Tiller0189ac02015-05-11 14:59:19 -0700319 grpc_fd *fdobj;
320 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800321
Craig Tillera82950e2015-09-22 12:33:20 -0700322 if (!success) {
323 goto error;
324 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800325
326 /* loop until accept4 returns EAGAIN, and then re-arm notification */
Craig Tillera82950e2015-09-22 12:33:20 -0700327 for (;;) {
328 struct sockaddr_storage addr;
329 socklen_t addrlen = sizeof(addr);
330 char *addr_str;
331 char *name;
332 /* Note: If we ever decide to return this address to the user, remember to
333 strip off the ::ffff:0.0.0.0/96 prefix first. */
334 int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1);
335 if (fd < 0) {
336 switch (errno) {
337 case EINTR:
338 continue;
339 case EAGAIN:
340 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
341 return;
342 default:
343 gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
344 goto error;
345 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800346 }
347
Craig Tillera82950e2015-09-22 12:33:20 -0700348 grpc_set_socket_no_sigpipe_if_possible(fd);
349
350 addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr);
351 gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
352
353 if (grpc_tcp_trace) {
354 gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
355 }
356
357 fdobj = grpc_fd_create(fd, name);
358 /* TODO(ctiller): revise this when we have server-side sharding
359 of channels -- we certainly should not be automatically adding every
360 incoming channel to every pollset owned by the server */
361 for (i = 0; i < sp->server->pollset_count; i++) {
362 grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj);
363 }
364 sp->server->on_accept_cb(
365 exec_ctx, sp->server->on_accept_cb_arg,
Dan Bornfa6b6062016-01-08 21:01:59 -0800366 grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
Dan Born5d81d152016-01-12 20:29:29 -0800367 &acceptor);
Craig Tillera82950e2015-09-22 12:33:20 -0700368
369 gpr_free(name);
370 gpr_free(addr_str);
371 }
372
yang-gb063c872015-10-07 11:40:13 -0700373 GPR_UNREACHABLE_CODE(return );
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800374
375error:
Craig Tillera82950e2015-09-22 12:33:20 -0700376 gpr_mu_lock(&sp->server->mu);
377 if (0 == --sp->server->active_ports) {
378 gpr_mu_unlock(&sp->server->mu);
379 deactivated_all_ports(exec_ctx, sp->server);
380 } else {
381 gpr_mu_unlock(&sp->server->mu);
382 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800383}
384
Nicolas Noble8f714622015-11-19 11:16:54 -0800385static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
yang-g3ff97272015-11-20 17:01:57 -0800386 const struct sockaddr *addr,
Dan Bornfa6b6062016-01-08 21:01:59 -0800387 size_t addr_len,
388 unsigned port_index,
389 unsigned fd_index) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800390 grpc_tcp_listener *sp = NULL;
ctiller570d1f42015-01-12 16:29:52 -0800391 int port;
Craig Tillerfa275a92015-06-01 13:55:54 -0700392 char *addr_str;
393 char *name;
nnoble0c475f02014-12-05 15:37:39 -0800394
Craig Tillera82950e2015-09-22 12:33:20 -0700395 port = prepare_socket(fd, addr, addr_len);
396 if (port >= 0) {
397 grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
398 gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
399 gpr_mu_lock(&s->mu);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800400 s->nports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700401 GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
Nicolas Noble8f714622015-11-19 11:16:54 -0800402 sp = gpr_malloc(sizeof(grpc_tcp_listener));
Dan Bornfa6b6062016-01-08 21:01:59 -0800403 sp->next = NULL;
404 if (s->head == NULL) {
405 s->head = sp;
406 } else {
407 s->tail->next = sp;
408 }
409 s->tail = sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700410 sp->server = s;
411 sp->fd = fd;
412 sp->emfd = grpc_fd_create(fd, name);
413 memcpy(sp->addr.untyped, addr, addr_len);
414 sp->addr_len = addr_len;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800415 sp->port = port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800416 sp->port_index = port_index;
417 sp->fd_index = fd_index;
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100418 sp->is_sibling = 0;
419 sp->sibling = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700420 GPR_ASSERT(sp->emfd);
421 gpr_mu_unlock(&s->mu);
422 gpr_free(addr_str);
423 gpr_free(name);
424 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800425
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800426 return sp;
nnoble0c475f02014-12-05 15:37:39 -0800427}
428
Dan Bornfa6b6062016-01-08 21:01:59 -0800429int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
430 size_t addr_len) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800431 grpc_tcp_listener *sp;
432 grpc_tcp_listener *sp2 = NULL;
nnoble0c475f02014-12-05 15:37:39 -0800433 int fd;
434 grpc_dualstack_mode dsmode;
435 struct sockaddr_in6 addr6_v4mapped;
436 struct sockaddr_in wild4;
437 struct sockaddr_in6 wild6;
438 struct sockaddr_in addr4_copy;
ctiller570d1f42015-01-12 16:29:52 -0800439 struct sockaddr *allocated_addr = NULL;
440 struct sockaddr_storage sockname_temp;
441 socklen_t sockname_len;
nnoble0c475f02014-12-05 15:37:39 -0800442 int port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800443 unsigned port_index = 0;
444 unsigned fd_index = 0;
445 if (s->tail != NULL) {
446 port_index = s->tail->port_index + 1;
447 }
Craig Tillera82950e2015-09-22 12:33:20 -0700448 if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
449 unlink_if_unix_domain_socket(addr);
450 }
Craig Tilleraa31da42015-02-17 16:33:35 -0800451
ctiller570d1f42015-01-12 16:29:52 -0800452 /* Check if this is a wildcard port, and if so, try to keep the port the same
453 as some previously created listener. */
Craig Tillera82950e2015-09-22 12:33:20 -0700454 if (grpc_sockaddr_get_port(addr) == 0) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800455 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700456 sockname_len = sizeof(sockname_temp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800457 if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
Craig Tillera82950e2015-09-22 12:33:20 -0700458 &sockname_len)) {
459 port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
460 if (port > 0) {
461 allocated_addr = malloc(addr_len);
462 memcpy(allocated_addr, addr, addr_len);
463 grpc_sockaddr_set_port(allocated_addr, port);
464 addr = allocated_addr;
465 break;
466 }
467 }
ctiller570d1f42015-01-12 16:29:52 -0800468 }
Craig Tillera82950e2015-09-22 12:33:20 -0700469 }
ctiller570d1f42015-01-12 16:29:52 -0800470
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800471 sp = NULL;
472
Craig Tillera82950e2015-09-22 12:33:20 -0700473 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
474 addr = (const struct sockaddr *)&addr6_v4mapped;
475 addr_len = sizeof(addr6_v4mapped);
476 }
nnoble0c475f02014-12-05 15:37:39 -0800477
478 /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
Craig Tillera82950e2015-09-22 12:33:20 -0700479 if (grpc_sockaddr_is_wildcard(addr, &port)) {
480 grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
nnoble0c475f02014-12-05 15:37:39 -0800481
Craig Tillera82950e2015-09-22 12:33:20 -0700482 /* Try listening on IPv6 first. */
483 addr = (struct sockaddr *)&wild6;
484 addr_len = sizeof(wild6);
485 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
Dan Bornfa6b6062016-01-08 21:01:59 -0800486 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Craig Tillera82950e2015-09-22 12:33:20 -0700487 if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
488 goto done;
nnoble0c475f02014-12-05 15:37:39 -0800489 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800490 if (sp != NULL) {
491 ++fd_index;
492 }
Craig Tillera82950e2015-09-22 12:33:20 -0700493 /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
Craig Tillere57ba132015-12-09 15:00:28 -0800494 if (port == 0 && sp != NULL) {
495 grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800496 sp2 = sp;
ctiller570d1f42015-01-12 16:29:52 -0800497 }
Craig Tillera82950e2015-09-22 12:33:20 -0700498 addr = (struct sockaddr *)&wild4;
499 addr_len = sizeof(wild4);
500 }
501
502 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
503 if (fd < 0) {
504 gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
505 }
506 if (dsmode == GRPC_DSMODE_IPV4 &&
507 grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
508 addr = (struct sockaddr *)&addr4_copy;
509 addr_len = sizeof(addr4_copy);
510 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800511 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Dan Born03c8a9b2016-01-12 21:14:29 -0800512 if (sp2 != NULL && sp != NULL) {
513 sp2->sibling = sp;
514 sp->is_sibling = 1;
Dan Bornfa6b6062016-01-08 21:01:59 -0800515 }
ctiller570d1f42015-01-12 16:29:52 -0800516
517done:
Craig Tillera82950e2015-09-22 12:33:20 -0700518 gpr_free(allocated_addr);
Dan Bornfa6b6062016-01-08 21:01:59 -0800519 if (sp != NULL) {
520 return sp->port;
521 } else {
522 return -1;
523 }
nnoble0c475f02014-12-05 15:37:39 -0800524}
525
Dan Born5d81d152016-01-12 20:29:29 -0800526unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
527 unsigned port_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800528 unsigned num_fds = 0;
Nicolas Noble8f714622015-11-19 11:16:54 -0800529 grpc_tcp_listener *sp;
Dan Bornfa6b6062016-01-08 21:01:59 -0800530 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
531 if (!sp->is_sibling) {
532 --port_index;
533 }
534 }
535 for (; sp; sp = sp->sibling, ++num_fds)
yang-g3ff97272015-11-20 17:01:57 -0800536 ;
Dan Bornfa6b6062016-01-08 21:01:59 -0800537 return num_fds;
538}
539
Dan Born5d81d152016-01-12 20:29:29 -0800540int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
541 unsigned fd_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800542 grpc_tcp_listener *sp;
543 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
544 if (!sp->is_sibling) {
545 --port_index;
546 }
547 }
548 for (; sp && fd_index != 0; sp = sp->sibling, --fd_index)
549 ;
550 if (sp) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800551 return sp->fd;
552 } else {
553 return -1;
554 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800555}
556
Craig Tillera82950e2015-09-22 12:33:20 -0700557void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
558 grpc_pollset **pollsets, size_t pollset_count,
559 grpc_tcp_server_cb on_accept_cb,
560 void *on_accept_cb_arg) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800561 size_t i;
Nicolas Noble8f714622015-11-19 11:16:54 -0800562 grpc_tcp_listener *sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700563 GPR_ASSERT(on_accept_cb);
564 gpr_mu_lock(&s->mu);
565 GPR_ASSERT(!s->on_accept_cb);
566 GPR_ASSERT(s->active_ports == 0);
Robbie Shade3cd2d182015-08-28 14:30:35 -0400567 s->on_accept_cb = on_accept_cb;
568 s->on_accept_cb_arg = on_accept_cb_arg;
Craig Tiller0189ac02015-05-11 14:59:19 -0700569 s->pollsets = pollsets;
570 s->pollset_count = pollset_count;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800571 for (sp = s->head; sp; sp = sp->next) {
572 for (i = 0; i < pollset_count; i++) {
573 grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
ctiller58393c22015-01-07 14:03:30 -0800574 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800575 sp->read_closure.cb = on_read;
576 sp->read_closure.cb_arg = sp;
yang-g3ff97272015-11-20 17:01:57 -0800577 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
Craig Tillera82950e2015-09-22 12:33:20 -0700578 s->active_ports++;
579 }
580 gpr_mu_unlock(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800581}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800582
Dan Bornfa6b6062016-01-08 21:01:59 -0800583grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
584 gpr_ref(&s->refs);
585 return s;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800586}
587
Dan Bornfa6b6062016-01-08 21:01:59 -0800588void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
589 if (gpr_unref(&s->refs)) {
590 if (exec_ctx == NULL) {
591 grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
Dan Born5d81d152016-01-12 20:29:29 -0800592 tcp_server_destroy(&local_exec_ctx, s);
Dan Bornfa6b6062016-01-08 21:01:59 -0800593 grpc_exec_ctx_finish(&local_exec_ctx);
594 } else {
Dan Born5d81d152016-01-12 20:29:29 -0800595 tcp_server_destroy(exec_ctx, s);
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100596 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800597 }
598}
599
Craig Tiller190d3602015-02-18 09:23:38 -0800600#endif