Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * 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 :
36 : #include "src/core/channel/http_server_filter.h"
37 : #include "src/core/iomgr/resolve_address.h"
38 : #include "src/core/iomgr/tcp_server.h"
39 : #include "src/core/surface/api_trace.h"
40 : #include "src/core/surface/server.h"
41 : #include "src/core/transport/chttp2_transport.h"
42 : #include <grpc/support/alloc.h>
43 : #include <grpc/support/log.h>
44 : #include <grpc/support/useful.h>
45 :
46 1716 : static void setup_transport(grpc_exec_ctx *exec_ctx, void *server,
47 : grpc_transport *transport) {
48 : static grpc_channel_filter const *extra_filters[] = {
49 : &grpc_http_server_filter};
50 1716 : grpc_server_setup_transport(exec_ctx, server, transport, extra_filters,
51 : GPR_ARRAY_SIZE(extra_filters),
52 : grpc_server_get_channel_args(server));
53 1716 : }
54 :
55 1716 : static void new_transport(grpc_exec_ctx *exec_ctx, void *server,
56 : grpc_endpoint *tcp) {
57 : /*
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 : */
64 1716 : grpc_transport *transport = grpc_create_chttp2_transport(
65 : exec_ctx, grpc_server_get_channel_args(server), tcp, 0);
66 1716 : setup_transport(exec_ctx, server, transport);
67 1716 : grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
68 1716 : }
69 :
70 : /* Server callback: start listening on our ports */
71 2047 : static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
72 : grpc_pollset **pollsets, size_t pollset_count) {
73 2021 : grpc_tcp_server *tcp = tcpp;
74 2047 : grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport,
75 : server);
76 2047 : }
77 :
78 : /* Server callback: destroy the tcp listener (so we don't generate further
79 : callbacks) */
80 2048 : static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
81 : grpc_closure *destroy_done) {
82 2022 : grpc_tcp_server *tcp = tcpp;
83 2048 : grpc_tcp_server_destroy(exec_ctx, tcp, destroy_done);
84 2048 : }
85 :
86 2050 : int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
87 2023 : grpc_resolved_addresses *resolved = NULL;
88 2023 : grpc_tcp_server *tcp = NULL;
89 : size_t i;
90 2023 : unsigned count = 0;
91 2023 : int port_num = -1;
92 : int port_temp;
93 2050 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
94 :
95 2050 : GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2,
96 : (server, addr));
97 :
98 2050 : resolved = grpc_blocking_resolve_address(addr, "http");
99 2050 : if (!resolved) {
100 1 : goto error;
101 : }
102 :
103 2049 : tcp = grpc_tcp_server_create();
104 2049 : GPR_ASSERT(tcp);
105 :
106 5200 : for (i = 0; i < resolved->naddrs; i++) {
107 : grpc_tcp_listener *listener;
108 6356 : listener = grpc_tcp_server_add_port(
109 3178 : tcp, (struct sockaddr *)&resolved->addrs[i].addr,
110 3178 : resolved->addrs[i].len);
111 3178 : port_temp = grpc_tcp_listener_get_port(listener);
112 3178 : if (port_temp >= 0) {
113 3178 : if (port_num == -1) {
114 2022 : port_num = port_temp;
115 : } else {
116 1129 : GPR_ASSERT(port_num == port_temp);
117 : }
118 3178 : count++;
119 : }
120 : }
121 2049 : if (count == 0) {
122 0 : gpr_log(GPR_ERROR, "No address added out of total %d resolved",
123 : resolved->naddrs);
124 0 : goto error;
125 : }
126 2049 : if (count != resolved->naddrs) {
127 0 : gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
128 : count, resolved->naddrs);
129 : }
130 2049 : grpc_resolved_addresses_destroy(resolved);
131 :
132 : /* Register with the server only upon success */
133 2049 : grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy);
134 2049 : goto done;
135 :
136 : /* Error path: cleanup and return */
137 : error:
138 1 : if (resolved) {
139 0 : grpc_resolved_addresses_destroy(resolved);
140 : }
141 1 : if (tcp) {
142 0 : grpc_tcp_server_destroy(&exec_ctx, tcp, NULL);
143 : }
144 1 : port_num = 0;
145 :
146 : done:
147 2050 : grpc_exec_ctx_finish(&exec_ctx);
148 2050 : return port_num;
149 : }
|