static int handler_tcp_tun_to_net(int fd, const struct worker_struct *ws,
				  char *buff, size_t len)
{
	int dfd, keep = 1;
	char *cbuff;
	ssize_t rlen, err, clen;
	struct ct_proto *hdr;
	struct curve25519_proto *p;
	socklen_t nlen;
	size_t off = sizeof(struct ct_proto) + crypto_box_zerobytes;

	if (!buff || len <= off)
		return 0;

	memset(buff, 0, len);
	while ((rlen = read(fd, buff + off, len - off)) > 0) {
		dfd = -1; p = NULL;

		hdr = (struct ct_proto *) buff;
		memset(hdr, 0, sizeof(*hdr));
		hdr->flags = 0;

		trie_addr_lookup(buff + off, rlen, ws->parent.ipv4, &dfd, NULL,
				 (size_t *) &nlen);
		if (unlikely(dfd < 0)) {
			memset(buff, 0, len);
			continue;
		}

		err = get_user_by_socket(dfd, &p);
		if (unlikely(err || !p)) {
			memset(buff, 0, len);
			continue;
		}

		clen = curve25519_encode(ws->c, p, (unsigned char *) (buff + off -
					 crypto_box_zerobytes), (rlen +
					 crypto_box_zerobytes), (unsigned char **)
					 &cbuff);
		if (unlikely(clen <= 0)) {
			memset(buff, 0, len);
			continue;
		}

		hdr->payload = htons((uint16_t) clen);

		set_tcp_cork(dfd);

		write_exact(dfd, hdr, sizeof(struct ct_proto), 0);
		write_exact(dfd, cbuff, clen, 0);

		set_tcp_uncork(dfd);

		memset(buff, 0, len);
	}

	return keep;
}
Exemple #2
0
int toggle_tcp_cork(int fd)
{
#ifdef __LINUX__
	int opt = 0;

	DEBUG_MSG(LOG_WARNING, "Clearing TCP_CORK on fd %d", fd);
	if (setsockopt(fd, SOL_TCP, TCP_CORK, &opt, sizeof(opt)) == -1)
		return -1;
	return set_tcp_cork(fd);
#else
	UNUSED_ARGUMENT(fd);
	DEBUG_MSG(LOG_ERR, "Cannot toggle TCP_CORK for OS other than Linux");
	return -1;
#endif
}
Exemple #3
0
static void handler_tcp_tun_to_net(int sfd, int dfd, struct curve25519_proto *p,
				   struct curve25519_struct *c, char *buff,
				   size_t len)
{
	char *cbuff;
	ssize_t rlen, clen;
	struct ct_proto *hdr;
	size_t off = sizeof(struct ct_proto) + crypto_box_zerobytes;

	if (!buff || len <= off)
		return;

	memset(buff, 0, len);
	while ((rlen = read(sfd, buff + off, len - off)) > 0) {
		hdr = (struct ct_proto *) buff;

		memset(hdr, 0, sizeof(*hdr));
		hdr->flags = 0;

		clen = curve25519_encode(c, p, (unsigned char *) (buff + off -
					 crypto_box_zerobytes), (rlen +
					 crypto_box_zerobytes), (unsigned char **)
					 &cbuff);
		if (unlikely(clen <= 0))
			goto close;

		hdr->payload = htons((uint16_t) clen);

		set_tcp_cork(dfd);

		write_exact(dfd, hdr, sizeof(struct ct_proto), 0);
		write_exact(dfd, cbuff, clen, 0);

		set_tcp_uncork(dfd);

		memset(buff, 0, len);
	}

	return;
close:
	closed_by_server = 1;
}