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 30static int udp_options_test(const struct sockaddr* addr) { 31 static int invalid_ttls[] = { -1, 0, 256 }; 32 uv_loop_t* loop; 33 uv_udp_t h; 34 int i, r; 35 36 loop = uv_default_loop(); 37 38 r = uv_udp_init(loop, &h); 39 ASSERT(r == 0); 40 41 uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */ 42 43 r = uv_udp_bind(&h, addr, 0); 44 ASSERT(r == 0); 45 46 r = uv_udp_set_broadcast(&h, 1); 47 r |= uv_udp_set_broadcast(&h, 1); 48 r |= uv_udp_set_broadcast(&h, 0); 49 r |= uv_udp_set_broadcast(&h, 0); 50 ASSERT(r == 0); 51 52 /* values 1-255 should work */ 53 for (i = 1; i <= 255; i++) { 54 r = uv_udp_set_ttl(&h, i); 55#if defined(__MVS__) 56 if (addr->sa_family == AF_INET6) 57 ASSERT(r == 0); 58 else 59 ASSERT(r == UV_ENOTSUP); 60#else 61 ASSERT(r == 0); 62#endif 63 } 64 65 for (i = 0; i < (int) ARRAY_SIZE(invalid_ttls); i++) { 66 r = uv_udp_set_ttl(&h, invalid_ttls[i]); 67 ASSERT(r == UV_EINVAL); 68 } 69 70 r = uv_udp_set_multicast_loop(&h, 1); 71 r |= uv_udp_set_multicast_loop(&h, 1); 72 r |= uv_udp_set_multicast_loop(&h, 0); 73 r |= uv_udp_set_multicast_loop(&h, 0); 74 ASSERT(r == 0); 75 76 /* values 0-255 should work */ 77 for (i = 0; i <= 255; i++) { 78 r = uv_udp_set_multicast_ttl(&h, i); 79 ASSERT(r == 0); 80 } 81 82 /* anything >255 should fail */ 83 r = uv_udp_set_multicast_ttl(&h, 256); 84 ASSERT(r == UV_EINVAL); 85 /* don't test ttl=-1, it's a valid value on some platforms */ 86 87 r = uv_run(loop, UV_RUN_DEFAULT); 88 ASSERT(r == 0); 89 90 MAKE_VALGRIND_HAPPY(); 91 return 0; 92} 93 94 95TEST_IMPL(udp_options) { 96 struct sockaddr_in addr; 97 98 ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); 99 return udp_options_test((const struct sockaddr*) &addr); 100} 101 102 103TEST_IMPL(udp_options6) { 104 struct sockaddr_in6 addr; 105 106 if (!can_ipv6()) 107 RETURN_SKIP("IPv6 not supported"); 108 109 ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); 110 return udp_options_test((const struct sockaddr*) &addr); 111} 112 113 114TEST_IMPL(udp_no_autobind) { 115 uv_loop_t* loop; 116 uv_udp_t h; 117 uv_udp_t h2; 118 119 loop = uv_default_loop(); 120 121 /* Test a lazy initialized socket. */ 122 ASSERT(0 == uv_udp_init(loop, &h)); 123 ASSERT(UV_EBADF == uv_udp_set_multicast_ttl(&h, 32)); 124 ASSERT(UV_EBADF == uv_udp_set_broadcast(&h, 1)); 125#if defined(__MVS__) 126 ASSERT(UV_ENOTSUP == uv_udp_set_ttl(&h, 1)); 127#else 128 ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1)); 129#endif 130 ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1)); 131/* TODO(gengjiawen): Fix test on QEMU. */ 132#if defined(__QEMU__) 133 RETURN_SKIP("Test does not currently work in QEMU"); 134#endif 135 ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0")); 136 137 uv_close((uv_handle_t*) &h, NULL); 138 139 /* Test a non-lazily initialized socket. */ 140 ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET | UV_UDP_RECVMMSG)); 141 ASSERT(0 == uv_udp_set_multicast_ttl(&h2, 32)); 142 ASSERT(0 == uv_udp_set_broadcast(&h2, 1)); 143 144#if defined(__MVS__) 145 /* zOS only supports setting ttl for IPv6 sockets. */ 146 ASSERT(UV_ENOTSUP == uv_udp_set_ttl(&h2, 1)); 147#else 148 ASSERT(0 == uv_udp_set_ttl(&h2, 1)); 149#endif 150 151 ASSERT(0 == uv_udp_set_multicast_loop(&h2, 1)); 152 ASSERT(0 == uv_udp_set_multicast_interface(&h2, "0.0.0.0")); 153 154 uv_close((uv_handle_t*) &h2, NULL); 155 156 ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); 157 158 MAKE_VALGRIND_HAPPY(); 159 return 0; 160} 161