blob: adf14aeb5979f53d125a3c1c2788db79b9b4e32e [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Dan Born725ee282016-01-13 13:14:56 -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
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
Dan Born9c12bc22016-01-13 16:52:20 -0800131 /* List of closures passed to shutdown_starting_add(). */
132 grpc_closure_list shutdown_starting;
133
Craig Tilleraec96aa2015-04-07 14:32:15 -0700134 /* shutdown callback */
Craig Tillerd1bec032015-09-18 17:29:00 -0700135 grpc_closure *shutdown_complete;
Craig Tiller0189ac02015-05-11 14:59:19 -0700136
Craig Tiller6174b9a2015-06-18 08:13:05 -0700137 /* all pollsets interested in new connections */
Craig Tiller0189ac02015-05-11 14:59:19 -0700138 grpc_pollset **pollsets;
Craig Tiller6174b9a2015-06-18 08:13:05 -0700139 /* number of pollsets in the pollsets array */
Craig Tiller0189ac02015-05-11 14:59:19 -0700140 size_t pollset_count;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800141};
142
Dan Bornfa6b6062016-01-08 21:01:59 -0800143grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
Craig Tillera82950e2015-09-22 12:33:20 -0700144 grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
Dan Bornfa6b6062016-01-08 21:01:59 -0800145 gpr_ref_init(&s->refs, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700146 gpr_mu_init(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800147 s->active_ports = 0;
Craig Tilleraec96aa2015-04-07 14:32:15 -0700148 s->destroyed_ports = 0;
Craig Tiller6f051402015-05-13 11:42:42 -0700149 s->shutdown = 0;
Dan Born9c12bc22016-01-13 16:52:20 -0800150 s->shutdown_starting.head = NULL;
151 s->shutdown_starting.tail = NULL;
Dan Bornfa6b6062016-01-08 21:01:59 -0800152 s->shutdown_complete = shutdown_complete;
Robbie Shade3cd2d182015-08-28 14:30:35 -0400153 s->on_accept_cb = NULL;
154 s->on_accept_cb_arg = NULL;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800155 s->head = NULL;
Dan Bornfa6b6062016-01-08 21:01:59 -0800156 s->tail = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800157 s->nports = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800158 return s;
159}
160
Craig Tillera82950e2015-09-22 12:33:20 -0700161static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800162 if (s->shutdown_complete != NULL) {
163 grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
164 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700165
Craig Tillera82950e2015-09-22 12:33:20 -0700166 gpr_mu_destroy(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700167
Nicolas "Pixel" Noblec6a7c6e2015-11-19 21:55:44 +0100168 while (s->head) {
169 grpc_tcp_listener *sp = s->head;
170 s->head = sp->next;
Dan Bornfa6b6062016-01-08 21:01:59 -0800171 gpr_free(sp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800172 }
173
Craig Tillera82950e2015-09-22 12:33:20 -0700174 gpr_free(s);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700175}
176
Craig Tillera82950e2015-09-22 12:33:20 -0700177static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, int success) {
Craig Tilleraec96aa2015-04-07 14:32:15 -0700178 grpc_tcp_server *s = server;
Craig Tillera82950e2015-09-22 12:33:20 -0700179 gpr_mu_lock(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700180 s->destroyed_ports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700181 if (s->destroyed_ports == s->nports) {
182 gpr_mu_unlock(&s->mu);
183 finish_shutdown(exec_ctx, s);
184 } else {
185 GPR_ASSERT(s->destroyed_ports < s->nports);
186 gpr_mu_unlock(&s->mu);
187 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700188}
189
Craig Tiller6174b9a2015-06-18 08:13:05 -0700190/* called when all listening endpoints have been shutdown, so no further
191 events will be received on them - at this point it's safe to destroy
192 things */
Craig Tillera82950e2015-09-22 12:33:20 -0700193static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800194 /* delete ALL the things */
Craig Tillera82950e2015-09-22 12:33:20 -0700195 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700196
Craig Tillera82950e2015-09-22 12:33:20 -0700197 if (!s->shutdown) {
198 gpr_mu_unlock(&s->mu);
199 return;
200 }
Craig Tiller45724b32015-09-22 10:42:19 -0700201
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800202 if (s->head) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800203 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800204 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700205 if (sp->addr.sockaddr.sa_family == AF_UNIX) {
206 unlink_if_unix_domain_socket(&sp->addr.un);
207 }
208 sp->destroyed_closure.cb = destroyed_port;
209 sp->destroyed_closure.cb_arg = s;
yang-g5d850372015-12-01 10:32:28 -0800210 grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
Craig Tillera82950e2015-09-22 12:33:20 -0700211 "tcp_listener_shutdown");
Craig Tiller45724b32015-09-22 10:42:19 -0700212 }
Craig Tillera82950e2015-09-22 12:33:20 -0700213 gpr_mu_unlock(&s->mu);
214 } else {
215 gpr_mu_unlock(&s->mu);
216 finish_shutdown(exec_ctx, s);
217 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800218}
219
Dan Born5d81d152016-01-12 20:29:29 -0800220static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Craig Tillera82950e2015-09-22 12:33:20 -0700221 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700222
Craig Tillera82950e2015-09-22 12:33:20 -0700223 GPR_ASSERT(!s->shutdown);
Craig Tiller6f051402015-05-13 11:42:42 -0700224 s->shutdown = 1;
225
Craig Tiller6f051402015-05-13 11:42:42 -0700226 /* shutdown all fd's */
Craig Tillera82950e2015-09-22 12:33:20 -0700227 if (s->active_ports) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800228 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800229 for (sp = s->head; sp; sp = sp->next) {
230 grpc_fd_shutdown(exec_ctx, sp->emfd);
Craig Tiller6f051402015-05-13 11:42:42 -0700231 }
Craig Tillera82950e2015-09-22 12:33:20 -0700232 gpr_mu_unlock(&s->mu);
233 } else {
234 gpr_mu_unlock(&s->mu);
235 deactivated_all_ports(exec_ctx, s);
236 }
Craig Tiller6f051402015-05-13 11:42:42 -0700237}
238
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800239/* get max listen queue size on linux */
Craig Tillera82950e2015-09-22 12:33:20 -0700240static void init_max_accept_queue_size(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800241 int n = SOMAXCONN;
242 char buf[64];
Craig Tillera82950e2015-09-22 12:33:20 -0700243 FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
244 if (fp == NULL) {
245 /* 2.4 kernel. */
246 s_max_accept_queue_size = SOMAXCONN;
247 return;
248 }
249 if (fgets(buf, sizeof buf, fp)) {
250 char *end;
251 long i = strtol(buf, &end, 10);
252 if (i > 0 && i <= INT_MAX && end && *end == 0) {
253 n = (int)i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800254 }
Craig Tillera82950e2015-09-22 12:33:20 -0700255 }
256 fclose(fp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800257 s_max_accept_queue_size = n;
258
Craig Tillera82950e2015-09-22 12:33:20 -0700259 if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
260 gpr_log(GPR_INFO,
261 "Suspiciously small accept queue (%d) will probably lead to "
262 "connection drops",
263 s_max_accept_queue_size);
264 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800265}
266
Craig Tillera82950e2015-09-22 12:33:20 -0700267static int get_max_accept_queue_size(void) {
268 gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800269 return s_max_accept_queue_size;
270}
271
nnoble0c475f02014-12-05 15:37:39 -0800272/* Prepare a recently-created socket for listening. */
Craig Tillera82950e2015-09-22 12:33:20 -0700273static int prepare_socket(int fd, const struct sockaddr *addr,
274 size_t addr_len) {
ctiller570d1f42015-01-12 16:29:52 -0800275 struct sockaddr_storage sockname_temp;
276 socklen_t sockname_len;
277
Craig Tillera82950e2015-09-22 12:33:20 -0700278 if (fd < 0) {
279 goto error;
280 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800281
Craig Tillera82950e2015-09-22 12:33:20 -0700282 if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
283 (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) ||
284 !grpc_set_socket_reuse_addr(fd, 1))) ||
285 !grpc_set_socket_no_sigpipe_if_possible(fd)) {
286 gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
287 strerror(errno));
288 goto error;
289 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800290
Craig Tillera82950e2015-09-22 12:33:20 -0700291 GPR_ASSERT(addr_len < ~(socklen_t)0);
292 if (bind(fd, addr, (socklen_t)addr_len) < 0) {
293 char *addr_str;
294 grpc_sockaddr_to_string(&addr_str, addr, 0);
295 gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
296 gpr_free(addr_str);
297 goto error;
298 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800299
Craig Tillera82950e2015-09-22 12:33:20 -0700300 if (listen(fd, get_max_accept_queue_size()) < 0) {
301 gpr_log(GPR_ERROR, "listen: %s", strerror(errno));
302 goto error;
303 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800304
Craig Tillera82950e2015-09-22 12:33:20 -0700305 sockname_len = sizeof(sockname_temp);
306 if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
307 goto error;
308 }
ctiller570d1f42015-01-12 16:29:52 -0800309
Craig Tillera82950e2015-09-22 12:33:20 -0700310 return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800311
312error:
Craig Tillera82950e2015-09-22 12:33:20 -0700313 if (fd >= 0) {
314 close(fd);
315 }
ctiller570d1f42015-01-12 16:29:52 -0800316 return -1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800317}
318
319/* event manager callback when reads are ready */
Craig Tillera82950e2015-09-22 12:33:20 -0700320static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800321 grpc_tcp_listener *sp = arg;
Dan Born5d81d152016-01-12 20:29:29 -0800322 grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
323 sp->fd_index};
Craig Tiller0189ac02015-05-11 14:59:19 -0700324 grpc_fd *fdobj;
325 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800326
Craig Tillera82950e2015-09-22 12:33:20 -0700327 if (!success) {
328 goto error;
329 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800330
331 /* loop until accept4 returns EAGAIN, and then re-arm notification */
Craig Tillera82950e2015-09-22 12:33:20 -0700332 for (;;) {
333 struct sockaddr_storage addr;
334 socklen_t addrlen = sizeof(addr);
335 char *addr_str;
336 char *name;
337 /* Note: If we ever decide to return this address to the user, remember to
338 strip off the ::ffff:0.0.0.0/96 prefix first. */
339 int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1);
340 if (fd < 0) {
341 switch (errno) {
342 case EINTR:
343 continue;
344 case EAGAIN:
345 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
346 return;
347 default:
348 gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
349 goto error;
350 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800351 }
352
Craig Tillera82950e2015-09-22 12:33:20 -0700353 grpc_set_socket_no_sigpipe_if_possible(fd);
354
355 addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr);
356 gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
357
358 if (grpc_tcp_trace) {
359 gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
360 }
361
362 fdobj = grpc_fd_create(fd, name);
363 /* TODO(ctiller): revise this when we have server-side sharding
364 of channels -- we certainly should not be automatically adding every
365 incoming channel to every pollset owned by the server */
366 for (i = 0; i < sp->server->pollset_count; i++) {
367 grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj);
368 }
369 sp->server->on_accept_cb(
370 exec_ctx, sp->server->on_accept_cb_arg,
Dan Bornfa6b6062016-01-08 21:01:59 -0800371 grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
Dan Born5d81d152016-01-12 20:29:29 -0800372 &acceptor);
Craig Tillera82950e2015-09-22 12:33:20 -0700373
374 gpr_free(name);
375 gpr_free(addr_str);
376 }
377
yang-gb063c872015-10-07 11:40:13 -0700378 GPR_UNREACHABLE_CODE(return );
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800379
380error:
Craig Tillera82950e2015-09-22 12:33:20 -0700381 gpr_mu_lock(&sp->server->mu);
382 if (0 == --sp->server->active_ports) {
383 gpr_mu_unlock(&sp->server->mu);
384 deactivated_all_ports(exec_ctx, sp->server);
385 } else {
386 gpr_mu_unlock(&sp->server->mu);
387 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800388}
389
Nicolas Noble8f714622015-11-19 11:16:54 -0800390static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
yang-g3ff97272015-11-20 17:01:57 -0800391 const struct sockaddr *addr,
Dan Bornfa6b6062016-01-08 21:01:59 -0800392 size_t addr_len,
393 unsigned port_index,
394 unsigned fd_index) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800395 grpc_tcp_listener *sp = NULL;
ctiller570d1f42015-01-12 16:29:52 -0800396 int port;
Craig Tillerfa275a92015-06-01 13:55:54 -0700397 char *addr_str;
398 char *name;
nnoble0c475f02014-12-05 15:37:39 -0800399
Craig Tillera82950e2015-09-22 12:33:20 -0700400 port = prepare_socket(fd, addr, addr_len);
401 if (port >= 0) {
402 grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
403 gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
404 gpr_mu_lock(&s->mu);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800405 s->nports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700406 GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
Nicolas Noble8f714622015-11-19 11:16:54 -0800407 sp = gpr_malloc(sizeof(grpc_tcp_listener));
Dan Bornfa6b6062016-01-08 21:01:59 -0800408 sp->next = NULL;
409 if (s->head == NULL) {
410 s->head = sp;
411 } else {
412 s->tail->next = sp;
413 }
414 s->tail = sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700415 sp->server = s;
416 sp->fd = fd;
417 sp->emfd = grpc_fd_create(fd, name);
418 memcpy(sp->addr.untyped, addr, addr_len);
419 sp->addr_len = addr_len;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800420 sp->port = port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800421 sp->port_index = port_index;
422 sp->fd_index = fd_index;
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100423 sp->is_sibling = 0;
424 sp->sibling = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700425 GPR_ASSERT(sp->emfd);
426 gpr_mu_unlock(&s->mu);
427 gpr_free(addr_str);
428 gpr_free(name);
429 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800430
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800431 return sp;
nnoble0c475f02014-12-05 15:37:39 -0800432}
433
Dan Bornfa6b6062016-01-08 21:01:59 -0800434int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
435 size_t addr_len) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800436 grpc_tcp_listener *sp;
437 grpc_tcp_listener *sp2 = NULL;
nnoble0c475f02014-12-05 15:37:39 -0800438 int fd;
439 grpc_dualstack_mode dsmode;
440 struct sockaddr_in6 addr6_v4mapped;
441 struct sockaddr_in wild4;
442 struct sockaddr_in6 wild6;
443 struct sockaddr_in addr4_copy;
ctiller570d1f42015-01-12 16:29:52 -0800444 struct sockaddr *allocated_addr = NULL;
445 struct sockaddr_storage sockname_temp;
446 socklen_t sockname_len;
nnoble0c475f02014-12-05 15:37:39 -0800447 int port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800448 unsigned port_index = 0;
449 unsigned fd_index = 0;
450 if (s->tail != NULL) {
451 port_index = s->tail->port_index + 1;
452 }
Craig Tillera82950e2015-09-22 12:33:20 -0700453 if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
454 unlink_if_unix_domain_socket(addr);
455 }
Craig Tilleraa31da42015-02-17 16:33:35 -0800456
ctiller570d1f42015-01-12 16:29:52 -0800457 /* Check if this is a wildcard port, and if so, try to keep the port the same
458 as some previously created listener. */
Craig Tillera82950e2015-09-22 12:33:20 -0700459 if (grpc_sockaddr_get_port(addr) == 0) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800460 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700461 sockname_len = sizeof(sockname_temp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800462 if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
Craig Tillera82950e2015-09-22 12:33:20 -0700463 &sockname_len)) {
464 port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
465 if (port > 0) {
466 allocated_addr = malloc(addr_len);
467 memcpy(allocated_addr, addr, addr_len);
468 grpc_sockaddr_set_port(allocated_addr, port);
469 addr = allocated_addr;
470 break;
471 }
472 }
ctiller570d1f42015-01-12 16:29:52 -0800473 }
Craig Tillera82950e2015-09-22 12:33:20 -0700474 }
ctiller570d1f42015-01-12 16:29:52 -0800475
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800476 sp = NULL;
477
Craig Tillera82950e2015-09-22 12:33:20 -0700478 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
479 addr = (const struct sockaddr *)&addr6_v4mapped;
480 addr_len = sizeof(addr6_v4mapped);
481 }
nnoble0c475f02014-12-05 15:37:39 -0800482
483 /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
Craig Tillera82950e2015-09-22 12:33:20 -0700484 if (grpc_sockaddr_is_wildcard(addr, &port)) {
485 grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
nnoble0c475f02014-12-05 15:37:39 -0800486
Craig Tillera82950e2015-09-22 12:33:20 -0700487 /* Try listening on IPv6 first. */
488 addr = (struct sockaddr *)&wild6;
489 addr_len = sizeof(wild6);
490 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
Dan Bornfa6b6062016-01-08 21:01:59 -0800491 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Craig Tillera82950e2015-09-22 12:33:20 -0700492 if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
493 goto done;
nnoble0c475f02014-12-05 15:37:39 -0800494 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800495 if (sp != NULL) {
496 ++fd_index;
497 }
Craig Tillera82950e2015-09-22 12:33:20 -0700498 /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
Craig Tillere57ba132015-12-09 15:00:28 -0800499 if (port == 0 && sp != NULL) {
500 grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800501 sp2 = sp;
ctiller570d1f42015-01-12 16:29:52 -0800502 }
Craig Tillera82950e2015-09-22 12:33:20 -0700503 addr = (struct sockaddr *)&wild4;
504 addr_len = sizeof(wild4);
505 }
506
507 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
508 if (fd < 0) {
509 gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
510 }
511 if (dsmode == GRPC_DSMODE_IPV4 &&
512 grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
513 addr = (struct sockaddr *)&addr4_copy;
514 addr_len = sizeof(addr4_copy);
515 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800516 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Dan Born03c8a9b2016-01-12 21:14:29 -0800517 if (sp2 != NULL && sp != NULL) {
518 sp2->sibling = sp;
519 sp->is_sibling = 1;
Dan Bornfa6b6062016-01-08 21:01:59 -0800520 }
ctiller570d1f42015-01-12 16:29:52 -0800521
522done:
Craig Tillera82950e2015-09-22 12:33:20 -0700523 gpr_free(allocated_addr);
Dan Bornfa6b6062016-01-08 21:01:59 -0800524 if (sp != NULL) {
525 return sp->port;
526 } else {
527 return -1;
528 }
nnoble0c475f02014-12-05 15:37:39 -0800529}
530
Dan Born5d81d152016-01-12 20:29:29 -0800531unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
532 unsigned port_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800533 unsigned num_fds = 0;
Nicolas Noble8f714622015-11-19 11:16:54 -0800534 grpc_tcp_listener *sp;
Dan Bornfa6b6062016-01-08 21:01:59 -0800535 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
536 if (!sp->is_sibling) {
537 --port_index;
538 }
539 }
540 for (; sp; sp = sp->sibling, ++num_fds)
yang-g3ff97272015-11-20 17:01:57 -0800541 ;
Dan Bornfa6b6062016-01-08 21:01:59 -0800542 return num_fds;
543}
544
Dan Born5d81d152016-01-12 20:29:29 -0800545int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
546 unsigned fd_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800547 grpc_tcp_listener *sp;
548 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
549 if (!sp->is_sibling) {
550 --port_index;
551 }
552 }
553 for (; sp && fd_index != 0; sp = sp->sibling, --fd_index)
554 ;
555 if (sp) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800556 return sp->fd;
557 } else {
558 return -1;
559 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800560}
561
Craig Tillera82950e2015-09-22 12:33:20 -0700562void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
563 grpc_pollset **pollsets, size_t pollset_count,
564 grpc_tcp_server_cb on_accept_cb,
565 void *on_accept_cb_arg) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800566 size_t i;
Nicolas Noble8f714622015-11-19 11:16:54 -0800567 grpc_tcp_listener *sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700568 GPR_ASSERT(on_accept_cb);
569 gpr_mu_lock(&s->mu);
570 GPR_ASSERT(!s->on_accept_cb);
571 GPR_ASSERT(s->active_ports == 0);
Robbie Shade3cd2d182015-08-28 14:30:35 -0400572 s->on_accept_cb = on_accept_cb;
573 s->on_accept_cb_arg = on_accept_cb_arg;
Craig Tiller0189ac02015-05-11 14:59:19 -0700574 s->pollsets = pollsets;
575 s->pollset_count = pollset_count;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800576 for (sp = s->head; sp; sp = sp->next) {
577 for (i = 0; i < pollset_count; i++) {
578 grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
ctiller58393c22015-01-07 14:03:30 -0800579 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800580 sp->read_closure.cb = on_read;
581 sp->read_closure.cb_arg = sp;
yang-g3ff97272015-11-20 17:01:57 -0800582 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
Craig Tillera82950e2015-09-22 12:33:20 -0700583 s->active_ports++;
584 }
585 gpr_mu_unlock(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800586}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800587
Dan Bornfa6b6062016-01-08 21:01:59 -0800588grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
589 gpr_ref(&s->refs);
590 return s;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800591}
592
Dan Born9c12bc22016-01-13 16:52:20 -0800593void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
594 grpc_closure *shutdown_starting) {
595 gpr_mu_lock(&s->mu);
596 grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
597 gpr_mu_unlock(&s->mu);
598}
599
Dan Bornfa6b6062016-01-08 21:01:59 -0800600void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
601 if (gpr_unref(&s->refs)) {
Dan Born9c12bc22016-01-13 16:52:20 -0800602 /* Complete shutdown_starting work before destroying. */
603 grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
604 gpr_mu_lock(&s->mu);
605 grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting);
606 gpr_mu_unlock(&s->mu);
Dan Bornfa6b6062016-01-08 21:01:59 -0800607 if (exec_ctx == NULL) {
Dan Born9c12bc22016-01-13 16:52:20 -0800608 grpc_exec_ctx_flush(&local_exec_ctx);
Dan Born5d81d152016-01-12 20:29:29 -0800609 tcp_server_destroy(&local_exec_ctx, s);
Dan Bornfa6b6062016-01-08 21:01:59 -0800610 grpc_exec_ctx_finish(&local_exec_ctx);
611 } else {
Dan Born9c12bc22016-01-13 16:52:20 -0800612 grpc_exec_ctx_finish(&local_exec_ctx);
Dan Born5d81d152016-01-12 20:29:29 -0800613 tcp_server_destroy(exec_ctx, s);
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100614 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800615 }
616}
617
Craig Tiller190d3602015-02-18 09:23:38 -0800618#endif