test-udp-ipv6.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "uv.h"
23 #include "task.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
30 #include <sys/sysctl.h>
31 #endif
32 
33 #define CHECK_HANDLE(handle) \
34  ASSERT((uv_udp_t*)(handle) == &server \
35  || (uv_udp_t*)(handle) == &client \
36  || (uv_timer_t*)(handle) == &timeout)
37 
38 #define CHECK_REQ(req) \
39  ASSERT((req) == &req_);
40 
44 static char data[10];
46 
47 static int send_cb_called;
48 static int recv_cb_called;
49 static int close_cb_called;
51 
52 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
53 static int can_ipv6_ipv4_dual(void) {
54  int v6only;
55  size_t size = sizeof(int);
56 
57  if (sysctlbyname("net.inet6.ip6.v6only", &v6only, &size, NULL, 0))
58  return 0;
59 
60  return v6only != 1;
61 }
62 #endif
63 
64 
66  size_t suggested_size,
67  uv_buf_t* buf) {
68  static char slab[65536];
70  buf->base = slab;
71  buf->len = sizeof(slab);
72 }
73 
74 
75 static void close_cb(uv_handle_t* handle) {
78 }
79 
80 
81 static void send_cb(uv_udp_send_t* req, int status) {
82  CHECK_REQ(req);
84  ASSERT(status == 0);
86 }
87 
88 static int is_from_client(const struct sockaddr* addr) {
89  const struct sockaddr_in6* addr6;
90  char dst[256];
91  int r;
92 
93  /* Debugging output, and filter out unwanted network traffic */
94  if (addr != NULL) {
95  ASSERT(addr->sa_family == AF_INET6);
96  addr6 = (struct sockaddr_in6*) addr;
97  r = uv_inet_ntop(addr->sa_family, &addr6->sin6_addr, dst, sizeof(dst));
98  if (r == 0)
99  printf("from [%.*s]:%d\n", (int) sizeof(dst), dst, addr6->sin6_port);
100  if (addr6->sin6_port != client_port)
101  return 0;
102  if (r != 0 || strcmp(dst, "::ffff:127.0.0.1"))
103  return 0;
104  }
105  return 1;
106 }
107 
108 
110  ssize_t nread,
111  const uv_buf_t* buf,
112  const struct sockaddr* addr,
113  unsigned flags) {
114  printf("got %d %.*s\n", (int) nread, nread > 0 ? (int) nread : 0, buf->base);
115  if (!is_from_client(addr) || (nread == 0 && addr == NULL))
116  return;
117  ASSERT(0 && "this function should not have been called");
118 }
119 
120 
122  ssize_t nread,
123  const uv_buf_t* buf,
124  const struct sockaddr* addr,
125  unsigned flags) {
127 
128  printf("got %d %.*s\n", (int) nread, nread > 0 ? (int) nread : 0, buf->base);
129  if (!is_from_client(addr) || (nread == 0 && addr == NULL))
130  return;
131 
132  ASSERT(nread == 9);
133  ASSERT(!memcmp(buf->base, data, 9));
134  recv_cb_called++;
135 }
136 
137 
138 static void timeout_cb(uv_timer_t* timer) {
142 }
143 
144 
145 static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) {
146  struct sockaddr_in6 addr6;
147  struct sockaddr_in addr;
148  int addr6_len;
149  int addr_len;
150  uv_buf_t buf;
151  char dst[256];
152  int r;
153 
154  ASSERT(0 == uv_ip6_addr("::0", TEST_PORT, &addr6));
155 
157  ASSERT(r == 0);
158 
159  r = uv_udp_bind(&server, (const struct sockaddr*) &addr6, bind_flags);
160  ASSERT(r == 0);
161 
162  addr6_len = sizeof(addr6);
163  ASSERT(uv_udp_getsockname(&server, (struct sockaddr*) &addr6, &addr6_len) == 0);
165  printf("on [%.*s]:%d\n", (int) sizeof(dst), dst, addr6.sin6_port);
166 
168  ASSERT(r == 0);
169 
171  ASSERT(r == 0);
172 
173  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
174  ASSERT(uv_inet_ntop(addr.sin_family, &addr.sin_addr, dst, sizeof(dst)) == 0);
175  printf("to [%.*s]:%d\n", (int) sizeof(dst), dst, addr.sin_port);
176 
177  /* Create some unique data to send */
178  ASSERT(9 == snprintf(data, sizeof(data), "PING%5u", uv_os_getpid() & 0xFFFF));
179  buf = uv_buf_init(data, 9);
180  printf("sending %s\n", data);
181 
182  r = uv_udp_send(&req_,
183  &client,
184  &buf,
185  1,
186  (const struct sockaddr*) &addr,
187  send_cb);
188  ASSERT(r == 0);
189 
190  addr_len = sizeof(addr);
191  ASSERT(uv_udp_getsockname(&client, (struct sockaddr*) &addr, &addr_len) == 0);
192  ASSERT(uv_inet_ntop(addr.sin_family, &addr.sin_addr, dst, sizeof(dst)) == 0);
193  printf("from [%.*s]:%d\n", (int) sizeof(dst), dst, addr.sin_port);
194  client_port = addr.sin_port;
195 
197  ASSERT(r == 0);
198 
199  r = uv_timer_start(&timeout, timeout_cb, 500, 0);
200  ASSERT(r == 0);
201 
202  ASSERT(close_cb_called == 0);
203  ASSERT(send_cb_called == 0);
204  ASSERT(recv_cb_called == 0);
205 
207 
208  ASSERT(close_cb_called == 3);
209 
211 }
212 
213 
214 TEST_IMPL(udp_dual_stack) {
215 #if defined(__CYGWIN__) || defined(__MSYS__)
216  /* FIXME: Does Cygwin support this? */
217  RETURN_SKIP("FIXME: This test needs more investigation on Cygwin");
218 #endif
219 
220  if (!can_ipv6())
221  RETURN_SKIP("IPv6 not supported");
222 
223 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
224  if (!can_ipv6_ipv4_dual())
225  RETURN_SKIP("IPv6-IPv4 dual stack not supported");
226 #elif defined(__OpenBSD__)
227  RETURN_SKIP("IPv6-IPv4 dual stack not supported");
228 #endif
229 
230  do_test(ipv6_recv_ok, 0);
231 
232  printf("recv_cb_called %d\n", recv_cb_called);
233  printf("send_cb_called %d\n", send_cb_called);
234  ASSERT(recv_cb_called == 1);
235  ASSERT(send_cb_called == 1);
236 
237  return 0;
238 }
239 
240 
241 TEST_IMPL(udp_ipv6_only) {
242  if (!can_ipv6())
243  RETURN_SKIP("IPv6 not supported");
244 
246 
247  ASSERT(recv_cb_called == 0);
248  ASSERT(send_cb_called == 1);
249 
250  return 0;
251 }
timeout_cb
static void timeout_cb(uv_timer_t *timer)
Definition: test-udp-ipv6.c:138
slab
static char slab[1]
Definition: test-watcher-cross-stop.c:37
uv_ip6_addr
UV_EXTERN int uv_ip6_addr(const char *ip, int port, struct sockaddr_in6 *addr)
Definition: uv-common.c:232
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
task.h
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
CHECK_HANDLE
#define CHECK_HANDLE(handle)
Definition: test-udp-ipv6.c:33
req_
static uv_udp_send_t req_
Definition: test-udp-ipv6.c:43
timeout
static uv_timer_t timeout
Definition: test-udp-ipv6.c:45
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
uv_os_getpid
UV_EXTERN uv_pid_t uv_os_getpid(void)
Definition: unix/core.c:1392
client
Definition: examples/python/async_streaming/client.py:1
data
static char data[10]
Definition: test-udp-ipv6.c:44
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
UV_UDP_IPV6ONLY
@ UV_UDP_IPV6ONLY
Definition: uv.h:594
uv_connect_s::handle
uv_stream_t * handle
Definition: uv.h:583
uv_udp_send
UV_EXTERN int uv_udp_send(uv_udp_send_t *req, uv_udp_t *handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr *addr, uv_udp_send_cb send_cb)
Definition: uv-common.c:408
ASSERT
#define ASSERT(expr)
Definition: task.h:102
status
absl::Status status
Definition: rls.cc:251
CHECK_REQ
#define CHECK_REQ(req)
Definition: test-udp-ipv6.c:38
uv_udp_getsockname
UV_EXTERN int uv_udp_getsockname(const uv_udp_t *handle, struct sockaddr *name, int *namelen)
Definition: unix/udp.c:1293
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
TEST_PORT
#define TEST_PORT
Definition: task.h:53
uv_close
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: unix/core.c:112
is_from_client
static int is_from_client(const struct sockaddr *addr)
Definition: test-udp-ipv6.c:88
uv_ip4_addr
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
Definition: uv-common.c:221
client
static uv_udp_t client
Definition: test-udp-ipv6.c:41
ipv6_recv_ok
static void ipv6_recv_ok(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
Definition: test-udp-ipv6.c:121
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
uv_udp_init
UV_EXTERN int uv_udp_init(uv_loop_t *, uv_udp_t *handle)
Definition: unix/udp.c:988
TEST_IMPL
TEST_IMPL(udp_dual_stack)
Definition: test-udp-ipv6.c:214
ssize_t
intptr_t ssize_t
Definition: win.h:27
xds_interop_client.int
int
Definition: xds_interop_client.py:113
sockaddr_in6
Definition: ares_ipv6.h:25
sockaddr_in6::sin6_port
unsigned short sin6_port
Definition: ares_ipv6.h:28
close_cb
static void close_cb(uv_handle_t *handle)
Definition: test-udp-ipv6.c:75
req
static uv_connect_t req
Definition: test-connection-fail.c:30
do_test
static void do_test(uv_udp_recv_cb recv_cb, int bind_flags)
Definition: test-udp-ipv6.c:145
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
uv_udp_s
Definition: uv.h:629
client_port
static uint16_t client_port
Definition: test-udp-ipv6.c:50
addr6
static struct sockaddr_in6 addr6
Definition: test-getnameinfo.c:34
sockaddr_in6::sin6_family
unsigned short sin6_family
Definition: ares_ipv6.h:27
recv_cb
static void recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
Definition: benchmark-udp-pummel.c:109
uv_udp_recv_cb
void(* uv_udp_recv_cb)(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
Definition: uv.h:622
uv_timer_s
Definition: uv.h:850
uv_udp_send_s
Definition: uv.h:645
uv.h
uv_udp_recv_start
UV_EXTERN int uv_udp_recv_start(uv_udp_t *handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
Definition: uv-common.c:438
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
uv_buf_t
Definition: unix.h:121
uv_udp_bind
UV_EXTERN int uv_udp_bind(uv_udp_t *handle, const struct sockaddr *addr, unsigned int flags)
Definition: uv-common.c:296
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
server
Definition: examples/python/async_streaming/server.py:1
recv_cb_called
static int recv_cb_called
Definition: test-udp-ipv6.c:48
fix_build_deps.r
r
Definition: fix_build_deps.py:491
uv_inet_ntop
UV_EXTERN int uv_inet_ntop(int af, const void *src, char *dst, size_t size)
Definition: inet.c:40
server
static uv_udp_t server
Definition: test-udp-ipv6.c:42
send_cb
static void send_cb(uv_udp_send_t *req, int status)
Definition: test-udp-ipv6.c:81
uv_buf_init
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157
can_ipv6
static UNUSED int can_ipv6(void)
Definition: task.h:315
sockaddr_in6::sin6_addr
struct ares_in6_addr sin6_addr
Definition: ares_ipv6.h:30
RETURN_SKIP
#define RETURN_SKIP(explanation)
Definition: task.h:262
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
uv_timer_start
UV_EXTERN int uv_timer_start(uv_timer_t *handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
Definition: timer.c:66
ipv6_recv_fail
static void ipv6_recv_fail(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags)
Definition: test-udp-ipv6.c:109
uv_timer_init
UV_EXTERN int uv_timer_init(uv_loop_t *, uv_timer_t *handle)
Definition: timer.c:58
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
alloc_cb
static void alloc_cb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
Definition: test-udp-ipv6.c:65
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
send_cb_called
static int send_cb_called
Definition: test-udp-ipv6.c:47
close_cb_called
static int close_cb_called
Definition: test-udp-ipv6.c:49
timer
static uv_timer_t timer
Definition: test-callback-stack.c:34


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:27