Skip to content

Commit e46cad3

Browse files
committed
Add RFC5425 length field
Add a format to pick framing the message with an RFC 5425 length field. The RFC doesn't specify a maximum length, but does suggest 8192; added a digit over that to make sure systemd-netlogd is not the limit.
1 parent db21ab6 commit e46cad3

File tree

6 files changed

+29
-7
lines changed

6 files changed

+29
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ systemd-netlogd reads configuration files named `/etc/systemd/netlogd.conf` and
5959
Specifies whether to use udp, tcp, tls or dtls (Datagram Transport Layer Security) protocol. Defaults to udp.
6060

6161
LogFormat=
62-
Specifies whether to use RFC 5424 format or RFC 3339 format. Takes one of rfc5424 or rfc3339. Defaults to rfc5424.
62+
Specifies whether to use RFC 5424, RFC 5425, or RFC 3339 format. Takes one of rfc5424, rfc5425, or rfc3339. Defaults to rfc5424. RFC 5425 is mainly useful for sending over TLS; it prepends a message length field to the RFC 5424 format.
6363

6464
Directory=
6565
Takes a directory path. Specifies whether to operate on the specified journal directory DIR instead of the default runtime and system journal paths.

doc/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ This will create a user systemd-journal-netlog
3434
Specifies whether to use udp, tcp, tls or dtls (Datagram Transport Layer Security) protocol. Defaults to udp.
3535
3636
| ``LogFormat=``
37-
Specifies whether to use RFC 5424 format or RFC 3339 format. Takes one of rfc5424 or rfc3339. Defaults to rfc5424.
37+
Specifies whether to use RFC 5424, RFC 5425, or RFC 3339 format. Takes one of rfc5424, rfc5425, or rfc3339. Defaults to rfc5424. RFC 5425 is mainly useful for sending over TLS; it prepends a message length field to the RFC 5424 format.
3838
3939
| ``Directory=``
4040
Takes a directory path. Specifies whether to operate on the specified journal directory DIR instead of the default runtime and system journal paths.

src/netlog/netlog-manager.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ DEFINE_STRING_TABLE_LOOKUP(protocol, SysLogTransmissionProtocol);
3939

4040
static const char *const log_format_table[_SYSLOG_TRANSMISSION_LOG_FORMAT_MAX] = {
4141
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424] = "rfc5424",
42+
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5425] = "rfc5425",
4243
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_3339] = "rfc3339",
4344
};
4445

src/netlog/netlog-manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef enum SysLogTransmissionProtocol {
2525
typedef enum SysLogTransmissionLogFormat {
2626
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424 = 1 << 0,
2727
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_3339 = 1 << 1,
28+
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5425 = 1 << 2,
2829
_SYSLOG_TRANSMISSION_LOG_FORMAT_MAX,
2930
_SYSLOG_TRANSMISSION_LOG_FORMAT_INVALID = -EINVAL,
3031
} SysLogTransmissionLogFormat;

src/netlog/netlog-network.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int manager_push_to_network(Manager *m,
112112
break;
113113
}
114114

115-
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424)
115+
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424 || m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5425)
116116
r = format_rfc5424(m, severity, facility, identifier, message, hostname, pid, tv, syslog_structured_data, syslog_msgid);
117117
else
118118
r = format_rfc3339(m, severity, facility, identifier, message, hostname, pid, tv);

src/netlog/netlog-protocol.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,23 @@ int format_rfc5424(Manager *m,
9797

9898
char header_time[FORMAT_TIMESTAMP_MAX];
9999
char header_priority[sizeof("< >1 ")];
100-
struct iovec iov[14];
100+
char header_msglen[1 + sizeof("99999 ")];
101+
struct iovec iov[15];
101102
uint8_t makepri;
102-
int n = 0, r;
103+
int n = 0, r, msglen_idx;
104+
size_t msglen_len;
103105

104106
assert(m);
105107
assert(message);
106108

107109
makepri = (facility << 3) + severity;
108110

111+
/* Zeroth: for RFC5425, the message length (octet count). Will be filled below */
112+
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5425) {
113+
msglen_idx = n;
114+
IOVEC_SET_STRING(iov[n++], "");
115+
}
116+
109117
/* First: priority field Second: Version '<pri>version' */
110118
r = snprintf(header_priority, sizeof(header_priority), "<%i>%i ", makepri, RFC_5424_PROTOCOL);
111119
assert(r > 0 && (size_t)r < sizeof(header_priority));
@@ -161,11 +169,23 @@ int format_rfc5424(Manager *m,
161169
IOVEC_SET_STRING(iov[n++], message);
162170

163171
/* Last Optional newline message separator, if not implicitly terminated by end of UDP frame
164-
* De facto standard: separate messages by a newline
172+
* De facto standard: separate messages by a newline (alternative is RFC 5425, with explicit
173+
* lengths)
165174
*/
166-
if (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP || m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TLS)
175+
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424
176+
&& (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP || m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TLS))
167177
IOVEC_SET_STRING(iov[n++], "\n");
168178

179+
/* Finally, for RFC5425 format, compute the length field which goes at the start, before the
180+
* message. This is what we left space for above. */
181+
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5425) {
182+
msglen_len = snprintf(header_msglen, sizeof(header_msglen), "%zi ", IOVEC_TOTAL_SIZE(iov, n));
183+
if (msglen_len >= sizeof(header_msglen))
184+
return -EMSGSIZE;
185+
iov[msglen_idx].iov_base = header_msglen;
186+
iov[msglen_idx].iov_len = msglen_len;
187+
}
188+
169189
return protocol_send(m, iov, n);
170190
}
171191

0 commit comments

Comments
 (0)