libuv-svace-build
213 строк · 5.4 Кб
1/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
2* All rights reserved.
3*
4* Permission is hereby granted, free of charge, to any person obtaining a copy
5* of this software and associated documentation files (the "Software"), to
6* deal in the Software without restriction, including without limitation the
7* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8* sell copies of the Software, and to permit persons to whom the Software is
9* furnished to do so, subject to the following conditions:
10*
11* The above copyright notice and this permission notice shall be included in
12* all copies or substantial portions of the Software.
13*
14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20* IN THE SOFTWARE.
21*/
22
23#include "uv.h"24#include "task.h"25#include <string.h>26
27#ifdef _WIN3228# define INVALID_FD (INVALID_HANDLE_VALUE)29#else30# define INVALID_FD (-1)31#endif32
33
34static void on_connect(uv_connect_t* req, int status) {35ASSERT_OK(status);36uv_close((uv_handle_t*) req->handle, NULL);37}
38
39
40static void on_connection(uv_stream_t* server, int status) {41uv_tcp_t* handle;42int r;43
44ASSERT_OK(status);45
46handle = malloc(sizeof(*handle));47ASSERT_NOT_NULL(handle);48
49r = uv_tcp_init_ex(server->loop, handle, AF_INET);50ASSERT_OK(r);51
52r = uv_accept(server, (uv_stream_t*)handle);53ASSERT_EQ(r, UV_EBUSY);54
55uv_close((uv_handle_t*) server, NULL);56uv_close((uv_handle_t*) handle, (uv_close_cb)free);57}
58
59
60static void tcp_listener(uv_loop_t* loop, uv_tcp_t* server) {61struct sockaddr_in addr;62int r;63
64ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));65
66r = uv_tcp_init(loop, server);67ASSERT_OK(r);68
69r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0);70ASSERT_OK(r);71
72r = uv_listen((uv_stream_t*) server, 128, on_connection);73ASSERT_OK(r);74}
75
76
77static void tcp_connector(uv_loop_t* loop, uv_tcp_t* client, uv_connect_t* req) {78struct sockaddr_in server_addr;79int r;80
81ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));82
83r = uv_tcp_init(loop, client);84ASSERT_OK(r);85
86r = uv_tcp_connect(req,87client,88(const struct sockaddr*) &server_addr,89on_connect);90ASSERT_OK(r);91}
92
93
94TEST_IMPL(tcp_create_early) {95struct sockaddr_in addr;96struct sockaddr_in sockname;97uv_tcp_t client;98uv_os_fd_t fd;99int r, namelen;100
101ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));102
103r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET);104ASSERT_OK(r);105
106r = uv_fileno((const uv_handle_t*) &client, &fd);107ASSERT_OK(r);108
109/* Windows returns WSAEINVAL if the socket is not bound */110#ifndef _WIN32111ASSERT_NE(fd, INVALID_FD);112namelen = sizeof sockname;113r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);114ASSERT_OK(r);115ASSERT_EQ(sockname.sin_family, AF_INET);116#else117ASSERT_PTR_NE(fd, INVALID_FD);118#endif119
120r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0);121ASSERT_OK(r);122
123namelen = sizeof sockname;124r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);125ASSERT_OK(r);126ASSERT_OK(memcmp(&addr.sin_addr,127&sockname.sin_addr,128sizeof(addr.sin_addr)));129
130uv_close((uv_handle_t*) &client, NULL);131uv_run(uv_default_loop(), UV_RUN_DEFAULT);132
133MAKE_VALGRIND_HAPPY(uv_default_loop());134return 0;135}
136
137
138TEST_IMPL(tcp_create_early_bad_bind) {139struct sockaddr_in addr;140uv_tcp_t client;141uv_os_fd_t fd;142int r;143
144if (!can_ipv6())145RETURN_SKIP("IPv6 not supported");146
147ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));148
149r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET6);150ASSERT_OK(r);151
152r = uv_fileno((const uv_handle_t*) &client, &fd);153ASSERT_OK(r);154
155/* Windows returns WSAEINVAL if the socket is not bound */156#ifndef _WIN32157ASSERT_NE(fd, INVALID_FD);158{159int namelen;160struct sockaddr_in6 sockname;161namelen = sizeof sockname;162r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);163ASSERT_OK(r);164ASSERT_EQ(sockname.sin6_family, AF_INET6);165}166#else167ASSERT_PTR_NE(fd, INVALID_FD);168#endif169
170r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0);171#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__)172ASSERT_EQ(r, UV_EINVAL);173#else174ASSERT_EQ(r, UV_EFAULT);175#endif176
177uv_close((uv_handle_t*) &client, NULL);178uv_run(uv_default_loop(), UV_RUN_DEFAULT);179
180MAKE_VALGRIND_HAPPY(uv_default_loop());181return 0;182}
183
184
185TEST_IMPL(tcp_create_early_bad_domain) {186uv_tcp_t client;187int r;188
189r = uv_tcp_init_ex(uv_default_loop(), &client, 47);190ASSERT_EQ(r, UV_EINVAL);191
192r = uv_tcp_init_ex(uv_default_loop(), &client, 1024);193ASSERT_EQ(r, UV_EINVAL);194
195uv_run(uv_default_loop(), UV_RUN_DEFAULT);196
197MAKE_VALGRIND_HAPPY(uv_default_loop());198return 0;199}
200
201
202TEST_IMPL(tcp_create_early_accept) {203uv_tcp_t client, server;204uv_connect_t connect_req;205
206tcp_listener(uv_default_loop(), &server);207tcp_connector(uv_default_loop(), &client, &connect_req);208
209uv_run(uv_default_loop(), UV_RUN_DEFAULT);210
211MAKE_VALGRIND_HAPPY(uv_default_loop());212return 0;213}
214