blob: 2a3042750436280a73f1f4299f0085e2bcc1c3c3 [file] [log] [blame]
Robbie Shade4b70e032015-07-10 15:44:33 -04001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Robbie Shade4b70e032015-07-10 15:44:33 -04004 * 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
Craig Tiller9533d042016-03-25 17:11:06 -070034#include "src/core/lib/iomgr/udp_server.h"
Robbie Shade4b70e032015-07-10 15:44:33 -040035
Robbie Shade4b70e032015-07-10 15:44:33 -040036#include <netinet/in.h>
37#include <string.h>
Craig Tillerf40df232016-03-25 13:38:14 -070038#include <sys/socket.h>
Robbie Shade4b70e032015-07-10 15:44:33 -040039#include <unistd.h>
40
Craig Tillerfe01b582016-05-11 08:05:59 -070041#include <grpc/grpc.h>
42#include <grpc/support/alloc.h>
Robbie Shade4b70e032015-07-10 15:44:33 -040043#include <grpc/support/log.h>
44#include <grpc/support/sync.h>
45#include <grpc/support/time.h>
Robbie Shade4b70e032015-07-10 15:44:33 -040046
Craig Tillerd9a60bb2016-03-28 23:13:19 -070047#include "src/core/lib/iomgr/ev_posix.h"
48#include "src/core/lib/iomgr/iomgr.h"
Craig Tillerc2278152016-03-21 08:59:54 -070049#include "test/core/util/test_config.h"
Robbie Shade4b70e032015-07-10 15:44:33 -040050
51#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
52
Craig Tiller3ab2fe02016-04-11 20:11:18 -070053static grpc_pollset *g_pollset;
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +010054static gpr_mu *g_mu;
Robbie Shade4b70e032015-07-10 15:44:33 -040055static int g_number_of_reads = 0;
Robbie Shade2b107672015-08-04 19:55:42 -040056static int g_number_of_bytes_read = 0;
Robbie Shade9aa6f402016-05-12 13:28:04 -040057static int g_number_of_orphan_calls = 0;
Robbie Shade4b70e032015-07-10 15:44:33 -040058
Robbie Shadec6787b22015-10-07 10:13:53 -040059static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
60 grpc_server *server) {
Robbie Shade2b107672015-08-04 19:55:42 -040061 char read_buffer[512];
Craig Tillerf96dfc32015-09-10 14:43:18 -070062 ssize_t byte_count;
Robbie Shade2b107672015-08-04 19:55:42 -040063
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +010064 gpr_mu_lock(g_mu);
Craig Tiller3ab2fe02016-04-11 20:11:18 -070065 byte_count =
66 recv(grpc_fd_wrapped_fd(emfd), read_buffer, sizeof(read_buffer), 0);
Robbie Shade2b107672015-08-04 19:55:42 -040067
Robbie Shade4b70e032015-07-10 15:44:33 -040068 g_number_of_reads++;
Craig Tillera82950e2015-09-22 12:33:20 -070069 g_number_of_bytes_read += (int)byte_count;
Robbie Shade2b107672015-08-04 19:55:42 -040070
Nicolas "Pixel" Noblecede7742016-07-19 01:52:36 +020071 GPR_ASSERT(
72 GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, NULL)));
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +010073 gpr_mu_unlock(g_mu);
Robbie Shade4b70e032015-07-10 15:44:33 -040074}
75
Robbie Shade9aa6f402016-05-12 13:28:04 -040076static void on_fd_orphaned(grpc_fd *emfd) {
77 gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d",
78 grpc_fd_wrapped_fd(emfd));
79 g_number_of_orphan_calls++;
80}
81
Craig Tillera82950e2015-09-22 12:33:20 -070082static void test_no_op(void) {
Craig Tillerb8b1a462015-09-22 12:50:03 -070083 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -070084 grpc_udp_server *s = grpc_udp_server_create();
Craig Tillerb8b1a462015-09-22 12:50:03 -070085 grpc_udp_server_destroy(&exec_ctx, s, NULL);
86 grpc_exec_ctx_finish(&exec_ctx);
Robbie Shade4b70e032015-07-10 15:44:33 -040087}
88
Craig Tillera82950e2015-09-22 12:33:20 -070089static void test_no_op_with_start(void) {
Craig Tillerf5768a62015-09-22 10:54:34 -070090 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -070091 grpc_udp_server *s = grpc_udp_server_create();
92 LOG_TEST("test_no_op_with_start");
Robbie Shade147fe702015-09-25 15:04:40 -040093 grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
Craig Tillerb8b1a462015-09-22 12:50:03 -070094 grpc_udp_server_destroy(&exec_ctx, s, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -070095 grpc_exec_ctx_finish(&exec_ctx);
Robbie Shade4b70e032015-07-10 15:44:33 -040096}
97
Craig Tillera82950e2015-09-22 12:33:20 -070098static void test_no_op_with_port(void) {
Robbie Shade9aa6f402016-05-12 13:28:04 -040099 g_number_of_orphan_calls = 0;
Craig Tillerb8b1a462015-09-22 12:50:03 -0700100 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Robbie Shade4b70e032015-07-10 15:44:33 -0400101 struct sockaddr_in addr;
Craig Tillera82950e2015-09-22 12:33:20 -0700102 grpc_udp_server *s = grpc_udp_server_create();
103 LOG_TEST("test_no_op_with_port");
Robbie Shade4b70e032015-07-10 15:44:33 -0400104
Craig Tillera82950e2015-09-22 12:33:20 -0700105 memset(&addr, 0, sizeof(addr));
Robbie Shade4b70e032015-07-10 15:44:33 -0400106 addr.sin_family = AF_INET;
Craig Tillera82950e2015-09-22 12:33:20 -0700107 GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
Robbie Shade9aa6f402016-05-12 13:28:04 -0400108 on_read, on_fd_orphaned));
Robbie Shade4b70e032015-07-10 15:44:33 -0400109
Craig Tillerb8b1a462015-09-22 12:50:03 -0700110 grpc_udp_server_destroy(&exec_ctx, s, NULL);
111 grpc_exec_ctx_finish(&exec_ctx);
Robbie Shade9aa6f402016-05-12 13:28:04 -0400112
Robbie Shade006314a2016-05-13 10:35:02 -0400113 /* The server had a single FD, which should have been orphaned. */
Robbie Shade9aa6f402016-05-12 13:28:04 -0400114 GPR_ASSERT(g_number_of_orphan_calls == 1);
Robbie Shade4b70e032015-07-10 15:44:33 -0400115}
116
Craig Tillera82950e2015-09-22 12:33:20 -0700117static void test_no_op_with_port_and_start(void) {
Robbie Shade9aa6f402016-05-12 13:28:04 -0400118 g_number_of_orphan_calls = 0;
Craig Tillerf5768a62015-09-22 10:54:34 -0700119 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Robbie Shade4b70e032015-07-10 15:44:33 -0400120 struct sockaddr_in addr;
Craig Tillera82950e2015-09-22 12:33:20 -0700121 grpc_udp_server *s = grpc_udp_server_create();
122 LOG_TEST("test_no_op_with_port_and_start");
Robbie Shade4b70e032015-07-10 15:44:33 -0400123
Craig Tillera82950e2015-09-22 12:33:20 -0700124 memset(&addr, 0, sizeof(addr));
Robbie Shade4b70e032015-07-10 15:44:33 -0400125 addr.sin_family = AF_INET;
Craig Tillera82950e2015-09-22 12:33:20 -0700126 GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
Robbie Shade9aa6f402016-05-12 13:28:04 -0400127 on_read, on_fd_orphaned));
Robbie Shade4b70e032015-07-10 15:44:33 -0400128
Robbie Shade147fe702015-09-25 15:04:40 -0400129 grpc_udp_server_start(&exec_ctx, s, NULL, 0, NULL);
Robbie Shade4b70e032015-07-10 15:44:33 -0400130
Craig Tillera82950e2015-09-22 12:33:20 -0700131 grpc_udp_server_destroy(&exec_ctx, s, NULL);
132 grpc_exec_ctx_finish(&exec_ctx);
Robbie Shade9aa6f402016-05-12 13:28:04 -0400133
Robbie Shade006314a2016-05-13 10:35:02 -0400134 /* The server had a single FD, which should have been orphaned. */
Robbie Shade9aa6f402016-05-12 13:28:04 -0400135 GPR_ASSERT(g_number_of_orphan_calls == 1);
Robbie Shade4b70e032015-07-10 15:44:33 -0400136}
137
Craig Tillera82950e2015-09-22 12:33:20 -0700138static void test_receive(int number_of_clients) {
Craig Tillerf5768a62015-09-22 10:54:34 -0700139 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Robbie Shade4b70e032015-07-10 15:44:33 -0400140 struct sockaddr_storage addr;
Craig Tillera82950e2015-09-22 12:33:20 -0700141 socklen_t addr_len = sizeof(addr);
Robbie Shadeaeb386c2015-08-04 19:20:41 -0400142 int clifd, svrfd;
Craig Tillera82950e2015-09-22 12:33:20 -0700143 grpc_udp_server *s = grpc_udp_server_create();
Robbie Shade4b70e032015-07-10 15:44:33 -0400144 int i;
145 int number_of_reads_before;
146 gpr_timespec deadline;
147 grpc_pollset *pollsets[1];
Craig Tillera82950e2015-09-22 12:33:20 -0700148 LOG_TEST("test_receive");
149 gpr_log(GPR_INFO, "clients=%d", number_of_clients);
Robbie Shade2b107672015-08-04 19:55:42 -0400150
151 g_number_of_bytes_read = 0;
Robbie Shade9aa6f402016-05-12 13:28:04 -0400152 g_number_of_orphan_calls = 0;
Robbie Shade4b70e032015-07-10 15:44:33 -0400153
Craig Tillera82950e2015-09-22 12:33:20 -0700154 memset(&addr, 0, sizeof(addr));
Robbie Shade4b70e032015-07-10 15:44:33 -0400155 addr.ss_family = AF_INET;
Robbie Shade9aa6f402016-05-12 13:28:04 -0400156 GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, addr_len,
157 on_read, on_fd_orphaned));
Robbie Shade1cef6dc2015-07-15 14:16:48 -0400158
Craig Tillera82950e2015-09-22 12:33:20 -0700159 svrfd = grpc_udp_server_get_fd(s, 0);
160 GPR_ASSERT(svrfd >= 0);
161 GPR_ASSERT(getsockname(svrfd, (struct sockaddr *)&addr, &addr_len) == 0);
162 GPR_ASSERT(addr_len <= sizeof(addr));
Robbie Shadeaeb386c2015-08-04 19:20:41 -0400163
Craig Tiller3ab2fe02016-04-11 20:11:18 -0700164 pollsets[0] = g_pollset;
Robbie Shade147fe702015-09-25 15:04:40 -0400165 grpc_udp_server_start(&exec_ctx, s, pollsets, 1, NULL);
Robbie Shade4b70e032015-07-10 15:44:33 -0400166
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +0100167 gpr_mu_lock(g_mu);
Robbie Shade1cef6dc2015-07-15 14:16:48 -0400168
Craig Tillera82950e2015-09-22 12:33:20 -0700169 for (i = 0; i < number_of_clients; i++) {
170 deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
Robbie Shade4b70e032015-07-10 15:44:33 -0400171
Craig Tillera82950e2015-09-22 12:33:20 -0700172 number_of_reads_before = g_number_of_reads;
173 /* Create a socket, send a packet to the UDP server. */
174 clifd = socket(addr.ss_family, SOCK_DGRAM, 0);
175 GPR_ASSERT(clifd >= 0);
176 GPR_ASSERT(connect(clifd, (struct sockaddr *)&addr, addr_len) == 0);
177 GPR_ASSERT(5 == write(clifd, "hello", 5));
178 while (g_number_of_reads == number_of_reads_before &&
179 gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +0100180 grpc_pollset_worker *worker = NULL;
Nicolas "Pixel" Noblecede7742016-07-19 01:52:36 +0200181 GPR_ASSERT(GRPC_LOG_IF_ERROR(
182 "pollset_work",
183 grpc_pollset_work(&exec_ctx, g_pollset, &worker,
184 gpr_now(GPR_CLOCK_MONOTONIC), deadline)));
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +0100185 gpr_mu_unlock(g_mu);
Craig Tillera82950e2015-09-22 12:33:20 -0700186 grpc_exec_ctx_finish(&exec_ctx);
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +0100187 gpr_mu_lock(g_mu);
Robbie Shade4b70e032015-07-10 15:44:33 -0400188 }
Craig Tillera82950e2015-09-22 12:33:20 -0700189 GPR_ASSERT(g_number_of_reads == number_of_reads_before + 1);
190 close(clifd);
191 }
192 GPR_ASSERT(g_number_of_bytes_read == 5 * number_of_clients);
Robbie Shade4b70e032015-07-10 15:44:33 -0400193
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +0100194 gpr_mu_unlock(g_mu);
Robbie Shade1cef6dc2015-07-15 14:16:48 -0400195
Craig Tillerb8b1a462015-09-22 12:50:03 -0700196 grpc_udp_server_destroy(&exec_ctx, s, NULL);
197 grpc_exec_ctx_finish(&exec_ctx);
Robbie Shade9aa6f402016-05-12 13:28:04 -0400198
Robbie Shade006314a2016-05-13 10:35:02 -0400199 /* The server had a single FD, which should have been orphaned. */
200 GPR_ASSERT(g_number_of_orphan_calls == 1);
Robbie Shade4b70e032015-07-10 15:44:33 -0400201}
202
Nicolas "Pixel" Noblecede7742016-07-19 01:52:36 +0200203static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
204 grpc_error *error) {
Craig Tillera82950e2015-09-22 12:33:20 -0700205 grpc_pollset_destroy(p);
Craig Tiller294d0ec2015-09-21 14:59:45 -0700206}
Robbie Shade4b70e032015-07-10 15:44:33 -0400207
Craig Tillera82950e2015-09-22 12:33:20 -0700208int main(int argc, char **argv) {
Craig Tiller294d0ec2015-09-21 14:59:45 -0700209 grpc_closure destroyed;
Craig Tillerf5768a62015-09-22 10:54:34 -0700210 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -0700211 grpc_test_init(argc, argv);
Nicolas "Pixel" Nobleb9012fc2016-03-14 23:19:04 +0100212 grpc_init();
Craig Tiller3ab2fe02016-04-11 20:11:18 -0700213 g_pollset = gpr_malloc(grpc_pollset_size());
214 grpc_pollset_init(g_pollset, &g_mu);
Robbie Shade4b70e032015-07-10 15:44:33 -0400215
Craig Tillera82950e2015-09-22 12:33:20 -0700216 test_no_op();
217 test_no_op_with_start();
218 test_no_op_with_port();
219 test_no_op_with_port_and_start();
220 test_receive(1);
221 test_receive(10);
Robbie Shade4b70e032015-07-10 15:44:33 -0400222
Craig Tiller3ab2fe02016-04-11 20:11:18 -0700223 grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
224 grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
Craig Tillera82950e2015-09-22 12:33:20 -0700225 grpc_exec_ctx_finish(&exec_ctx);
Craig Tiller3ab2fe02016-04-11 20:11:18 -0700226 gpr_free(g_pollset);
Craig Tillera82950e2015-09-22 12:33:20 -0700227 grpc_iomgr_shutdown();
Robbie Shade4b70e032015-07-10 15:44:33 -0400228 return 0;
229}