Beispiel #1
0
void
net_send_stream(struct connection *c, void *data, u_int32_t len,
    int (*cb)(struct netbuf *), struct netbuf **out)
{
	struct netbuf		*nb;

	kore_debug("net_send_stream(%p, %p, %d)", c, data, len);

	nb = kore_pool_get(&nb_pool);
	nb->cb = cb;
	nb->owner = c;
	nb->s_off = 0;
	nb->buf = data;
	nb->b_len = len;
	nb->m_len = nb->b_len;
	nb->type = NETBUF_SEND;
	nb->flags  = NETBUF_IS_STREAM;

	TAILQ_INSERT_TAIL(&(c->send_queue), nb, list);
	if (out != NULL)
		*out = nb;
}
Beispiel #2
0
int
net_write_ssl(struct connection *c, int len, int *written)
{
	int		r;

	r = SSL_write(c->ssl, (c->snb->buf + c->snb->s_off), len);
	if (c->tls_reneg > 1)
		return (KORE_RESULT_ERROR);

	if (r <= 0) {
		r = SSL_get_error(c->ssl, r);
		switch (r) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			c->snb->flags |= NETBUF_MUST_RESEND;
			c->flags &= ~CONN_WRITE_POSSIBLE;
			return (KORE_RESULT_OK);
		case SSL_ERROR_SYSCALL:
			switch (errno) {
			case EINTR:
				*written = 0;
				return (KORE_RESULT_OK);
			case EAGAIN:
				c->snb->flags |= NETBUF_MUST_RESEND;
				c->flags &= ~CONN_WRITE_POSSIBLE;
				return (KORE_RESULT_OK);
			default:
				break;
			}
			/* FALLTHROUGH */
		default:
			kore_debug("SSL_write(): %s", ssl_errno_s);
			return (KORE_RESULT_ERROR);
		}
	}

	*written = r;
	return (KORE_RESULT_OK);
}
Beispiel #3
0
int
net_read(struct connection *c, int *bytes)
{
	int		r;

	r = read(c->fd, (c->rnb->buf + c->rnb->s_off),
	    (c->rnb->b_len - c->rnb->s_off));
	if (r <= 0) {
		switch (errno) {
		case EINTR:
		case EAGAIN:
			c->flags &= ~CONN_READ_POSSIBLE;
			return (KORE_RESULT_OK);
		default:
			kore_debug("read(): %s", errno_s);
			return (KORE_RESULT_ERROR);
		}
	}

	*bytes = r;
	return (KORE_RESULT_OK);
}
Beispiel #4
0
Datei: net.c Projekt: jdiego/kore
int
net_read_ssl(struct connection *c, int *bytes)
{
	int		r;

	r = SSL_read(c->ssl, (c->rnb->buf + c->rnb->s_off),
	    (c->rnb->b_len - c->rnb->s_off));
	if (r <= 0) {
		r = SSL_get_error(c->ssl, r);
		switch (r) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			c->flags &= ~CONN_READ_POSSIBLE;
			return (KORE_RESULT_OK);
		default:
			kore_debug("SSL_read(): %s", ssl_errno_s);
			return (KORE_RESULT_ERROR);
		}
	}

	*bytes = r;
	return (KORE_RESULT_OK);
}
Beispiel #5
0
Datei: net.c Projekt: jdiego/kore
int
net_write_ssl(struct connection *c, int len, int *written)
{
	int		r;

	r = SSL_write(c->ssl, (c->snb->buf + c->snb->s_off), len);
	if (r <= 0) {
		r = SSL_get_error(c->ssl, r);
		switch (r) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			c->snb->flags |= NETBUF_MUST_RESEND;
			c->flags &= ~CONN_WRITE_POSSIBLE;
			return (KORE_RESULT_OK);
		default:
			kore_debug("SSL_write(): %s", ssl_errno_s);
			return (KORE_RESULT_ERROR);
		}
	}

	*written = r;
	return (KORE_RESULT_OK);
}
Beispiel #6
0
int
net_write(struct connection *c, int len, int *written)
{
	int		r;

	r = write(c->fd, (c->snb->buf + c->snb->s_off), len);
	if (r <= -1) {
		switch (errno) {
		case EINTR:
			*written = 0;
			return (KORE_RESULT_OK);
		case EAGAIN:
			c->flags &= ~CONN_WRITE_POSSIBLE;
			return (KORE_RESULT_OK);
		default:
			kore_debug("write: %s", errno_s);
			return (KORE_RESULT_ERROR);
		}
	}

	*written = r;
	return (KORE_RESULT_OK);
}
Beispiel #7
0
void
kore_platform_proctitle(char *title)
{
	if (prctl(PR_SET_NAME, title) == -1)
		kore_debug("prctl(): %s", errno_s);
}
Beispiel #8
0
Datei: bsd.c Projekt: abpin/kore
int
kore_platform_event_wait(void)
{
	struct connection	*c;
	struct timespec		timeo;
	int			n, i, *fd;

	timeo.tv_sec = 0;
	timeo.tv_nsec = 100000000;
	n = kevent(kfd, changelist, nchanges, events, event_count, &timeo);
	if (n == -1) {
		if (errno == EINTR)
			return (0);
		fatal("kevent(): %s", errno_s);
	}

	nchanges = 0;
	if (n > 0)
		kore_debug("main(): %d sockets available", n);

	for (i = 0; i < n; i++) {
		fd = (int *)events[i].udata;

		if (events[i].flags & EV_EOF ||
		    events[i].flags & EV_ERROR) {
			if (*fd == server.fd)
				fatal("error on server socket");

			c = (struct connection *)events[i].udata;
			kore_connection_disconnect(c);
			continue;
		}

		if (*fd == server.fd) {
			while (worker->accepted < worker->accept_treshold) {
				kore_connection_accept(&server, &c);
				if (c == NULL)
					continue;

				worker->accepted++;
				kore_platform_event_schedule(c->fd,
				    EVFILT_READ, EV_ADD, c);
				kore_platform_event_schedule(c->fd,
				    EVFILT_WRITE, EV_ADD | EV_ONESHOT, c);
			}
		} else {
			c = (struct connection *)events[i].udata;
			if (events[i].filter == EVFILT_READ)
				c->flags |= CONN_READ_POSSIBLE;
			if (events[i].filter == EVFILT_WRITE)
				c->flags |= CONN_WRITE_POSSIBLE;

			if (!kore_connection_handle(c)) {
				kore_connection_disconnect(c);
			} else {
				if (!TAILQ_EMPTY(&(c->send_queue))) {
					kore_platform_event_schedule(c->fd,
					    EVFILT_WRITE, EV_ADD | EV_ONESHOT,
					    c);
				}
			}
		}
	}

	return (count);
}
Beispiel #9
0
int
kore_connection_handle(struct connection *c)
{
	int			r;
	u_int32_t		len;
	const u_char		*data;

	kore_debug("kore_connection_handle(%p)", c);

	if (c->proto != CONN_PROTO_SPDY)
		kore_connection_stop_idletimer(c);

	switch (c->state) {
	case CONN_STATE_SSL_SHAKE:
		if (c->ssl == NULL) {
			c->ssl = SSL_new(primary_dom->ssl_ctx);
			if (c->ssl == NULL) {
				kore_debug("SSL_new(): %s", ssl_errno_s);
				return (KORE_RESULT_ERROR);
			}

			SSL_set_fd(c->ssl, c->fd);
			SSL_set_accept_state(c->ssl);
		}

		r = SSL_accept(c->ssl);
		if (r <= 0) {
			r = SSL_get_error(c->ssl, r);
			switch (r) {
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				return (KORE_RESULT_OK);
			default:
				kore_debug("SSL_accept(): %s", ssl_errno_s);
				return (KORE_RESULT_ERROR);
			}
		}

		r = SSL_get_verify_result(c->ssl);
		if (r != X509_V_OK) {
			kore_debug("SSL_get_verify_result(): %s", ssl_errno_s);
			return (KORE_RESULT_ERROR);
		}

		SSL_get0_next_proto_negotiated(c->ssl, &data, &len);
		if (data) {
			if (!memcmp(data, "spdy/3", MIN(6, len))) {
				c->proto = CONN_PROTO_SPDY;
				net_recv_queue(c, SPDY_FRAME_SIZE, 0,
				    NULL, spdy_frame_recv);
			} else if (!memcmp(data, "http/1.1", MIN(8, len))) {
				c->proto = CONN_PROTO_HTTP;
				net_recv_queue(c, HTTP_HEADER_MAX_LEN,
				    NETBUF_CALL_CB_ALWAYS, NULL,
				    http_header_recv);
			} else {
				kore_debug("npn: received unknown protocol");
			}
		} else {
			c->proto = CONN_PROTO_HTTP;
			net_recv_queue(c, HTTP_HEADER_MAX_LEN,
			    NETBUF_CALL_CB_ALWAYS, NULL,
			    http_header_recv);
		}

		c->state = CONN_STATE_ESTABLISHED;
		/* FALLTHROUGH */
	case CONN_STATE_ESTABLISHED:
		if (c->flags & CONN_READ_POSSIBLE) {
			if (!net_recv_flush(c))
				return (KORE_RESULT_ERROR);
		}

		if (c->flags & CONN_WRITE_POSSIBLE) {
			if (!net_send_flush(c))
				return (KORE_RESULT_ERROR);
		}
		break;
	case CONN_STATE_DISCONNECTING:
		break;
	default:
		kore_debug("unknown state on %d (%d)", c->fd, c->state);
		break;
	}

	if (c->proto != CONN_PROTO_SPDY)
		kore_connection_start_idletimer(c);

	return (KORE_RESULT_OK);
}
Beispiel #10
0
void
kore_task_finish(struct kore_task *t)
{
	kore_debug("kore_task_finished: %p (%d)", t, t->result);
	close(t->fds[1]);
}