Exemplo n.º 1
0
void
evsignal_dealloc(struct event_base *base)
{
	int i = 0;
	if (base->sig.ev_signal_added) {
		event_del(&base->sig.ev_signal);
		base->sig.ev_signal_added = 0;
	}
	for (i = 0; i < NSIG; ++i) {
		if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL)
			_evsignal_restore_handler(base, i);
	}

	if (base->sig.ev_signal_pair[0] != -1) {
		EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
		base->sig.ev_signal_pair[0] = -1;
	}
	if (base->sig.ev_signal_pair[1] != -1) {
		EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
		base->sig.ev_signal_pair[1] = -1;
	}
	base->sig.sh_old_max = 0;

	/* per index frees are handled in evsignal_del() */
	if (base->sig.sh_old) {
		free(base->sig.sh_old);
		base->sig.sh_old = NULL;
	}
}
Exemplo n.º 2
0
/*
 * Server events (listener, accept & error).
 * v4c_srv_accept: accept new connection and create associated bufferevent.
 * v4c_srv_accept_error: handle errors on connection.
 */
static void v4c_srv_accept(struct evconnlistener *listener, evutil_socket_t fd,
                           struct sockaddr *sa, int salen, void *ctx)
{
    struct event_base *base = evconnlistener_get_base(listener);
    unused(sa);
    unused(salen);
    unused(ctx);

    if (client) {
        WRN("A client is connected already, droping new connection.");
        EVUTIL_CLOSESOCKET(fd);
        return;
    }

    client = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if (!client) {
        WRN("Could not setup connection with the client.");
        return;
    }
    bufferevent_setcb(client, v4c_srv_recv, NULL, v4c_srv_event, client);

    input = v4c_stdin_ev_new(base, client);
    if (!input) {
        WRN("Could not setup read event on STDIN.");
        bufferevent_free(client);
        EVUTIL_CLOSESOCKET(fd);
        return;
    }

    bufferevent_enable(client, EV_READ | EV_WRITE);
}
Exemplo n.º 3
0
// close pipes to admin process
static void adminClosePipes(struct Admin* admin)
{
    EVUTIL_CLOSESOCKET(admin->inFd);
    admin->inFd = -1;
    EVUTIL_CLOSESOCKET(admin->outFd);
    admin->outFd = -1;
    event_free(admin->pipeEv);
}
Exemplo n.º 4
0
struct evconnlistener *
evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
    void *ptr, unsigned flags, int backlog, const struct sockaddr *sa,
    int socklen)
{
	struct evconnlistener *listener;
	evutil_socket_t fd;
	int on = 1;
	int family = sa ? sa->sa_family : AF_UNSPEC;

	if (backlog == 0)
		return NULL;

	fd = socket(family, SOCK_STREAM, 0);
	if (fd == -1)
		return NULL;

	if (evutil_make_socket_nonblocking(fd) < 0) {
		EVUTIL_CLOSESOCKET(fd);
		return NULL;
	}

	if (flags & LEV_OPT_CLOSE_ON_EXEC) {
		if (evutil_make_socket_closeonexec(fd) < 0) {
			EVUTIL_CLOSESOCKET(fd);
			return NULL;
		}
	}

	setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on));
	if (flags & LEV_OPT_REUSEABLE) {
		evutil_make_listen_socket_reuseable(fd);
	}

	if (sa) {
		if (bind(fd, sa, socklen)<0) {
			EVUTIL_CLOSESOCKET(fd);
			return NULL;
		}
	}

	listener = evconnlistener_new(base, cb, ptr, flags, backlog, fd);
	if (!listener) {
		EVUTIL_CLOSESOCKET(fd);
		return NULL;
	}

	return listener;
}
Exemplo n.º 5
0
void
tr_eventClose( tr_handle * handle )
{
    handle->events->die = TRUE;
    tr_deepLog( __FILE__, __LINE__, NULL, "closing trevent pipe" );
    EVUTIL_CLOSESOCKET( handle->events->fds[1] );
}
Exemplo n.º 6
0
void incomingFromParent(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct ChildContext* context = (struct ChildContext*) vcontext;
    eventType = eventType;
    socket = socket;
    errno = 0;
    ssize_t amount = read(context->inFd, context->buffer, MAX_API_REQUEST_SIZE);

    if (amount < 1) {
        if (errno == EAGAIN) {
            return;
        }
        perror("broken pipe");
        exit(0);
        return;
    }

    for (int i = 0; i < MAX_CONNECTIONS; i++) {
        if (context->connections[i].read != NULL) {
            struct Connection* conn = &context->connections[i];
            ssize_t sent = send(conn->socket, context->buffer, amount, 0);
            if (sent != amount) {
                // All errors lead to closing the socket.
                EVUTIL_CLOSESOCKET(conn->socket);
                event_free(conn->read);
                conn->read = NULL;
            }
        }
    }
}
Exemplo n.º 7
0
// Only happens in Admin process.
static void incomingFromClient(evutil_socket_t socket, short eventType, void* vconn)
{
    struct Connection* conn = (struct Connection*) vconn;
    struct ChildContext* context = conn->context;
    errno = 0;
    uint8_t buf[MAX_API_REQUEST_SIZE + TXID_LEN];
    ssize_t result = recv(socket, buf + TXID_LEN, MAX_API_REQUEST_SIZE, 0);

    if (result > 0) {

        Assert_compileTime(TXID_LEN == 4);
        uint32_t connNumber = conn - context->connections;
        Bits_memcpyConst(buf, &connNumber, TXID_LEN);

        size_t amountWritten = write(context->outFd, buf, result + TXID_LEN);
        if (amountWritten != (size_t)result + TXID_LEN) {
            printf("Admin process failed to write data across pipe to main process.");
            exit(0);
        }
    } else if (result < 0 && errno == EAGAIN) {
        return;
    } else {
        // The return value will be 0 when the peer has performed an orderly shutdown.
        EVUTIL_CLOSESOCKET(conn->socket);
        event_free(conn->read);
        conn->read = NULL;
    }
}
Exemplo n.º 8
0
void
regress_clean_dnsserver(void)
{
        if (dns_port)
                evdns_close_server_port(dns_port);
        if (dns_sock >= 0)
                EVUTIL_CLOSESOCKET(dns_sock);
}
Exemplo n.º 9
0
void
tr_eventClose( tr_session * session )
{
    assert( tr_isSession( session ) );

    session->events->die = TRUE;
    tr_deepLog( __FILE__, __LINE__, NULL, "closing trevent pipe" );
    EVUTIL_CLOSESOCKET( session->events->fds[1] );
}
Exemplo n.º 10
0
static void
event_listener_destroy(struct evconnlistener *lev)
{
	struct evconnlistener_event *lev_e =
	    EVUTIL_UPCAST(lev, struct evconnlistener_event, base);

	event_del(&lev_e->listener);
	if (lev->flags & LEV_OPT_CLOSE_ON_FREE)
		EVUTIL_CLOSESOCKET(event_get_fd(&lev_e->listener));
	event_debug_unassign(&lev_e->listener);
}
Exemplo n.º 11
0
static void
acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
    struct sockaddr *addr, int socklen, void *arg)
{
	int *ptr = arg;
	--*ptr;
	TT_BLATHER(("Got one for %p", ptr));
	EVUTIL_CLOSESOCKET(fd);

	if (! *ptr)
		evconnlistener_disable(listener);
}
Exemplo n.º 12
0
static void
http_base_test(void)
{
	struct bufferevent *bev;
	int fd;
	const char *http_request;
	short port = -1;

	test_ok = 0;
	fprintf(stdout, "Testing HTTP Server Event Base: ");

	base = event_init();

	/* 
	 * create another bogus base - which is being used by all subsequen
	 * tests - yuck!
	 */
	event_init();

	http = http_setup(&port, base);
	
	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, http_readcb, http_writecb,
	    http_errorcb, NULL);
	bufferevent_base_set(base, bev);

	http_request =
	    "GET /test HTTP/1.1\r\n"
	    "Host: somehost\r\n"
	    "Connection: close\r\n"
	    "\r\n";

	bufferevent_write(bev, http_request, strlen(http_request));
	
	event_base_dispatch(base);

	bufferevent_free(bev);
	EVUTIL_CLOSESOCKET(fd);

	evhttp_free(http);

	event_base_free(base);
	base = NULL;
	
	if (test_ok != 2) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}
	
	fprintf(stdout, "OK\n");
}
Exemplo n.º 13
0
static void
be_socket_destruct(struct bufferevent *bufev)
{
	struct bufferevent_private *bufev_p =
	    EVUTIL_UPCAST(bufev, struct bufferevent_private, bev);
	evutil_socket_t fd;
	EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket);

	fd = event_get_fd(&bufev->ev_read);

	if ((bufev_p->options & BEV_OPT_CLOSE_ON_FREE) && fd >= 0)
		EVUTIL_CLOSESOCKET(fd);
}
Exemplo n.º 14
0
// Happens only in the admin process.
static void acceptConn(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct ChildContext* context = (struct ChildContext*) vcontext;

    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);
    evutil_socket_t fd = accept(socket, (struct sockaddr*)&ss, &slen);
    if (fd < 0) {
        perror("acceptConn() fd < 0");
        return;
    } else if (fd > (evutil_socket_t) FD_SETSIZE) {
        EVUTIL_CLOSESOCKET(fd);
        return;
    }

    evutil_make_socket_nonblocking(fd);

    struct Connection* conn = newConnection(context, fd);
    if (!conn) {
        EVUTIL_CLOSESOCKET(fd);
    }
}
Exemplo n.º 15
0
static void
be_async_destruct(struct bufferevent *bev)
{
	struct bufferevent_private *bev_p = BEV_UPCAST(bev);
	evutil_socket_t fd;

	EVUTIL_ASSERT(!upcast(bev)->write_in_progress && !upcast(bev)->read_in_progress);

	/* XXX cancel any outstanding I/O operations */
	fd = _evbuffer_overlapped_get_fd(bev->input);
	/* delete this in case non-blocking connect was used */
	event_del(&bev->ev_write);
	if (bev_p->options & BEV_OPT_CLOSE_ON_FREE)
		EVUTIL_CLOSESOCKET(fd);
	_bufferevent_del_generic_timeout_cbs(bev);
}
Exemplo n.º 16
0
static void incomingFromParent(evutil_socket_t socket, short eventType, void* vcontext)
{
    struct ChildContext* context = (struct ChildContext*) vcontext;
    errno = 0;
    ssize_t amount = read(context->inFd, context->buffer, MAX_API_REQUEST_SIZE + TXID_LEN);

    if (amount < 1) {
        if (errno == EAGAIN) {
            return;
        }
        if (amount < 0) {
            perror("broken pipe");
        } else {
            fprintf(stderr, "admin connection closed\n");
        }
        exit(0);
        return;
    } else if (amount < 4) {
        return;
    }

    Assert_compileTime(TXID_LEN == 4);
    uint32_t connNumber;
    Bits_memcpyConst(&connNumber, context->buffer, TXID_LEN);

    if (connNumber >= MAX_CONNECTIONS) {
        fprintf(stderr, "got message for connection #%u, max connections is %d\n",
                connNumber, MAX_CONNECTIONS);
        return;
    }

    struct Connection* conn = &context->connections[connNumber];
    if (!conn->read) {
        fprintf(stderr, "got message for closed #%u", connNumber);
        return;
    }

    amount -= TXID_LEN;
    ssize_t sent = send(conn->socket, context->buffer + TXID_LEN, amount, 0);
    if (sent != amount) {
        // All errors lead to closing the socket.
        EVUTIL_CLOSESOCKET(conn->socket);
        event_free(conn->read);
        conn->read = NULL;
    }
}
Exemplo n.º 17
0
static void
http_multi_line_header_test(void)
{
	struct bufferevent *bev;
	int fd;
	const char *http_start_request;
	short port = -1;
	
	test_ok = 0;
	fprintf(stdout, "Testing HTTP Server with multi line: ");

	http = http_setup(&port, NULL);
	
	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, http_readcb, http_writecb,
	    http_errorcb, NULL);

	http_start_request =
	    "GET /test HTTP/1.1\r\n"
	    "Host: somehost\r\n"
	    "Connection: close\r\n"
	    "X-Multi:  aaaaaaaa\r\n"
	    " a\r\n"
	    "\tEND\r\n"
	    "X-Last: last\r\n"
	    "\r\n";
		
	bufferevent_write(bev, http_start_request, strlen(http_start_request));

	event_dispatch();
	
	bufferevent_free(bev);
	EVUTIL_CLOSESOCKET(fd);

	evhttp_free(http);

	if (test_ok != 4) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}
	
	fprintf(stdout, "OK\n");
}
Exemplo n.º 18
0
Arquivo: Admin.c Projeto: Ralith/cjdns
static void incomingFromClient(evutil_socket_t socket, short eventType, void* vconn)
{
    struct Connection* conn = (struct Connection*) vconn;
    struct ChildContext* context = conn->context;
    errno = 0;
    char buf[MAX_API_REQUEST_SIZE];
    ssize_t result = recv(socket, buf, MAX_API_REQUEST_SIZE, 0);
    if (result > 0) {
        size_t amountWritten = write(context->outFd, buf, result);
        if (amountWritten != (size_t)result) {
            exit(0);
        }
    } else if (result < 0 && errno == EAGAIN) {
        return;
    } else {
        // The return value will be 0 when the peer has performed an orderly shutdown.
        EVUTIL_CLOSESOCKET(conn->socket);
        event_free(conn->read);
        conn->read = NULL;
    }
}
Exemplo n.º 19
0
/*
 * Testing that the HTTP server can deal with a malformed request.
 */
static void
http_failure_test(void)
{
	struct bufferevent *bev;
	int fd;
	const char *http_request;
	short port = -1;

	test_ok = 0;
	fprintf(stdout, "Testing Bad HTTP Request: ");

	http = http_setup(&port, NULL);
	
	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, http_failure_readcb, http_writecb,
	    http_errorcb, NULL);

	http_request = "illegal request\r\n";

	bufferevent_write(bev, http_request, strlen(http_request));
	
	event_dispatch();

	bufferevent_free(bev);
	EVUTIL_CLOSESOCKET(fd);

	evhttp_free(http);
	
	if (test_ok != 2) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}
	
	fprintf(stdout, "OK\n");
}
Exemplo n.º 20
0
static void
regress_pick_a_port(void *arg)
{
	struct basic_test_data *data = arg;
	struct event_base *base = data->base;
	struct evconnlistener *listener1 = NULL, *listener2 = NULL;
	//struct event *connecting;
	struct sockaddr_in sin;
	int count1 = 2, count2 = 1;
	struct sockaddr_storage ss1, ss2;
	struct sockaddr_in *sin1, *sin2;
	ev_socklen_t slen1 = sizeof(ss1), slen2 = sizeof(ss2);
	unsigned int flags =
	    LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC;

	evutil_socket_t fd1 = -1, fd2 = -1, fd3 = -1;

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
	sin.sin_port = 0; /* "You pick!" */

	listener1 = evconnlistener_new_bind(base, acceptcb, &count1,
	    flags, -1, (struct sockaddr *)&sin, sizeof(sin));
	tt_assert(listener1);
	listener2 = evconnlistener_new_bind(base, acceptcb, &count2,
	    flags, -1, (struct sockaddr *)&sin, sizeof(sin));
	tt_assert(listener2);

	tt_int_op(evconnlistener_get_fd(listener1), >=, 0);
	tt_int_op(evconnlistener_get_fd(listener2), >=, 0);
	tt_assert(getsockname(evconnlistener_get_fd(listener1),
		(struct sockaddr*)&ss1, &slen1) == 0);
	tt_assert(getsockname(evconnlistener_get_fd(listener2),
		(struct sockaddr*)&ss2, &slen2) == 0);
	tt_int_op(ss1.ss_family, ==, AF_INET);
	tt_int_op(ss2.ss_family, ==, AF_INET);

	sin1 = (struct sockaddr_in*)&ss1;
	sin2 = (struct sockaddr_in*)&ss2;
	tt_int_op(ntohl(sin1->sin_addr.s_addr), ==, 0x7f000001);
	tt_int_op(ntohl(sin2->sin_addr.s_addr), ==, 0x7f000001);
	tt_int_op(sin1->sin_port, !=, sin2->sin_port);

	tt_ptr_op(evconnlistener_get_base(listener1), ==, base);
	tt_ptr_op(evconnlistener_get_base(listener2), ==, base);

	fd1 = fd2 = fd3 = -1;
	evutil_socket_connect(&fd1, (struct sockaddr*)&ss1, slen1);
	evutil_socket_connect(&fd2, (struct sockaddr*)&ss1, slen1);
	evutil_socket_connect(&fd3, (struct sockaddr*)&ss2, slen2);

#ifdef WIN32
	Sleep(100); /* XXXX this is a stupid stopgap. */
#endif
	event_base_dispatch(base);

	tt_int_op(count1, ==, 0);
	tt_int_op(count2, ==, 0);

end:
	if (fd1>=0)
		EVUTIL_CLOSESOCKET(fd1);
	if (fd2>=0)
		EVUTIL_CLOSESOCKET(fd2);
	if (fd3>=0)
		EVUTIL_CLOSESOCKET(fd3);
}
Exemplo n.º 21
0
void
test_bufferevent_zlib(void *arg)
{
	struct bufferevent *bev1=NULL, *bev2=NULL, *bev1_orig, *bev2_orig;
	char buffer[8333];
	z_stream z_input, z_output;
	int i, pair[2]={-1,-1}, r;
        (void)arg;

	infilter_calls = outfilter_calls = readcb_finished = writecb_finished
            = errorcb_invoked = 0;

	if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
		tt_abort_perror("socketpair");
	}

	evutil_make_socket_nonblocking(pair[0]);
	evutil_make_socket_nonblocking(pair[1]);

	bev1_orig = bev1 = bufferevent_socket_new(NULL, pair[0], 0);
	bev2_orig = bev2 = bufferevent_socket_new(NULL, pair[1], 0);

	memset(&z_output, 0, sizeof(z_output));
	r = deflateInit(&z_output, Z_DEFAULT_COMPRESSION);
	tt_int_op(r, ==, Z_OK);
	memset(&z_input, 0, sizeof(z_input));
	r = inflateInit(&z_input);

	/* initialize filters */
	bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter, 0,
	    zlib_deflate_free, &z_output);
	bev2 = bufferevent_filter_new(bev2, zlib_input_filter,
	    NULL, 0, zlib_inflate_free, &z_input);
	bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL);
	bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL);

	bufferevent_disable(bev1, EV_READ);
	bufferevent_enable(bev1, EV_WRITE);

	bufferevent_enable(bev2, EV_READ);

	for (i = 0; i < sizeof(buffer); i++)
		buffer[i] = i;

	/* break it up into multiple buffer chains */
	bufferevent_write(bev1, buffer, 1800);
	bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800);

	/* we are done writing - we need to flush everything */
	bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED);

	event_dispatch();

        tt_want(infilter_calls);
        tt_want(outfilter_calls);
        tt_want(readcb_finished);
        tt_want(writecb_finished);
        tt_want(!errorcb_invoked);

        test_ok = 1;
end:
        if (bev1)
                bufferevent_free(bev1);
        if (bev2)
		bufferevent_free(bev2);

	if (pair[0] >= 0)
		EVUTIL_CLOSESOCKET(pair[0]);
	if (pair[1] >= 0)
		EVUTIL_CLOSESOCKET(pair[1]);
}
Exemplo n.º 22
0
int
evutil_socketpair(int family, int type, int protocol, int fd[2])
{
#ifndef WIN32
	return socketpair(family, type, protocol, fd);
#else
	/* This code is originally from Tor.  Used with permission. */

	/* This socketpair does not work when localhost is down. So
	 * it's really not the same thing at all. But it's close enough
	 * for now, and really, when localhost is down sometimes, we
	 * have other problems too.
	 */
	int listener = -1;
	int connector = -1;
	int acceptor = -1;
	struct sockaddr_in listen_addr;
	struct sockaddr_in connect_addr;
	int size;
	int saved_errno = -1;

	if (protocol
#ifdef AF_UNIX
		|| family != AF_UNIX
#endif
		) {
		EVUTIL_SET_SOCKET_ERROR(WSAEAFNOSUPPORT);
		return -1;
	}
	if (!fd) {
		EVUTIL_SET_SOCKET_ERROR(WSAEINVAL);
		return -1;
	}

	listener = socket(AF_INET, type, 0);
	if (listener < 0)
		return -1;
	memset(&listen_addr, 0, sizeof(listen_addr));
	listen_addr.sin_family = AF_INET;
	listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	listen_addr.sin_port = 0;	/* kernel chooses port.	 */
	if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
		== -1)
		goto tidy_up_and_fail;
	if (listen(listener, 1) == -1)
		goto tidy_up_and_fail;

	connector = socket(AF_INET, type, 0);
	if (connector < 0)
		goto tidy_up_and_fail;
	/* We want to find out the port number to connect to.  */
	size = sizeof(connect_addr);
	if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
		goto tidy_up_and_fail;
	if (size != sizeof (connect_addr))
		goto abort_tidy_up_and_fail;
	if (connect(connector, (struct sockaddr *) &connect_addr,
				sizeof(connect_addr)) == -1)
		goto tidy_up_and_fail;

	size = sizeof(listen_addr);
	acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
	if (acceptor < 0)
		goto tidy_up_and_fail;
	if (size != sizeof(listen_addr))
		goto abort_tidy_up_and_fail;
	EVUTIL_CLOSESOCKET(listener);
	/* Now check we are talking to ourself by matching port and host on the
	   two sockets.	 */
	if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
		goto tidy_up_and_fail;
	if (size != sizeof (connect_addr)
		|| listen_addr.sin_family != connect_addr.sin_family
		|| listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
		|| listen_addr.sin_port != connect_addr.sin_port)
		goto abort_tidy_up_and_fail;
	fd[0] = connector;
	fd[1] = acceptor;

	return 0;

 abort_tidy_up_and_fail:
	saved_errno = WSAECONNABORTED;
 tidy_up_and_fail:
	if (saved_errno < 0)
		saved_errno = WSAGetLastError();
	if (listener != -1)
		EVUTIL_CLOSESOCKET(listener);
	if (connector != -1)
		EVUTIL_CLOSESOCKET(connector);
	if (acceptor != -1)
		EVUTIL_CLOSESOCKET(acceptor);

	EVUTIL_SET_SOCKET_ERROR(saved_errno);
	return -1;
#endif
}
Exemplo n.º 23
0
static void
test_bufferevent_connect_hostname(void *arg)
{
	struct basic_test_data *data = arg;
	struct evconnlistener *listener = NULL;
	struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL;
	int be1_outcome=0, be2_outcome=0, be3_outcome=0, be4_outcome=0,
	    be5_outcome=0;
	struct evdns_base *dns=NULL;
	struct evdns_server_port *port=NULL;
	evutil_socket_t server_fd=-1;
	struct sockaddr_in sin;
	int listener_port=-1;
	ev_uint16_t dns_port=0;
	int n_accept=0, n_dns=0;
	char buf[128];

	be_connect_hostname_base = data->base;

	/* Bind an address and figure out what port it's on. */
	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
	sin.sin_port = 0;
	listener = evconnlistener_new_bind(data->base, nil_accept_cb,
	    &n_accept,
	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC,
	    -1, (struct sockaddr *)&sin, sizeof(sin));
	listener_port = regress_get_socket_port(
		evconnlistener_get_fd(listener));

	port = regress_get_dnsserver(data->base, &dns_port, NULL,
	    be_getaddrinfo_server_cb, &n_dns);
	tt_assert(port);
	tt_int_op(dns_port, >=, 0);

	/* Start an evdns_base that uses the server as its resolver. */
	dns = evdns_base_new(data->base, 0);
	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", dns_port);
	evdns_base_nameserver_ip_add(dns, buf);

	/* Now, finally, at long last, launch the bufferevents.  One should do
	 * a failing lookup IP, one should do a successful lookup by IP,
	 * and one should do a successful lookup by hostname. */
	be1 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
	be2 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
	be3 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
	be4 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
	be5 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);

	bufferevent_setcb(be1, NULL, NULL, be_connect_hostname_event_cb,
	    &be1_outcome);
	bufferevent_setcb(be2, NULL, NULL, be_connect_hostname_event_cb,
	    &be2_outcome);
	bufferevent_setcb(be3, NULL, NULL, be_connect_hostname_event_cb,
	    &be3_outcome);
	bufferevent_setcb(be4, NULL, NULL, be_connect_hostname_event_cb,
	    &be4_outcome);
	bufferevent_setcb(be5, NULL, NULL, be_connect_hostname_event_cb,
	    &be5_outcome);

	/* Launch an async resolve that will fail. */
	tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET,
		"nosuchplace.example.com", listener_port));
	/* Connect to the IP without resolving. */
	tt_assert(!bufferevent_socket_connect_hostname(be2, dns, AF_INET,
		"127.0.0.1", listener_port));
	/* Launch an async resolve that will succeed. */
	tt_assert(!bufferevent_socket_connect_hostname(be3, dns, AF_INET,
		"nobodaddy.example.com", listener_port));
	/* Use the blocking resolver.  This one will fail if your resolver
	 * can't resolve localhost to 127.0.0.1 */
	tt_assert(!bufferevent_socket_connect_hostname(be4, NULL, AF_INET,
		"localhost", listener_port));
	/* Use the blocking resolver with a nonexistent hostname. */
	tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET,
		"nonesuch.nowhere.example.com", 80));

	event_base_dispatch(data->base);

	tt_int_op(be1_outcome, ==, BEV_EVENT_ERROR);
	tt_int_op(be2_outcome, ==, BEV_EVENT_CONNECTED);
	tt_int_op(be3_outcome, ==, BEV_EVENT_CONNECTED);
	tt_int_op(be4_outcome, ==, BEV_EVENT_CONNECTED);
	tt_int_op(be5_outcome, ==, BEV_EVENT_ERROR);

	tt_int_op(n_accept, ==, 3);
	tt_int_op(n_dns, ==, 2);

end:
	if (listener)
		evconnlistener_free(listener);
	if (server_fd>=0)
		EVUTIL_CLOSESOCKET(server_fd);
	if (port)
                evdns_close_server_port(port);
	if (dns)
		evdns_base_free(dns, 0);
	if (be1)
		bufferevent_free(be1);
	if (be2)
		bufferevent_free(be2);
	if (be3)
		bufferevent_free(be3);
	if (be4)
		bufferevent_free(be4);
	if (be5)
		bufferevent_free(be5);
}
Exemplo n.º 24
0
static void
dns_server(void)
{
        evutil_socket_t sock=-1;
	struct sockaddr_in my_addr;
	struct evdns_server_port *port=NULL;
	struct in_addr resolve_addr;
	struct in6_addr resolve_addr6;
	struct evdns_base *base=NULL;
	struct evdns_request *req=NULL;

	dns_ok = 1;

	base = evdns_base_new(NULL, 0);

	/* Add ourself as the only nameserver, and make sure we really are
	 * the only nameserver. */
	evdns_base_nameserver_ip_add(base, "127.0.0.1:35353");

	tt_int_op(evdns_base_count_nameservers(base), ==, 1);
	/* Now configure a nameserver port. */
	sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock<0) {
                tt_abort_perror("socket");
        }

        evutil_make_socket_nonblocking(sock);

	memset(&my_addr, 0, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(35353);
	my_addr.sin_addr.s_addr = htonl(0x7f000001UL);
	if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) {
		tt_abort_perror("bind");
	}
	port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL);

	/* Send some queries. */
	evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
					   dns_server_gethostbyname_cb, NULL);
	evdns_base_resolve_ipv6(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
					   dns_server_gethostbyname_cb, NULL);
	resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
	evdns_base_resolve_reverse(base, &resolve_addr, 0,
            dns_server_gethostbyname_cb, NULL);
	memcpy(resolve_addr6.s6_addr,
	    "\xff\xf0\x00\x00\x00\x00\xaa\xaa"
	    "\x11\x11\x00\x00\x00\x00\xef\xef", 16);
	evdns_base_resolve_reverse_ipv6(base, &resolve_addr6, 0,
            dns_server_gethostbyname_cb, (void*)6);

	req = evdns_base_resolve_ipv4(base,
	    "drop.example.com", DNS_QUERY_NO_SEARCH,
	    dns_server_gethostbyname_cb, (void*)(char*)90909);

	evdns_cancel_request(base, req);

	event_dispatch();

	tt_assert(dns_got_cancel);
        test_ok = dns_ok;

end:
        if (port)
                evdns_close_server_port(port);
        if (sock >= 0)
                EVUTIL_CLOSESOCKET(sock);
	if (base)
		evdns_base_free(base, 0);
}
Exemplo n.º 25
0
int
bufferevent_socket_connect(struct bufferevent *bev,
    struct sockaddr *sa, int socklen)
{
	struct bufferevent_private *bufev_p =
	    EVUTIL_UPCAST(bev, struct bufferevent_private, bev);

	evutil_socket_t fd;
	int r = 0;
	int result=-1;
	int ownfd = 0;

	_bufferevent_incref_and_lock(bev);

	if (!bufev_p)
		goto done;

	fd = bufferevent_getfd(bev);
	if (fd < 0) {
		if (!sa)
			goto done;
		fd = socket(sa->sa_family, SOCK_STREAM, 0);
		if (fd < 0)
			goto done;
		if (evutil_make_socket_nonblocking(fd)<0)
			goto done;
		ownfd = 1;
	}
	if (sa) {
#ifdef WIN32
		if (bufferevent_async_can_connect(bev)) {
			bufferevent_setfd(bev, fd);
			r = bufferevent_async_connect(bev, fd, sa, socklen);
			if (r < 0)
				goto freesock;
			bufev_p->connecting = 1;
			result = 0;
			goto done;
		} else
#endif
		r = evutil_socket_connect(&fd, sa, socklen);
		if (r < 0)
			goto freesock;
	}
#ifdef WIN32
	/* ConnectEx() isn't always around, even when IOCP is enabled.
	 * Here, we borrow the socket object's write handler to fall back
	 * on a non-blocking connect() when ConnectEx() is unavailable. */
	if (BEV_IS_ASYNC(bev)) {
		event_assign(&bev->ev_write, bev->ev_base, fd,
		    EV_WRITE|EV_PERSIST, bufferevent_writecb, bev);
	}
#endif
	bufferevent_setfd(bev, fd);
	if (r == 0) {
		if (! be_socket_enable(bev, EV_WRITE)) {
			bufev_p->connecting = 1;
			result = 0;
			goto done;
		}
	} else if (r == 1) {
		/* The connect succeeded already. How very BSD of it. */
		result = 0;
		bufev_p->connecting = 1;
		event_active(&bev->ev_write, EV_WRITE, 1);
	} else {
		/* The connect failed already.  How very BSD of it. */
		bufev_p->connection_refused = 1;
		bufev_p->connecting = 1;
		result = 0;
		event_active(&bev->ev_write, EV_WRITE, 1);
	}

	goto done;

freesock:
	_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
	if (ownfd)
		EVUTIL_CLOSESOCKET(fd);
	/* do something about the error? */
done:
	_bufferevent_decref_and_unlock(bev);
	return result;
}
Exemplo n.º 26
0
static void libcouchbase_io_close(struct libcouchbase_io_opt_st *iops,
                                  libcouchbase_socket_t sock)
{
    (void)iops;
    EVUTIL_CLOSESOCKET(sock);
}
Exemplo n.º 27
0
static void
socketClose( int fd )
{
    EVUTIL_CLOSESOCKET( fd );
}
Exemplo n.º 28
0
static void
test_evutil_log(void *ptr)
{
	evutil_socket_t fd = -1;
	char buf[128];

	event_set_log_callback(logfn);
	event_set_fatal_callback(fatalfn);
#define RESET() do {				\
		logsev = exited = exitcode = 0;	\
		if (logmsg) free(logmsg);	\
		logmsg = NULL;			\
	} while (0)
#define LOGEQ(sev,msg) do {			\
		tt_int_op(logsev,==,sev);	\
		tt_assert(logmsg != NULL);	\
		tt_str_op(logmsg,==,msg);	\
	} while (0)

	event_errx(2, "Fatal error; too many kumquats (%d)", 5);
	LOGEQ(_EVENT_LOG_ERR, "Fatal error; too many kumquats (5)");
	tt_int_op(exitcode,==,2);
	RESET();

	event_warnx("Far too many %s (%d)", "wombats", 99);
	LOGEQ(_EVENT_LOG_WARN, "Far too many wombats (99)");
	tt_int_op(exited,==,0);
	RESET();

	event_msgx("Connecting lime to coconut");
	LOGEQ(_EVENT_LOG_MSG, "Connecting lime to coconut");
	tt_int_op(exited,==,0);
	RESET();

	event_debug(("A millisecond passed!  We should log that!"));
#ifdef USE_DEBUG
	LOGEQ(_EVENT_LOG_DEBUG, "A millisecond passed!	We should log that!");
#else
	tt_int_op(logsev,==,0);
	tt_ptr_op(logmsg,==,NULL);
#endif
	RESET();

	/* Try with an errno. */
	errno = ENOENT;
	event_warn("Couldn't open %s", "/bad/file");
	evutil_snprintf(buf, sizeof(buf),
	    "Couldn't open /bad/file: %s",strerror(ENOENT));
	LOGEQ(_EVENT_LOG_WARN,buf);
	tt_int_op(exited, ==, 0);
	RESET();

	errno = ENOENT;
	event_err(5,"Couldn't open %s", "/very/bad/file");
	evutil_snprintf(buf, sizeof(buf),
	    "Couldn't open /very/bad/file: %s",strerror(ENOENT));
	LOGEQ(_EVENT_LOG_ERR,buf);
	tt_int_op(exitcode, ==, 5);
	RESET();

	/* Try with a socket errno. */
	fd = socket(AF_INET, SOCK_STREAM, 0);
#ifdef WIN32
	evutil_snprintf(buf, sizeof(buf),
	    "Unhappy socket: %s",
	    evutil_socket_error_to_string(WSAEWOULDBLOCK));
	EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK);
#else
	evutil_snprintf(buf, sizeof(buf),
	    "Unhappy socket: %s", strerror(EAGAIN));
	errno = EAGAIN;
#endif
	event_sock_warn(fd, "Unhappy socket");
	LOGEQ(_EVENT_LOG_WARN, buf);
	tt_int_op(exited,==,0);
	RESET();

#ifdef WIN32
	EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK);
#else
	errno = EAGAIN;
#endif
	event_sock_err(200, fd, "Unhappy socket");
	LOGEQ(_EVENT_LOG_ERR, buf);
	tt_int_op(exitcode,==,200);
	RESET();

#undef RESET
#undef LOGEQ
end:
	if (logmsg)
		free(logmsg);
	if (fd >= 0)
		EVUTIL_CLOSESOCKET(fd);
}
Exemplo n.º 29
0
static void
http_basic_test(void)
{
	struct timeval tv;
	struct bufferevent *bev;
	int fd;
	const char *http_request;
	short port = -1;

	test_ok = 0;
	fprintf(stdout, "Testing Basic HTTP Server: ");

	http = http_setup(&port, NULL);

	/* bind to a second socket */
	if (evhttp_bind_socket(http, "127.0.0.1", port + 1) == -1) {
		fprintf(stdout, "FAILED (bind)\n");
		exit(1);
	}
	
	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, http_readcb, http_writecb,
	    http_errorcb, NULL);

	/* first half of the http request */
	http_request =
	    "GET /test HTTP/1.1\r\n"
	    "Host: some";

	bufferevent_write(bev, http_request, strlen(http_request));
	timerclear(&tv);
	tv.tv_usec = 10000;
	event_once(-1, EV_TIMEOUT, http_complete_write, bev, &tv);
	
	event_dispatch();

	if (test_ok != 3) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* connect to the second port */
	bufferevent_free(bev);
	EVUTIL_CLOSESOCKET(fd);

	fd = http_connect("127.0.0.1", port + 1);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, http_readcb, http_writecb,
	    http_errorcb, NULL);

	http_request =
	    "GET /test HTTP/1.1\r\n"
	    "Host: somehost\r\n"
	    "Connection: close\r\n"
	    "\r\n";

	bufferevent_write(bev, http_request, strlen(http_request));
	
	event_dispatch();

	bufferevent_free(bev);
	EVUTIL_CLOSESOCKET(fd);

	evhttp_free(http);
	
	if (test_ok != 5) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	fprintf(stdout, "OK\n");
}
Exemplo n.º 30
0
int stream_request_disconnect(int fd)
{
    EVUTIL_CLOSESOCKET(fd);
}