Exemple #1
0
void
kore_accesslog(struct http_request *req)
{
	struct kore_log_packet	logpacket;

	logpacket.addrtype = req->owner->addrtype;
	if (logpacket.addrtype == AF_INET) {
		memcpy(logpacket.addr,
		    &(req->owner->addr.ipv4.sin_addr),
		    sizeof(req->owner->addr.ipv4.sin_addr));
	} else {
		memcpy(logpacket.addr,
		    &(req->owner->addr.ipv6.sin6_addr),
		    sizeof(req->owner->addr.ipv6.sin6_addr));
	}

	logpacket.status = req->status;
	logpacket.method = req->method;
	logpacket.worker_id = worker->id;
	logpacket.worker_cpu = worker->cpu;
	logpacket.time_req = req->total;

	if (kore_strlcpy(logpacket.host,
	    req->host, sizeof(logpacket.host)) >= sizeof(logpacket.host))
		kore_log(LOG_NOTICE, "kore_accesslog: host truncated");

	if (kore_strlcpy(logpacket.path,
	    req->path, sizeof(logpacket.path)) >= sizeof(logpacket.path))
		kore_log(LOG_NOTICE, "kore_accesslog: path truncated");

	if (req->agent != NULL) {
		if (kore_strlcpy(logpacket.agent, req->agent,
		    sizeof(logpacket.agent)) >= sizeof(logpacket.agent))
			kore_log(LOG_NOTICE, "kore_accesslog: agent truncated");
	} else {
		(void)kore_strlcpy(logpacket.agent, "unknown",
		    sizeof(logpacket.agent));
	}

#if !defined(KORE_NO_TLS)
	memset(logpacket.cn, '\0', sizeof(logpacket.cn));
	if (req->owner->cert != NULL) {
		if (X509_GET_CN(req->owner->cert,
		    logpacket.cn, sizeof(logpacket.cn)) == -1) {
			kore_log(LOG_WARNING, "client cert without a CN?");
		}
	}
#endif

	kore_msg_send(KORE_MSG_PARENT,
	    KORE_MSG_ACCESSLOG, &logpacket, sizeof(logpacket));
}
Exemple #2
0
void
kore_accesslog(struct http_request *req)
{
	ssize_t			len;
	struct kore_log_packet	logpacket;

	logpacket.addrtype = req->owner->addrtype;
	if (logpacket.addrtype == AF_INET) {
		memcpy(logpacket.addr,
		    &(req->owner->addr.ipv4.sin_addr),
		    sizeof(req->owner->addr.ipv4.sin_addr));
	} else {
		memcpy(logpacket.addr,
		    &(req->owner->addr.ipv6.sin6_addr),
		    sizeof(req->owner->addr.ipv6.sin6_addr));
	}

	logpacket.status = req->status;
	logpacket.method = req->method;
	logpacket.worker_id = worker->id;
	logpacket.worker_cpu = worker->cpu;
	logpacket.time_req = req->total;
	kore_strlcpy(logpacket.host, req->host, sizeof(logpacket.host));
	kore_strlcpy(logpacket.path, req->path, sizeof(logpacket.path));

	if (req->agent != NULL) {
		kore_strlcpy(logpacket.agent,
		    req->agent, sizeof(logpacket.agent));
	} else {
		kore_strlcpy(logpacket.agent, "unknown",
		    sizeof(logpacket.agent));
	}

	memset(logpacket.cn, '\0', sizeof(logpacket.cn));
#if !defined(KORE_BENCHMARK)
	if (req->owner->cert != NULL) {
		if (X509_GET_CN(req->owner->cert,
		    logpacket.cn, sizeof(logpacket.cn)) == -1) {
			kore_log(LOG_WARNING, "client cert without a CN?");
		}
	}
#endif

	len = send(accesslog_fd[1], &logpacket, sizeof(logpacket), 0);
	if (len == -1) {
		kore_log(LOG_WARNING, "kore_accesslog(): send(): %s", errno_s);
	} else if (len != sizeof(logpacket)) {
		kore_log(LOG_WARNING, "short accesslog packet sent");
	}
}
Exemple #3
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);
}