Esempio n. 1
0
void
kore_connection_start_idletimer(struct connection *c)
{
	kore_debug("kore_connection_start_idletimer(%p)", c);

	c->flags |= CONN_IDLE_TIMER_ACT;
	c->idle_timer.start = kore_time_ms();
}
Esempio n. 2
0
void
kore_accesslog(struct http_request *req)
{
	struct timespec		ts;
	struct tm		*tm;
	u_int64_t		now;
	struct kore_alog_header	*hdr;
	size_t			avail;
	time_t			curtime;
	int			len, attempts;
	char			addr[INET6_ADDRSTRLEN];
	const char		*ptr, *method, *cn, *referer;

	switch (req->method) {
	case HTTP_METHOD_GET:
		method = "GET";
		break;
	case HTTP_METHOD_POST:
		method = "POST";
		break;
	case HTTP_METHOD_PUT:
		method = "PUT";
		break;
	case HTTP_METHOD_DELETE:
		method = "DELETE";
		break;
	case HTTP_METHOD_HEAD:
		method = "HEAD";
		break;
	case HTTP_METHOD_PATCH:
		method = "PATCH";
		break;
	default:
		method = "UNKNOWN";
		break;
	}

	if (req->referer != NULL)
		referer = req->referer;
	else
		referer = "-";

	cn = "-";
#if !defined(KORE_NO_TLS)
	if (req->owner->cert != NULL) {
		if (X509_GET_CN(req->owner->cert, cnbuf, sizeof(cnbuf)) != -1)
			cn = cnbuf;
	}
#endif

	switch (req->owner->family) {
	case AF_INET:
		ptr = inet_ntop(req->owner->family,
		    &(req->owner->addr.ipv4.sin_addr), addr, sizeof(addr));
		break;
	case AF_INET6:
		ptr = inet_ntop(req->owner->family,
		    &(req->owner->addr.ipv6.sin6_addr), addr, sizeof(addr));
		break;
	case AF_UNIX:
		ptr = NULL;
		break;
	default:
		fatal("unknown family %d", req->owner->family);
	}

	if (ptr == NULL) {
		addr[0] = '-';
		addr[1] = '\0';
	}

	now = kore_time_ms();
	if ((now - time_cache) >= 1000) {
		time(&curtime);
		tm = localtime(&curtime);
		(void)strftime(tbuf, sizeof(tbuf), "%d/%b/%Y:%H:%M:%S %z", tm);
		time_cache = now;
	}

	attempts = 0;
	ts.tv_sec = 0;
	ts.tv_nsec = 1000000;

	for (;;) {
		if (attempts++ > 1000) {
			if (getppid() == 1) {
				if (kill(worker->pid, SIGQUIT) == -1)
					fatal("failed to shutdown");
				return;
			}

			attempts = 0;
		}

		accesslog_lock(worker);

		avail = KORE_ACCESSLOG_BUFLEN - worker->lb.offset;
		if (avail < sizeof(*hdr) + LOG_ENTRY_MINSIZE_GUESS) {
			accesslog_unlock(worker);
			nanosleep(&ts, NULL);
			continue;
		}

		hdr = (struct kore_alog_header *)
		    (worker->lb.buf + worker->lb.offset);
		worker->lb.offset += sizeof(*hdr);

		len = snprintf(worker->lb.buf + worker->lb.offset, avail,
		    "%s - %s [%s] \"%s %s HTTP/1.1\" %d %zu \"%s\" \"%s\"\n",
		    addr, cn, tbuf, method, req->path, req->status,
		    req->content_length, referer, req->agent);
		if (len == -1)
			fatal("failed to create log entry");

		if ((size_t)len >= avail) {
			worker->lb.offset -= sizeof(*hdr);
			accesslog_unlock(worker);
			nanosleep(&ts, NULL);
			continue;
		}

		if ((size_t)len > USHRT_MAX) {
			kore_log(LOG_WARNING,
			    "log entry length exceeds limit (%d)", len);
			worker->lb.offset -= sizeof(*hdr);
			break;
		}

		hdr->loglen = len;
		hdr->domain = req->hdlr->dom->id;

		worker->lb.offset += (size_t)len;
		break;
	}

	accesslog_unlock(worker);
}