blob: df63d99dead2dbc4828d627a3be168248f678415 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <grpc/grpc.h>
35
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036#include "src/core/channel/http_server_filter.h"
ctiller18b49ab2014-12-09 14:39:16 -080037#include "src/core/iomgr/resolve_address.h"
38#include "src/core/iomgr/tcp_server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039#include "src/core/surface/server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080040#include "src/core/transport/chttp2_transport.h"
41#include <grpc/support/alloc.h>
42#include <grpc/support/log.h>
43#include <grpc/support/useful.h>
44
Craig Tiller1064f8b2015-06-25 13:52:57 -070045static void setup_transport(void *server, grpc_transport *transport,
Craig Tillerdfff1b82015-09-21 14:39:57 -070046 grpc_mdctx *mdctx, grpc_workqueue *workqueue,
47 grpc_call_list *call_list) {
Craig Tiller06aeea72015-04-23 10:54:45 -070048 static grpc_channel_filter const *extra_filters[] = {
49 &grpc_http_server_filter};
Craig Tiller1064f8b2015-06-25 13:52:57 -070050 grpc_server_setup_transport(server, transport, extra_filters,
Craig Tiller47a708e2015-09-15 16:16:06 -070051 GPR_ARRAY_SIZE(extra_filters), mdctx, workqueue,
Craig Tillerdfff1b82015-09-21 14:39:57 -070052 grpc_server_get_channel_args(server), call_list);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080053}
54
Craig Tillerdfff1b82015-09-21 14:39:57 -070055static void new_transport(void *server, grpc_endpoint *tcp,
56 grpc_call_list *call_list) {
David Klempnerfd5d8ff2015-03-05 14:17:38 -080057 /*
58 * Beware that the call to grpc_create_chttp2_transport() has to happen before
59 * grpc_tcp_server_destroy(). This is fine here, but similar code
60 * asynchronously doing a handshake instead of calling grpc_tcp_server_start()
61 * (as in server_secure_chttp2.c) needs to add synchronization to avoid this
62 * case.
63 */
Craig Tiller1064f8b2015-06-25 13:52:57 -070064 grpc_mdctx *mdctx = grpc_mdctx_create();
Craig Tillerdfff1b82015-09-21 14:39:57 -070065 grpc_workqueue *workqueue = grpc_workqueue_create(call_list);
Craig Tiller1064f8b2015-06-25 13:52:57 -070066 grpc_transport *transport = grpc_create_chttp2_transport(
Craig Tillerdfff1b82015-09-21 14:39:57 -070067 grpc_server_get_channel_args(server), tcp, mdctx, 0, call_list);
68 setup_transport(server, transport, mdctx, workqueue, call_list);
69 grpc_chttp2_transport_start_reading(transport, NULL, 0, call_list);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080070}
71
72/* Server callback: start listening on our ports */
Craig Tillerc02c1d82015-04-07 16:21:55 -070073static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets,
Craig Tillerdfff1b82015-09-21 14:39:57 -070074 size_t pollset_count, grpc_call_list *call_list) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080075 grpc_tcp_server *tcp = tcpp;
Craig Tillerdfff1b82015-09-21 14:39:57 -070076 grpc_tcp_server_start(tcp, pollsets, pollset_count, new_transport, server,
77 call_list);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080078}
79
80/* Server callback: destroy the tcp listener (so we don't generate further
81 callbacks) */
Craig Tillerdfff1b82015-09-21 14:39:57 -070082static void destroy(grpc_server *server, void *tcpp, grpc_closure *destroy_done,
83 grpc_call_list *call_list) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080084 grpc_tcp_server *tcp = tcpp;
Craig Tillerdfff1b82015-09-21 14:39:57 -070085 grpc_tcp_server_destroy(tcp, destroy_done, call_list);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080086}
87
Craig Tillerc5ae3eb2015-08-03 10:42:22 -070088int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080089 grpc_resolved_addresses *resolved = NULL;
90 grpc_tcp_server *tcp = NULL;
91 size_t i;
Nicolas "Pixel" Noble213ed912015-01-30 02:11:35 +010092 unsigned count = 0;
ctiller570d1f42015-01-12 16:29:52 -080093 int port_num = -1;
94 int port_temp;
Craig Tillerdfff1b82015-09-21 14:39:57 -070095 grpc_call_list call_list = GRPC_CALL_LIST_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080096
97 resolved = grpc_blocking_resolve_address(addr, "http");
98 if (!resolved) {
99 goto error;
100 }
101
ctiller18b49ab2014-12-09 14:39:16 -0800102 tcp = grpc_tcp_server_create();
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800103 if (!tcp) {
104 goto error;
105 }
106
107 for (i = 0; i < resolved->naddrs; i++) {
ctiller570d1f42015-01-12 16:29:52 -0800108 port_temp = grpc_tcp_server_add_port(
109 tcp, (struct sockaddr *)&resolved->addrs[i].addr,
110 resolved->addrs[i].len);
111 if (port_temp >= 0) {
112 if (port_num == -1) {
113 port_num = port_temp;
114 } else {
115 GPR_ASSERT(port_num == port_temp);
116 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800117 count++;
118 }
119 }
120 if (count == 0) {
121 gpr_log(GPR_ERROR, "No address added out of total %d resolved",
122 resolved->naddrs);
123 goto error;
124 }
125 if (count != resolved->naddrs) {
126 gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
127 count, resolved->naddrs);
128 }
129 grpc_resolved_addresses_destroy(resolved);
130
131 /* Register with the server only upon success */
Craig Tillerdfff1b82015-09-21 14:39:57 -0700132 grpc_server_add_listener(server, tcp, start, destroy, &call_list);
133 goto done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800134
135/* Error path: cleanup and return */
136error:
137 if (resolved) {
138 grpc_resolved_addresses_destroy(resolved);
139 }
140 if (tcp) {
Craig Tilleraec96aa2015-04-07 14:32:15 -0700141 grpc_tcp_server_destroy(tcp, NULL, NULL);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700143 port_num = 0;
144
145done:
146 grpc_call_list_run(&call_list);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800147 return 0;
Craig Tiller190d3602015-02-18 09:23:38 -0800148}