|
160
|
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_OK(uv_ip6_addr("::", TEST_PORT, &addr));
|
|
|
46
|
|
|
47 r = uv_tcp_init(uv_default_loop(), &server1);
|
|
|
48 ASSERT_OK(r);
|
|
|
49 r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
|
|
|
50 ASSERT_OK(r);
|
|
|
51
|
|
|
52 r = uv_tcp_init(uv_default_loop(), &server2);
|
|
|
53 ASSERT_OK(r);
|
|
|
54 r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
|
|
|
55 ASSERT_OK(r);
|
|
|
56
|
|
|
57 r = uv_listen((uv_stream_t*)&server1, 128, NULL);
|
|
|
58 ASSERT_OK(r);
|
|
|
59 r = uv_listen((uv_stream_t*)&server2, 128, NULL);
|
|
|
60 ASSERT_EQ(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_EQ(2, close_cb_called);
|
|
|
68
|
|
|
69 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
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_OK(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_OK(r);
|
|
|
86 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
|
|
|
87 ASSERT_EQ(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_EQ(1, close_cb_called);
|
|
|
94
|
|
|
95 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
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_OK(r);
|
|
|
114 r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
|
|
|
115 ASSERT_EQ(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_EQ(1, close_cb_called);
|
|
|
122
|
|
|
123 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
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_OK(uv_ip6_addr("::", TEST_PORT, &addr1));
|
|
|
139 ASSERT_OK(uv_ip6_addr("::", TEST_PORT_2, &addr2));
|
|
|
140
|
|
|
141 r = uv_tcp_init(uv_default_loop(), &server);
|
|
|
142 ASSERT_OK(r);
|
|
|
143 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
|
|
|
144 ASSERT_OK(r);
|
|
|
145 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
|
|
|
146 ASSERT_EQ(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_EQ(1, close_cb_called);
|
|
|
153
|
|
|
154 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
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_OK(uv_ip6_addr("::1", TEST_PORT, &addr));
|
|
|
168
|
|
|
169 r = uv_tcp_init(uv_default_loop(), &server);
|
|
|
170 ASSERT_OK(r);
|
|
|
171 r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
|
|
|
172 ASSERT_OK(r);
|
|
|
173
|
|
|
174 MAKE_VALGRIND_HAPPY(uv_default_loop());
|
|
|
175 return 0;
|
|
|
176 }
|