Home | History | Annotate | Line # | Download | only in test
test-tcp-bind-error.c revision 1.1
      1  1.1  christos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
      2  1.1  christos  *
      3  1.1  christos  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  1.1  christos  * of this software and associated documentation files (the "Software"), to
      5  1.1  christos  * deal in the Software without restriction, including without limitation the
      6  1.1  christos  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      7  1.1  christos  * sell copies of the Software, and to permit persons to whom the Software is
      8  1.1  christos  * furnished to do so, subject to the following conditions:
      9  1.1  christos  *
     10  1.1  christos  * The above copyright notice and this permission notice shall be included in
     11  1.1  christos  * all copies or substantial portions of the Software.
     12  1.1  christos  *
     13  1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  1.1  christos  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  1.1  christos  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  1.1  christos  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  1.1  christos  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     18  1.1  christos  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     19  1.1  christos  * IN THE SOFTWARE.
     20  1.1  christos  */
     21  1.1  christos 
     22  1.1  christos #include "uv.h"
     23  1.1  christos #include "task.h"
     24  1.1  christos #include <stdio.h>
     25  1.1  christos #include <stdlib.h>
     26  1.1  christos 
     27  1.1  christos 
     28  1.1  christos static int close_cb_called = 0;
     29  1.1  christos 
     30  1.1  christos 
     31  1.1  christos static void close_cb(uv_handle_t* handle) {
     32  1.1  christos   ASSERT(handle != NULL);
     33  1.1  christos   close_cb_called++;
     34  1.1  christos }
     35  1.1  christos 
     36  1.1  christos 
     37  1.1  christos TEST_IMPL(tcp_bind_error_addrinuse) {
     38  1.1  christos   struct sockaddr_in addr;
     39  1.1  christos   uv_tcp_t server1, server2;
     40  1.1  christos   int r;
     41  1.1  christos 
     42  1.1  christos   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
     43  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server1);
     44  1.1  christos   ASSERT(r == 0);
     45  1.1  christos   r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
     46  1.1  christos   ASSERT(r == 0);
     47  1.1  christos 
     48  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server2);
     49  1.1  christos   ASSERT(r == 0);
     50  1.1  christos   r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
     51  1.1  christos   ASSERT(r == 0);
     52  1.1  christos 
     53  1.1  christos   r = uv_listen((uv_stream_t*)&server1, 128, NULL);
     54  1.1  christos   ASSERT(r == 0);
     55  1.1  christos   r = uv_listen((uv_stream_t*)&server2, 128, NULL);
     56  1.1  christos   ASSERT(r == UV_EADDRINUSE);
     57  1.1  christos 
     58  1.1  christos   uv_close((uv_handle_t*)&server1, close_cb);
     59  1.1  christos   uv_close((uv_handle_t*)&server2, close_cb);
     60  1.1  christos 
     61  1.1  christos   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
     62  1.1  christos 
     63  1.1  christos   ASSERT(close_cb_called == 2);
     64  1.1  christos 
     65  1.1  christos   MAKE_VALGRIND_HAPPY();
     66  1.1  christos   return 0;
     67  1.1  christos }
     68  1.1  christos 
     69  1.1  christos 
     70  1.1  christos TEST_IMPL(tcp_bind_error_addrnotavail_1) {
     71  1.1  christos   struct sockaddr_in addr;
     72  1.1  christos   uv_tcp_t server;
     73  1.1  christos   int r;
     74  1.1  christos 
     75  1.1  christos   ASSERT(0 == uv_ip4_addr("127.255.255.255", TEST_PORT, &addr));
     76  1.1  christos 
     77  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
     78  1.1  christos   ASSERT(r == 0);
     79  1.1  christos 
     80  1.1  christos   /* It seems that Linux is broken here - bind succeeds. */
     81  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
     82  1.1  christos   ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);
     83  1.1  christos 
     84  1.1  christos   uv_close((uv_handle_t*)&server, close_cb);
     85  1.1  christos 
     86  1.1  christos   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
     87  1.1  christos 
     88  1.1  christos   ASSERT(close_cb_called == 1);
     89  1.1  christos 
     90  1.1  christos   MAKE_VALGRIND_HAPPY();
     91  1.1  christos   return 0;
     92  1.1  christos }
     93  1.1  christos 
     94  1.1  christos 
     95  1.1  christos TEST_IMPL(tcp_bind_error_addrnotavail_2) {
     96  1.1  christos   struct sockaddr_in addr;
     97  1.1  christos   uv_tcp_t server;
     98  1.1  christos   int r;
     99  1.1  christos 
    100  1.1  christos   ASSERT(0 == uv_ip4_addr("4.4.4.4", TEST_PORT, &addr));
    101  1.1  christos 
    102  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    103  1.1  christos   ASSERT(r == 0);
    104  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
    105  1.1  christos   ASSERT(r == UV_EADDRNOTAVAIL);
    106  1.1  christos 
    107  1.1  christos   uv_close((uv_handle_t*)&server, close_cb);
    108  1.1  christos 
    109  1.1  christos   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    110  1.1  christos 
    111  1.1  christos   ASSERT(close_cb_called == 1);
    112  1.1  christos 
    113  1.1  christos   MAKE_VALGRIND_HAPPY();
    114  1.1  christos   return 0;
    115  1.1  christos }
    116  1.1  christos 
    117  1.1  christos 
    118  1.1  christos TEST_IMPL(tcp_bind_error_fault) {
    119  1.1  christos   char garbage[] =
    120  1.1  christos       "blah blah blah blah blah blah blah blah blah blah blah blah";
    121  1.1  christos   struct sockaddr_in* garbage_addr;
    122  1.1  christos   uv_tcp_t server;
    123  1.1  christos   int r;
    124  1.1  christos 
    125  1.1  christos   garbage_addr = (struct sockaddr_in*) &garbage;
    126  1.1  christos 
    127  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    128  1.1  christos   ASSERT(r == 0);
    129  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
    130  1.1  christos   ASSERT(r == UV_EINVAL);
    131  1.1  christos 
    132  1.1  christos   uv_close((uv_handle_t*)&server, close_cb);
    133  1.1  christos 
    134  1.1  christos   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    135  1.1  christos 
    136  1.1  christos   ASSERT(close_cb_called == 1);
    137  1.1  christos 
    138  1.1  christos   MAKE_VALGRIND_HAPPY();
    139  1.1  christos   return 0;
    140  1.1  christos }
    141  1.1  christos 
    142  1.1  christos /* Notes: On Linux uv_bind(server, NULL) will segfault the program.  */
    143  1.1  christos 
    144  1.1  christos TEST_IMPL(tcp_bind_error_inval) {
    145  1.1  christos   struct sockaddr_in addr1;
    146  1.1  christos   struct sockaddr_in addr2;
    147  1.1  christos   uv_tcp_t server;
    148  1.1  christos   int r;
    149  1.1  christos 
    150  1.1  christos   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1));
    151  1.1  christos   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2));
    152  1.1  christos 
    153  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    154  1.1  christos   ASSERT(r == 0);
    155  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
    156  1.1  christos   ASSERT(r == 0);
    157  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
    158  1.1  christos   ASSERT(r == UV_EINVAL);
    159  1.1  christos 
    160  1.1  christos   uv_close((uv_handle_t*)&server, close_cb);
    161  1.1  christos 
    162  1.1  christos   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    163  1.1  christos 
    164  1.1  christos   ASSERT(close_cb_called == 1);
    165  1.1  christos 
    166  1.1  christos   MAKE_VALGRIND_HAPPY();
    167  1.1  christos   return 0;
    168  1.1  christos }
    169  1.1  christos 
    170  1.1  christos 
    171  1.1  christos TEST_IMPL(tcp_bind_localhost_ok) {
    172  1.1  christos   struct sockaddr_in addr;
    173  1.1  christos   uv_tcp_t server;
    174  1.1  christos   int r;
    175  1.1  christos 
    176  1.1  christos   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
    177  1.1  christos 
    178  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    179  1.1  christos   ASSERT(r == 0);
    180  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
    181  1.1  christos   ASSERT(r == 0);
    182  1.1  christos 
    183  1.1  christos   MAKE_VALGRIND_HAPPY();
    184  1.1  christos   return 0;
    185  1.1  christos }
    186  1.1  christos 
    187  1.1  christos 
    188  1.1  christos TEST_IMPL(tcp_bind_invalid_flags) {
    189  1.1  christos   struct sockaddr_in addr;
    190  1.1  christos   uv_tcp_t server;
    191  1.1  christos   int r;
    192  1.1  christos 
    193  1.1  christos   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
    194  1.1  christos 
    195  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    196  1.1  christos   ASSERT(r == 0);
    197  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY);
    198  1.1  christos   ASSERT(r == UV_EINVAL);
    199  1.1  christos 
    200  1.1  christos   MAKE_VALGRIND_HAPPY();
    201  1.1  christos   return 0;
    202  1.1  christos }
    203  1.1  christos 
    204  1.1  christos 
    205  1.1  christos TEST_IMPL(tcp_listen_without_bind) {
    206  1.1  christos   int r;
    207  1.1  christos   uv_tcp_t server;
    208  1.1  christos 
    209  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    210  1.1  christos   ASSERT(r == 0);
    211  1.1  christos   r = uv_listen((uv_stream_t*)&server, 128, NULL);
    212  1.1  christos   ASSERT(r == 0);
    213  1.1  christos 
    214  1.1  christos   MAKE_VALGRIND_HAPPY();
    215  1.1  christos   return 0;
    216  1.1  christos }
    217  1.1  christos 
    218  1.1  christos 
    219  1.1  christos TEST_IMPL(tcp_bind_writable_flags) {
    220  1.1  christos   struct sockaddr_in addr;
    221  1.1  christos   uv_tcp_t server;
    222  1.1  christos   uv_buf_t buf;
    223  1.1  christos   uv_write_t write_req;
    224  1.1  christos   uv_shutdown_t shutdown_req;
    225  1.1  christos   int r;
    226  1.1  christos 
    227  1.1  christos   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
    228  1.1  christos   r = uv_tcp_init(uv_default_loop(), &server);
    229  1.1  christos   ASSERT(r == 0);
    230  1.1  christos   r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
    231  1.1  christos   ASSERT(r == 0);
    232  1.1  christos   r = uv_listen((uv_stream_t*)&server, 128, NULL);
    233  1.1  christos   ASSERT(r == 0);
    234  1.1  christos 
    235  1.1  christos   ASSERT(0 == uv_is_writable((uv_stream_t*) &server));
    236  1.1  christos   ASSERT(0 == uv_is_readable((uv_stream_t*) &server));
    237  1.1  christos 
    238  1.1  christos   buf = uv_buf_init("PING", 4);
    239  1.1  christos   r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
    240  1.1  christos   ASSERT(r == UV_EPIPE);
    241  1.1  christos   r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
    242  1.1  christos   ASSERT(r == UV_ENOTCONN);
    243  1.1  christos   r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
    244  1.1  christos   ASSERT(r == UV_ENOTCONN);
    245  1.1  christos 
    246  1.1  christos   uv_close((uv_handle_t*)&server, close_cb);
    247  1.1  christos 
    248  1.1  christos   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    249  1.1  christos 
    250  1.1  christos   ASSERT(close_cb_called == 1);
    251  1.1  christos 
    252  1.1  christos   MAKE_VALGRIND_HAPPY();
    253  1.1  christos   return 0;
    254  1.1  christos }
    255