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 _WIN32
28 # define INVALID_FD (INVALID_HANDLE_VALUE)
29 #else
30 # define INVALID_FD (-1)
31 #endif
32 
33 
TEST_IMPL(udp_create_early)34 TEST_IMPL(udp_create_early) {
35   struct sockaddr_in addr;
36   struct sockaddr_in sockname;
37   uv_udp_t client;
38   uv_os_fd_t fd;
39   int r, namelen;
40 
41   ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
42 
43   r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET);
44   ASSERT_OK(r);
45 
46   r = uv_fileno((const uv_handle_t*) &client, &fd);
47   ASSERT_OK(r);
48 
49   /* Windows returns WSAEINVAL if the socket is not bound */
50 #ifndef _WIN32
51   ASSERT_NE(fd, INVALID_FD);
52   namelen = sizeof sockname;
53   r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
54   ASSERT_OK(r);
55   ASSERT_EQ(sockname.sin_family, AF_INET);
56 #else
57   ASSERT_PTR_NE(fd, INVALID_FD);
58 #endif
59 
60   r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
61   ASSERT_OK(r);
62 
63   namelen = sizeof sockname;
64   r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
65   ASSERT_OK(r);
66   ASSERT_OK(memcmp(&addr.sin_addr,
67                    &sockname.sin_addr,
68                    sizeof(addr.sin_addr)));
69 
70   uv_close((uv_handle_t*) &client, NULL);
71   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
72 
73   MAKE_VALGRIND_HAPPY(uv_default_loop());
74   return 0;
75 }
76 
77 
TEST_IMPL(udp_create_early_bad_bind)78 TEST_IMPL(udp_create_early_bad_bind) {
79   struct sockaddr_in addr;
80   uv_udp_t client;
81   uv_os_fd_t fd;
82   int r;
83 
84   if (!can_ipv6())
85     RETURN_SKIP("IPv6 not supported");
86 
87   ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
88 
89   r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET6);
90   ASSERT_OK(r);
91 
92   r = uv_fileno((const uv_handle_t*) &client, &fd);
93   ASSERT_OK(r);
94 
95   /* Windows returns WSAEINVAL if the socket is not bound */
96 #ifndef _WIN32
97   ASSERT_NE(fd, INVALID_FD);
98   {
99     int namelen;
100     struct sockaddr_in6 sockname;
101     namelen = sizeof sockname;
102     r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
103     ASSERT_OK(r);
104     ASSERT_EQ(sockname.sin6_family, AF_INET6);
105   }
106 #else
107   ASSERT_PTR_NE(fd, INVALID_FD);
108 #endif
109 
110   r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
111 #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__)
112   ASSERT_EQ(r, UV_EINVAL);
113 #else
114   ASSERT_EQ(r, UV_EFAULT);
115 #endif
116 
117   uv_close((uv_handle_t*) &client, NULL);
118   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
119 
120   MAKE_VALGRIND_HAPPY(uv_default_loop());
121   return 0;
122 }
123 
124 
TEST_IMPL(udp_create_early_bad_domain)125 TEST_IMPL(udp_create_early_bad_domain) {
126   uv_udp_t client;
127   int r;
128 
129   r = uv_udp_init_ex(uv_default_loop(), &client, 47);
130   ASSERT_EQ(r, UV_EINVAL);
131 
132   r = uv_udp_init_ex(uv_default_loop(), &client, 1024);
133   ASSERT_EQ(r, UV_EINVAL);
134 
135   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
136 
137   MAKE_VALGRIND_HAPPY(uv_default_loop());
138   return 0;
139 }
140