libuv-svace-build
317 строк · 8.4 Кб
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
28static int connect_cb_called = 0;29static int close_cb_called = 0;30
31
32static void close_cb(uv_handle_t* handle) {33ASSERT_NOT_NULL(handle);34close_cb_called++;35}
36
37
38static void connect_cb(uv_connect_t* req, int status) {39ASSERT_EQ(status, UV_EADDRINUSE);40uv_close((uv_handle_t*) req->handle, close_cb);41connect_cb_called++;42}
43
44
45TEST_IMPL(tcp_bind_error_addrinuse_connect) {46struct sockaddr_in addr;47int addrlen;48uv_connect_t req;49uv_tcp_t conn;50
51/* 127.0.0.1:<TEST_PORT> is already taken by tcp4_echo_server running in52* another process. uv_tcp_bind() and uv_tcp_connect() should still succeed
53* (greatest common denominator across platforms) but the connect callback
54* should receive an UV_EADDRINUSE error.
55*/
56ASSERT_OK(uv_tcp_init(uv_default_loop(), &conn));57ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));58ASSERT_OK(uv_tcp_bind(&conn, (const struct sockaddr*) &addr, 0));59
60ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT + 1, &addr));61ASSERT_OK(uv_tcp_connect(&req,62&conn,63(const struct sockaddr*) &addr,64connect_cb));65
66addrlen = sizeof(addr);67ASSERT_EQ(UV_EADDRINUSE, uv_tcp_getsockname(&conn,68(struct sockaddr*) &addr,69&addrlen));70
71ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));72ASSERT_EQ(1, connect_cb_called);73ASSERT_EQ(1, close_cb_called);74
75MAKE_VALGRIND_HAPPY(uv_default_loop());76return 0;77}
78
79
80TEST_IMPL(tcp_bind_error_addrinuse_listen) {81struct sockaddr_in addr;82uv_tcp_t server1, server2;83int r;84
85ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));86r = uv_tcp_init(uv_default_loop(), &server1);87ASSERT_OK(r);88r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);89ASSERT_OK(r);90
91r = uv_tcp_init(uv_default_loop(), &server2);92ASSERT_OK(r);93r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);94ASSERT_OK(r);95
96r = uv_listen((uv_stream_t*)&server1, 128, NULL);97ASSERT_OK(r);98r = uv_listen((uv_stream_t*)&server2, 128, NULL);99ASSERT_EQ(r, UV_EADDRINUSE);100
101uv_close((uv_handle_t*)&server1, close_cb);102uv_close((uv_handle_t*)&server2, close_cb);103
104uv_run(uv_default_loop(), UV_RUN_DEFAULT);105
106ASSERT_EQ(2, close_cb_called);107
108MAKE_VALGRIND_HAPPY(uv_default_loop());109return 0;110}
111
112
113TEST_IMPL(tcp_bind_error_addrnotavail_1) {114struct sockaddr_in addr;115uv_tcp_t server;116int r;117
118ASSERT_OK(uv_ip4_addr("127.255.255.255", TEST_PORT, &addr));119
120r = uv_tcp_init(uv_default_loop(), &server);121ASSERT_OK(r);122
123/* It seems that Linux is broken here - bind succeeds. */124r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);125ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);126
127uv_close((uv_handle_t*)&server, close_cb);128
129uv_run(uv_default_loop(), UV_RUN_DEFAULT);130
131ASSERT_EQ(1, close_cb_called);132
133MAKE_VALGRIND_HAPPY(uv_default_loop());134return 0;135}
136
137
138TEST_IMPL(tcp_bind_error_addrnotavail_2) {139struct sockaddr_in addr;140uv_tcp_t server;141int r;142
143ASSERT_OK(uv_ip4_addr("4.4.4.4", TEST_PORT, &addr));144
145r = uv_tcp_init(uv_default_loop(), &server);146ASSERT_OK(r);147r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);148ASSERT_EQ(r, UV_EADDRNOTAVAIL);149
150uv_close((uv_handle_t*)&server, close_cb);151
152uv_run(uv_default_loop(), UV_RUN_DEFAULT);153
154ASSERT_EQ(1, close_cb_called);155
156MAKE_VALGRIND_HAPPY(uv_default_loop());157return 0;158}
159
160
161TEST_IMPL(tcp_bind_error_fault) {162char garbage[] =163"blah blah blah blah blah blah blah blah blah blah blah blah";164struct sockaddr_in* garbage_addr;165uv_tcp_t server;166int r;167
168garbage_addr = (struct sockaddr_in*) &garbage;169
170r = uv_tcp_init(uv_default_loop(), &server);171ASSERT_OK(r);172r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);173ASSERT_EQ(r, UV_EINVAL);174
175uv_close((uv_handle_t*)&server, close_cb);176
177uv_run(uv_default_loop(), UV_RUN_DEFAULT);178
179ASSERT_EQ(1, close_cb_called);180
181MAKE_VALGRIND_HAPPY(uv_default_loop());182return 0;183}
184
185/* Notes: On Linux uv_bind(server, NULL) will segfault the program. */
186
187TEST_IMPL(tcp_bind_error_inval) {188struct sockaddr_in addr1;189struct sockaddr_in addr2;190uv_tcp_t server;191int r;192
193ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1));194ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2));195
196r = uv_tcp_init(uv_default_loop(), &server);197ASSERT_OK(r);198r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);199ASSERT_OK(r);200r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);201ASSERT_EQ(r, UV_EINVAL);202
203uv_close((uv_handle_t*)&server, close_cb);204
205uv_run(uv_default_loop(), UV_RUN_DEFAULT);206
207ASSERT_EQ(1, close_cb_called);208
209MAKE_VALGRIND_HAPPY(uv_default_loop());210return 0;211}
212
213
214TEST_IMPL(tcp_bind_localhost_ok) {215struct sockaddr_in addr;216uv_tcp_t server;217int r;218
219ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));220
221r = uv_tcp_init(uv_default_loop(), &server);222ASSERT_OK(r);223r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);224ASSERT_OK(r);225
226MAKE_VALGRIND_HAPPY(uv_default_loop());227return 0;228}
229
230
231TEST_IMPL(tcp_bind_invalid_flags) {232struct sockaddr_in addr;233uv_tcp_t server;234int r;235
236ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));237
238r = uv_tcp_init(uv_default_loop(), &server);239ASSERT_OK(r);240r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY);241ASSERT_EQ(r, UV_EINVAL);242
243MAKE_VALGRIND_HAPPY(uv_default_loop());244return 0;245}
246
247
248TEST_IMPL(tcp_listen_without_bind) {249int r;250uv_tcp_t server;251
252r = uv_tcp_init(uv_default_loop(), &server);253ASSERT_OK(r);254r = uv_listen((uv_stream_t*)&server, 128, NULL);255ASSERT_OK(r);256
257MAKE_VALGRIND_HAPPY(uv_default_loop());258return 0;259}
260
261
262TEST_IMPL(tcp_bind_writable_flags) {263struct sockaddr_in addr;264uv_tcp_t server;265uv_buf_t buf;266uv_write_t write_req;267uv_shutdown_t shutdown_req;268int r;269
270ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));271r = uv_tcp_init(uv_default_loop(), &server);272ASSERT_OK(r);273r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);274ASSERT_OK(r);275r = uv_listen((uv_stream_t*)&server, 128, NULL);276ASSERT_OK(r);277
278ASSERT_OK(uv_is_writable((uv_stream_t*) &server));279ASSERT_OK(uv_is_readable((uv_stream_t*) &server));280
281buf = uv_buf_init("PING", 4);282r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);283ASSERT_EQ(r, UV_EPIPE);284r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);285ASSERT_EQ(r, UV_ENOTCONN);286r = uv_read_start((uv_stream_t*) &server,287(uv_alloc_cb) abort,288(uv_read_cb) abort);289ASSERT_EQ(r, UV_ENOTCONN);290
291uv_close((uv_handle_t*)&server, close_cb);292
293uv_run(uv_default_loop(), UV_RUN_DEFAULT);294
295ASSERT_EQ(1, close_cb_called);296
297MAKE_VALGRIND_HAPPY(uv_default_loop());298return 0;299}
300
301TEST_IMPL(tcp_bind_or_listen_error_after_close) {302uv_tcp_t tcp;303struct sockaddr_in addr;304
305memset(&addr, 0, sizeof(addr));306addr.sin_addr.s_addr = htonl(INADDR_ANY);307addr.sin_port = htons(9999);308addr.sin_family = AF_INET;309
310ASSERT_OK(uv_tcp_init(uv_default_loop(), &tcp));311uv_close((uv_handle_t*) &tcp, NULL);312ASSERT_EQ(uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0), UV_EINVAL);313ASSERT_EQ(uv_listen((uv_stream_t*) &tcp, 5, NULL), UV_EINVAL);314ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));315MAKE_VALGRIND_HAPPY(uv_default_loop());316return 0;317}
318