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 1094 : static void setup_transport(grpc_exec_ctx *exec_ctx, void *server,
47 : grpc_transport *transport, grpc_mdctx *mdctx) {
48 : static grpc_channel_filter const *extra_filters[] = {
49 : &grpc_http_server_filter};
50 1094 : grpc_server_setup_transport(exec_ctx, server, transport, extra_filters,
51 : GPR_ARRAY_SIZE(extra_filters), mdctx,
52 : grpc_server_get_channel_args(server));
53 1094 : }
54 :
55 1094 : 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 1094 : grpc_mdctx *mdctx = grpc_mdctx_create();
65 1094 : grpc_transport *transport = grpc_create_chttp2_transport(
66 : exec_ctx, grpc_server_get_channel_args(server), tcp, mdctx, 0);
67 1094 : setup_transport(exec_ctx, server, transport, mdctx);
68 1094 : grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
69 1094 : }
70 :
71 : /* Server callback: start listening on our ports */
72 1250 : static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
73 : grpc_pollset **pollsets, size_t pollset_count) {
74 1250 : grpc_tcp_server *tcp = tcpp;
75 1250 : grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport,
76 : server);
77 1250 : }
78 :
79 : /* Server callback: destroy the tcp listener (so we don't generate further
80 : callbacks) */
81 1250 : static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
82 : grpc_closure *destroy_done) {
83 1250 : grpc_tcp_server *tcp = tcpp;
84 1250 : grpc_tcp_server_destroy(exec_ctx, tcp, destroy_done);
85 1250 : }
86 :
87 1250 : int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
88 1250 : grpc_resolved_addresses *resolved = NULL;
89 1250 : grpc_tcp_server *tcp = NULL;
90 : size_t i;
91 1250 : unsigned count = 0;
92 1250 : int port_num = -1;
93 : int port_temp;
94 1250 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
95 :
96 1250 : GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2,
97 : (server, addr));
98 :
99 1250 : resolved = grpc_blocking_resolve_address(addr, "http");
100 1250 : if (!resolved) {
101 0 : goto error;
102 : }
103 :
104 1250 : tcp = grpc_tcp_server_create();
105 1250 : if (!tcp) {
106 0 : goto error;
107 : }
108 :
109 2504 : for (i = 0; i < resolved->naddrs; i++) {
110 2508 : port_temp = grpc_tcp_server_add_port(
111 1254 : tcp, (struct sockaddr *)&resolved->addrs[i].addr,
112 1254 : resolved->addrs[i].len);
113 1254 : if (port_temp >= 0) {
114 1254 : if (port_num == -1) {
115 1250 : port_num = port_temp;
116 : } else {
117 4 : GPR_ASSERT(port_num == port_temp);
118 : }
119 1254 : count++;
120 : }
121 : }
122 1250 : if (count == 0) {
123 0 : gpr_log(GPR_ERROR, "No address added out of total %d resolved",
124 : resolved->naddrs);
125 0 : goto error;
126 : }
127 1250 : if (count != resolved->naddrs) {
128 0 : gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
129 : count, resolved->naddrs);
130 : }
131 1250 : grpc_resolved_addresses_destroy(resolved);
132 :
133 : /* Register with the server only upon success */
134 1250 : grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy);
135 1250 : goto done;
136 :
137 : /* Error path: cleanup and return */
138 : error:
139 0 : if (resolved) {
140 0 : grpc_resolved_addresses_destroy(resolved);
141 : }
142 0 : if (tcp) {
143 0 : grpc_tcp_server_destroy(&exec_ctx, tcp, NULL);
144 : }
145 0 : port_num = 0;
146 :
147 : done:
148 1250 : grpc_exec_ctx_finish(&exec_ctx);
149 1250 : return port_num;
150 : }
|