示例#1
0
文件: proxy.c 项目: 1514louluo/kore
/*
 * Called for every new connection on a certain ip/port. Which one is
 * configured in the TLS proxy its configuration file.
 */
void
client_setup(struct connection *c)
{
	int			i, fd;
	struct connection	*backend;

	/* Paranoia. */
	if (c->ssl->session == NULL ||
	    c->ssl->session->tlsext_hostname == NULL) {
		kore_connection_disconnect(c);
		return;
	}

	/* Figure out what backend to use. */
	for (i = 0; backends[i].name != NULL; i++) {
		if (!strcasecmp(backends[i].name,
		    c->ssl->session->tlsext_hostname))
			break;
	}

	/* If we don't have any backends, we just disconnect the client. */
	if (backends[i].name == NULL) {
		kore_connection_disconnect(c);
		return;
	}

	/* Create new socket for the backend connection. */
	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		kore_log(LOG_ERR, "socket(): %s", errno_s);
		kore_connection_disconnect(c);
		return;
	}

	/* Set it to non blocking as well. */
	if (!kore_connection_nonblock(fd, 1)) {
		close(fd);
		kore_connection_disconnect(c);
		return;
	}

	/* Grab a new connection from Kore to hook backend into. */
	backend = kore_connection_new(NULL);

	/* Prepare our connection. */
	backend->addrtype = AF_INET;
	backend->addr.ipv4.sin_family = AF_INET;
	backend->addr.ipv4.sin_port = htons(backends[i].port);
	backend->addr.ipv4.sin_addr.s_addr = inet_addr(backends[i].ip);

	/* Set the file descriptor for the backend. */
	backend->fd = fd;

	/* Default write/read callbacks for backend. */
	backend->read = net_read;
	backend->write = net_write;

	/* Connection type (unknown to Kore). */
	backend->proto = CONN_PROTO_UNKNOWN;
	backend->state = CONN_STATE_ESTABLISHED;

	/* The backend idle timer is set first to connection timeout. */
	backend->idle_timer.length = PROXY_CONNECT_TIMEOUT;

	/* The client idle timer is set to default idle time. */
	c->idle_timer.length = PROXY_TIMEOUT;

	/* Now link both the client and the backend connection together. */
	c->hdlr_extra = backend;
	backend->hdlr_extra = c;

	/*
	 * The handle function pointer for the backend is set to the
	 * backend_handle_connect() while connecting.
	 */
	c->handle = client_handle;
	backend->handle = backend_handle_connect;

	/* Set the disconnect method for both connections. */
	c->disconnect = disconnect;
	backend->disconnect = disconnect;

	/* Queue write events for the backend connection for now. */
	kore_platform_schedule_write(backend->fd, backend);

	/* Start idle timer for the backend. */
	kore_connection_start_idletimer(backend);

	/* Set our client connection to established. */
	c->state = CONN_STATE_ESTABLISHED;

	/* Insert the backend into the list of Kore connections. */
	TAILQ_INSERT_TAIL(&connections, backend, list);

	/* Kick off connecting. */
	backend->flags |= CONN_WRITE_POSSIBLE;
	backend->handle(backend);
}
示例#2
0
文件: ktunnel.c 项目: 2ion/kore
/*
 * Connect to our target host:port and attach it to a struct connection that
 * Kore understands. We set the disconnect method so we get a callback
 * whenever either of the connections will go away so we can cleanup the
 * one it is attached to.
 */
static int
ktunnel_pipe_create(struct connection *c, const char *host, const char *port)
{
	struct sockaddr_in	sin;
	struct connection	*cpipe;
	u_int16_t		nport;
	int			fd, err;

	nport = kore_strtonum(port, 10, 1, SHRT_MAX, &err);
	if (err == KORE_RESULT_ERROR) {
		kore_log(LOG_ERR, "invalid port given %s", port);
		return (KORE_RESULT_ERROR);
	}

	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		kore_log(LOG_ERR, "socket(): %s", errno_s);
		return (KORE_RESULT_ERROR);
	}

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(nport);
	sin.sin_addr.s_addr = inet_addr(host);

	kore_log(LOG_NOTICE, "Attempting to connect to %s:%s", host, port);

	if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
		close(fd);
		kore_log(LOG_ERR, "connect(): %s", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (!kore_connection_nonblock(fd)) {
		close(fd);
		return (KORE_RESULT_ERROR);
	}

	cpipe = kore_connection_new(c);
	cpipe->fd = fd;
	cpipe->addr.ipv4 = sin;
	cpipe->read = net_read;
	cpipe->write = net_write;
	cpipe->addrtype = AF_INET;
	cpipe->proto = CONN_PROTO_UNKNOWN;
	cpipe->state = CONN_STATE_ESTABLISHED;

	/* Don't let these connections timeout any time soon. */
	cpipe->idle_timer.length = 10000000000;
	c->idle_timer.length = 10000000000;

	c->hdlr_extra = cpipe;
	cpipe->hdlr_extra = c;
	c->disconnect = ktunnel_pipe_disconnect;
	cpipe->disconnect = ktunnel_pipe_disconnect;

	kore_worker_connection_add(cpipe);
	kore_connection_start_idletimer(cpipe);
	kore_platform_event_all(cpipe->fd, cpipe);

	net_recv_reset(c, NETBUF_SEND_PAYLOAD_MAX, ktunnel_pipe_data);
	net_recv_queue(cpipe, NETBUF_SEND_PAYLOAD_MAX, NETBUF_CALL_CB_ALWAYS,
	    ktunnel_pipe_data);

	printf("connection started to %s (%p -> %p)\n", host, c, cpipe);
	return (KORE_RESULT_OK);
}