sysklogd/src/syslogd.h
Joachim Nilsson b7d4225ef1 syslogd: Retry address lookup forever, never give up
When logging to a remote server, using @fqdn syntax in syslog.conf,
syslogd calls getaddrinfo() to resolve the IP address.  Older versions
of syslogd gave up after 10 retries.  We want to retry forever since we
may be running in a setup with bad network connection to the DNS server
for longer periods of time.

This patch only removes the 'give up' mechanism, which unfortunately
reused the f_prevcount value, which in turn could cause that value to
become -1 and thus trigger an assert().  With this code out of the way,
and the type change in the previous commit, the counter can never again
be negative.

Note: The configurable suspend time before trying again remains at its
default of 3 minutes.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2019-11-28 14:53:07 +01:00

276 lines
8.6 KiB
C

/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1983, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef SYSKLOGD_SYSLOGD_H_
#define SYSKLOGD_SYSLOGD_H_
#include <netdb.h> /* struct addrinfo */
#include <sys/param.h> /* MAXHOSTNAMELEN */
#include <sys/socket.h>
#include <sys/un.h> /* struct sockaddr_un */
#include "queue.h"
#include "syslog.h"
#define MAXLINE 2048 /* maximum line length */
#define MAXSVLINE MAXLINE /* maximum saved line length */
#define DEFUPRI (LOG_USER | LOG_NOTICE)
#define DEFSPRI (LOG_KERN | LOG_CRIT)
#define TIMERINTVL 30 /* interval for checking flush, mark */
#define RCVBUF_MINSIZE (80 * MAXLINE) /* minimum size of dgram rcv buffer */
/*
* Linux uses EIO instead of EBADFD (mrn 12 May 96)
*/
#ifdef linux
#define EHANGUP EIO
#else
#define EHANGUP EBADFD
#endif
#ifndef UTMP_FILE
#ifdef UTMP_FILENAME
#define UTMP_FILE UTMP_FILENAME
#else
#ifdef _PATH_UTMP
#define UTMP_FILE _PATH_UTMP
#else
#define UTMP_FILE "/etc/utmp"
#endif
#endif
#endif
#ifndef _PATH_LOGCONF
#define _PATH_LOGCONF SYSCONFDIR "/syslog.conf"
#endif
#ifndef _PATH_LOGPID
#define _PATH_LOGPID RUNSTATEDIR "/syslogd.pid"
#endif
#ifndef _PATH_DEV
#define _PATH_DEV "/dev/"
#endif
#ifndef _PATH_CONSOLE
#define _PATH_CONSOLE "/dev/console"
#endif
#ifndef _PATH_TTY
#define _PATH_TTY "/dev/tty"
#endif
#ifndef _PATH_LOG
#define _PATH_LOG "/dev/log"
#endif
#ifndef _PATH_KLOG
#define _PATH_KLOG "/proc/kmsg"
#endif
#ifdef UT_NAMESIZE
#define UNAMESZ UT_NAMESIZE /* length of a login name */
#else
#define UNAMESZ 8 /* length of a login name */
#endif
#define MAXUNAMES 20 /* maximum number of user names */
#define MAXFNAME 200 /* max file pathname length */
#ifndef INET_SUSPEND_TIME
#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
#endif
#define LIST_DELIMITER ':' /* delimiter between two hosts */
#define AI_SECURE 0x8000 /* Tell socket_create() to not bind() */
/* From The Practice of Programming, by Kernighan and Pike */
#ifndef NELEMS
#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
#endif
/* Helper internal log macros */
#define ERR(fmt, args...) flog(LOG_SYSLOG | LOG_ERR, fmt ": %m", ##args)
#define ERRX(fmt, args...) flog(LOG_SYSLOG | LOG_ERR, fmt, ##args)
#define WARN(fmt, args...) flog(LOG_SYSLOG | LOG_WARN, fmt, ##args)
#define NOTE(fmt, args...) flog(LOG_SYSLOG | LOG_NOTICE, fmt, ##args)
#define INFO(fmt, args...) flog(LOG_SYSLOG | LOG_INFO, fmt, ##args)
/*
* Help macros to convert between sockaddr types
*/
#define sstosa(ss) ((struct sockaddr *)(ss))
#define sstosin(ss) ((struct sockaddr_in *)(void *)(ss))
#define satosin(sa) ((struct sockaddr_in *)(void *)(sa))
#define sstosin6(ss) ((struct sockaddr_in6 *)(void *)(ss))
#define satosin6(sa) ((struct sockaddr_in6 *)(void *)(sa))
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
(((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \
(((d)->s6_addr32[1] ^ (a)->s6_addr32[1]) & (m)->s6_addr32[1]) == 0 && \
(((d)->s6_addr32[2] ^ (a)->s6_addr32[2]) & (m)->s6_addr32[2]) == 0 && \
(((d)->s6_addr32[3] ^ (a)->s6_addr32[3]) & (m)->s6_addr32[3]) == 0 )
/*
* Flags to logmsg().
*/
#define IGN_CONS 0x001 /* don't print on console */
#define SYNC_FILE 0x002 /* do fsync on file after printing */
#define ADDDATE 0x004 /* add a date to the message */
#define MARK 0x008 /* this message is a mark */
#define RFC3164 0x010 /* format log message according to RFC 3164 */
#define RFC5424 0x020 /* format log message according to RFC 5424 */
/* Syslog timestamp formats. */
#define BSDFMT_DATELEN 0
#define BSDFMT_DATEFMT NULL
#define RFC3164_DATELEN 15
#define RFC3164_DATEFMT "%b %e %H:%M:%S"
#define RFC5424_DATELEN 32
#define RFC5424_DATEFMT "%FT%T.______%z"
/*
* Helper macros for "message repeated" messages
*/
#define MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])
#define BACKOFF(f) \
if (++(f)->f_repeatcount > MAXREPEAT) \
(f)->f_repeatcount = MAXREPEAT;
/* values for f_type */
#define F_UNUSED 0 /* unused entry */
#define F_FILE 1 /* regular file */
#define F_TTY 2 /* terminal */
#define F_CONSOLE 3 /* console terminal */
#define F_FORW 4 /* remote machine */
#define F_USERS 5 /* list of users */
#define F_WALL 6 /* everyone logged on */
#define F_FORW_SUSP 7 /* suspended host forwarding */
#define F_FORW_UNKN 8 /* unknown host forwarding */
#define F_PIPE 9 /* named pipe */
/*
* Struct to hold records of peers and sockets
*/
struct peer {
SIMPLEQ_ENTRY(peer) pe_link;
const char *pe_name;
const char *pe_serv;
mode_t pe_mode;
int pe_sock[16];
size_t pe_socknum;
};
/*
* Struct to hold records of network addresses that are allowed to log
* to us.
*/
struct allowedpeer {
SIMPLEQ_ENTRY(allowedpeer) next;
int isnumeric;
u_short port;
union {
struct {
struct sockaddr_storage addr;
struct sockaddr_storage mask;
} numeric;
char *name;
} u;
#define a_addr u.numeric.addr
#define a_mask u.numeric.mask
#define a_name u.name
};
/* Timestamps of log entries. */
struct logtime {
struct tm tm;
suseconds_t usec;
};
/* message buffer container used for processing, formatting, and queueing */
struct buf_msg {
int pri;
char pribuf[8];
int flags;
struct logtime timestamp;
char timebuf[33];
char *recvhost;
char *hostname;
char *app_name;
char *proc_id;
char *msgid;
char *sd; /* structured data */
char *msg; /* message content */
};
/*
* This structure represents the files that will have log
* copies printed.
* We require f_file to be valid if f_type is F_FILE, F_CONSOLE, F_TTY
* or if f_type is F_PIPE and f_pid > 0.
*/
struct filed {
SIMPLEQ_ENTRY(filed) f_link;
short f_type; /* entry type, see below */
short f_file; /* file descriptor */
time_t f_time; /* time this was last written */
char *f_host; /* host from which to recd. */
u_char f_pmask[LOG_NFACILITIES + 1]; /* priority mask */
union {
char f_uname[MAXUNAMES][UNAMESZ + 1];
struct {
char f_hname[MAXHOSTNAMELEN + 1];
char f_serv[20];
struct addrinfo *f_addr;
} f_forw; /* forwarding address */
char f_fname[MAXFNAME];
} f_un;
char f_prevline[MAXSVLINE]; /* last message logged */
struct logtime f_lasttime; /* time of last occurrence */
char f_prevhost[MAXHOSTNAMELEN + 1]; /* host from which recd. */
int f_prevpri; /* pri of f_prevline */
size_t f_prevlen; /* length of f_prevline */
size_t f_prevcount; /* repetition cnt of prevline */
size_t f_repeatcount; /* number of "repeated" msgs */
int f_flags; /* store some additional flags */
int f_rotatecount;
int f_rotatesz;
};
void flog(int pri, char *fmt, ...);
#endif /* SYSKLOGD_SYSLOGD_H_ */