blob: c1ccfbf6390c2887eec801d6ef651cd3d62f2272 [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
34#include <grpc/grpc.h>
35
Craig Tillerf40df232016-03-25 13:38:14 -070036#include <grpc/support/alloc.h>
37#include <grpc/support/log.h>
38#include <grpc/support/useful.h>
Craig Tilleradcb92d2016-03-28 10:14:05 -070039#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
Craig Tiller9533d042016-03-25 17:11:06 -070040#include "src/core/lib/channel/http_server_filter.h"
41#include "src/core/lib/iomgr/resolve_address.h"
42#include "src/core/lib/iomgr/tcp_server.h"
43#include "src/core/lib/surface/api_trace.h"
44#include "src/core/lib/surface/server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045
Craig Tillera82950e2015-09-22 12:33:20 -070046static void setup_transport(grpc_exec_ctx *exec_ctx, void *server,
Craig Tillerb2b42612015-11-20 12:02:17 -080047 grpc_transport *transport) {
Craig Tiller178edfa2016-02-17 20:54:46 -080048 grpc_server_setup_transport(exec_ctx, server, transport,
Craig Tillera82950e2015-09-22 12:33:20 -070049 grpc_server_get_channel_args(server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080050}
51
Craig Tillera82950e2015-09-22 12:33:20 -070052static void new_transport(grpc_exec_ctx *exec_ctx, void *server,
Dan Born5d81d152016-01-12 20:29:29 -080053 grpc_endpoint *tcp,
54 grpc_tcp_server_acceptor *acceptor) {
David Klempnerfd5d8ff2015-03-05 14:17:38 -080055 /*
56 * Beware that the call to grpc_create_chttp2_transport() has to happen before
57 * grpc_tcp_server_destroy(). This is fine here, but similar code
58 * asynchronously doing a handshake instead of calling grpc_tcp_server_start()
59 * (as in server_secure_chttp2.c) needs to add synchronization to avoid this
60 * case.
61 */
Craig Tillera82950e2015-09-22 12:33:20 -070062 grpc_transport *transport = grpc_create_chttp2_transport(
Craig Tillerb2b42612015-11-20 12:02:17 -080063 exec_ctx, grpc_server_get_channel_args(server), tcp, 0);
64 setup_transport(exec_ctx, server, transport);
Craig Tillera82950e2015-09-22 12:33:20 -070065 grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066}
67
68/* Server callback: start listening on our ports */
Craig Tillera82950e2015-09-22 12:33:20 -070069static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
70 grpc_pollset **pollsets, size_t pollset_count) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080071 grpc_tcp_server *tcp = tcpp;
Craig Tillera82950e2015-09-22 12:33:20 -070072 grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport,
73 server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080074}
75
76/* Server callback: destroy the tcp listener (so we don't generate further
77 callbacks) */
Craig Tillera82950e2015-09-22 12:33:20 -070078static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
79 grpc_closure *destroy_done) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080080 grpc_tcp_server *tcp = tcpp;
Dan Bornfa6b6062016-01-08 21:01:59 -080081 grpc_tcp_server_unref(exec_ctx, tcp);
Craig Tiller6c396862016-01-28 13:53:40 -080082 grpc_exec_ctx_enqueue(exec_ctx, destroy_done, true, NULL);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080083}
84
Craig Tillera82950e2015-09-22 12:33:20 -070085int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080086 grpc_resolved_addresses *resolved = NULL;
87 grpc_tcp_server *tcp = NULL;
88 size_t i;
Nicolas "Pixel" Noble213ed912015-01-30 02:11:35 +010089 unsigned count = 0;
ctiller570d1f42015-01-12 16:29:52 -080090 int port_num = -1;
91 int port_temp;
Craig Tillerf5768a62015-09-22 10:54:34 -070092 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080093
Masood Malekghassemi76c3d742015-08-19 18:22:53 -070094 GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2,
95 (server, addr));
96
Craig Tillera82950e2015-09-22 12:33:20 -070097 resolved = grpc_blocking_resolve_address(addr, "http");
98 if (!resolved) {
99 goto error;
100 }
Craig Tiller45724b32015-09-22 10:42:19 -0700101
Dan Bornfa6b6062016-01-08 21:01:59 -0800102 tcp = grpc_tcp_server_create(NULL);
yang-gfe9a9752015-12-09 10:47:18 -0800103 GPR_ASSERT(tcp);
Craig Tiller45724b32015-09-22 10:42:19 -0700104
Craig Tillera82950e2015-09-22 12:33:20 -0700105 for (i = 0; i < resolved->naddrs; i++) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800106 port_temp = grpc_tcp_server_add_port(
Craig Tillera82950e2015-09-22 12:33:20 -0700107 tcp, (struct sockaddr *)&resolved->addrs[i].addr,
108 resolved->addrs[i].len);
Jan Tattermusch1d7ccec2015-12-14 09:33:30 -0800109 if (port_temp > 0) {
Craig Tillera82950e2015-09-22 12:33:20 -0700110 if (port_num == -1) {
111 port_num = port_temp;
112 } else {
113 GPR_ASSERT(port_num == port_temp);
114 }
115 count++;
Craig Tiller45724b32015-09-22 10:42:19 -0700116 }
Craig Tillera82950e2015-09-22 12:33:20 -0700117 }
118 if (count == 0) {
119 gpr_log(GPR_ERROR, "No address added out of total %d resolved",
120 resolved->naddrs);
121 goto error;
122 }
123 if (count != resolved->naddrs) {
124 gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
125 count, resolved->naddrs);
126 }
127 grpc_resolved_addresses_destroy(resolved);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800128
129 /* Register with the server only upon success */
Craig Tillera82950e2015-09-22 12:33:20 -0700130 grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700131 goto done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800132
133/* Error path: cleanup and return */
134error:
Craig Tillera82950e2015-09-22 12:33:20 -0700135 if (resolved) {
136 grpc_resolved_addresses_destroy(resolved);
137 }
138 if (tcp) {
Dan Bornfa6b6062016-01-08 21:01:59 -0800139 grpc_tcp_server_unref(&exec_ctx, tcp);
Craig Tillera82950e2015-09-22 12:33:20 -0700140 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700141 port_num = 0;
142
143done:
Craig Tillera82950e2015-09-22 12:33:20 -0700144 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerba496452015-09-21 17:15:19 -0700145 return port_num;
Craig Tiller190d3602015-02-18 09:23:38 -0800146}