Esempio n. 1
0
static void
pool_region_create(struct kore_pool *pool, u_int32_t elms)
{
	u_int32_t			i;
	u_int8_t			*p;
	struct kore_pool_region		*reg;
	struct kore_pool_entry		*entry;

	kore_debug("pool_region_create(%p, %d)", pool, elms);

	reg = kore_malloc(sizeof(struct kore_pool_region));
	LIST_INSERT_HEAD(&(pool->regions), reg, list);

	reg->start = kore_malloc(elms * pool->slen);
	p = (u_int8_t *)reg->start;

	for (i = 0; i < elms; i++) {
		entry = (struct kore_pool_entry *)p;
		entry->region = reg;
		entry->state = POOL_ELEMENT_FREE;
		LIST_INSERT_HEAD(&(pool->freelist), entry, list);

		p = p + pool->slen;
	}

	pool->elms += elms;
}
Esempio n. 2
0
struct kore_buf *
kore_buf_create(u_int32_t initial)
{
	struct kore_buf		*buf;

	buf = kore_malloc(sizeof(*buf));
	buf->data = kore_malloc(initial);
	buf->length = initial;
	buf->offset = 0;

	return (buf);
}
Esempio n. 3
0
File: buf.c Progetto: SDAIA/kore
void
kore_buf_replace_string(struct kore_buf *b, char *src, void *dst, size_t len)
{
	char		*key, *end, *tmp, *p;
	size_t		blen, off, off2, nlen, klen;

	off = 0;
	klen = strlen(src);
	for (;;) {
		blen = b->offset;
		nlen = blen + len;
		p = (char *)b->data;

		key = kore_mem_find(p + off, b->offset - off, src, klen);
		if (key == NULL)
			break;

		end = key + klen;
		off = key - p;
		off2 = ((char *)(b->data + b->offset) - end);

		tmp = kore_malloc(nlen);
		memcpy(tmp, p, off);
		if (dst != NULL)
			memcpy((tmp + off), dst, len);
		memcpy((tmp + off + len), end, off2);

		kore_free(b->data);
		b->data = (u_int8_t *)tmp;
		b->offset = off + len + off2;
		b->length = nlen;

		off = off + len;
	}
}
Esempio n. 4
0
/* The initial state, we setup our context and fire off the pgsql query. */
int
request_perform_query(struct http_request *req)
{
	struct rstate	*state;

	/* Setup our state context. */
	state = kore_malloc(sizeof(*state));

	/* Attach the state to our request. */
	req->hdlr_extra = state;

	/* We want to move to read result after this. */
	req->fsm_state = REQ_STATE_DB_WAIT;

	/* Fire off the query. */
	if (!kore_pgsql_async(&state->sql, req, "SELECT * FROM coders")) {
		/* If the state was still INIT, we'll try again later. */
		if (state->sql.state == KORE_PGSQL_STATE_INIT) {
			req->fsm_state = REQ_STATE_QUERY;
			return (HTTP_STATE_RETRY);
		}

		/*
		 * Let the state machine continue immediately since we
		 * have an error anyway.
		 */
		return (HTTP_STATE_CONTINUE);
	}

	/* Resume state machine later when the query results start coming in. */
	return (HTTP_STATE_RETRY);
}
Esempio n. 5
0
File: attr.c Progetto: bgraves/dowse
attrlist_t attrinit(void)
{
    attrlist_t al;
    al=kore_malloc(sizeof *al);
    al->len=0;
    al->data=NULL;
    return al;
}
Esempio n. 6
0
File: net.c Progetto: jdiego/kore
void
net_send_queue(struct connection *c, void *data, u_int32_t len,
    struct spdy_stream *s, int before)
{
	u_int8_t		*d;
	struct netbuf		*nb;
	u_int32_t		avail;

	kore_debug("net_send_queue(%p, %p, %d, %p, %d)",
	    c, data, len, s, before);

	d = data;
	if (before == NETBUF_LAST_CHAIN) {
		nb = TAILQ_LAST(&(c->send_queue), netbuf_head);
		if (nb != NULL && !(nb->flags & NETBUF_IS_STREAM) &&
		    nb->stream == s && nb->b_len < nb->m_len) {
			avail = nb->m_len - nb->b_len;
			if (len < avail) {
				memcpy(nb->buf + nb->b_len, d, len);
				nb->b_len += len;
				return;
			} else if (len > avail) {
				memcpy(nb->buf + nb->b_len, d, avail);
				nb->b_len += avail;

				len -= avail;
				d += avail;
				if (len == 0)
					return;
			}
		}
	}

	nb = kore_pool_get(&nb_pool);
	nb->flags = 0;
	nb->cb = NULL;
	nb->owner = c;
	nb->s_off = 0;
	nb->stream = s;
	nb->b_len = len;
	nb->type = NETBUF_SEND;

	if (nb->b_len < NETBUF_SEND_PAYLOAD_MAX)
		nb->m_len = NETBUF_SEND_PAYLOAD_MAX;
	else
		nb->m_len = nb->b_len;

	nb->buf = kore_malloc(nb->m_len);
	if (len > 0)
		memcpy(nb->buf, d, nb->b_len);

	if (before == NETBUF_BEFORE_CHAIN) {
		TAILQ_INSERT_BEFORE(c->snb, nb, list);
	} else {
		TAILQ_INSERT_TAIL(&(c->send_queue), nb, list);
	}
}
Esempio n. 7
0
static struct entry *create_entry(unsigned type, const char *data, unsigned len) {
	struct entry *ret;
	ret=kore_malloc(sizeof *ret);
	ret->type=type;
	ret->len=len;
	ret->data=data;
	ret->next=0;
	return ret;
}
Esempio n. 8
0
void *
kore_calloc(size_t memb, size_t len)
{
	if (memb == 0 || len == 0)
		fatal("kore_calloc(): zero size");
	if (SIZE_MAX / memb < len)
		fatal("kore_calloc: memb * len > SIZE_MAX");

	return (kore_malloc(memb * len));
}
Esempio n. 9
0
File: buf.c Progetto: SDAIA/kore
struct kore_buf *
kore_buf_alloc(size_t initial)
{
	struct kore_buf		*buf;

	buf = kore_malloc(sizeof(*buf));
	kore_buf_init(buf, initial);
	buf->flags = KORE_BUF_OWNER_API;

	return (buf);
}
Esempio n. 10
0
File: mem.c Progetto: skymeyer/kore
void *
kore_realloc(void *ptr, size_t len)
{
	struct meminfo		*mem;
	void			*nptr;

	if (ptr == NULL) {
		nptr = kore_malloc(len);
	} else {
		mem = KORE_MEMINFO(ptr);
		if (mem->magic != KORE_MEM_MAGIC)
			fatal("kore_realloc(): magic boundary not found");

		nptr = kore_malloc(len);
		memcpy(nptr, ptr, KORE_MEMSIZE(ptr));
		kore_mem_free(ptr);
	}

	return (nptr);
}
Esempio n. 11
0
File: buf.c Progetto: SDAIA/kore
void
kore_buf_init(struct kore_buf *buf, size_t initial)
{
	if (initial > 0)
		buf->data = kore_malloc(initial);
	else
		buf->data = NULL;

	buf->length = initial;
	buf->offset = 0;
	buf->flags = 0;
}
Esempio n. 12
0
File: mem.c Progetto: skymeyer/kore
char *
kore_strdup(const char *str)
{
	size_t		len;
	char		*nstr;

	len = strlen(str) + 1;
	nstr = kore_malloc(len);
	kore_strlcpy(nstr, str, len);

	return (nstr);
}
Esempio n. 13
0
File: attr.c Progetto: bgraves/dowse
/* set an attribute */
static void attrsetn_internal(attrlist_t al, const char *name, int safe_fl, const _char *value, size_t len)
{
    attr_t *at;
    at=setup_access(al, name);
    /* a null value would delete the attribute */
    if(value==NULL) {
        if(at) attrdel(al, at); /* delete if there is no value */
        return;
    }
    /* discard the old attribute values */
    kore_mem_free(at->value);
    at->value=NULL;
    /* set the attribute */
    if(safe_fl) {
        at->len=html_escape_len(value, len);
        at->value=kore_malloc(at->len+1);
        html_escape(at->value, at->len, value);
    } else {
        at->len=len;
        at->value=kore_malloc(len+1);
        memcpy(at->value, value, at->len+1);
    }
}
Esempio n. 14
0
static void
task_thread_spawn(struct kore_task_thread **out)
{
	struct kore_task_thread		*tt;

	tt = kore_malloc(sizeof(*tt));
	tt->idx = threads++;

	TAILQ_INIT(&(tt->tasks));
	pthread_cond_init(&(tt->cond), NULL);
	pthread_mutex_init(&(tt->lock), NULL);

	if (pthread_create(&(tt->tid), NULL, task_thread, tt) != 0)
		fatal("pthread_create: %s", errno_s);

	*out = tt;
}
Esempio n. 15
0
int
kore_connection_accept(struct listener *l, struct connection **out)
{
	socklen_t		len;
	struct connection	*c;

	kore_debug("kore_connection_accept(%p)", l);

	*out = NULL;
	len = sizeof(struct sockaddr_in);
	c = (struct connection *)kore_malloc(sizeof(*c));
	if ((c->fd = accept(l->fd, (struct sockaddr *)&(c->sin), &len)) == -1) {
		kore_mem_free(c);
		kore_debug("accept(): %s", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (!kore_connection_nonblock(c->fd)) {
		close(c->fd);
		kore_mem_free(c);
		return (KORE_RESULT_ERROR);
	}

	c->owner = l;
	c->ssl = NULL;
	c->flags = 0;
	c->inflate_started = 0;
	c->deflate_started = 0;
	c->client_stream_id = 0;
	c->proto = CONN_PROTO_UNKNOWN;
	c->state = CONN_STATE_SSL_SHAKE;
	c->wsize_initial = SPDY_INIT_WSIZE;
	c->idle_timer.start = 0;
	c->idle_timer.length = KORE_IDLE_TIMER_MAX;

	TAILQ_INIT(&(c->send_queue));
	TAILQ_INIT(&(c->recv_queue));
	TAILQ_INIT(&(c->spdy_streams));

	kore_worker_connection_add(c);
	kore_connection_start_idletimer(c);

	*out = c;
	return (KORE_RESULT_OK);
}
Esempio n. 16
0
void
net_recv_queue(struct connection *c, u_int32_t len, int flags,
    int (*cb)(struct netbuf *))
{
	kore_debug("net_recv_queue(): %p %d %d", c, len, flags);

	if (c->rnb != NULL)
		fatal("net_recv_queue(): called incorrectly for %p", c);

	c->rnb = kore_pool_get(&nb_pool);
	c->rnb->cb = cb;
	c->rnb->owner = c;
	c->rnb->s_off = 0;
	c->rnb->b_len = len;
	c->rnb->m_len = len;
	c->rnb->extra = NULL;
	c->rnb->flags = flags;
	c->rnb->type = NETBUF_RECV;
	c->rnb->buf = kore_malloc(c->rnb->b_len);
}
Esempio n. 17
0
File: net.c Progetto: jdiego/kore
void
net_recv_reset(struct connection *c, u_int32_t len, int (*cb)(struct netbuf *))
{
	kore_debug("net_recv_reset(): %p %d", c, len);

	if (c->rnb->type != NETBUF_RECV)
		fatal("net_recv_reset(): wrong netbuf type");

	c->rnb->cb = cb;
	c->rnb->s_off = 0;
	c->rnb->b_len = len;

	if (c->rnb->b_len <= c->rnb->m_len &&
	    c->rnb->m_len < (NETBUF_SEND_PAYLOAD_MAX / 2))
		return;

	kore_mem_free(c->rnb->buf);
	c->rnb->m_len = len;
	c->rnb->buf = kore_malloc(c->rnb->m_len);
}
Esempio n. 18
0
File: mem.c Progetto: skymeyer/kore
void *
kore_calloc(size_t memb, size_t len)
{
	return (kore_malloc(memb * len));
}
Esempio n. 19
0
File: kore.c Progetto: SDAIA/kore
int
main(int argc, char *argv[])
{
	int		ch, flags;

	flags = 0;

#if !defined(KORE_SINGLE_BINARY)
	while ((ch = getopt(argc, argv, "c:dfhnrv")) != -1) {
#else
	while ((ch = getopt(argc, argv, "dfhnrv")) != -1) {
#endif
		flags++;
		switch (ch) {
#if !defined(KORE_SINGLE_BINARY)
		case 'c':
			config_file = optarg;
			break;
#endif
#if defined(KORE_DEBUG)
		case 'd':
			kore_debug = 1;
			break;
#endif
		case 'f':
			foreground = 1;
			break;
		case 'h':
			usage();
			break;
		case 'n':
			skip_chroot = 1;
			break;
		case 'r':
			skip_runas = 1;
			break;
		case 'v':
			version();
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	kore_mem_init();

#if !defined(KORE_SINGLE_BINARY)
	if (argc > 0) {
		if (flags)
			fatal("You cannot specify kore flags and a command");
		return (kore_cli_main(argc, argv));
	}
#endif

	kore_pid = getpid();
	nlisteners = 0;
	LIST_INIT(&listeners);

	kore_log_init();
#if !defined(KORE_NO_HTTP)
	kore_auth_init();
	kore_validator_init();
#endif
	kore_domain_init();
	kore_module_init();
	kore_server_sslstart();

#if !defined(KORE_SINGLE_BINARY)
	if (config_file == NULL)
		usage();
#else
	kore_module_load(NULL, NULL);
#endif

	kore_parse_config();
	kore_platform_init();

#if !defined(KORE_NO_HTTP)
	kore_accesslog_init();
	if (http_body_disk_offload > 0) {
		if (mkdir(http_body_disk_path, 0700) == -1 && errno != EEXIST) {
			printf("can't create http_body_disk_path '%s': %s\n",
			    http_body_disk_path, errno_s);
			return (KORE_RESULT_ERROR);
		}
	}
#endif

	sig_recv = 0;
	signal(SIGHUP, kore_signal);
	signal(SIGQUIT, kore_signal);
	signal(SIGTERM, kore_signal);

	if (foreground)
		signal(SIGINT, kore_signal);
	else
		signal(SIGINT, SIG_IGN);

	kore_server_start();

	kore_log(LOG_NOTICE, "server shutting down");
	kore_worker_shutdown();

	if (!foreground)
		unlink(kore_pidfile);

	kore_listener_cleanup();
	kore_log(LOG_NOTICE, "goodbye");

	return (0);
}

#if !defined(KORE_NO_TLS)
int
kore_tls_sni_cb(SSL *ssl, int *ad, void *arg)
{
	struct kore_domain	*dom;
	const char		*sname;

	sname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	kore_debug("kore_tls_sni_cb(): received host %s", sname);

	if (sname != NULL && (dom = kore_domain_lookup(sname)) != NULL) {
		kore_debug("kore_ssl_sni_cb(): Using %s CTX", sname);
		SSL_set_SSL_CTX(ssl, dom->ssl_ctx);

		if (dom->cafile != NULL) {
			SSL_set_verify(ssl, SSL_VERIFY_PEER |
			    SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
		} else {
			SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
		}

		return (SSL_TLSEXT_ERR_OK);
	}

	return (SSL_TLSEXT_ERR_NOACK);
}

void
kore_tls_info_callback(const SSL *ssl, int flags, int ret)
{
	struct connection	*c;

	if (flags & SSL_CB_HANDSHAKE_START) {
		if ((c = SSL_get_app_data(ssl)) == NULL)
			fatal("no SSL_get_app_data");
		c->tls_reneg++;
	}
}
#endif

int
kore_server_bind(const char *ip, const char *port, const char *ccb)
{
	struct listener		*l;
	int			on, r;
	struct addrinfo		hints, *results;

	kore_debug("kore_server_bind(%s, %s)", ip, port);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = 0;

	r = getaddrinfo(ip, port, &hints, &results);
	if (r != 0)
		fatal("getaddrinfo(%s): %s", ip, gai_strerror(r));

	l = kore_malloc(sizeof(struct listener));
	l->type = KORE_TYPE_LISTENER;
	l->addrtype = results->ai_family;

	if (l->addrtype != AF_INET && l->addrtype != AF_INET6)
		fatal("getaddrinfo(): unknown address family %d", l->addrtype);

	if ((l->fd = socket(results->ai_family, SOCK_STREAM, 0)) == -1) {
		kore_free(l);
		freeaddrinfo(results);
		kore_debug("socket(): %s", errno_s);
		printf("failed to create socket: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (!kore_connection_nonblock(l->fd, 1)) {
		kore_free(l);
		freeaddrinfo(results);
		printf("failed to make socket non blocking: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	on = 1;
	if (setsockopt(l->fd, SOL_SOCKET,
	    SO_REUSEADDR, (const char *)&on, sizeof(on)) == -1) {
		close(l->fd);
		kore_free(l);
		freeaddrinfo(results);
		kore_debug("setsockopt(): %s", errno_s);
		printf("failed to set SO_REUSEADDR: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (bind(l->fd, results->ai_addr, results->ai_addrlen) == -1) {
		close(l->fd);
		kore_free(l);
		freeaddrinfo(results);
		kore_debug("bind(): %s", errno_s);
		printf("failed to bind to %s port %s: %s\n", ip, port, errno_s);
		return (KORE_RESULT_ERROR);
	}

	freeaddrinfo(results);

	if (listen(l->fd, kore_socket_backlog) == -1) {
		close(l->fd);
		kore_free(l);
		kore_debug("listen(): %s", errno_s);
		printf("failed to listen on socket: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (ccb != NULL) {
		*(void **)&(l->connect) = kore_module_getsym(ccb);
		if (l->connect == NULL) {
			printf("no such callback: '%s'\n", ccb);
			close(l->fd);
			kore_free(l);
			return (KORE_RESULT_ERROR);
		}
	} else {
		l->connect = NULL;
	}

	nlisteners++;
	LIST_INSERT_HEAD(&listeners, l, list);

	if (foreground) {
#if !defined(KORE_NO_TLS)
		kore_log(LOG_NOTICE, "running on https://%s:%s", ip, port);
#else
		kore_log(LOG_NOTICE, "running on http://%s:%s", ip, port);
#endif
	}

	return (KORE_RESULT_OK);
}

void
kore_listener_cleanup(void)
{
	struct listener		*l;

	while (!LIST_EMPTY(&listeners)) {
		l = LIST_FIRST(&listeners);
		LIST_REMOVE(l, list);
		close(l->fd);
		kore_free(l);
	}
}

void
kore_signal(int sig)
{
	sig_recv = sig;
}

static void
kore_server_sslstart(void)
{
#if !defined(KORE_NO_TLS)
	kore_debug("kore_server_sslstart()");

	SSL_library_init();
	SSL_load_error_strings();
#endif
}
Esempio n. 20
0
File: tasks.c Progetto: 2ion/kore
int
page_handler(struct http_request *req)
{
	u_int32_t	len;
	struct rstate	*state;
	char		*user, result[64];

	/*
	 * Lets check if a task has been created yet, this is important
	 * as we only want to fire this off once and we will be called
	 * again once it has been created.
	 *
	 * In this example, we'll store our state with our task in hdlr_extra.
	 */
	if (req->hdlr_extra == NULL) {
		/* Grab the user argument */
		http_populate_arguments(req);
		if (!http_argument_get_string("user", &user, &len)) {
			http_response(req, 500, "ERROR\n", 6);
			return (KORE_RESULT_OK);
		}

		/*
		 * Allocate rstate and bind it to the hdlr_extra field.
		 * Kore automatically frees this when freeing the result.
		 */
		state = kore_malloc(sizeof(*state));
		req->hdlr_extra = state;

		/*
		 * Create a new task that will execute the run_curl()
		 * function and bind it to our request.
		 *
		 * Binding a task to a request means Kore will reschedule
		 * the page handler for that request to refire after the
		 * task has completed or when it writes on the task channel.
		 */
		kore_task_create(&state->task, run_curl);
		kore_task_bind_request(&state->task, req);

		/*
		 * Start the task and write the user we received in our
		 * GET request to its channel.
		 */
		kore_task_run(&state->task);
		kore_task_channel_write(&state->task, user, len);

		/*
		 * Tell Kore to retry us later.
		 */
		return (KORE_RESULT_RETRY);
	} else {
		state = req->hdlr_extra;
	}

	/*
	 * Our page handler is scheduled to be called when either the
	 * task finishes or has written data onto the channel.
	 *
	 * In order to distinguish between the two we can inspect the
	 * state of the task.
	 */
	if (kore_task_state(&state->task) != KORE_TASK_STATE_FINISHED) {
		http_request_sleep(req);
		return (KORE_RESULT_RETRY);
	}

	/*
	 * Task is finished, check the result.
	 */
	if (kore_task_result(&state->task) != KORE_RESULT_OK) {
		kore_task_destroy(&state->task);
		http_response(req, 500, NULL, 0);
		return (KORE_RESULT_OK);
	}

	/*
	 * Lets read what our task has written to the channel.
	 *
	 * kore_task_channel_read() will return the amount of bytes
	 * that it received for that read. If the returned bytes is
	 * larger then the buffer you passed this is a sign of truncation
	 * and should be treated carefully.
	 */
	len = kore_task_channel_read(&state->task, result, sizeof(result));
	if (len > sizeof(result)) {
		http_response(req, 500, NULL, 0);
	} else {
		http_response(req, 200, result, len);
	}

	/* We good, destroy the task. */
	kore_task_destroy(&state->task);

	return (KORE_RESULT_OK);
}