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 25 1.1 christos #include <stdio.h> 26 1.1 christos #include <stdlib.h> 27 1.1 christos 28 1.1 christos typedef struct { 29 1.1 christos uv_tcp_t handle; 30 1.1 christos uv_shutdown_t shutdown_req; 31 1.1 christos } conn_rec; 32 1.1 christos 33 1.1 christos static uv_tcp_t tcp_server; 34 1.1 christos 35 1.1 christos static void connection_cb(uv_stream_t* stream, int status); 36 1.1 christos static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); 37 1.1 christos static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); 38 1.1 christos static void shutdown_cb(uv_shutdown_t* req, int status); 39 1.1 christos static void close_cb(uv_handle_t* handle); 40 1.1 christos 41 1.1 christos 42 1.1 christos static void connection_cb(uv_stream_t* stream, int status) { 43 1.1 christos conn_rec* conn; 44 1.1 christos int r; 45 1.1 christos 46 1.1.1.3 christos ASSERT_OK(status); 47 1.1.1.3 christos ASSERT_PTR_EQ(stream, (uv_stream_t*)&tcp_server); 48 1.1 christos 49 1.1 christos conn = malloc(sizeof *conn); 50 1.1.1.2 christos ASSERT_NOT_NULL(conn); 51 1.1 christos 52 1.1 christos r = uv_tcp_init(stream->loop, &conn->handle); 53 1.1.1.3 christos ASSERT_OK(r); 54 1.1 christos 55 1.1 christos r = uv_accept(stream, (uv_stream_t*)&conn->handle); 56 1.1.1.3 christos ASSERT_OK(r); 57 1.1 christos 58 1.1 christos r = uv_read_start((uv_stream_t*)&conn->handle, alloc_cb, read_cb); 59 1.1.1.3 christos ASSERT_OK(r); 60 1.1 christos } 61 1.1 christos 62 1.1 christos 63 1.1 christos static void alloc_cb(uv_handle_t* handle, 64 1.1 christos size_t suggested_size, 65 1.1 christos uv_buf_t* buf) { 66 1.1 christos static char slab[65536]; 67 1.1 christos buf->base = slab; 68 1.1 christos buf->len = sizeof(slab); 69 1.1 christos } 70 1.1 christos 71 1.1 christos 72 1.1 christos static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { 73 1.1 christos conn_rec* conn; 74 1.1 christos int r; 75 1.1 christos 76 1.1 christos if (nread >= 0) 77 1.1 christos return; 78 1.1 christos 79 1.1.1.3 christos ASSERT_EQ(nread, UV_EOF); 80 1.1 christos 81 1.1 christos conn = container_of(stream, conn_rec, handle); 82 1.1 christos 83 1.1 christos r = uv_shutdown(&conn->shutdown_req, stream, shutdown_cb); 84 1.1.1.3 christos ASSERT_OK(r); 85 1.1 christos } 86 1.1 christos 87 1.1 christos 88 1.1 christos static void shutdown_cb(uv_shutdown_t* req, int status) { 89 1.1 christos conn_rec* conn = container_of(req, conn_rec, shutdown_req); 90 1.1 christos uv_close((uv_handle_t*)&conn->handle, close_cb); 91 1.1 christos } 92 1.1 christos 93 1.1 christos 94 1.1 christos static void close_cb(uv_handle_t* handle) { 95 1.1 christos conn_rec* conn = container_of(handle, conn_rec, handle); 96 1.1 christos free(conn); 97 1.1 christos } 98 1.1 christos 99 1.1 christos 100 1.1 christos HELPER_IMPL(tcp4_blackhole_server) { 101 1.1 christos struct sockaddr_in addr; 102 1.1 christos uv_loop_t* loop; 103 1.1 christos int r; 104 1.1 christos 105 1.1 christos loop = uv_default_loop(); 106 1.1.1.3 christos ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); 107 1.1 christos 108 1.1 christos r = uv_tcp_init(loop, &tcp_server); 109 1.1.1.3 christos ASSERT_OK(r); 110 1.1 christos 111 1.1 christos r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); 112 1.1.1.3 christos ASSERT_OK(r); 113 1.1 christos 114 1.1 christos r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb); 115 1.1.1.3 christos ASSERT_OK(r); 116 1.1 christos 117 1.1.1.2 christos notify_parent_process(); 118 1.1 christos r = uv_run(loop, UV_RUN_DEFAULT); 119 1.1 christos ASSERT(0 && "Blackhole server dropped out of event loop."); 120 1.1 christos 121 1.1 christos return 0; 122 1.1 christos } 123