OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * |
| 3 * Copyright 2015-2016, 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 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 grpc_server_setup_transport(exec_ctx, server, transport, extra_filters, |
| 51 GPR_ARRAY_SIZE(extra_filters), |
| 52 grpc_server_get_channel_args(server)); |
| 53 } |
| 54 |
| 55 static void new_transport(grpc_exec_ctx *exec_ctx, void *server, |
| 56 grpc_endpoint *tcp, |
| 57 grpc_tcp_server_acceptor *acceptor) { |
| 58 /* |
| 59 * Beware that the call to grpc_create_chttp2_transport() has to happen before |
| 60 * grpc_tcp_server_destroy(). This is fine here, but similar code |
| 61 * asynchronously doing a handshake instead of calling grpc_tcp_server_start() |
| 62 * (as in server_secure_chttp2.c) needs to add synchronization to avoid this |
| 63 * case. |
| 64 */ |
| 65 grpc_transport *transport = grpc_create_chttp2_transport( |
| 66 exec_ctx, grpc_server_get_channel_args(server), tcp, 0); |
| 67 setup_transport(exec_ctx, server, transport); |
| 68 grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); |
| 69 } |
| 70 |
| 71 /* Server callback: start listening on our ports */ |
| 72 static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, |
| 73 grpc_pollset **pollsets, size_t pollset_count) { |
| 74 grpc_tcp_server *tcp = tcpp; |
| 75 grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, |
| 76 server); |
| 77 } |
| 78 |
| 79 /* Server callback: destroy the tcp listener (so we don't generate further |
| 80 callbacks) */ |
| 81 static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, |
| 82 grpc_closure *destroy_done) { |
| 83 grpc_tcp_server *tcp = tcpp; |
| 84 grpc_tcp_server_unref(exec_ctx, tcp); |
| 85 grpc_exec_ctx_enqueue(exec_ctx, destroy_done, true, NULL); |
| 86 } |
| 87 |
| 88 int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) { |
| 89 grpc_resolved_addresses *resolved = NULL; |
| 90 grpc_tcp_server *tcp = NULL; |
| 91 size_t i; |
| 92 unsigned count = 0; |
| 93 int port_num = -1; |
| 94 int port_temp; |
| 95 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
| 96 |
| 97 GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2, |
| 98 (server, addr)); |
| 99 |
| 100 resolved = grpc_blocking_resolve_address(addr, "http"); |
| 101 if (!resolved) { |
| 102 goto error; |
| 103 } |
| 104 |
| 105 tcp = grpc_tcp_server_create(NULL); |
| 106 GPR_ASSERT(tcp); |
| 107 |
| 108 for (i = 0; i < resolved->naddrs; i++) { |
| 109 port_temp = grpc_tcp_server_add_port( |
| 110 tcp, (struct sockaddr *)&resolved->addrs[i].addr, |
| 111 resolved->addrs[i].len); |
| 112 if (port_temp > 0) { |
| 113 if (port_num == -1) { |
| 114 port_num = port_temp; |
| 115 } else { |
| 116 GPR_ASSERT(port_num == port_temp); |
| 117 } |
| 118 count++; |
| 119 } |
| 120 } |
| 121 if (count == 0) { |
| 122 gpr_log(GPR_ERROR, "No address added out of total %d resolved", |
| 123 resolved->naddrs); |
| 124 goto error; |
| 125 } |
| 126 if (count != resolved->naddrs) { |
| 127 gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved", |
| 128 count, resolved->naddrs); |
| 129 } |
| 130 grpc_resolved_addresses_destroy(resolved); |
| 131 |
| 132 /* Register with the server only upon success */ |
| 133 grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy); |
| 134 goto done; |
| 135 |
| 136 /* Error path: cleanup and return */ |
| 137 error: |
| 138 if (resolved) { |
| 139 grpc_resolved_addresses_destroy(resolved); |
| 140 } |
| 141 if (tcp) { |
| 142 grpc_tcp_server_unref(&exec_ctx, tcp); |
| 143 } |
| 144 port_num = 0; |
| 145 |
| 146 done: |
| 147 grpc_exec_ctx_finish(&exec_ctx); |
| 148 return port_num; |
| 149 } |
OLD | NEW |