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