blob: a5fdd0377400553133b4097864fa69e84730166c [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
3 * Copyright 2014, 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_filter.h"
37#include "src/core/channel/http_server_filter.h"
ctiller18b49ab2014-12-09 14:39:16 -080038#include "src/core/iomgr/resolve_address.h"
39#include "src/core/iomgr/tcp_server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080040#include "src/core/surface/server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080041#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
46static grpc_transport_setup_result setup_transport(void *server,
47 grpc_transport *transport,
48 grpc_mdctx *mdctx) {
49 static grpc_channel_filter const *extra_filters[] = {&grpc_http_server_filter,
50 &grpc_http_filter};
51 return grpc_server_setup_transport(server, transport, extra_filters,
52 GPR_ARRAY_SIZE(extra_filters), mdctx);
53}
54
55static void new_transport(void *server, grpc_endpoint *tcp) {
56 grpc_create_chttp2_transport(setup_transport, server,
57 grpc_server_get_channel_args(server), tcp, NULL,
58 0, grpc_mdctx_create(), 0);
59}
60
61/* Server callback: start listening on our ports */
62static void start(grpc_server *server, void *tcpp) {
63 grpc_tcp_server *tcp = tcpp;
64 grpc_tcp_server_start(tcp, new_transport, server);
65}
66
67/* Server callback: destroy the tcp listener (so we don't generate further
68 callbacks) */
69static void destroy(grpc_server *server, void *tcpp) {
70 grpc_tcp_server *tcp = tcpp;
71 grpc_tcp_server_destroy(tcp);
72}
73
74int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
75 grpc_resolved_addresses *resolved = NULL;
76 grpc_tcp_server *tcp = NULL;
77 size_t i;
78 int count = 0;
79
80 resolved = grpc_blocking_resolve_address(addr, "http");
81 if (!resolved) {
82 goto error;
83 }
84
ctiller18b49ab2014-12-09 14:39:16 -080085 tcp = grpc_tcp_server_create();
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080086 if (!tcp) {
87 goto error;
88 }
89
90 for (i = 0; i < resolved->naddrs; i++) {
91 if (grpc_tcp_server_add_port(tcp,
92 (struct sockaddr *)&resolved->addrs[i].addr,
nnoble0c475f02014-12-05 15:37:39 -080093 resolved->addrs[i].len)) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080094 count++;
95 }
96 }
97 if (count == 0) {
98 gpr_log(GPR_ERROR, "No address added out of total %d resolved",
99 resolved->naddrs);
100 goto error;
101 }
102 if (count != resolved->naddrs) {
103 gpr_log(GPR_ERROR, "Only %d addresses added out of total %d resolved",
104 count, resolved->naddrs);
105 }
106 grpc_resolved_addresses_destroy(resolved);
107
108 /* Register with the server only upon success */
109 grpc_server_add_listener(server, tcp, start, destroy);
110
111 return 1;
112
113/* Error path: cleanup and return */
114error:
115 if (resolved) {
116 grpc_resolved_addresses_destroy(resolved);
117 }
118 if (tcp) {
119 grpc_tcp_server_destroy(tcp);
120 }
121 return 0;
122}