1 1.1 christos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 1.1 christos * 3 1.1 christos * Permission is hereby granted, free of charge, to any person obtaining a copy 4 1.1 christos * of this software and associated documentation files (the "Software"), to 5 1.1 christos * deal in the Software without restriction, including without limitation the 6 1.1 christos * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 1.1 christos * sell copies of the Software, and to permit persons to whom the Software is 8 1.1 christos * furnished to do so, subject to the following conditions: 9 1.1 christos * 10 1.1 christos * The above copyright notice and this permission notice shall be included in 11 1.1 christos * all copies or substantial portions of the Software. 12 1.1 christos * 13 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 1.1 christos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 1.1 christos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 1.1 christos * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 1.1 christos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 1.1 christos * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 1.1 christos * IN THE SOFTWARE. 20 1.1 christos */ 21 1.1 christos 22 1.1 christos #include "uv.h" 23 1.1 christos #include "task.h" 24 1.1 christos #include <stdio.h> 25 1.1 christos #include <stdlib.h> 26 1.1 christos 27 1.1 christos 28 1.1 christos static int close_cb_called = 0; 29 1.1 christos 30 1.1 christos 31 1.1 christos static void close_cb(uv_handle_t* handle) { 32 1.1.1.2 christos ASSERT_NOT_NULL(handle); 33 1.1 christos close_cb_called++; 34 1.1 christos } 35 1.1 christos 36 1.1 christos 37 1.1 christos TEST_IMPL(tcp_bind6_error_addrinuse) { 38 1.1 christos struct sockaddr_in6 addr; 39 1.1 christos uv_tcp_t server1, server2; 40 1.1 christos int r; 41 1.1 christos 42 1.1 christos if (!can_ipv6()) 43 1.1 christos RETURN_SKIP("IPv6 not supported"); 44 1.1 christos 45 1.1.1.3 christos ASSERT_OK(uv_ip6_addr("::", TEST_PORT, &addr)); 46 1.1 christos 47 1.1 christos r = uv_tcp_init(uv_default_loop(), &server1); 48 1.1.1.3 christos ASSERT_OK(r); 49 1.1 christos r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0); 50 1.1.1.3 christos ASSERT_OK(r); 51 1.1 christos 52 1.1 christos r = uv_tcp_init(uv_default_loop(), &server2); 53 1.1.1.3 christos ASSERT_OK(r); 54 1.1 christos r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0); 55 1.1.1.3 christos ASSERT_OK(r); 56 1.1 christos 57 1.1 christos r = uv_listen((uv_stream_t*)&server1, 128, NULL); 58 1.1.1.3 christos ASSERT_OK(r); 59 1.1 christos r = uv_listen((uv_stream_t*)&server2, 128, NULL); 60 1.1.1.3 christos ASSERT_EQ(r, UV_EADDRINUSE); 61 1.1 christos 62 1.1 christos uv_close((uv_handle_t*)&server1, close_cb); 63 1.1 christos uv_close((uv_handle_t*)&server2, close_cb); 64 1.1 christos 65 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT); 66 1.1 christos 67 1.1.1.3 christos ASSERT_EQ(2, close_cb_called); 68 1.1 christos 69 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 70 1.1 christos return 0; 71 1.1 christos } 72 1.1 christos 73 1.1 christos 74 1.1 christos TEST_IMPL(tcp_bind6_error_addrnotavail) { 75 1.1 christos struct sockaddr_in6 addr; 76 1.1 christos uv_tcp_t server; 77 1.1 christos int r; 78 1.1 christos 79 1.1 christos if (!can_ipv6()) 80 1.1 christos RETURN_SKIP("IPv6 not supported"); 81 1.1 christos 82 1.1.1.3 christos ASSERT_OK(uv_ip6_addr("4:4:4:4:4:4:4:4", TEST_PORT, &addr)); 83 1.1 christos 84 1.1 christos r = uv_tcp_init(uv_default_loop(), &server); 85 1.1.1.3 christos ASSERT_OK(r); 86 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); 87 1.1.1.3 christos ASSERT_EQ(r, UV_EADDRNOTAVAIL); 88 1.1 christos 89 1.1 christos uv_close((uv_handle_t*)&server, close_cb); 90 1.1 christos 91 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT); 92 1.1 christos 93 1.1.1.3 christos ASSERT_EQ(1, close_cb_called); 94 1.1 christos 95 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 96 1.1 christos return 0; 97 1.1 christos } 98 1.1 christos 99 1.1 christos 100 1.1 christos TEST_IMPL(tcp_bind6_error_fault) { 101 1.1 christos char garbage[] = 102 1.1 christos "blah blah blah blah blah blah blah blah blah blah blah blah"; 103 1.1 christos struct sockaddr_in6* garbage_addr; 104 1.1 christos uv_tcp_t server; 105 1.1 christos int r; 106 1.1 christos 107 1.1 christos if (!can_ipv6()) 108 1.1 christos RETURN_SKIP("IPv6 not supported"); 109 1.1 christos 110 1.1 christos garbage_addr = (struct sockaddr_in6*) &garbage; 111 1.1 christos 112 1.1 christos r = uv_tcp_init(uv_default_loop(), &server); 113 1.1.1.3 christos ASSERT_OK(r); 114 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0); 115 1.1.1.3 christos ASSERT_EQ(r, UV_EINVAL); 116 1.1 christos 117 1.1 christos uv_close((uv_handle_t*)&server, close_cb); 118 1.1 christos 119 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT); 120 1.1 christos 121 1.1.1.3 christos ASSERT_EQ(1, close_cb_called); 122 1.1 christos 123 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 124 1.1 christos return 0; 125 1.1 christos } 126 1.1 christos 127 1.1 christos /* Notes: On Linux uv_bind6(server, NULL) will segfault the program. */ 128 1.1 christos 129 1.1 christos TEST_IMPL(tcp_bind6_error_inval) { 130 1.1 christos struct sockaddr_in6 addr1; 131 1.1 christos struct sockaddr_in6 addr2; 132 1.1 christos uv_tcp_t server; 133 1.1 christos int r; 134 1.1 christos 135 1.1 christos if (!can_ipv6()) 136 1.1 christos RETURN_SKIP("IPv6 not supported"); 137 1.1 christos 138 1.1.1.3 christos ASSERT_OK(uv_ip6_addr("::", TEST_PORT, &addr1)); 139 1.1.1.3 christos ASSERT_OK(uv_ip6_addr("::", TEST_PORT_2, &addr2)); 140 1.1 christos 141 1.1 christos r = uv_tcp_init(uv_default_loop(), &server); 142 1.1.1.3 christos ASSERT_OK(r); 143 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0); 144 1.1.1.3 christos ASSERT_OK(r); 145 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0); 146 1.1.1.3 christos ASSERT_EQ(r, UV_EINVAL); 147 1.1 christos 148 1.1 christos uv_close((uv_handle_t*)&server, close_cb); 149 1.1 christos 150 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT); 151 1.1 christos 152 1.1.1.3 christos ASSERT_EQ(1, close_cb_called); 153 1.1 christos 154 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 155 1.1 christos return 0; 156 1.1 christos } 157 1.1 christos 158 1.1 christos 159 1.1 christos TEST_IMPL(tcp_bind6_localhost_ok) { 160 1.1 christos struct sockaddr_in6 addr; 161 1.1 christos uv_tcp_t server; 162 1.1 christos int r; 163 1.1 christos 164 1.1 christos if (!can_ipv6()) 165 1.1 christos RETURN_SKIP("IPv6 not supported"); 166 1.1 christos 167 1.1.1.3 christos ASSERT_OK(uv_ip6_addr("::1", TEST_PORT, &addr)); 168 1.1 christos 169 1.1 christos r = uv_tcp_init(uv_default_loop(), &server); 170 1.1.1.3 christos ASSERT_OK(r); 171 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); 172 1.1.1.3 christos ASSERT_OK(r); 173 1.1 christos 174 1.1.1.3 christos MAKE_VALGRIND_HAPPY(uv_default_loop()); 175 1.1 christos return 0; 176 1.1 christos } 177