Home | History | Annotate | Line # | Download | only in test
      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 }
    177