diff options
author | 2015-02-08 15:17:30 +0000 | |
---|---|---|
committer | 2015-02-08 15:17:30 +0000 | |
commit | 1571ed073641914fe3a0be1ee71faa0fa34d58fc (patch) | |
tree | 136aea82690dcfdb5f957b951817d4227dcc2957 /usr.sbin/syslogd/syslogd.c | |
parent | The error message on firmware load failure in iwn(4) changed, sync man page. (diff) | |
download | wireguard-openbsd-1571ed073641914fe3a0be1ee71faa0fa34d58fc.tar.xz wireguard-openbsd-1571ed073641914fe3a0be1ee71faa0fa34d58fc.zip |
Implement octet counting for sending syslog over TCP and TLS streams.
For TCP the standard recommends it, but TLS must use this framing.
OK henning@
Diffstat (limited to 'usr.sbin/syslogd/syslogd.c')
-rw-r--r-- | usr.sbin/syslogd/syslogd.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index 18655df38aa..f3324c8ab14 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syslogd.c,v 1.150 2015/02/08 01:30:09 reyk Exp $ */ +/* $OpenBSD: syslogd.c,v 1.151 2015/02/08 15:17:30 bluhm Exp $ */ /* * Copyright (c) 1983, 1988, 1993, 1994 @@ -805,6 +805,8 @@ void tcp_errorcb(struct bufferevent *bufev, short event, void *arg) { struct filed *f = arg; + char *p, *buf, *end; + int l; char ebuf[ERRBUFSIZE]; if (event & EVBUFFER_EOF) @@ -828,10 +830,32 @@ tcp_errorcb(struct bufferevent *bufev, short event, void *arg) f->f_file = -1; /* - * XXX The messages in the output buffer may be out of sync. - * Here we should clear the buffer or at least remove partial - * messages from the beginning. + * The messages in the output buffer may be out of sync. + * Check that the buffer starts with "1234 <1234 octets>\n". + * Otherwise remove the partial message from the beginning. */ + buf = EVBUFFER_DATA(bufev->output); + end = buf + EVBUFFER_LENGTH(bufev->output); + for (p = buf; p < end && p < buf + 4; p++) { + if (!isdigit(*p)) + break; + } + if (buf < end && !(buf + 1 <= p && p < end && *p == ' ' && + (l = atoi(buf)) > 0 && buf + l < end && buf[l] == '\n')) { + for (p = buf; p < end; p++) { + if (*p == '\n') { + evbuffer_drain(bufev->output, p - buf + 1); + break; + } + } + /* Without '\n' discard everything. */ + if (p == end) + evbuffer_drain(bufev->output, p - buf); + dprintf("loghost \"%s\" dropped partial message\n", + f->f_un.f_forw.f_loghost); + f->f_un.f_forw.f_dropped++; + } + tcp_connectcb(-1, 0, f); /* Log the connection error to the fresh buffer after reconnecting. */ @@ -1252,17 +1276,30 @@ fprintlog(struct filed *f, int flags, char *msg) break; } /* - * RFC 6587 3.4.2. Non-Transparent-Framing - * Use \n to split messages for now. - * 3.4.1. Octet Counting might be implemented later. + * Syslog over TLS RFC 5425 4.3. Sending Data + * Syslog over TCP RFC 6587 3.4.1. Octet Counting + * Use an additional '\n' to split messages. This allows + * buffer synchronisation, helps legacy implementations, + * and makes line based testing easier. */ + l = snprintf(line, sizeof(line), "<%d>%.15s %s%s\n", + f->f_prevpri, (char *)iov[0].iov_base, + IncludeHostname ? LocalHostName : "", + IncludeHostname ? " " : ""); + if (l < 0) { + dprintf(" (dropped snprintf)\n"); + f->f_un.f_forw.f_dropped++; + break; + } l = evbuffer_add_printf(f->f_un.f_forw.f_bufev->output, - "<%d>%.15s %s%s%s\n", f->f_prevpri, (char *)iov[0].iov_base, + "%zu <%d>%.15s %s%s%s\n", + (size_t)l + strlen(iov[4].iov_base), + f->f_prevpri, (char *)iov[0].iov_base, IncludeHostname ? LocalHostName : "", IncludeHostname ? " " : "", (char *)iov[4].iov_base); if (l < 0) { - dprintf(" (dropped)\n"); + dprintf(" (dropped evbuffer_add_printf)\n"); f->f_un.f_forw.f_dropped++; break; } |