Hi,
When DNS lookup for remote loghost in @ line in syslog.conf does
not work at startup, retry in intervals.
Please test if you use the feature.
ok?
bluhm
Index: syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.277
diff -u -p -r1.277 syslogd.c
--- syslogd.c 16 Mar 2023 18:22:08 -0000 1.277
+++ syslogd.c 2 Sep 2023 23:42:22 -0000
@@ -156,9 +156,12 @@ struct filed {
struct sockaddr_storage f_addr;
struct buffertls f_buftls;
struct bufferevent *f_bufev;
+ struct event f_ev;
struct tls *f_ctx;
+ char *f_ipproto;
char *f_host;
- int f_reconnectwait;
+ char *f_port;
+ int f_retrywait;
} f_forw; /* forwarding address */
char f_fname[PATH_MAX];
struct {
@@ -320,6 +323,7 @@ void tcp_writecb(struct bufferevent *,
void tcp_errorcb(struct bufferevent *, short, void *);
void tcp_connectcb(int, short, void *);
void tcp_connect_retry(struct bufferevent *, struct filed *);
+void udp_resolvecb(int, short, void *);
int tcpbuf_countmsg(struct bufferevent *bufev);
void die_signalcb(int, short, void *);
void mark_timercb(int, short, void *);
@@ -1380,7 +1384,7 @@ tcp_writecb(struct bufferevent *bufev, v
* Successful write, connection to server is good, reset wait time.
*/
log_debug("loghost \"%s\" successful write", f->f_un.f_forw.f_loghost);
- f->f_un.f_forw.f_reconnectwait = 0;
+ f->f_un.f_forw.f_retrywait = 0;
if (f->f_dropped > 0 &&
EVBUFFER_LENGTH(f->f_un.f_forw.f_bufev->output) < MAX_TCPBUF) {
@@ -1453,6 +1457,18 @@ tcp_connectcb(int fd, short event, void
struct bufferevent *bufev = f->f_un.f_forw.f_bufev;
int s;
+ if (f->f_un.f_forw.f_addr.ss_family == AF_UNSPEC) {
+ if (priv_getaddrinfo(f->f_un.f_forw.f_ipproto,
+ f->f_un.f_forw.f_host, f->f_un.f_forw.f_port,
+ (struct sockaddr*)&f->f_un.f_forw.f_addr,
+ sizeof(f->f_un.f_forw.f_addr)) != 0) {
+ log_warnx("bad hostname \"%s\"",
+ f->f_un.f_forw.f_loghost);
+ tcp_connect_retry(bufev, f);
+ return;
+ }
+ }
+
if ((s = tcp_socket(f)) == -1) {
tcp_connect_retry(bufev, f);
return;
@@ -1511,21 +1527,66 @@ tcp_connect_retry(struct bufferevent *bu
{
struct timeval to;
- if (f->f_un.f_forw.f_reconnectwait == 0)
- f->f_un.f_forw.f_reconnectwait = 1;
+ if (f->f_un.f_forw.f_retrywait == 0)
+ f->f_un.f_forw.f_retrywait = 1;
else
- f->f_un.f_forw.f_reconnectwait <<= 1;
- if (f->f_un.f_forw.f_reconnectwait > 600)
- f->f_un.f_forw.f_reconnectwait = 600;
- to.tv_sec = f->f_un.f_forw.f_reconnectwait;
+ f->f_un.f_forw.f_retrywait <<= 1;
+ if (f->f_un.f_forw.f_retrywait > 600)
+ f->f_un.f_forw.f_retrywait = 600;
+ to.tv_sec = f->f_un.f_forw.f_retrywait;
to.tv_usec = 0;
+ evtimer_add(&f->f_un.f_forw.f_ev, &to);
- log_debug("tcp connect retry: wait %d",
- f->f_un.f_forw.f_reconnectwait);
+ log_debug("tcp connect retry: wait %d", f->f_un.f_forw.f_retrywait);
bufferevent_setfd(bufev, -1);
- /* We can reuse the write event as bufferevent is disabled. */
- evtimer_set(&bufev->ev_write, tcp_connectcb, f);
- evtimer_add(&bufev->ev_write, &to);
+}
+
+void
+udp_resolvecb(int fd, short event, void *arg)
+{
+ struct filed *f = arg;
+ struct timeval to;
+
+ if (priv_getaddrinfo(f->f_un.f_forw.f_ipproto,
+ f->f_un.f_forw.f_host, f->f_un.f_forw.f_port,
+ (struct sockaddr*)&f->f_un.f_forw.f_addr,
+ sizeof(f->f_un.f_forw.f_addr)) == 0) {
+ switch (f->f_un.f_forw.f_addr.ss_family) {
+ case AF_INET:
+ log_debug("resolved \"%s\" to IPv4 address",
+ f->f_un.f_forw.f_loghost);
+ f->f_file = fd_udp;
+ break;
+ case AF_INET6:
+ log_debug("resolved \"%s\" to IPv6 address",
+ f->f_un.f_forw.f_loghost);
+ f->f_file = fd_udp6;
+ break;
+ }
+ f->f_un.f_forw.f_retrywait = 0;
+
+ if (f->f_dropped > 0) {
+ char ebuf[ERRBUFSIZE];
+
+ snprintf(ebuf, sizeof(ebuf), "to udp loghost \"%s\"",
+ f->f_un.f_forw.f_loghost);
+ dropped_warn(&f->f_dropped, ebuf);
+ }
+ return;
+ }
+ log_warnx("bad hostname \"%s\"", f->f_un.f_forw.f_loghost);
+
+ if (f->f_un.f_forw.f_retrywait == 0)
+ f->f_un.f_forw.f_retrywait = 1;
+ else
+ f->f_un.f_forw.f_retrywait <<= 1;
+ if (f->f_un.f_forw.f_retrywait > 600)
+ f->f_un.f_forw.f_retrywait = 600;
+ to.tv_sec = f->f_un.f_forw.f_retrywait;
+ to.tv_usec = 0;
+ evtimer_add(&f->f_un.f_forw.f_ev, &to);
+
+ log_debug("udp resolve retry: wait %d", f->f_un.f_forw.f_retrywait);
}
int
@@ -1933,6 +1994,11 @@ fprintlog(struct filed *f, int flags, ch
case F_FORWUDP:
log_debug(" %s", f->f_un.f_forw.f_loghost);
+ if (f->f_un.f_forw.f_addr.ss_family == AF_UNSPEC) {
+ log_warnx("not resolved \"%s\"",
+ f->f_un.f_forw.f_loghost);
+ break;
+ }
l = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len +
iov[3].iov_len + iov[4].iov_len + iov[5].iov_len +
iov[6].iov_len;
@@ -2295,23 +2361,33 @@ init(void)
fprintlog(f, 0, (char *)NULL);
switch (f->f_type) {
+ case F_FORWUDP:
+ evtimer_del(&f->f_un.f_forw.f_ev);
+ free(f->f_un.f_forw.f_ipproto);
+ free(f->f_un.f_forw.f_host);
+ free(f->f_un.f_forw.f_port);
+ break;
case F_FORWTLS:
if (f->f_un.f_forw.f_ctx) {
tls_close(f->f_un.f_forw.f_ctx);
tls_free(f->f_un.f_forw.f_ctx);
}
- free(f->f_un.f_forw.f_host);
/* FALLTHROUGH */
case F_FORWTCP:
+ evtimer_del(&f->f_un.f_forw.f_ev);
tcpbuf_dropped += f->f_dropped +
tcpbuf_countmsg(f->f_un.f_forw.f_bufev);
bufferevent_free(f->f_un.f_forw.f_bufev);
+ free(f->f_un.f_forw.f_ipproto);
+ free(f->f_un.f_forw.f_host);
+ free(f->f_un.f_forw.f_port);
/* FALLTHROUGH */
case F_FILE:
if (f->f_type == F_FILE) {
file_dropped += f->f_dropped;
f->f_dropped = 0;
}
+ /* FALLTHROUGH */
case F_TTY:
case F_CONSOLE:
case F_PIPE:
@@ -2709,11 +2785,32 @@ cfline(char *line, char *progblock, char
sizeof(f->f_un.f_forw.f_addr)) != 0) {
log_warnx("bad hostname \"%s\"",
f->f_un.f_forw.f_loghost);
+ f->f_un.f_forw.f_addr.ss_family = AF_UNSPEC;
+ }
+ f->f_un.f_forw.f_ipproto = strdup(ipproto);
+ f->f_un.f_forw.f_host = strdup(host);
+ f->f_un.f_forw.f_port = strdup(port);
+ if (f->f_un.f_forw.f_ipproto == NULL ||
+ f->f_un.f_forw.f_host == NULL ||
+ f->f_un.f_forw.f_port == NULL) {
+ log_warnx("strdup ipproto host port \"%s\"",
+ f->f_un.f_forw.f_loghost);
+ free(f->f_un.f_forw.f_ipproto);
+ free(f->f_un.f_forw.f_host);
+ free(f->f_un.f_forw.f_port);
break;
}
f->f_file = -1;
if (strncmp(proto, "udp", 3) == 0) {
+ evtimer_set(&f->f_un.f_forw.f_ev, udp_resolvecb, f);
switch (f->f_un.f_forw.f_addr.ss_family) {
+ case AF_UNSPEC:
+ log_debug("resolve \"%s\" delayed",
+ f->f_un.f_forw.f_loghost);
+ to.tv_sec = 0;
+ to.tv_usec = 1;
+ evtimer_add(&f->f_un.f_forw.f_ev, &to);
+ break;
case AF_INET:
f->f_file = fd_udp;
break;
@@ -2727,26 +2824,23 @@ cfline(char *line, char *progblock, char
tcp_dropcb, tcp_writecb, tcp_errorcb, f)) == NULL) {
log_warn("bufferevent \"%s\"",
f->f_un.f_forw.f_loghost);
+ free(f->f_un.f_forw.f_ipproto);
+ free(f->f_un.f_forw.f_host);
+ free(f->f_un.f_forw.f_port);
break;
}
- if (strncmp(proto, "tls", 3) == 0) {
- f->f_un.f_forw.f_host = strdup(host);
- f->f_type = F_FORWTLS;
- } else {
- f->f_type = F_FORWTCP;
- }
/*
* If we try to connect to a TLS server immediately
* syslogd gets an SIGPIPE as the signal handlers have
* not been set up. Delay the connection until the
- * event loop is started. We can reuse the write event
- * for that as bufferevent is still disabled.
+ * event loop is started.
*/
+ evtimer_set(&f->f_un.f_forw.f_ev, tcp_connectcb, f);
to.tv_sec = 0;
to.tv_usec = 1;
- evtimer_set(&f->f_un.f_forw.f_bufev->ev_write,
- tcp_connectcb, f);
- evtimer_add(&f->f_un.f_forw.f_bufev->ev_write, &to);
+ evtimer_add(&f->f_un.f_forw.f_ev, &to);
+ f->f_type = (strncmp(proto, "tls", 3) == 0) ?
+ F_FORWTLS : F_FORWTCP;
}
break;