blob: f47a00c118c44c03456647ae15380b0f752b00c7 [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>
ahedberg803931d2016-03-11 17:24:12 -050055#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillerae7fe922015-02-13 23:16:32 -080056#include <sys/un.h>
ahedberg803931d2016-03-11 17:24:12 -050057#endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080058#include <unistd.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080059
ctiller58393c22015-01-07 14:03:30 -080060#include "src/core/iomgr/pollset_posix.h"
Craig Tillerae7fe922015-02-13 23:16:32 -080061#include "src/core/iomgr/resolve_address.h"
ctiller18b49ab2014-12-09 14:39:16 -080062#include "src/core/iomgr/sockaddr_utils.h"
63#include "src/core/iomgr/socket_utils_posix.h"
64#include "src/core/iomgr/tcp_posix.h"
Craig Tillerfa275a92015-06-01 13:55:54 -070065#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066#include <grpc/support/alloc.h>
67#include <grpc/support/log.h>
Masood Malekghassemi701af602015-06-03 15:01:17 -070068#include <grpc/support/string_util.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080069#include <grpc/support/sync.h>
70#include <grpc/support/time.h>
71
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080072#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
73
74static gpr_once s_init_max_accept_queue_size;
75static int s_max_accept_queue_size;
76
77/* one listening port */
Dan Bornfa6b6062016-01-08 21:01:59 -080078typedef struct grpc_tcp_listener grpc_tcp_listener;
Nicolas Noble8f714622015-11-19 11:16:54 -080079struct grpc_tcp_listener {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080080 int fd;
ctiller18b49ab2014-12-09 14:39:16 -080081 grpc_fd *emfd;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080082 grpc_tcp_server *server;
Craig Tillera82950e2015-09-22 12:33:20 -070083 union {
Craig Tiller7536af02015-12-22 13:49:30 -080084 uint8_t untyped[GRPC_MAX_SOCKADDR_SIZE];
Craig Tiller772c97b2015-02-17 08:07:34 -080085 struct sockaddr sockaddr;
ahedberg803931d2016-03-11 17:24:12 -050086#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tiller772c97b2015-02-17 08:07:34 -080087 struct sockaddr_un un;
ahedberg803931d2016-03-11 17:24:12 -050088#endif
Craig Tiller772c97b2015-02-17 08:07:34 -080089 } addr;
Craig Tillerf96dfc32015-09-10 14:43:18 -070090 size_t addr_len;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -080091 int port;
Dan Bornfa6b6062016-01-08 21:01:59 -080092 unsigned port_index;
93 unsigned fd_index;
Craig Tiller33825112015-09-18 07:44:19 -070094 grpc_closure read_closure;
95 grpc_closure destroyed_closure;
Nicolas Noble8f714622015-11-19 11:16:54 -080096 struct grpc_tcp_listener *next;
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +010097 /* When we add a listener, more than one can be created, mainly because of
98 IPv6. A sibling will still be in the normal list, but will be flagged
99 as such. Any action, such as ref or unref, will affect all of the
100 siblings in the list. */
101 struct grpc_tcp_listener *sibling;
102 int is_sibling;
Nicolas Noble8f714622015-11-19 11:16:54 -0800103};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800104
ahedberg803931d2016-03-11 17:24:12 -0500105#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillera82950e2015-09-22 12:33:20 -0700106static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) {
Craig Tilleraa31da42015-02-17 16:33:35 -0800107 struct stat st;
108
Craig Tillera82950e2015-09-22 12:33:20 -0700109 if (stat(un->sun_path, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) {
110 unlink(un->sun_path);
111 }
Craig Tilleraa31da42015-02-17 16:33:35 -0800112}
ahedberg803931d2016-03-11 17:24:12 -0500113#endif
Craig Tilleraa31da42015-02-17 16:33:35 -0800114
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800115/* the overall server */
Craig Tillera82950e2015-09-22 12:33:20 -0700116struct grpc_tcp_server {
Dan Bornfa6b6062016-01-08 21:01:59 -0800117 gpr_refcount refs;
Robbie Shade3cd2d182015-08-28 14:30:35 -0400118 /* Called whenever accept() succeeds on a server port. */
119 grpc_tcp_server_cb on_accept_cb;
120 void *on_accept_cb_arg;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800121
122 gpr_mu mu;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800123
124 /* active port count: how many ports are actually still listening */
Craig Tilleraec96aa2015-04-07 14:32:15 -0700125 size_t active_ports;
126 /* destroyed port count: how many ports are completely destroyed */
127 size_t destroyed_ports;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800128
Craig Tiller6174b9a2015-06-18 08:13:05 -0700129 /* is this server shutting down? (boolean) */
Craig Tiller6f051402015-05-13 11:42:42 -0700130 int shutdown;
131
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800132 /* linked list of server ports */
Nicolas Noble8f714622015-11-19 11:16:54 -0800133 grpc_tcp_listener *head;
Dan Bornfa6b6062016-01-08 21:01:59 -0800134 grpc_tcp_listener *tail;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800135 unsigned nports;
Craig Tilleraec96aa2015-04-07 14:32:15 -0700136
Dan Born9c12bc22016-01-13 16:52:20 -0800137 /* List of closures passed to shutdown_starting_add(). */
138 grpc_closure_list shutdown_starting;
139
Craig Tilleraec96aa2015-04-07 14:32:15 -0700140 /* shutdown callback */
Craig Tillerd1bec032015-09-18 17:29:00 -0700141 grpc_closure *shutdown_complete;
Craig Tiller0189ac02015-05-11 14:59:19 -0700142
Craig Tiller6174b9a2015-06-18 08:13:05 -0700143 /* all pollsets interested in new connections */
Craig Tiller0189ac02015-05-11 14:59:19 -0700144 grpc_pollset **pollsets;
Craig Tiller6174b9a2015-06-18 08:13:05 -0700145 /* number of pollsets in the pollsets array */
Craig Tiller0189ac02015-05-11 14:59:19 -0700146 size_t pollset_count;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800147};
148
Dan Bornfa6b6062016-01-08 21:01:59 -0800149grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
Craig Tillera82950e2015-09-22 12:33:20 -0700150 grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
Dan Bornfa6b6062016-01-08 21:01:59 -0800151 gpr_ref_init(&s->refs, 1);
Craig Tillera82950e2015-09-22 12:33:20 -0700152 gpr_mu_init(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800153 s->active_ports = 0;
Craig Tilleraec96aa2015-04-07 14:32:15 -0700154 s->destroyed_ports = 0;
Craig Tiller6f051402015-05-13 11:42:42 -0700155 s->shutdown = 0;
Dan Born9c12bc22016-01-13 16:52:20 -0800156 s->shutdown_starting.head = NULL;
157 s->shutdown_starting.tail = NULL;
Dan Bornfa6b6062016-01-08 21:01:59 -0800158 s->shutdown_complete = shutdown_complete;
Robbie Shade3cd2d182015-08-28 14:30:35 -0400159 s->on_accept_cb = NULL;
160 s->on_accept_cb_arg = NULL;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800161 s->head = NULL;
Dan Bornfa6b6062016-01-08 21:01:59 -0800162 s->tail = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800163 s->nports = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800164 return s;
165}
166
Craig Tillera82950e2015-09-22 12:33:20 -0700167static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800168 if (s->shutdown_complete != NULL) {
Craig Tiller6c396862016-01-28 13:53:40 -0800169 grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL);
Dan Bornfa6b6062016-01-08 21:01:59 -0800170 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700171
Craig Tillera82950e2015-09-22 12:33:20 -0700172 gpr_mu_destroy(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700173
Nicolas "Pixel" Noblec6a7c6e2015-11-19 21:55:44 +0100174 while (s->head) {
175 grpc_tcp_listener *sp = s->head;
176 s->head = sp->next;
Dan Bornfa6b6062016-01-08 21:01:59 -0800177 gpr_free(sp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800178 }
179
Craig Tillera82950e2015-09-22 12:33:20 -0700180 gpr_free(s);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700181}
182
Craig Tiller6c396862016-01-28 13:53:40 -0800183static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server,
184 bool success) {
Craig Tilleraec96aa2015-04-07 14:32:15 -0700185 grpc_tcp_server *s = server;
Craig Tillera82950e2015-09-22 12:33:20 -0700186 gpr_mu_lock(&s->mu);
Craig Tilleraec96aa2015-04-07 14:32:15 -0700187 s->destroyed_ports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700188 if (s->destroyed_ports == s->nports) {
189 gpr_mu_unlock(&s->mu);
190 finish_shutdown(exec_ctx, s);
191 } else {
192 GPR_ASSERT(s->destroyed_ports < s->nports);
193 gpr_mu_unlock(&s->mu);
194 }
Craig Tilleraec96aa2015-04-07 14:32:15 -0700195}
196
Craig Tiller6174b9a2015-06-18 08:13:05 -0700197/* called when all listening endpoints have been shutdown, so no further
198 events will be received on them - at this point it's safe to destroy
199 things */
Craig Tillera82950e2015-09-22 12:33:20 -0700200static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800201 /* delete ALL the things */
Craig Tillera82950e2015-09-22 12:33:20 -0700202 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700203
Craig Tillera82950e2015-09-22 12:33:20 -0700204 if (!s->shutdown) {
205 gpr_mu_unlock(&s->mu);
206 return;
207 }
Craig Tiller45724b32015-09-22 10:42:19 -0700208
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800209 if (s->head) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800210 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800211 for (sp = s->head; sp; sp = sp->next) {
ahedberg803931d2016-03-11 17:24:12 -0500212#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillera82950e2015-09-22 12:33:20 -0700213 if (sp->addr.sockaddr.sa_family == AF_UNIX) {
214 unlink_if_unix_domain_socket(&sp->addr.un);
215 }
ahedberg803931d2016-03-11 17:24:12 -0500216#endif
Craig Tillera82950e2015-09-22 12:33:20 -0700217 sp->destroyed_closure.cb = destroyed_port;
218 sp->destroyed_closure.cb_arg = s;
yang-g5d850372015-12-01 10:32:28 -0800219 grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
Craig Tillera82950e2015-09-22 12:33:20 -0700220 "tcp_listener_shutdown");
Craig Tiller45724b32015-09-22 10:42:19 -0700221 }
Craig Tillera82950e2015-09-22 12:33:20 -0700222 gpr_mu_unlock(&s->mu);
223 } else {
224 gpr_mu_unlock(&s->mu);
225 finish_shutdown(exec_ctx, s);
226 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800227}
228
Dan Born5d81d152016-01-12 20:29:29 -0800229static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
Craig Tillera82950e2015-09-22 12:33:20 -0700230 gpr_mu_lock(&s->mu);
Craig Tiller6f051402015-05-13 11:42:42 -0700231
Craig Tillera82950e2015-09-22 12:33:20 -0700232 GPR_ASSERT(!s->shutdown);
Craig Tiller6f051402015-05-13 11:42:42 -0700233 s->shutdown = 1;
234
Craig Tiller6f051402015-05-13 11:42:42 -0700235 /* shutdown all fd's */
Craig Tillera82950e2015-09-22 12:33:20 -0700236 if (s->active_ports) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800237 grpc_tcp_listener *sp;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800238 for (sp = s->head; sp; sp = sp->next) {
239 grpc_fd_shutdown(exec_ctx, sp->emfd);
Craig Tiller6f051402015-05-13 11:42:42 -0700240 }
Craig Tillera82950e2015-09-22 12:33:20 -0700241 gpr_mu_unlock(&s->mu);
242 } else {
243 gpr_mu_unlock(&s->mu);
244 deactivated_all_ports(exec_ctx, s);
245 }
Craig Tiller6f051402015-05-13 11:42:42 -0700246}
247
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800248/* get max listen queue size on linux */
Craig Tillera82950e2015-09-22 12:33:20 -0700249static void init_max_accept_queue_size(void) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800250 int n = SOMAXCONN;
251 char buf[64];
Craig Tillera82950e2015-09-22 12:33:20 -0700252 FILE *fp = fopen("/proc/sys/net/core/somaxconn", "r");
253 if (fp == NULL) {
254 /* 2.4 kernel. */
255 s_max_accept_queue_size = SOMAXCONN;
256 return;
257 }
258 if (fgets(buf, sizeof buf, fp)) {
259 char *end;
260 long i = strtol(buf, &end, 10);
261 if (i > 0 && i <= INT_MAX && end && *end == 0) {
262 n = (int)i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800263 }
Craig Tillera82950e2015-09-22 12:33:20 -0700264 }
265 fclose(fp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800266 s_max_accept_queue_size = n;
267
Craig Tillera82950e2015-09-22 12:33:20 -0700268 if (s_max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
269 gpr_log(GPR_INFO,
270 "Suspiciously small accept queue (%d) will probably lead to "
271 "connection drops",
272 s_max_accept_queue_size);
273 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800274}
275
Craig Tillera82950e2015-09-22 12:33:20 -0700276static int get_max_accept_queue_size(void) {
277 gpr_once_init(&s_init_max_accept_queue_size, init_max_accept_queue_size);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800278 return s_max_accept_queue_size;
279}
280
nnoble0c475f02014-12-05 15:37:39 -0800281/* Prepare a recently-created socket for listening. */
Craig Tillera82950e2015-09-22 12:33:20 -0700282static int prepare_socket(int fd, const struct sockaddr *addr,
283 size_t addr_len) {
ctiller570d1f42015-01-12 16:29:52 -0800284 struct sockaddr_storage sockname_temp;
285 socklen_t sockname_len;
286
Craig Tillera82950e2015-09-22 12:33:20 -0700287 if (fd < 0) {
288 goto error;
289 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800290
ahedberg803931d2016-03-11 17:24:12 -0500291#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillera82950e2015-09-22 12:33:20 -0700292 if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
293 (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) ||
294 !grpc_set_socket_reuse_addr(fd, 1))) ||
295 !grpc_set_socket_no_sigpipe_if_possible(fd)) {
296 gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
297 strerror(errno));
298 goto error;
299 }
ahedberg803931d2016-03-11 17:24:12 -0500300#else
301 if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
302 !grpc_set_socket_low_latency(fd, 1) ||
303 !grpc_set_socket_reuse_addr(fd, 1) ||
304 !grpc_set_socket_no_sigpipe_if_possible(fd)) {
305 gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
306 strerror(errno));
307 goto error;
308 }
309#endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800310
Craig Tillera82950e2015-09-22 12:33:20 -0700311 GPR_ASSERT(addr_len < ~(socklen_t)0);
312 if (bind(fd, addr, (socklen_t)addr_len) < 0) {
313 char *addr_str;
314 grpc_sockaddr_to_string(&addr_str, addr, 0);
315 gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
316 gpr_free(addr_str);
317 goto error;
318 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800319
Craig Tillera82950e2015-09-22 12:33:20 -0700320 if (listen(fd, get_max_accept_queue_size()) < 0) {
321 gpr_log(GPR_ERROR, "listen: %s", strerror(errno));
322 goto error;
323 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800324
Craig Tillera82950e2015-09-22 12:33:20 -0700325 sockname_len = sizeof(sockname_temp);
326 if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
327 goto error;
328 }
ctiller570d1f42015-01-12 16:29:52 -0800329
Craig Tillera82950e2015-09-22 12:33:20 -0700330 return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800331
332error:
Craig Tillera82950e2015-09-22 12:33:20 -0700333 if (fd >= 0) {
334 close(fd);
335 }
ctiller570d1f42015-01-12 16:29:52 -0800336 return -1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800337}
338
339/* event manager callback when reads are ready */
Craig Tiller6c396862016-01-28 13:53:40 -0800340static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800341 grpc_tcp_listener *sp = arg;
Dan Born5d81d152016-01-12 20:29:29 -0800342 grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
343 sp->fd_index};
Craig Tiller0189ac02015-05-11 14:59:19 -0700344 grpc_fd *fdobj;
345 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800346
Craig Tillera82950e2015-09-22 12:33:20 -0700347 if (!success) {
348 goto error;
349 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800350
351 /* loop until accept4 returns EAGAIN, and then re-arm notification */
Craig Tillera82950e2015-09-22 12:33:20 -0700352 for (;;) {
353 struct sockaddr_storage addr;
354 socklen_t addrlen = sizeof(addr);
355 char *addr_str;
356 char *name;
357 /* Note: If we ever decide to return this address to the user, remember to
358 strip off the ::ffff:0.0.0.0/96 prefix first. */
359 int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1);
360 if (fd < 0) {
361 switch (errno) {
362 case EINTR:
363 continue;
364 case EAGAIN:
365 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
366 return;
367 default:
368 gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
369 goto error;
370 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800371 }
372
Craig Tillera82950e2015-09-22 12:33:20 -0700373 grpc_set_socket_no_sigpipe_if_possible(fd);
374
375 addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr);
376 gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
377
378 if (grpc_tcp_trace) {
379 gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
380 }
381
382 fdobj = grpc_fd_create(fd, name);
383 /* TODO(ctiller): revise this when we have server-side sharding
384 of channels -- we certainly should not be automatically adding every
385 incoming channel to every pollset owned by the server */
386 for (i = 0; i < sp->server->pollset_count; i++) {
387 grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj);
388 }
389 sp->server->on_accept_cb(
390 exec_ctx, sp->server->on_accept_cb_arg,
Dan Bornfa6b6062016-01-08 21:01:59 -0800391 grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
Dan Born5d81d152016-01-12 20:29:29 -0800392 &acceptor);
Craig Tillera82950e2015-09-22 12:33:20 -0700393
394 gpr_free(name);
395 gpr_free(addr_str);
396 }
397
yang-gb063c872015-10-07 11:40:13 -0700398 GPR_UNREACHABLE_CODE(return );
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800399
400error:
Craig Tillera82950e2015-09-22 12:33:20 -0700401 gpr_mu_lock(&sp->server->mu);
402 if (0 == --sp->server->active_ports) {
403 gpr_mu_unlock(&sp->server->mu);
404 deactivated_all_ports(exec_ctx, sp->server);
405 } else {
406 gpr_mu_unlock(&sp->server->mu);
407 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800408}
409
Nicolas Noble8f714622015-11-19 11:16:54 -0800410static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
yang-g3ff97272015-11-20 17:01:57 -0800411 const struct sockaddr *addr,
Dan Bornfa6b6062016-01-08 21:01:59 -0800412 size_t addr_len,
413 unsigned port_index,
414 unsigned fd_index) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800415 grpc_tcp_listener *sp = NULL;
ctiller570d1f42015-01-12 16:29:52 -0800416 int port;
Craig Tillerfa275a92015-06-01 13:55:54 -0700417 char *addr_str;
418 char *name;
nnoble0c475f02014-12-05 15:37:39 -0800419
Craig Tillera82950e2015-09-22 12:33:20 -0700420 port = prepare_socket(fd, addr, addr_len);
421 if (port >= 0) {
422 grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
423 gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
424 gpr_mu_lock(&s->mu);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800425 s->nports++;
Craig Tillera82950e2015-09-22 12:33:20 -0700426 GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
Nicolas Noble8f714622015-11-19 11:16:54 -0800427 sp = gpr_malloc(sizeof(grpc_tcp_listener));
Dan Bornfa6b6062016-01-08 21:01:59 -0800428 sp->next = NULL;
429 if (s->head == NULL) {
430 s->head = sp;
431 } else {
432 s->tail->next = sp;
433 }
434 s->tail = sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700435 sp->server = s;
436 sp->fd = fd;
437 sp->emfd = grpc_fd_create(fd, name);
438 memcpy(sp->addr.untyped, addr, addr_len);
439 sp->addr_len = addr_len;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800440 sp->port = port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800441 sp->port_index = port_index;
442 sp->fd_index = fd_index;
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100443 sp->is_sibling = 0;
444 sp->sibling = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700445 GPR_ASSERT(sp->emfd);
446 gpr_mu_unlock(&s->mu);
447 gpr_free(addr_str);
448 gpr_free(name);
449 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800450
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800451 return sp;
nnoble0c475f02014-12-05 15:37:39 -0800452}
453
Dan Bornfa6b6062016-01-08 21:01:59 -0800454int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
455 size_t addr_len) {
Nicolas Noble8f714622015-11-19 11:16:54 -0800456 grpc_tcp_listener *sp;
457 grpc_tcp_listener *sp2 = NULL;
nnoble0c475f02014-12-05 15:37:39 -0800458 int fd;
459 grpc_dualstack_mode dsmode;
460 struct sockaddr_in6 addr6_v4mapped;
461 struct sockaddr_in wild4;
462 struct sockaddr_in6 wild6;
463 struct sockaddr_in addr4_copy;
ctiller570d1f42015-01-12 16:29:52 -0800464 struct sockaddr *allocated_addr = NULL;
465 struct sockaddr_storage sockname_temp;
466 socklen_t sockname_len;
nnoble0c475f02014-12-05 15:37:39 -0800467 int port;
Dan Bornfa6b6062016-01-08 21:01:59 -0800468 unsigned port_index = 0;
469 unsigned fd_index = 0;
470 if (s->tail != NULL) {
471 port_index = s->tail->port_index + 1;
472 }
ahedberg803931d2016-03-11 17:24:12 -0500473#ifdef GPR_HAVE_UNIX_SOCKET
Craig Tillera82950e2015-09-22 12:33:20 -0700474 if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
475 unlink_if_unix_domain_socket(addr);
476 }
ahedberg803931d2016-03-11 17:24:12 -0500477#endif
Craig Tilleraa31da42015-02-17 16:33:35 -0800478
ctiller570d1f42015-01-12 16:29:52 -0800479 /* Check if this is a wildcard port, and if so, try to keep the port the same
480 as some previously created listener. */
Craig Tillera82950e2015-09-22 12:33:20 -0700481 if (grpc_sockaddr_get_port(addr) == 0) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800482 for (sp = s->head; sp; sp = sp->next) {
Craig Tillera82950e2015-09-22 12:33:20 -0700483 sockname_len = sizeof(sockname_temp);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800484 if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
Craig Tillera82950e2015-09-22 12:33:20 -0700485 &sockname_len)) {
486 port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
487 if (port > 0) {
488 allocated_addr = malloc(addr_len);
489 memcpy(allocated_addr, addr, addr_len);
490 grpc_sockaddr_set_port(allocated_addr, port);
491 addr = allocated_addr;
492 break;
493 }
494 }
ctiller570d1f42015-01-12 16:29:52 -0800495 }
Craig Tillera82950e2015-09-22 12:33:20 -0700496 }
ctiller570d1f42015-01-12 16:29:52 -0800497
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800498 sp = NULL;
499
Craig Tillera82950e2015-09-22 12:33:20 -0700500 if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
501 addr = (const struct sockaddr *)&addr6_v4mapped;
502 addr_len = sizeof(addr6_v4mapped);
503 }
nnoble0c475f02014-12-05 15:37:39 -0800504
505 /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
Craig Tillera82950e2015-09-22 12:33:20 -0700506 if (grpc_sockaddr_is_wildcard(addr, &port)) {
507 grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
nnoble0c475f02014-12-05 15:37:39 -0800508
Craig Tillera82950e2015-09-22 12:33:20 -0700509 /* Try listening on IPv6 first. */
510 addr = (struct sockaddr *)&wild6;
511 addr_len = sizeof(wild6);
512 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
Dan Bornfa6b6062016-01-08 21:01:59 -0800513 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Craig Tillera82950e2015-09-22 12:33:20 -0700514 if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
515 goto done;
nnoble0c475f02014-12-05 15:37:39 -0800516 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800517 if (sp != NULL) {
518 ++fd_index;
519 }
Craig Tillera82950e2015-09-22 12:33:20 -0700520 /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
Craig Tillere57ba132015-12-09 15:00:28 -0800521 if (port == 0 && sp != NULL) {
522 grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800523 sp2 = sp;
ctiller570d1f42015-01-12 16:29:52 -0800524 }
Craig Tillera82950e2015-09-22 12:33:20 -0700525 addr = (struct sockaddr *)&wild4;
526 addr_len = sizeof(wild4);
527 }
528
529 fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
530 if (fd < 0) {
531 gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
532 }
533 if (dsmode == GRPC_DSMODE_IPV4 &&
534 grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
535 addr = (struct sockaddr *)&addr4_copy;
536 addr_len = sizeof(addr4_copy);
537 }
Dan Bornfa6b6062016-01-08 21:01:59 -0800538 sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
Dan Born03c8a9b2016-01-12 21:14:29 -0800539 if (sp2 != NULL && sp != NULL) {
540 sp2->sibling = sp;
541 sp->is_sibling = 1;
Dan Bornfa6b6062016-01-08 21:01:59 -0800542 }
ctiller570d1f42015-01-12 16:29:52 -0800543
544done:
Craig Tillera82950e2015-09-22 12:33:20 -0700545 gpr_free(allocated_addr);
Dan Bornfa6b6062016-01-08 21:01:59 -0800546 if (sp != NULL) {
547 return sp->port;
548 } else {
549 return -1;
550 }
nnoble0c475f02014-12-05 15:37:39 -0800551}
552
Dan Born5d81d152016-01-12 20:29:29 -0800553unsigned grpc_tcp_server_port_fd_count(grpc_tcp_server *s,
554 unsigned port_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800555 unsigned num_fds = 0;
Nicolas Noble8f714622015-11-19 11:16:54 -0800556 grpc_tcp_listener *sp;
Dan Bornfa6b6062016-01-08 21:01:59 -0800557 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
558 if (!sp->is_sibling) {
559 --port_index;
560 }
561 }
562 for (; sp; sp = sp->sibling, ++num_fds)
yang-g3ff97272015-11-20 17:01:57 -0800563 ;
Dan Bornfa6b6062016-01-08 21:01:59 -0800564 return num_fds;
565}
566
Dan Born5d81d152016-01-12 20:29:29 -0800567int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
568 unsigned fd_index) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800569 grpc_tcp_listener *sp;
570 for (sp = s->head; sp && port_index != 0; sp = sp->next) {
571 if (!sp->is_sibling) {
572 --port_index;
573 }
574 }
575 for (; sp && fd_index != 0; sp = sp->sibling, --fd_index)
576 ;
577 if (sp) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800578 return sp->fd;
579 } else {
580 return -1;
581 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800582}
583
Craig Tillera82950e2015-09-22 12:33:20 -0700584void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
585 grpc_pollset **pollsets, size_t pollset_count,
586 grpc_tcp_server_cb on_accept_cb,
587 void *on_accept_cb_arg) {
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800588 size_t i;
Nicolas Noble8f714622015-11-19 11:16:54 -0800589 grpc_tcp_listener *sp;
Craig Tillera82950e2015-09-22 12:33:20 -0700590 GPR_ASSERT(on_accept_cb);
591 gpr_mu_lock(&s->mu);
592 GPR_ASSERT(!s->on_accept_cb);
593 GPR_ASSERT(s->active_ports == 0);
Robbie Shade3cd2d182015-08-28 14:30:35 -0400594 s->on_accept_cb = on_accept_cb;
595 s->on_accept_cb_arg = on_accept_cb_arg;
Craig Tiller0189ac02015-05-11 14:59:19 -0700596 s->pollsets = pollsets;
597 s->pollset_count = pollset_count;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800598 for (sp = s->head; sp; sp = sp->next) {
599 for (i = 0; i < pollset_count; i++) {
600 grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
ctiller58393c22015-01-07 14:03:30 -0800601 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800602 sp->read_closure.cb = on_read;
603 sp->read_closure.cb_arg = sp;
yang-g3ff97272015-11-20 17:01:57 -0800604 grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
Craig Tillera82950e2015-09-22 12:33:20 -0700605 s->active_ports++;
606 }
607 gpr_mu_unlock(&s->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800608}
Craig Tiller0c0b60c2015-01-21 15:49:28 -0800609
Dan Bornfa6b6062016-01-08 21:01:59 -0800610grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
611 gpr_ref(&s->refs);
612 return s;
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800613}
614
Dan Born9c12bc22016-01-13 16:52:20 -0800615void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
616 grpc_closure *shutdown_starting) {
617 gpr_mu_lock(&s->mu);
618 grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
619 gpr_mu_unlock(&s->mu);
620}
621
Dan Bornfa6b6062016-01-08 21:01:59 -0800622void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
623 if (gpr_unref(&s->refs)) {
Dan Born9c12bc22016-01-13 16:52:20 -0800624 /* Complete shutdown_starting work before destroying. */
625 grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
626 gpr_mu_lock(&s->mu);
Craig Tiller6c396862016-01-28 13:53:40 -0800627 grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL);
Dan Born9c12bc22016-01-13 16:52:20 -0800628 gpr_mu_unlock(&s->mu);
Dan Bornfa6b6062016-01-08 21:01:59 -0800629 if (exec_ctx == NULL) {
Dan Born9c12bc22016-01-13 16:52:20 -0800630 grpc_exec_ctx_flush(&local_exec_ctx);
Dan Born5d81d152016-01-12 20:29:29 -0800631 tcp_server_destroy(&local_exec_ctx, s);
Dan Bornfa6b6062016-01-08 21:01:59 -0800632 grpc_exec_ctx_finish(&local_exec_ctx);
633 } else {
Dan Born9c12bc22016-01-13 16:52:20 -0800634 grpc_exec_ctx_finish(&local_exec_ctx);
Dan Born5d81d152016-01-12 20:29:29 -0800635 tcp_server_destroy(exec_ctx, s);
Nicolas "Pixel" Nobled86115e2015-11-20 05:56:25 +0100636 }
Nicolas Noble5eb4e1c2015-11-18 17:19:45 -0800637 }
638}
639
Craig Tiller190d3602015-02-18 09:23:38 -0800640#endif