Esempio n. 1
0
static void
echo_connected_cb(struct ev_loop *loop, ev_uinet *w, int revents)
{
	struct echo_connection *conn = w->data;
	struct uinet_demo_echo *echo = conn->echo;
	struct uinet_sockaddr_in *sin1, *sin2;
	char buf1[32], buf2[32];
	int error;
	
	if (conn->verbose) {
		uinet_sogetsockaddr(w->so, (struct uinet_sockaddr **)&sin1);
		uinet_sogetpeeraddr(w->so, (struct uinet_sockaddr **)&sin2);
		printf("%s: connection %llu: established (local=%s:%u foreign=%s:%u)\n",
		       echo->cfg.name, (unsigned long long)conn->id,
		       uinet_inet_ntoa(sin1->sin_addr, buf1, sizeof(buf1)), ntohs(sin1->sin_port),
		       uinet_inet_ntoa(sin2->sin_addr, buf2, sizeof(buf2)), ntohs(sin2->sin_port));
		uinet_free_sockaddr((struct uinet_sockaddr *)sin1);
		uinet_free_sockaddr((struct uinet_sockaddr *)sin2);
	}

	if ((echo->cfg.copy_mode & UINET_IP_COPY_MODE_MAYBE) &&
	    ((uinet_sogetserialno(w->so) % echo->cfg.copy_every) == 0)){
		if ((error =
		     uinet_sosetcopymode(w->so, UINET_IP_COPY_MODE_RX|UINET_IP_COPY_MODE_ON,
					 echo->cfg.copy_limit, echo->cfg.copy_uif)))
			printf("%s: Failed to set copy mode (%d)\n",
			       echo->cfg.name, error);	
	}
	ev_uinet_stop(loop, w);
}
Esempio n. 2
0
static struct passive_connection *
create_conn(struct uinet_demo_passive *passive, struct uinet_socket *so, int server)
{
	struct passive_connection *conn = NULL;
	struct ev_uinet_ctx *soctx = NULL;
	struct uinet_sockaddr_in *sin1, *sin2;
	char buf1[32], buf2[32];

	conn = calloc(1, sizeof(*conn));
	if (NULL == conn) {
		printf("%s: Failed to alloc connection context for new connection\n",
			passive->cfg.name);
		goto fail;
	}

	soctx = ev_uinet_attach(so);
	if (NULL == soctx) {
		printf("%s: Failed to alloc libev context for new connection socket\n",
			passive->cfg.name);
		goto fail;
	}

	uinet_sogetsockaddr(so, (struct uinet_sockaddr **)&sin1);
	uinet_sogetpeeraddr(so, (struct uinet_sockaddr **)&sin2);
	snprintf(conn->label, sizeof(conn->label), "%s (%s:%u <- %s:%u)",
		 server ? "SERVER" : "CLIENT",
		 uinet_inet_ntoa(sin1->sin_addr, buf1, sizeof(buf1)), ntohs(sin1->sin_port),
		 uinet_inet_ntoa(sin2->sin_addr, buf2, sizeof(buf2)), ntohs(sin2->sin_port));
	uinet_free_sockaddr((struct uinet_sockaddr *)sin1);
	uinet_free_sockaddr((struct uinet_sockaddr *)sin2);

	conn->verbose = passive->cfg.verbose;
	conn->server = passive;

	ev_init(&conn->watcher, passive_receive_cb);
	ev_uinet_set(&conn->watcher, soctx, EV_READ);
	conn->watcher.data = conn;

	ev_init(&conn->connected_watcher, passive_connected_cb);
	ev_uinet_set(&conn->connected_watcher, soctx, EV_WRITE);
	conn->connected_watcher.data = conn;

	return (conn);

fail:
	if (conn) free(conn);
	if (soctx) ev_uinet_detach(soctx);

	return (NULL);
}
Esempio n. 3
0
static void
nproxy_outbound_connected_cb(struct ev_loop *loop, ev_uinet *w, int revents)
{
	struct nproxy_splice *splice = w->data;
	struct uinet_demo_nproxy *nproxy = splice->nproxy;
	struct uinet_sockaddr_in *sin1, *sin2;
	char buf1[32], buf2[32];

	ev_uinet_stop(loop, w);

	if (splice->verbose) {
		uinet_sogetsockaddr(w->so, (struct uinet_sockaddr **)&sin1);
		uinet_sogetpeeraddr(w->so, (struct uinet_sockaddr **)&sin2);
		printf("%s: splice %llu: outbound connection established (local=%s:%u foreign=%s:%u)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id,
		       uinet_inet_ntoa(sin1->sin_addr, buf1, sizeof(buf1)), ntohs(sin1->sin_port),
		       uinet_inet_ntoa(sin2->sin_addr, buf2, sizeof(buf2)), ntohs(sin2->sin_port));
		uinet_free_sockaddr((struct uinet_sockaddr *)sin1);
		uinet_free_sockaddr((struct uinet_sockaddr *)sin2);
	}

	ev_uinet_start(loop, &splice->inbound.copy_watcher);
	ev_uinet_start(loop, &splice->outbound.copy_watcher);
}
Esempio n. 4
0
static struct connection_context *
create_conn(struct passive_context *passive, struct uinet_socket *so, int server)
{
	struct connection_context *conn = NULL;
	struct ev_uinet_ctx *soctx = NULL;
	struct uinet_sockaddr_in *sin1, *sin2;
	char buf1[32], buf2[32];
	time_t now_timet;
	struct tm now;
#define EXTRACT_BUFFER_SIZE 1024

	conn = calloc(1, sizeof(*conn));
	if (NULL == conn) {
		printf("Failed to alloc connection context for new connection\n");
		goto fail;
	}

	soctx = ev_uinet_attach(so);
	if (NULL == soctx) {
		printf("Failed to alloc libev context for new connection socket\n");
		goto fail;
	}

	uinet_sogetsockaddr(so, (struct uinet_sockaddr **)&sin1);
	uinet_sogetpeeraddr(so, (struct uinet_sockaddr **)&sin2);
	snprintf(conn->label, sizeof(conn->label), "%s (%s:%u <- %s:%u)",
		 server ? "SERVER" : "CLIENT",
		 uinet_inet_ntoa(sin1->sin_addr, buf1, sizeof(buf1)), ntohs(sin1->sin_port),
		 uinet_inet_ntoa(sin2->sin_addr, buf2, sizeof(buf2)), ntohs(sin2->sin_port));
#ifdef ENABLE_EXTRACT
	if (passive->extract && !server) {
		time(&now_timet);
		localtime_r(&now_timet, &now);
		snprintf(conn->filename_prefix, sizeof(conn->filename_prefix),
			 "extract-%04d%02d%02d-%02d%02d.%02d-%s.%u-%s.%u",
			 now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec,
			 uinet_inet_ntoa(sin1->sin_addr, buf1, sizeof(buf1)), ntohs(sin1->sin_port),
			 uinet_inet_ntoa(sin2->sin_addr, buf2, sizeof(buf2)), ntohs(sin2->sin_port));
	}
#endif
	uinet_free_sockaddr((struct uinet_sockaddr *)sin1);
	uinet_free_sockaddr((struct uinet_sockaddr *)sin2);

	conn->verbose = passive->verbose;
	conn->server = passive;
	if (passive->extract) {
#ifdef ENABLE_EXTRACT
		if (0 != parser_init(conn, server ? HTTP_REQUEST : HTTP_RESPONSE))
			goto fail;
		conn->buffer_size = EXTRACT_BUFFER_SIZE;
		conn->buffer = malloc(conn->buffer_size);
		if (NULL == conn->buffer)
			goto fail;
		ev_init(&conn->watcher, passive_extract_cb);
#else
		goto fail;
#endif
	} else {
		ev_init(&conn->watcher, passive_receive_cb);
	}
	ev_uinet_set(&conn->watcher, soctx, EV_READ);
	conn->watcher.data = conn;

	return (conn);

fail:
#ifdef ENABLE_EXTRACT
	if (conn->buffer) free(conn->buffer);
	if (conn->parser) free(conn->parser);
#endif
	if (conn) free(conn);
	if (soctx) ev_uinet_detach(soctx);

	return (NULL);
}
Esempio n. 5
0
static void
nproxy_inbound_connected_cb(struct ev_loop *loop, ev_uinet *w, int revents)
{
	struct nproxy_splice *splice = w->data;
	struct uinet_demo_nproxy *nproxy = splice->nproxy;
	struct uinet_sockaddr_in *sin_local, *sin_foreign;
	struct uinet_socket *outbound_socket = NULL;
	struct ev_uinet_ctx *soctx = NULL;
	struct uinet_in_l2info l2i;
	char buf1[32], buf2[32];
	int optlen, optval;
	int error;
	
	uinet_sogetsockaddr(w->so, (struct uinet_sockaddr **)&sin_local);
	uinet_sogetpeeraddr(w->so, (struct uinet_sockaddr **)&sin_foreign);
	if (splice->verbose)
		printf("%s: splice %llu: inbound connection established (local=%s:%u foreign=%s:%u)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id,
		       uinet_inet_ntoa(sin_local->sin_addr, buf1, sizeof(buf1)), ntohs(sin_local->sin_port),
		       uinet_inet_ntoa(sin_foreign->sin_addr, buf2, sizeof(buf2)), ntohs(sin_foreign->sin_port));

	if ((nproxy->cfg.copy_mode & UINET_IP_COPY_MODE_MAYBE) &&
	    ((uinet_sogetserialno(w->so) % nproxy->cfg.copy_every) == 0)){
		if ((error =
		     uinet_sosetcopymode(w->so, UINET_IP_COPY_MODE_RX|UINET_IP_COPY_MODE_ON,
					 nproxy->cfg.copy_limit, nproxy->cfg.copy_uif)))
			printf("%s: splice %llu: Failed to set copy mode (%d)\n",
			       nproxy->cfg.name, (unsigned long long)splice->id, error);	
	}

	/* don't need this watcher anymore */
	ev_uinet_stop(loop, w);
	
	/* Create the outbound connection */
	error = uinet_socreate(nproxy->cfg.uinst, UINET_PF_INET, &outbound_socket, UINET_SOCK_STREAM, 0);
	if (error != 0) {
		printf("%s: splice %llu: outbound socket creation failed (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}

	if ((error = uinet_make_socket_promiscuous(outbound_socket, nproxy->outbound_if))) {
		printf("%s: splice %llu: failed to make outbound socket promiscuous (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}
	
	/*
	 * Socket needs to be non-blocking to work with the event system
	 */
	uinet_sosetnonblocking(outbound_socket, 1);

	optlen = sizeof(optval);
	optval = 1;
	error = uinet_sosetsockopt(outbound_socket, UINET_IPPROTO_TCP, UINET_TCP_NODELAY,
				   &optval, optlen);
	if (error != 0) {
		printf("%s: splice %llu: failed to set TCP_NODELAY on outbound socket (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}

	/* Bind to the foreign address of the inbound connection */
	error = uinet_sobind(outbound_socket, (struct uinet_sockaddr *)sin_foreign);
	if (error != 0) {
		printf("%s: splice %llu: outbound socket bind failed (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}

	/*
	 * Use the same MAC addrs and VLAN tag stack as the inbound
	 * connection, which requires swapping the local and foreign MAC
	 * addrs.
	 */
	error = uinet_getl2info(w->so, &l2i);
	if (error != 0) {
		printf("%s: splice %llu: unable to get l2info from inbound socket (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}

	error = uinet_setl2info2(outbound_socket,
				 l2i.inl2i_foreign_addr, l2i.inl2i_local_addr,
				 l2i.inl2i_flags, &l2i.inl2i_tagstack);
	if (error != 0) {
		printf("%s: splice %llu: unable to set l2info for outbound socket (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}

	soctx = ev_uinet_attach(outbound_socket);
	if (NULL == soctx) {
		printf("%s: splice %llu: failed to alloc libev context for outbound socket\n",
		       nproxy->cfg.name, (unsigned long long)splice->id);
		goto fail;
	}

	/* The connection target is the local address of the inbound connection */
	error = uinet_soconnect(outbound_socket, (struct uinet_sockaddr *)sin_local);
	if ((error != 0) && (error != UINET_EINPROGRESS)) {
		printf("%s: splice %llu: outbound socket connect failed (%d)\n",
		       nproxy->cfg.name, (unsigned long long)splice->id, error);
		goto fail;
	}
	
	uinet_free_sockaddr((struct uinet_sockaddr *)sin_local);
	uinet_free_sockaddr((struct uinet_sockaddr *)sin_foreign);

	ev_init(&splice->outbound.connected_watcher, nproxy_outbound_connected_cb);
	ev_uinet_set(&splice->outbound.connected_watcher, soctx, EV_WRITE);
	splice->outbound.connected_watcher.data = splice;
	ev_uinet_start(loop, &splice->outbound.connected_watcher);

	ev_init(&splice->outbound.writable_watcher, nproxy_writable_cb);
	ev_uinet_set(&splice->outbound.writable_watcher, soctx, EV_WRITE);
	splice->outbound.writable_watcher.data = &splice->outbound;
	/* will be started as necessary by the inbound copy watcher */
	
	ev_init(&splice->outbound.copy_watcher, nproxy_copy_cb);
	ev_uinet_set(&splice->outbound.copy_watcher, soctx, EV_READ);
	splice->outbound.copy_watcher.data = &splice->outbound;
	/* will be started when the outbound connection is established */
	
	return;

 fail:
	uinet_free_sockaddr((struct uinet_sockaddr *)sin_local);
	uinet_free_sockaddr((struct uinet_sockaddr *)sin_foreign);
	if (soctx) ev_uinet_detach(soctx);
	if (outbound_socket) uinet_soclose(outbound_socket);
	free(splice);
}