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 #include <stdio.h> 25 #include <stdlib.h> 26 27 28 static int close_cb_called = 0; 29 30 31 static void close_cb(uv_handle_t* handle) { 32 ASSERT_NOT_NULL(handle); 33 close_cb_called++; 34 } 35 36 37 TEST_IMPL(tcp_bind6_error_addrinuse) { 38 struct sockaddr_in6 addr; 39 uv_tcp_t server1, server2; 40 int r; 41 42 if (!can_ipv6()) 43 RETURN_SKIP("IPv6 not supported"); 44 45 ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); 46 47 r = uv_tcp_init(uv_default_loop(), &server1); 48 ASSERT(r == 0); 49 r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0); 50 ASSERT(r == 0); 51 52 r = uv_tcp_init(uv_default_loop(), &server2); 53 ASSERT(r == 0); 54 r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0); 55 ASSERT(r == 0); 56 57 r = uv_listen((uv_stream_t*)&server1, 128, NULL); 58 ASSERT(r == 0); 59 r = uv_listen((uv_stream_t*)&server2, 128, NULL); 60 ASSERT(r == UV_EADDRINUSE); 61 62 uv_close((uv_handle_t*)&server1, close_cb); 63 uv_close((uv_handle_t*)&server2, close_cb); 64 65 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 66 67 ASSERT(close_cb_called == 2); 68 69 MAKE_VALGRIND_HAPPY(); 70 return 0; 71 } 72 73 74 TEST_IMPL(tcp_bind6_error_addrnotavail) { 75 struct sockaddr_in6 addr; 76 uv_tcp_t server; 77 int r; 78 79 if (!can_ipv6()) 80 RETURN_SKIP("IPv6 not supported"); 81 82 ASSERT(0 == uv_ip6_addr("4:4:4:4:4:4:4:4", TEST_PORT, &addr)); 83 84 r = uv_tcp_init(uv_default_loop(), &server); 85 ASSERT(r == 0); 86 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); 87 ASSERT(r == UV_EADDRNOTAVAIL); 88 89 uv_close((uv_handle_t*)&server, close_cb); 90 91 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 92 93 ASSERT(close_cb_called == 1); 94 95 MAKE_VALGRIND_HAPPY(); 96 return 0; 97 } 98 99 100 TEST_IMPL(tcp_bind6_error_fault) { 101 char garbage[] = 102 "blah blah blah blah blah blah blah blah blah blah blah blah"; 103 struct sockaddr_in6* garbage_addr; 104 uv_tcp_t server; 105 int r; 106 107 if (!can_ipv6()) 108 RETURN_SKIP("IPv6 not supported"); 109 110 garbage_addr = (struct sockaddr_in6*) &garbage; 111 112 r = uv_tcp_init(uv_default_loop(), &server); 113 ASSERT(r == 0); 114 r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0); 115 ASSERT(r == UV_EINVAL); 116 117 uv_close((uv_handle_t*)&server, close_cb); 118 119 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 120 121 ASSERT(close_cb_called == 1); 122 123 MAKE_VALGRIND_HAPPY(); 124 return 0; 125 } 126 127 /* Notes: On Linux uv_bind6(server, NULL) will segfault the program. */ 128 129 TEST_IMPL(tcp_bind6_error_inval) { 130 struct sockaddr_in6 addr1; 131 struct sockaddr_in6 addr2; 132 uv_tcp_t server; 133 int r; 134 135 if (!can_ipv6()) 136 RETURN_SKIP("IPv6 not supported"); 137 138 ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr1)); 139 ASSERT(0 == uv_ip6_addr("::", TEST_PORT_2, &addr2)); 140 141 r = uv_tcp_init(uv_default_loop(), &server); 142 ASSERT(r == 0); 143 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0); 144 ASSERT(r == 0); 145 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0); 146 ASSERT(r == UV_EINVAL); 147 148 uv_close((uv_handle_t*)&server, close_cb); 149 150 uv_run(uv_default_loop(), UV_RUN_DEFAULT); 151 152 ASSERT(close_cb_called == 1); 153 154 MAKE_VALGRIND_HAPPY(); 155 return 0; 156 } 157 158 159 TEST_IMPL(tcp_bind6_localhost_ok) { 160 struct sockaddr_in6 addr; 161 uv_tcp_t server; 162 int r; 163 164 if (!can_ipv6()) 165 RETURN_SKIP("IPv6 not supported"); 166 167 ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr)); 168 169 r = uv_tcp_init(uv_default_loop(), &server); 170 ASSERT(r == 0); 171 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); 172 ASSERT(r == 0); 173 174 MAKE_VALGRIND_HAPPY(); 175 return 0; 176 } 177