On Thu, Feb 05, 2015 at 02:00:15AM +0100, Alexander Bluhm wrote:
> Implement octet counting for syslog TCP and TLS streams.  For TCP
> it is optional, but TLS must use this framing.
> 
> Some interoperability tests with remote syslog servers would help.

I have updated the diff after my commit to count dropped messages.

tests? ok?

bluhm

Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.148
diff -u -p -r1.148 syslogd.c
--- usr.sbin/syslogd/syslogd.c  6 Feb 2015 00:17:58 -0000       1.148
+++ usr.sbin/syslogd/syslogd.c  6 Feb 2015 21:00:23 -0000
@@ -800,6 +800,8 @@ void
 tcp_errorcb(struct bufferevent *bufev, short event, void *arg)
 {
        struct filed    *f = arg;
+       char            *p, *buf, *end;
+       int              l;
        char             ebuf[256];
 
        if (event & EVBUFFER_EOF)
@@ -823,10 +825,32 @@ tcp_errorcb(struct bufferevent *bufev, s
        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. */
@@ -1247,17 +1271,29 @@ fprintlog(struct filed *f, int flags, ch
                        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.
+                * 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;
                }

Reply via email to