Ejemplo n.º 1
0
static struct passive_context *
create_passive(struct ev_loop *loop, struct server_config *cfg)
{
	struct passive_context *passive = NULL;
	struct uinet_socket *listener = NULL;
	struct ev_uinet_ctx *soctx = NULL;
	struct uinet_in_addr addr;
	int optlen, optval;
	int error;
	struct uinet_sockaddr_in sin;

	if (uinet_inet_pton(UINET_AF_INET, cfg->listen_addr, &addr) <= 0) {
		printf("Malformed address %s\n", cfg->listen_addr);
		goto fail;
	}

	error = uinet_socreate(UINET_PF_INET, &listener, UINET_SOCK_STREAM, 0);
	if (0 != error) {
		printf("Listen socket creation failed (%d)\n", error);
		goto fail;
	}

	soctx = ev_uinet_attach(listener);
	if (NULL == soctx) {
		printf("Failed to alloc libev socket context\n");
		goto fail;
	}
	
	if ((error = uinet_make_socket_passive(listener))) {
		printf("Failed to make listen socket passive (%d)\n", error);
		goto fail;
	}

	if (cfg->interface->promisc) {
		if ((error = uinet_make_socket_promiscuous(listener, cfg->interface->cdom))) {
			printf("Failed to make listen socket promiscuous (%d)\n", error);
			goto fail;
		}
	}

	/* 
	 * The following settings will be inherited by all sockets created
	 * by this listen socket.
	 */

	/*
	 * Need to be non-blocking to work with the event system.
	 */
	uinet_sosetnonblocking(listener, 1);

	/* Wait 5 seconds for connections to complete */
	optlen = sizeof(optval);
	optval = 5;
	if ((error = uinet_sosetsockopt(listener, UINET_IPPROTO_TCP, UINET_TCP_KEEPINIT, &optval, optlen)))
		goto fail;

	/* Begin counting down to close after 10 seconds of idle */
	optlen = sizeof(optval);
	optval = 10;
	if ((error = uinet_sosetsockopt(listener, UINET_IPPROTO_TCP, UINET_TCP_KEEPIDLE, &optval, optlen)))
		goto fail;

	/* Count down to close once per second */
	optlen = sizeof(optval);
	optval = 1;
	if ((error = uinet_sosetsockopt(listener, UINET_IPPROTO_TCP, UINET_TCP_KEEPINTVL, &optval, optlen)))
		goto fail;

	/* Close after idle for 3 counts */
	optlen = sizeof(optval);
	optval = 3;
	if ((error = uinet_sosetsockopt(listener, UINET_IPPROTO_TCP, UINET_TCP_KEEPCNT, &optval, optlen)))
		goto fail;

	/* Wait 100 milliseconds for missing TCP segments */
	optlen = sizeof(optval);
	optval = 100;
	if ((error = uinet_sosetsockopt(listener, UINET_IPPROTO_TCP, UINET_TCP_REASSDL, &optval, optlen)))
		goto fail;



	passive = calloc(1, sizeof(struct passive_context));
	if (NULL == passive) {
		goto fail;
	}

	passive->loop = loop;
	passive->listener = listener;
	passive->verbose = cfg->verbose;
	passive->interface = cfg->interface;
	passive->extract = cfg->extract;
	memcpy(passive->content_types, cfg->content_types, sizeof(passive->content_types));

	memset(&sin, 0, sizeof(struct uinet_sockaddr_in));
	sin.sin_len = sizeof(struct uinet_sockaddr_in);
	sin.sin_family = UINET_AF_INET;
	sin.sin_addr = addr;
	sin.sin_port = htons(cfg->listen_port);
	error = uinet_sobind(listener, (struct uinet_sockaddr *)&sin);
	if (0 != error) {
		printf("bind failed\n");
		goto fail;
	}
	
	error = uinet_solisten(passive->listener, -1);
	if (0 != error)
		goto fail;

	if (passive->verbose) {
		char buf[32];

		printf("Listening on %s:%u\n", uinet_inet_ntoa(addr, buf, sizeof(buf)), cfg->listen_port);
	}

	ev_init(&passive->listen_watcher, accept_cb);
	ev_uinet_set(&passive->listen_watcher, soctx, EV_READ);
	passive->listen_watcher.data = passive;
	ev_uinet_start(loop, &passive->listen_watcher);

	return (passive);

fail:
	if (soctx) ev_uinet_detach(soctx);
	if (listener) uinet_soclose(listener);
	if (passive) free(passive);

	return (NULL);
}
Ejemplo n.º 2
0
static int
passive_start(struct uinet_demo_config *cfg, uinet_instance_t uinst, struct ev_loop *loop)
{
	struct uinet_demo_passive *passive = (struct uinet_demo_passive *)cfg;
	struct uinet_socket *listen_socket = NULL;
	struct ev_uinet_ctx *soctx = NULL;
	struct uinet_in_addr addr;
	int optlen, optval;
	int error;
	struct uinet_sockaddr_in sin;

	if (uinet_inet_pton(UINET_AF_INET, passive->listen_addr, &addr) <= 0) {
		printf("%s: Malformed address %s\n", passive->cfg.name, passive->listen_addr);
		error = UINET_EINVAL;
		goto fail;
	}

	error = uinet_socreate(passive->cfg.uinst, UINET_PF_INET, &listen_socket, UINET_SOCK_STREAM, 0);
	if (0 != error) {
		printf("%s: Listen socket creation failed (%d)\n", passive->cfg.name, error);
		goto fail;
	}

	soctx = ev_uinet_attach(listen_socket);
	if (NULL == soctx) {
		printf("%s: Failed to alloc libev socket context\n", passive->cfg.name);
		error = UINET_ENOMEM;
		goto fail;
	}
	
	if ((error = uinet_make_socket_passive(listen_socket))) {
		printf("%s: Failed to make listen socket passive (%d)\n", passive->cfg.name, error);
		goto fail;
	}

	if (passive->promisc) {
		if ((error = uinet_make_socket_promiscuous(listen_socket, NULL))) {
			printf("%s: Failed to make listen socket promiscuous (%d)\n", passive->cfg.name, error);
			goto fail;
		}
	}

	/* 
	 * The following settings will be inherited by all sockets created
	 * by this listen socket.
	 */

	/*
	 * Need to be non-blocking to work with the event system.
	 */
	uinet_sosetnonblocking(listen_socket, 1);

	/* Wait 5 seconds for connections to complete */
	optlen = sizeof(optval);
	optval = 5;
	if ((error = uinet_sosetsockopt(listen_socket, UINET_IPPROTO_TCP, UINET_TCP_KEEPINIT, &optval, optlen))) {
		printf("%s: Failed to set TCP_KEEPINIT (%d)\n", passive->cfg.name, error);
		goto fail;
	}

	/* Begin counting down to close after 10 seconds of idle */
	optlen = sizeof(optval);
	optval = 10;
	if ((error = uinet_sosetsockopt(listen_socket, UINET_IPPROTO_TCP, UINET_TCP_KEEPIDLE, &optval, optlen))) {
		printf("%s: Failed to set TCP_KEEPIDLE (%d)\n", passive->cfg.name, error);
		goto fail;
	}

	/* Count down to close once per second */
	optlen = sizeof(optval);
	optval = 1;
	if ((error = uinet_sosetsockopt(listen_socket, UINET_IPPROTO_TCP, UINET_TCP_KEEPINTVL, &optval, optlen))) {
		printf("%s: Failed to set TCP_KEEPINTVL (%d)\n", passive->cfg.name, error);
		goto fail;
	}

	/* Close after idle for 3 counts */
	optlen = sizeof(optval);
	optval = 3;
	if ((error = uinet_sosetsockopt(listen_socket, UINET_IPPROTO_TCP, UINET_TCP_KEEPCNT, &optval, optlen))) {
		printf("%s: Failed to set TCP_KEEPCNT (%d)\n", passive->cfg.name, error);
		goto fail;
	}

	/* Wait 100 milliseconds for missing TCP segments */
	optlen = sizeof(optval);
	optval = 100;
	if ((error = uinet_sosetsockopt(listen_socket, UINET_IPPROTO_TCP, UINET_TCP_REASSDL, &optval, optlen))) {
		printf("%s: Failed to set TCP_REASSDL (%d)\n", passive->cfg.name, error);
		goto fail;
	}


	passive->listen_socket = listen_socket;

	memset(&sin, 0, sizeof(struct uinet_sockaddr_in));
	sin.sin_len = sizeof(struct uinet_sockaddr_in);
	sin.sin_family = UINET_AF_INET;
	sin.sin_addr = addr;
	sin.sin_port = htons(passive->listen_port);
	error = uinet_sobind(listen_socket, (struct uinet_sockaddr *)&sin);
	if (0 != error) {
		printf("%s: Bind to %s:%u failed\n", passive->cfg.name,
		       passive->listen_addr, passive->listen_port);
		goto fail;
	}
	
	error = uinet_solisten(passive->listen_socket, -1);
	if (0 != error) {
		printf("%s: Listen on %s:%u failed\n", passive->cfg.name,
		       passive->listen_addr, passive->listen_port);
		goto fail;
	}

	if (passive->cfg.verbose)
		printf("%s: Listening on %s:%u\n", passive->cfg.name,
		       passive->listen_addr, passive->listen_port);

	ev_init(&passive->listen_watcher, passive_accept_cb);
	ev_uinet_set(&passive->listen_watcher, soctx, EV_READ);
	passive->listen_watcher.data = passive;
	ev_uinet_start(loop, &passive->listen_watcher);

	return (0);

fail:
	if (soctx) ev_uinet_detach(soctx);
	if (listen_socket) uinet_soclose(listen_socket);

	return (error);
}