On Sun, Sep 03, 2023 at 02:00:46AM +0200, Alexander Bluhm wrote:
> 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?

anyone?

> 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;
>  

Reply via email to