test-tcp-bind-error.c revision 1.1 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 christos ASSERT(handle != NULL);
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_bind_error_addrinuse) {
38 1.1 christos struct sockaddr_in addr;
39 1.1 christos uv_tcp_t server1, server2;
40 1.1 christos int r;
41 1.1 christos
42 1.1 christos ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
43 1.1 christos r = uv_tcp_init(uv_default_loop(), &server1);
44 1.1 christos ASSERT(r == 0);
45 1.1 christos r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
46 1.1 christos ASSERT(r == 0);
47 1.1 christos
48 1.1 christos r = uv_tcp_init(uv_default_loop(), &server2);
49 1.1 christos ASSERT(r == 0);
50 1.1 christos r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
51 1.1 christos ASSERT(r == 0);
52 1.1 christos
53 1.1 christos r = uv_listen((uv_stream_t*)&server1, 128, NULL);
54 1.1 christos ASSERT(r == 0);
55 1.1 christos r = uv_listen((uv_stream_t*)&server2, 128, NULL);
56 1.1 christos ASSERT(r == UV_EADDRINUSE);
57 1.1 christos
58 1.1 christos uv_close((uv_handle_t*)&server1, close_cb);
59 1.1 christos uv_close((uv_handle_t*)&server2, close_cb);
60 1.1 christos
61 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT);
62 1.1 christos
63 1.1 christos ASSERT(close_cb_called == 2);
64 1.1 christos
65 1.1 christos MAKE_VALGRIND_HAPPY();
66 1.1 christos return 0;
67 1.1 christos }
68 1.1 christos
69 1.1 christos
70 1.1 christos TEST_IMPL(tcp_bind_error_addrnotavail_1) {
71 1.1 christos struct sockaddr_in addr;
72 1.1 christos uv_tcp_t server;
73 1.1 christos int r;
74 1.1 christos
75 1.1 christos ASSERT(0 == uv_ip4_addr("127.255.255.255", TEST_PORT, &addr));
76 1.1 christos
77 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
78 1.1 christos ASSERT(r == 0);
79 1.1 christos
80 1.1 christos /* It seems that Linux is broken here - bind succeeds. */
81 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
82 1.1 christos ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);
83 1.1 christos
84 1.1 christos uv_close((uv_handle_t*)&server, close_cb);
85 1.1 christos
86 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT);
87 1.1 christos
88 1.1 christos ASSERT(close_cb_called == 1);
89 1.1 christos
90 1.1 christos MAKE_VALGRIND_HAPPY();
91 1.1 christos return 0;
92 1.1 christos }
93 1.1 christos
94 1.1 christos
95 1.1 christos TEST_IMPL(tcp_bind_error_addrnotavail_2) {
96 1.1 christos struct sockaddr_in addr;
97 1.1 christos uv_tcp_t server;
98 1.1 christos int r;
99 1.1 christos
100 1.1 christos ASSERT(0 == uv_ip4_addr("4.4.4.4", TEST_PORT, &addr));
101 1.1 christos
102 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
103 1.1 christos ASSERT(r == 0);
104 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
105 1.1 christos ASSERT(r == UV_EADDRNOTAVAIL);
106 1.1 christos
107 1.1 christos uv_close((uv_handle_t*)&server, close_cb);
108 1.1 christos
109 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT);
110 1.1 christos
111 1.1 christos ASSERT(close_cb_called == 1);
112 1.1 christos
113 1.1 christos MAKE_VALGRIND_HAPPY();
114 1.1 christos return 0;
115 1.1 christos }
116 1.1 christos
117 1.1 christos
118 1.1 christos TEST_IMPL(tcp_bind_error_fault) {
119 1.1 christos char garbage[] =
120 1.1 christos "blah blah blah blah blah blah blah blah blah blah blah blah";
121 1.1 christos struct sockaddr_in* garbage_addr;
122 1.1 christos uv_tcp_t server;
123 1.1 christos int r;
124 1.1 christos
125 1.1 christos garbage_addr = (struct sockaddr_in*) &garbage;
126 1.1 christos
127 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
128 1.1 christos ASSERT(r == 0);
129 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
130 1.1 christos ASSERT(r == UV_EINVAL);
131 1.1 christos
132 1.1 christos uv_close((uv_handle_t*)&server, close_cb);
133 1.1 christos
134 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT);
135 1.1 christos
136 1.1 christos ASSERT(close_cb_called == 1);
137 1.1 christos
138 1.1 christos MAKE_VALGRIND_HAPPY();
139 1.1 christos return 0;
140 1.1 christos }
141 1.1 christos
142 1.1 christos /* Notes: On Linux uv_bind(server, NULL) will segfault the program. */
143 1.1 christos
144 1.1 christos TEST_IMPL(tcp_bind_error_inval) {
145 1.1 christos struct sockaddr_in addr1;
146 1.1 christos struct sockaddr_in addr2;
147 1.1 christos uv_tcp_t server;
148 1.1 christos int r;
149 1.1 christos
150 1.1 christos ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1));
151 1.1 christos ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2));
152 1.1 christos
153 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
154 1.1 christos ASSERT(r == 0);
155 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
156 1.1 christos ASSERT(r == 0);
157 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
158 1.1 christos ASSERT(r == UV_EINVAL);
159 1.1 christos
160 1.1 christos uv_close((uv_handle_t*)&server, close_cb);
161 1.1 christos
162 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT);
163 1.1 christos
164 1.1 christos ASSERT(close_cb_called == 1);
165 1.1 christos
166 1.1 christos MAKE_VALGRIND_HAPPY();
167 1.1 christos return 0;
168 1.1 christos }
169 1.1 christos
170 1.1 christos
171 1.1 christos TEST_IMPL(tcp_bind_localhost_ok) {
172 1.1 christos struct sockaddr_in addr;
173 1.1 christos uv_tcp_t server;
174 1.1 christos int r;
175 1.1 christos
176 1.1 christos ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
177 1.1 christos
178 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
179 1.1 christos ASSERT(r == 0);
180 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
181 1.1 christos ASSERT(r == 0);
182 1.1 christos
183 1.1 christos MAKE_VALGRIND_HAPPY();
184 1.1 christos return 0;
185 1.1 christos }
186 1.1 christos
187 1.1 christos
188 1.1 christos TEST_IMPL(tcp_bind_invalid_flags) {
189 1.1 christos struct sockaddr_in addr;
190 1.1 christos uv_tcp_t server;
191 1.1 christos int r;
192 1.1 christos
193 1.1 christos ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
194 1.1 christos
195 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
196 1.1 christos ASSERT(r == 0);
197 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY);
198 1.1 christos ASSERT(r == UV_EINVAL);
199 1.1 christos
200 1.1 christos MAKE_VALGRIND_HAPPY();
201 1.1 christos return 0;
202 1.1 christos }
203 1.1 christos
204 1.1 christos
205 1.1 christos TEST_IMPL(tcp_listen_without_bind) {
206 1.1 christos int r;
207 1.1 christos uv_tcp_t server;
208 1.1 christos
209 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
210 1.1 christos ASSERT(r == 0);
211 1.1 christos r = uv_listen((uv_stream_t*)&server, 128, NULL);
212 1.1 christos ASSERT(r == 0);
213 1.1 christos
214 1.1 christos MAKE_VALGRIND_HAPPY();
215 1.1 christos return 0;
216 1.1 christos }
217 1.1 christos
218 1.1 christos
219 1.1 christos TEST_IMPL(tcp_bind_writable_flags) {
220 1.1 christos struct sockaddr_in addr;
221 1.1 christos uv_tcp_t server;
222 1.1 christos uv_buf_t buf;
223 1.1 christos uv_write_t write_req;
224 1.1 christos uv_shutdown_t shutdown_req;
225 1.1 christos int r;
226 1.1 christos
227 1.1 christos ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
228 1.1 christos r = uv_tcp_init(uv_default_loop(), &server);
229 1.1 christos ASSERT(r == 0);
230 1.1 christos r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
231 1.1 christos ASSERT(r == 0);
232 1.1 christos r = uv_listen((uv_stream_t*)&server, 128, NULL);
233 1.1 christos ASSERT(r == 0);
234 1.1 christos
235 1.1 christos ASSERT(0 == uv_is_writable((uv_stream_t*) &server));
236 1.1 christos ASSERT(0 == uv_is_readable((uv_stream_t*) &server));
237 1.1 christos
238 1.1 christos buf = uv_buf_init("PING", 4);
239 1.1 christos r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
240 1.1 christos ASSERT(r == UV_EPIPE);
241 1.1 christos r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
242 1.1 christos ASSERT(r == UV_ENOTCONN);
243 1.1 christos r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
244 1.1 christos ASSERT(r == UV_ENOTCONN);
245 1.1 christos
246 1.1 christos uv_close((uv_handle_t*)&server, close_cb);
247 1.1 christos
248 1.1 christos uv_run(uv_default_loop(), UV_RUN_DEFAULT);
249 1.1 christos
250 1.1 christos ASSERT(close_cb_called == 1);
251 1.1 christos
252 1.1 christos MAKE_VALGRIND_HAPPY();
253 1.1 christos return 0;
254 1.1 christos }
255