diff options
-rw-r--r-- | sysklogd/syslogd.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 8338d6be8..33203697d 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -57,6 +57,15 @@ struct shbuf_ds { char data[1]; /* data/messages */ }; +#if ENABLE_FEATURE_REMOTE_LOG +typedef struct { + int remoteFD; + unsigned last_dns_resolve; + len_and_sockaddr *remoteAddr; + const char *remoteHostname; +} remoteHost_t; +#endif + /* Allows us to have smaller initializer. Ugly. */ #define GLOBALS \ const char *logFilePath; \ @@ -73,11 +82,6 @@ IF_FEATURE_ROTATE_LOGFILE( \ unsigned curFileSize; \ smallint isRegular; \ ) \ -IF_FEATURE_REMOTE_LOG( \ - /* udp socket for remote logging */ \ - int remoteFD; \ - len_and_sockaddr* remoteAddr; \ -) \ IF_FEATURE_IPC_SYSLOG( \ int shmid; /* ipc shared memory id */ \ int s_semid; /* ipc semaphore id */ \ @@ -94,10 +98,8 @@ struct globals { GLOBALS #if ENABLE_FEATURE_REMOTE_LOG - unsigned last_dns_resolve; - char *remoteAddrStr; + llist_t *remoteHosts; #endif - #if ENABLE_FEATURE_IPC_SYSLOG struct shbuf_ds *shbuf; #endif @@ -127,9 +129,6 @@ static const struct init_globals init_data = { .logFileSize = 200 * 1024, .logFileRotate = 1, #endif -#if ENABLE_FEATURE_REMOTE_LOG - .remoteFD = -1, -#endif #if ENABLE_FEATURE_IPC_SYSLOG .shmid = -1, .s_semid = -1, @@ -185,7 +184,7 @@ enum { #define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \ IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ - IF_FEATURE_REMOTE_LOG( ,&G.remoteAddrStr) \ + IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ IF_FEATURE_IPC_SYSLOG( ,&opt_C) @@ -534,20 +533,20 @@ static NOINLINE int create_socket(void) } #if ENABLE_FEATURE_REMOTE_LOG -static int try_to_resolve_remote(void) +static int try_to_resolve_remote(remoteHost_t *rh) { - if (!G.remoteAddr) { + if (!rh->remoteAddr) { unsigned now = monotonic_sec(); /* Don't resolve name too often - DNS timeouts can be big */ - if ((now - G.last_dns_resolve) < DNS_WAIT_SEC) + if ((now - rh->last_dns_resolve) < DNS_WAIT_SEC) return -1; - G.last_dns_resolve = now; - G.remoteAddr = host2sockaddr(G.remoteAddrStr, 514); - if (!G.remoteAddr) + rh->last_dns_resolve = now; + rh->remoteAddr = host2sockaddr(rh->remoteHostname, 514); + if (!rh->remoteAddr) return -1; } - return socket(G.remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0); + return socket(rh->remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0); } #endif @@ -555,6 +554,9 @@ static void do_syslogd(void) NORETURN; static void do_syslogd(void) { int sock_fd; +#if ENABLE_FEATURE_REMOTE_LOG + llist_t *item; +#endif #if ENABLE_FEATURE_SYSLOGD_DUP int last_sz = -1; char *last_buf; @@ -620,23 +622,25 @@ static void do_syslogd(void) last_sz = sz; #endif #if ENABLE_FEATURE_REMOTE_LOG + /* Stock syslogd sends it '\n'-terminated + * over network, mimic that */ + recvbuf[sz] = '\n'; + /* We are not modifying log messages in any way before send */ /* Remote site cannot trust _us_ anyway and need to do validation again */ - if (G.remoteAddrStr) { - if (-1 == G.remoteFD) { - G.remoteFD = try_to_resolve_remote(); - if (-1 == G.remoteFD) - goto no_luck; + for (item = G.remoteHosts; item != NULL; item = item->link) { + remoteHost_t *rh = (remoteHost_t *)item->data; + + if (rh->remoteFD == -1) { + rh->remoteFD = try_to_resolve_remote(rh); + if (rh->remoteFD == -1) + continue; } - /* Stock syslogd sends it '\n'-terminated - * over network, mimic that */ - recvbuf[sz] = '\n'; - /* send message to remote logger, ignore possible error */ + /* Send message to remote logger, ignore possible error */ /* TODO: on some errors, close and set G.remoteFD to -1 * so that DNS resolution and connect is retried? */ - sendto(G.remoteFD, recvbuf, sz+1, MSG_DONTWAIT, - &G.remoteAddr->u.sa, G.remoteAddr->len); - no_luck: ; + sendto(rh->remoteFD, recvbuf, sz+1, MSG_DONTWAIT, + &(rh->remoteAddr->u.sa), rh->remoteAddr->len); } #endif if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { @@ -656,17 +660,27 @@ static void do_syslogd(void) int syslogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int syslogd_main(int argc UNUSED_PARAM, char **argv) { - char OPTION_DECL; int opts; + char OPTION_DECL; +#if ENABLE_FEATURE_REMOTE_LOG + llist_t *remoteAddrList = NULL; +#endif INIT_G(); + + /* No non-option params, -R can occur multiple times */ + opt_complementary = "=0" IF_FEATURE_REMOTE_LOG(":R::"); + opts = getopt32(argv, OPTION_STR, OPTION_PARAM); #if ENABLE_FEATURE_REMOTE_LOG - G.last_dns_resolve = monotonic_sec() - DNS_WAIT_SEC - 1; + while (remoteAddrList) { + remoteHost_t *rh = xzalloc(sizeof(*rh)); + rh->remoteHostname = llist_pop(&remoteAddrList); + rh->remoteFD = -1; + rh->last_dns_resolve = monotonic_sec() - DNS_WAIT_SEC - 1; + llist_add_to(&G.remoteHosts, rh); + } #endif - /* do normal option parsing */ - opt_complementary = "=0"; /* no non-option params */ - opts = getopt32(argv, OPTION_STR, OPTION_PARAM); #ifdef SYSLOGD_MARK if (opts & OPT_mark) // -m G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60; |