blob: 5e07f8261c223e4cd410ab2deab9e34cb0d99c2b [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) {
Craig Tiller6c396862016-01-28 13:53:40 -0800163 grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL);
Dan Bornfa6b6062016-01-08 21:01:59 -0800164 }
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 Tiller6c396862016-01-28 13:53:40 -0800177static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server,
178 bool success) {
Craig Tilleraec96aa2015-04-07 14:32:15 -0700179 grpc_tcp_server *s = server;
Craig Tillera82950e2015-09-22 12:33:20 -0700180 gpr_mu_lock(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700181 s->destroyed_ports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700182 if (s->destroyed_ports == s->nports) {
183 gpr_mu_unlock(&s->mu);
184 finish_shutdown(exec_ctx, s);
185 } else {
186 GPR_ASSERT(s->destroyed_ports < s->nports);
187 gpr_mu_unlock(&s->mu);
188 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700189}
190
Craig Tiller6174b9a2015-06-18 08:13:05 -0700191/* called when all listening endpoints have been shutdown, so no further
192 events will be received on them - at this point it's safe to destroy
193 things */
Craig Tillera82950e2015-09-22 12:33:20 -0700194static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800195 /* delete ALL the things */
Craig Tillera82950e2015-09-22 12:33:20 -0700196 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700197
Craig Tillera82950e2015-09-22 12:33:20 -0700198 if (!s->shutdown) {
199 gpr_mu_unlock(&s->mu);
200 return;
201 }
Craig Tiller45724b32015-09-22 10:42:19 -0700202
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800203 if (s->head) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800204 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800205 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700206 if (sp->addr.sockaddr.sa_family == AF_UNIX) {
207 unlink_if_unix_domain_socket(&sp->addr.un);
208 }
209 sp->destroyed_closure.cb = destroyed_port;
210 sp->destroyed_closure.cb_arg = s;
yang-g5d850372015-12-01 10:32:28 -0800211 grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
Craig Tillera82950e2015-09-22 12:33:20 -0700212 "tcp_listener_shutdown");
Craig Tiller45724b32015-09-22 10:42:19 -0700213 }
Craig Tillera82950e2015-09-22 12:33:20 -0700214 gpr_mu_unlock(&s->mu);
215 } else {
216 gpr_mu_unlock(&s->mu);
217 finish_shutdown(exec_ctx, s);
218 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800219}
220
Dan Born5d81d152016-01-12 20:29:29 -0800221static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Craig Tillera82950e2015-09-22 12:33:20 -0700222 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700223
Craig Tillera82950e2015-09-22 12:33:20 -0700224 GPR_ASSERT(!s->shutdown);
Craig Tiller6f051402015-05-13 11:42:42 -0700225 s->shutdown = 1;
226
Craig Tiller6f051402015-05-13 11:42:42 -0700227 /* shutdown all fd's */
Craig Tillera82950e2015-09-22 12:33:20 -0700228 if (s->active_ports) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800229 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800230 for (sp = s->head; sp; sp = sp->next) {
231 grpc_fd_shutdown(exec_ctx, sp->emfd);
Craig Tiller6f051402015-05-13 11:42:42 -0700232 }
Craig Tillera82950e2015-09-22 12:33:20 -0700233 gpr_mu_unlock(&s->mu);
234 } else {
235 gpr_mu_unlock(&s->mu);
236 deactivated_all_ports(exec_ctx, s);
237 }
Craig Tiller6f051402015-05-13 11:42:42 -0700238}
239
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800240/* get max listen queue size on linux */
Craig Tillera82950e2015-09-22 12:33:20 -0700241static void init_max_accept_queue_size(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800242 int n = SOMAXCONN;
243 char buf[64];
Craig Tillera82950e2015-09-22 12:33:20 -0700244 FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
245 if (fp == NULL) {
246 /* 2.4 kernel. */
247 s_max_accept_queue_size = SOMAXCONN;
248 return;
249 }
250 if (fgets(buf, sizeof buf, fp)) {
251 char *end;
252 long i = strtol(buf, &end, 10);
253 if (i > 0 && i <= INT_MAX && end && *end == 0) {
254 n = (int)i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800255 }
Craig Tillera82950e2015-09-22 12:33:20 -0700256 }
257 fclose(fp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800258 s_max_accept_queue_size = n;
259
Craig Tillera82950e2015-09-22 12:33:20 -0700260 if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
261 gpr_log(GPR_INFO,
262 "Suspiciously small accept queue (%d) will probably lead to "
263 "connection drops",
264 s_max_accept_queue_size);
265 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800266}
267
Craig Tillera82950e2015-09-22 12:33:20 -0700268static int get_max_accept_queue_size(void) {
269 gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800270 return s_max_accept_queue_size;
271}
272
nnoble0c475f02014-12-05 15:37:39 -0800273/* Prepare a recently-created socket for listening. */
Craig Tillera82950e2015-09-22 12:33:20 -0700274static int prepare_socket(int fd, const struct sockaddr *addr,
275 size_t addr_len) {
ctiller570d1f42015-01-12 16:29:52 -0800276 struct sockaddr_storage sockname_temp;
277 socklen_t sockname_len;
278
Craig Tillera82950e2015-09-22 12:33:20 -0700279 if (fd < 0) {
280 goto error;
281 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800282
Craig Tillera82950e2015-09-22 12:33:20 -0700283 if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
284 (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) ||
285 !grpc_set_socket_reuse_addr(fd, 1))) ||
286 !grpc_set_socket_no_sigpipe_if_possible(fd)) {
287 gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
288 strerror(errno));
289 goto error;
290 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800291
Craig Tillera82950e2015-09-22 12:33:20 -0700292 GPR_ASSERT(addr_len < ~(socklen_t)0);
293 if (bind(fd, addr, (socklen_t)addr_len) < 0) {
294 char *addr_str;
295 grpc_sockaddr_to_string(&addr_str, addr, 0);
296 gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
297 gpr_free(addr_str);
298 goto error;
299 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800300
Craig Tillera82950e2015-09-22 12:33:20 -0700301 if (listen(fd, get_max_accept_queue_size()) < 0) {
302 gpr_log(GPR_ERROR, "listen: %s", strerror(errno));
303 goto error;
304 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800305
Craig Tillera82950e2015-09-22 12:33:20 -0700306 sockname_len = sizeof(sockname_temp);
307 if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
308 goto error;
309 }
ctiller570d1f42015-01-12 16:29:52 -0800310
Craig Tillera82950e2015-09-22 12:33:20 -0700311 return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800312
313error:
Craig Tillera82950e2015-09-22 12:33:20 -0700314 if (fd >= 0) {
315 close(fd);
316 }
ctiller570d1f42015-01-12 16:29:52 -0800317 return -1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800318}
319
320/* event manager callback when reads are ready */
Craig Tiller6c396862016-01-28 13:53:40 -0800321static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800322 grpc_tcp_listener *sp = arg;
Dan Born5d81d152016-01-12 20:29:29 -0800323 grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
324 sp->fd_index};
Craig Tiller0189ac02015-05-11 14:59:19 -0700325 grpc_fd *fdobj;
326 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800327
Craig Tillera82950e2015-09-22 12:33:20 -0700328 if (!success) {
329 goto error;
330 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800331
332 /* loop until accept4 returns EAGAIN, and then re-arm notification */
Craig Tillera82950e2015-09-22 12:33:20 -0700333 for (;;) {
334 struct sockaddr_storage addr;
335 socklen_t addrlen = sizeof(addr);
336 char *addr_str;
337 char *name;
338 /* Note: If we ever decide to return this address to the user, remember to
339 strip off the ::ffff:0.0.0.0/96 prefix first. */
340 int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1);
341 if (fd < 0) {
342 switch (errno) {
343 case EINTR:
344 continue;
345 case EAGAIN:
346 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
347 return;
348 default:
349 gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
350 goto error;
351 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800352 }
353
Craig Tillera82950e2015-09-22 12:33:20 -0700354 grpc_set_socket_no_sigpipe_if_possible(fd);
355
356 addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr);
357 gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
358
359 if (grpc_tcp_trace) {
360 gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
361 }
362
363 fdobj = grpc_fd_create(fd, name);
364 /* TODO(ctiller): revise this when we have server-side sharding
365 of channels -- we certainly should not be automatically adding every
366 incoming channel to every pollset owned by the server */
367 for (i = 0; i < sp->server->pollset_count; i++) {
368 grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj);
369 }
370 sp->server->on_accept_cb(
371 exec_ctx, sp->server->on_accept_cb_arg,
Dan Bornfa6b6062016-01-08 21:01:59 -0800372 grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
Dan Born5d81d152016-01-12 20:29:29 -0800373 &acceptor);
Craig Tillera82950e2015-09-22 12:33:20 -0700374
375 gpr_free(name);
376 gpr_free(addr_str);
377 }
378
yang-gb063c872015-10-07 11:40:13 -0700379 GPR_UNREACHABLE_CODE(return );
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800380
381error:
Craig Tillera82950e2015-09-22 12:33:20 -0700382 gpr_mu_lock(&sp->server->mu);
383 if (0 == --sp->server->active_ports) {
384 gpr_mu_unlock(&sp->server->mu);
385 deactivated_all_ports(exec_ctx, sp->server);
386 } else {
387 gpr_mu_unlock(&sp->server->mu);
388 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800389}
390
Nicolas Noble8f714622015-11-19 11:16:54 -0800391static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
yang-g3ff97272015-11-20 17:01:57 -0800392 const struct sockaddr *addr,
Dan Bornfa6b6062016-01-08 21:01:59 -0800393 size_t addr_len,
394 unsigned port_index,
395 unsigned fd_index) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800396 grpc_tcp_listener *sp = NULL;
ctiller570d1f42015-01-12 16:29:52 -0800397 int port;
Craig Tillerfa275a92015-06-01 13:55:54 -0700398 char *addr_str;
399 char *name;
nnoble0c475f02014-12-05 15:37:39 -0800400
Craig Tillera82950e2015-09-22 12:33:20 -0700401 port = prepare_socket(fd, addr, addr_len);
402 if (port >= 0) {
403 grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
404 gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
405 gpr_mu_lock(&s->mu);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800406 s->nports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700407 GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
Nicolas Noble8f714622015-11-19 11:16:54 -0800408 sp = gpr_malloc(sizeof(grpc_tcp_listener));
Dan Bornfa6b6062016-01-08 21:01:59 -0800409 sp->next = NULL;
410 if (s->head == NULL) {
411 s->head = sp;
412 } else {
413 s->tail->next = sp;
414 }
415 s->tail = sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700416 sp->server = s;
417 sp->fd = fd;
418 sp->emfd = grpc_fd_create(fd, name);
419 memcpy(sp->addr.untyped, addr, addr_len);
420 sp->addr_len = addr_len;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800421 sp->port = port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800422 sp->port_index = port_index;
423 sp->fd_index = fd_index;
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100424 sp->is_sibling = 0;
425 sp->sibling = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700426 GPR_ASSERT(sp->emfd);
427 gpr_mu_unlock(&s->mu);
428 gpr_free(addr_str);
429 gpr_free(name);
430 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800431
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800432 return sp;
nnoble0c475f02014-12-05 15:37:39 -0800433}
434
Dan Bornfa6b6062016-01-08 21:01:59 -0800435int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
436 size_t addr_len) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800437 grpc_tcp_listener *sp;
438 grpc_tcp_listener *sp2 = NULL;
nnoble0c475f02014-12-05 15:37:39 -0800439 int fd;
440 grpc_dualstack_mode dsmode;
441 struct sockaddr_in6 addr6_v4mapped;
442 struct sockaddr_in wild4;
443 struct sockaddr_in6 wild6;
444 struct sockaddr_in addr4_copy;
ctiller570d1f42015-01-12 16:29:52 -0800445 struct sockaddr *allocated_addr = NULL;
446 struct sockaddr_storage sockname_temp;
447 socklen_t sockname_len;
nnoble0c475f02014-12-05 15:37:39 -0800448 int port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800449 unsigned port_index = 0;
450 unsigned fd_index = 0;
451 if (s->tail != NULL) {
452 port_index = s->tail->port_index + 1;
453 }
Craig Tillera82950e2015-09-22 12:33:20 -0700454 if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
455 unlink_if_unix_domain_socket(addr);
456 }
Craig Tilleraa31da42015-02-17 16:33:35 -0800457
ctiller570d1f42015-01-12 16:29:52 -0800458 /* Check if this is a wildcard port, and if so, try to keep the port the same
459 as some previously created listener. */
Craig Tillera82950e2015-09-22 12:33:20 -0700460 if (grpc_sockaddr_get_port(addr) == 0) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800461 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700462 sockname_len = sizeof(sockname_temp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800463 if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
Craig Tillera82950e2015-09-22 12:33:20 -0700464 &sockname_len)) {
465 port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
466 if (port > 0) {
467 allocated_addr = malloc(addr_len);
468 memcpy(allocated_addr, addr, addr_len);
469 grpc_sockaddr_set_port(allocated_addr, port);
470 addr = allocated_addr;
471 break;
472 }
473 }
ctiller570d1f42015-01-12 16:29:52 -0800474 }
Craig Tillera82950e2015-09-22 12:33:20 -0700475 }
ctiller570d1f42015-01-12 16:29:52 -0800476
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800477 sp = NULL;
478
Craig Tillera82950e2015-09-22 12:33:20 -0700479 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
480 addr = (const struct sockaddr *)&addr6_v4mapped;
481 addr_len = sizeof(addr6_v4mapped);
482 }
nnoble0c475f02014-12-05 15:37:39 -0800483
484 /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
Craig Tillera82950e2015-09-22 12:33:20 -0700485 if (grpc_sockaddr_is_wildcard(addr, &port)) {
486 grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
nnoble0c475f02014-12-05 15:37:39 -0800487
Craig Tillera82950e2015-09-22 12:33:20 -0700488 /* Try listening on IPv6 first. */
489 addr = (struct sockaddr *)&wild6;
490 addr_len = sizeof(wild6);
491 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
Dan Bornfa6b6062016-01-08 21:01:59 -0800492 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Craig Tillera82950e2015-09-22 12:33:20 -0700493 if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
494 goto done;
nnoble0c475f02014-12-05 15:37:39 -0800495 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800496 if (sp != NULL) {
497 ++fd_index;
498 }
Craig Tillera82950e2015-09-22 12:33:20 -0700499 /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
Craig Tillere57ba132015-12-09 15:00:28 -0800500 if (port == 0 && sp != NULL) {
501 grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800502 sp2 = sp;
ctiller570d1f42015-01-12 16:29:52 -0800503 }
Craig Tillera82950e2015-09-22 12:33:20 -0700504 addr = (struct sockaddr *)&wild4;
505 addr_len = sizeof(wild4);
506 }
507
508 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
509 if (fd < 0) {
510 gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
511 }
512 if (dsmode == GRPC_DSMODE_IPV4 &&
513 grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
514 addr = (struct sockaddr *)&addr4_copy;
515 addr_len = sizeof(addr4_copy);
516 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800517 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Dan Born03c8a9b2016-01-12 21:14:29 -0800518 if (sp2 != NULL && sp != NULL) {
519 sp2->sibling = sp;
520 sp->is_sibling = 1;
Dan Bornfa6b6062016-01-08 21:01:59 -0800521 }
ctiller570d1f42015-01-12 16:29:52 -0800522
523done:
Craig Tillera82950e2015-09-22 12:33:20 -0700524 gpr_free(allocated_addr);
Dan Bornfa6b6062016-01-08 21:01:59 -0800525 if (sp != NULL) {
526 return sp->port;
527 } else {
528 return -1;
529 }
nnoble0c475f02014-12-05 15:37:39 -0800530}
531
Dan Born5d81d152016-01-12 20:29:29 -0800532unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
533 unsigned port_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800534 unsigned num_fds = 0;
Nicolas Noble8f714622015-11-19 11:16:54 -0800535 grpc_tcp_listener *sp;
Dan Bornfa6b6062016-01-08 21:01:59 -0800536 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
537 if (!sp->is_sibling) {
538 --port_index;
539 }
540 }
541 for (; sp; sp = sp->sibling, ++num_fds)
yang-g3ff97272015-11-20 17:01:57 -0800542 ;
Dan Bornfa6b6062016-01-08 21:01:59 -0800543 return num_fds;
544}
545
Dan Born5d81d152016-01-12 20:29:29 -0800546int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
547 unsigned fd_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800548 grpc_tcp_listener *sp;
549 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
550 if (!sp->is_sibling) {
551 --port_index;
552 }
553 }
554 for (; sp && fd_index != 0; sp = sp->sibling, --fd_index)
555 ;
556 if (sp) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800557 return sp->fd;
558 } else {
559 return -1;
560 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800561}
562
Craig Tillera82950e2015-09-22 12:33:20 -0700563void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
564 grpc_pollset **pollsets, size_t pollset_count,
565 grpc_tcp_server_cb on_accept_cb,
566 void *on_accept_cb_arg) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800567 size_t i;
Nicolas Noble8f714622015-11-19 11:16:54 -0800568 grpc_tcp_listener *sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700569 GPR_ASSERT(on_accept_cb);
570 gpr_mu_lock(&s->mu);
571 GPR_ASSERT(!s->on_accept_cb);
572 GPR_ASSERT(s->active_ports == 0);
Robbie Shade3cd2d182015-08-28 14:30:35 -0400573 s->on_accept_cb = on_accept_cb;
574 s->on_accept_cb_arg = on_accept_cb_arg;
Craig Tiller0189ac02015-05-11 14:59:19 -0700575 s->pollsets = pollsets;
576 s->pollset_count = pollset_count;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800577 for (sp = s->head; sp; sp = sp->next) {
578 for (i = 0; i < pollset_count; i++) {
579 grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
ctiller58393c22015-01-07 14:03:30 -0800580 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800581 sp->read_closure.cb = on_read;
582 sp->read_closure.cb_arg = sp;
yang-g3ff97272015-11-20 17:01:57 -0800583 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
Craig Tillera82950e2015-09-22 12:33:20 -0700584 s->active_ports++;
585 }
586 gpr_mu_unlock(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800587}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800588
Dan Bornfa6b6062016-01-08 21:01:59 -0800589grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
590 gpr_ref(&s->refs);
591 return s;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800592}
593
Dan Born9c12bc22016-01-13 16:52:20 -0800594void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
595 grpc_closure *shutdown_starting) {
596 gpr_mu_lock(&s->mu);
597 grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
598 gpr_mu_unlock(&s->mu);
599}
600
Dan Bornfa6b6062016-01-08 21:01:59 -0800601void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
602 if (gpr_unref(&s->refs)) {
Dan Born9c12bc22016-01-13 16:52:20 -0800603 /* Complete shutdown_starting work before destroying. */
604 grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
605 gpr_mu_lock(&s->mu);
Craig Tiller6c396862016-01-28 13:53:40 -0800606 grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL);
Dan Born9c12bc22016-01-13 16:52:20 -0800607 gpr_mu_unlock(&s->mu);
Dan Bornfa6b6062016-01-08 21:01:59 -0800608 if (exec_ctx == NULL) {
Dan Born9c12bc22016-01-13 16:52:20 -0800609 grpc_exec_ctx_flush(&local_exec_ctx);
Dan Born5d81d152016-01-12 20:29:29 -0800610 tcp_server_destroy(&local_exec_ctx, s);
Dan Bornfa6b6062016-01-08 21:01:59 -0800611 grpc_exec_ctx_finish(&local_exec_ctx);
612 } else {
Dan Born9c12bc22016-01-13 16:52:20 -0800613 grpc_exec_ctx_finish(&local_exec_ctx);
Dan Born5d81d152016-01-12 20:29:29 -0800614 tcp_server_destroy(exec_ctx, s);
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100615 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800616 }
617}
618
Craig Tiller190d3602015-02-18 09:23:38 -0800619#endif