diff options
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | doc/stats/conntrackd.conf | 22 | ||||
-rw-r--r-- | include/conntrackd.h | 6 | ||||
-rw-r--r-- | include/log.h | 7 | ||||
-rw-r--r-- | src/cache_iterators.c | 10 | ||||
-rw-r--r-- | src/ignore_pool.c | 4 | ||||
-rw-r--r-- | src/log.c | 56 | ||||
-rw-r--r-- | src/main.c | 14 | ||||
-rw-r--r-- | src/netlink.c | 6 | ||||
-rw-r--r-- | src/network.c | 4 | ||||
-rw-r--r-- | src/read_config_yy.y | 70 | ||||
-rw-r--r-- | src/run.c | 26 | ||||
-rw-r--r-- | src/stats-mode.c | 9 | ||||
-rw-r--r-- | src/sync-mode.c | 5 |
14 files changed, 182 insertions, 59 deletions
@@ -25,6 +25,8 @@ o rename `examples' directory to `doc' o add support for related conntracks (requires Linux kernel >= 2.6.22) o show error and warning messages to stderr o hash lookup speedups based on comments from netdev's discussions +o add support for connection logging to the statistics mode via Logfile +o minor irrelevant fixes for uncommon error paths and fix several typos version 0.9.5 (2007/07/29) ------------------------------ diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 07deaa8..198b8a3 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -49,6 +49,23 @@ General { SocketBufferSizeMaxGrown 655355 } +Stats { + # + # Enable connection logging. Default is off. + # Logfile: on, off, or a filename + # Default file: (/var/log/conntrackd-stats.log) + # + LogFile on + + # + # Enable connection logging via Syslog. Default is off. + # Syslog: on, off or a facility name (daemon (default) or local0..7) + # If you set the facility, use the same as in the General clause, + # otherwise you'll get a warning message. + # + #Syslog on +} + # # Ignore traffic for a certain set of IP's: Usually # all the IP assigned to the firewall since local @@ -69,8 +86,3 @@ IgnoreProtocol { # VRRP # numeric numbers also valid } - -# -# Strip NAT traffic -# -StripNAT diff --git a/include/conntrackd.h b/include/conntrackd.h index 1bb3879..e5b8a4e 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -31,6 +31,7 @@ #define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf" #define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock" #define DEFAULT_LOGFILE "/var/log/conntrackd.log" +#define DEFAULT_STATS_LOGFILE "/var/log/conntrackd-stats.log" #define DEFAULT_SYSLOG_FACILITY LOG_DAEMON enum { @@ -87,6 +88,10 @@ struct ct_conf { unsigned int resend_buffer_size;/* FTFW protocol */ unsigned int window_size; int cache_write_through; + struct { + char logfile[FILENAME_MAXLEN]; + int syslog_facility; + } stats; }; #define STATE(x) st.x @@ -94,6 +99,7 @@ struct ct_conf { struct ct_general_state { sigset_t block; FILE *log; + FILE *stats_log; int local; struct ct_mode *mode; struct ignore_pool *ignore_pool; diff --git a/include/log.h b/include/log.h index f6f450c..467ae8f 100644 --- a/include/log.h +++ b/include/log.h @@ -1,10 +1,9 @@ #ifndef _LOG_H_ #define _LOG_H_ -#include <stdio.h> - -FILE *init_log(char *filename); +int init_log(); void dlog(FILE *fd, int priority, char *format, ...); -void close_log(FILE *fd); +void dlog_ct(FILE *fd, struct nf_conntrack *ct); +void close_log(); #endif diff --git a/src/cache_iterators.c b/src/cache_iterators.c index c29100c..85f87ab 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -120,14 +120,14 @@ void cache_commit(struct cache *c) commit_exist = c->commit_exist - commit_exist; /* log results */ - dlog(STATE(log), LOG_INFO, "Committed %u new entries", commit_ok); + dlog(STATE(log), LOG_NOTICE, "Committed %u new entries", commit_ok); if (commit_exist) - dlog(STATE(log), LOG_INFO, "%u entries ignored, " - "already exist", commit_exist); + dlog(STATE(log), LOG_NOTICE, "%u entries ignored, " + "already exist", commit_exist); if (commit_fail) - dlog(STATE(log), LOG_INFO, "%u entries can't be " - "committed", commit_fail); + dlog(STATE(log), LOG_NOTICE, "%u entries can't be " + "committed", commit_fail); } static int do_flush(void *data1, void *data2) diff --git a/src/ignore_pool.c b/src/ignore_pool.c index 619c2fa..ee457ba 100644 --- a/src/ignore_pool.c +++ b/src/ignore_pool.c @@ -118,7 +118,7 @@ int __ignore_pool_test_ipv6(struct ignore_pool *ip, struct nf_conntrack *ct) int ignore_pool_test(struct ignore_pool *ip, struct nf_conntrack *ct) { - int ret; + int ret = 0; switch(nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO)) { case AF_INET: @@ -128,7 +128,7 @@ int ignore_pool_test(struct ignore_pool *ip, struct nf_conntrack *ct) ret = __ignore_pool_test_ipv6(ip, ct); break; default: - dlog(STATE(log), "unknown conntrack layer 3 protocol?"); + dlog(STATE(log), LOG_WARNING, "unknown layer 3 protocol?"); break; } @@ -24,22 +24,31 @@ #include <string.h> #include "conntrackd.h" -FILE *init_log(char *filename) +int init_log(void) { - FILE *fd = NULL; + if (CONFIG(logfile)[0]) { + STATE(log) = fopen(CONFIG(logfile), "a+"); + if (STATE(log) == NULL) { + fprintf(stderr, "can't open log file `%s'\n", + CONFIG(logfile)); + return -1; + } + } - if (filename[0]) { - fd = fopen(filename, "a+"); - if (fd == NULL) { - fprintf(stderr, "can't open log file `%s'\n", filename); - return NULL; + if (CONFIG(stats).logfile[0]) { + STATE(stats_log) = fopen(CONFIG(stats).logfile, "a+"); + if (STATE(stats_log) == NULL) { + fprintf(stderr, "can't open log file `%s'\n", + CONFIG(stats).logfile); + return -1; } } - if (CONFIG(syslog_facility) != -1) + if (CONFIG(syslog_facility) != -1 || + CONFIG(stats).syslog_facility != -1) openlog(PACKAGE, LOG_PID, CONFIG(syslog_facility)); - return fd; + return 0; } void dlog(FILE *fd, int priority, char *format, ...) @@ -85,10 +94,33 @@ void dlog(FILE *fd, int priority, char *format, ...) } } -void close_log(FILE *fd) +void dlog_ct(FILE *fd, struct nf_conntrack *ct) +{ + time_t t; + char buf[1024]; + char *tmp; + + if (fd) { + t = time(NULL); + ctime_r(&t, buf); + tmp = buf + strlen(buf); + buf[strlen(buf)-1]='\t'; + nfct_snprintf(buf+strlen(buf), 1024-strlen(buf), ct, 0, 0, 0); + fprintf(fd, "%s\n", buf); + fflush(fd); + } + + if (CONFIG(stats).syslog_facility != -1) + syslog(LOG_INFO, "%s", tmp); +} + +void close_log(void) { - if (fd != NULL) - fclose(fd); + if (STATE(log) != NULL) + fclose(STATE(log)); + + if (STATE(stats_log) != NULL) + fclose(STATE(stats_log)); if (CONFIG(syslog_facility) != -1) closelog(); @@ -246,8 +246,7 @@ int main(int argc, char *argv[]) /* * Setting up logging */ - STATE(log) = init_log(CONFIG(logfile)); - if (config_set && !STATE(log)) { + if (config_set && init_log() == -1) { fprintf(stderr, "can't open logfile `%s\n'", CONFIG(logfile)); exit(EXIT_FAILURE); } @@ -255,7 +254,7 @@ int main(int argc, char *argv[]) if (type == REQUEST) { if (do_local_request(action, &conf.local, local_step) == -1) { fprintf(stderr, "can't connect: is conntrackd " - "running? appropiate permissions?\n"); + "running? appropriate permissions?\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); @@ -276,22 +275,21 @@ int main(int argc, char *argv[]) pid_t pid; if ((pid = fork()) == -1) { - dlog(STATE(log), LOG_ERR, "fork() failed: " - "%s", strerror(errno)); + perror("fork has failed: "); exit(EXIT_FAILURE); } else if (pid) exit(EXIT_SUCCESS); - dlog(STATE(log), LOG_INFO, "--- starting in daemon mode ---"); + dlog(STATE(log), LOG_NOTICE, "-- starting in daemon mode --"); } else - dlog(STATE(log), LOG_INFO, "--- starting in console mode ---"); + dlog(STATE(log), LOG_NOTICE, "-- starting in console mode --"); /* * initialization process */ if (init(mode) == -1) { - close_log(STATE(log)); + close_log(); fprintf(stderr, "ERROR: conntrackd cannot start, please " "check the logfile for more info\n"); unlink(CONFIG(lockfile)); diff --git a/src/netlink.c b/src/netlink.c index d453fe1..ab945d8 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -185,9 +185,9 @@ void nl_resize_socket_buffer(struct nfct_handle *h) CONFIG(netlink_buffer_size) = nfnl_rcvbufsiz(nfct_nfnlh(h), s); /* notify the sysadmin */ - dlog(STATE(log), LOG_INFO, "netlink socket buffer size " - "has been set to %u bytes", - CONFIG(netlink_buffer_size)); + dlog(STATE(log), LOG_NOTICE, "netlink socket buffer size " + "has been set to %u bytes", + CONFIG(netlink_buffer_size)); } int nl_dump_conntrack_table(void) diff --git a/src/network.c b/src/network.c index 9bd3469..a20c1e0 100644 --- a/src/network.c +++ b/src/network.c @@ -221,8 +221,8 @@ int mcast_track_seq(u_int32_t seq, u_int32_t *exp_seq) /* out of sequence: replayed/delayed packet? */ if (before(seq, STATE_SYNC(last_seq_recv)+1)) - dlog(STATE(log), "delayed packet? exp=%u rcv=%u", - STATE_SYNC(last_seq_recv)+1, seq); + dlog(STATE(log), LOG_WARNING, "delayed packet? exp=%u rcv=%u", + STATE_SYNC(last_seq_recv)+1, seq); out: *exp_seq = STATE_SYNC(last_seq_recv)+1; diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 92806f8..ebb1c73 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -123,6 +123,11 @@ syslog_facility : T_SYSLOG T_STRING "ignoring.\n", $2); return; } + + if (conf.stats.syslog_facility != -1 && + conf.syslog_facility != conf.stats.syslog_facility) + fprintf(stderr, "WARNING: Conflicting Syslog facility " + "values, defaulting to General.\n"); }; lock : T_LOCK T_PATH_VAL @@ -549,16 +554,74 @@ family : T_FAMILY T_STRING conf.family = AF_INET; }; -stats: T_SYNC '{' stats_list '}'; +stats: T_STATS '{' stats_list '}'; stats_list: | stats_list stat_line ; -stat_line: - | +stat_line: stat_logfile_bool + | stat_logfile_path + | stat_syslog_bool + | stat_syslog_facility ; +stat_logfile_bool : T_LOG T_ON +{ + strncpy(conf.stats.logfile, DEFAULT_STATS_LOGFILE, FILENAME_MAXLEN); +}; + +stat_logfile_bool : T_LOG T_OFF +{ +}; + +stat_logfile_path : T_LOG T_PATH_VAL +{ + strncpy(conf.stats.logfile, $2, FILENAME_MAXLEN); +}; + +stat_syslog_bool : T_SYSLOG T_ON +{ + conf.stats.syslog_facility = DEFAULT_SYSLOG_FACILITY; +}; + +stat_syslog_bool : T_SYSLOG T_OFF +{ + conf.stats.syslog_facility = -1; +} + +stat_syslog_facility : T_SYSLOG T_STRING +{ + if (!strcmp($2, "daemon")) + conf.stats.syslog_facility = LOG_DAEMON; + else if (!strcmp($2, "local0")) + conf.stats.syslog_facility = LOG_LOCAL0; + else if (!strcmp($2, "local1")) + conf.stats.syslog_facility = LOG_LOCAL1; + else if (!strcmp($2, "local2")) + conf.stats.syslog_facility = LOG_LOCAL2; + else if (!strcmp($2, "local3")) + conf.stats.syslog_facility = LOG_LOCAL3; + else if (!strcmp($2, "local4")) + conf.stats.syslog_facility = LOG_LOCAL4; + else if (!strcmp($2, "local5")) + conf.stats.syslog_facility = LOG_LOCAL5; + else if (!strcmp($2, "local6")) + conf.stats.syslog_facility = LOG_LOCAL6; + else if (!strcmp($2, "local7")) + conf.stats.syslog_facility = LOG_LOCAL7; + else { + fprintf(stderr, "'%s' is not a known syslog facility, " + "ignoring.\n", $2); + return; + } + + if (conf.syslog_facility != -1 && + conf.stats.syslog_facility != conf.syslog_facility) + fprintf(stderr, "WARNING: Conflicting Syslog facility " + "values, defaulting to General.\n"); +}; + %% int @@ -580,6 +643,7 @@ init_config(char *filename) /* Zero may be a valid facility */ CONFIG(syslog_facility) = -1; + CONFIG(stats).syslog_facility = -1; yyrestart(fp); yyparse(); @@ -40,7 +40,7 @@ void killer(int foo) STATE(mode)->kill(); destroy_alarm_scheduler(); unlink(CONFIG(lockfile)); - dlog(STATE(log), LOG_INFO, "------- shutdown received ----"); + dlog(STATE(log), LOG_NOTICE, "---- shutdown received ----"); close_log(STATE(log)); sigprocmask(SIG_UNBLOCK, &STATE(block), NULL); @@ -60,18 +60,16 @@ void local_handler(int fd, void *data) ret = read(fd, &type, sizeof(type)); if (ret == -1) { - dlog(STATE(log), LOG_INFO, "can't read from unix socket"); + dlog(STATE(log), LOG_ERR, "can't read from unix socket"); return; } - if (ret == 0) { - dlog(STATE(log), LOG_INFO, "local request: nothing received?"); + if (ret == 0) return; - } switch(type) { case FLUSH_MASTER: - dlog(STATE(log), LOG_NOTICE, "`conntrackd -F' is deprecated. " - "Use conntrack -F instead."); + dlog(STATE(log), LOG_WARNING, "`conntrackd -F' is deprecated. " + "Use conntrack -F instead."); if (fork() == 0) { execlp("conntrack", "conntrack", "-F", NULL); exit(EXIT_SUCCESS); @@ -84,7 +82,7 @@ void local_handler(int fd, void *data) } if (!STATE(mode)->local(fd, type, data)) - dlog(STATE(log), LOG_ERR, "unknown local request %d", type); + dlog(STATE(log), LOG_WARNING, "unknown local request %d", type); } int init(int mode) @@ -152,7 +150,7 @@ int init(int mode) if (signal(SIGCHLD, child) == SIG_ERR) return -1; - dlog(STATE(log), LOG_INFO, "initialization completed"); + dlog(STATE(log), LOG_NOTICE, "initialization completed"); return 0; } @@ -181,7 +179,8 @@ static void __run(long credit, int step) if (errno == EINTR) return; - dlog(STATE(log), "select() failed: %s", strerror(errno)); + dlog(STATE(log), LOG_WARNING, + "select failed: %s", strerror(errno)); return; } @@ -218,8 +217,8 @@ static void __run(long credit, int step) case EAGAIN: break; default: - dlog(STATE(log), "event catch says: %s", - strerror(errno)); + dlog(STATE(log), LOG_WARNING, + "event catch says: %s", strerror(errno)); break; } } @@ -251,7 +250,8 @@ void run(void) timer_stop(&timer); if (timer_adjust_credit(&timer)) - dlog(STATE(log), "alarm run takes too long!"); + dlog(STATE(log), LOG_WARNING, + "alarm run takes too long!"); step = (step + 1) < STEPS_PER_SECONDS ? step + 1 : 0; } diff --git a/src/stats-mode.c b/src/stats-mode.c index 1d68e02..e817c4e 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -88,6 +88,8 @@ static int local_handler_stats(int fd, int type, void *data) static void dump_stats(struct nf_conntrack *ct) { + nfct_attr_unset(ct, ATTR_TIMEOUT); + if (cache_update_force(STATE_STATS(cache), ct)) debug_ct(ct, "resync entry"); } @@ -140,6 +142,8 @@ static void overrun_stats() static void event_new_stats(struct nf_conntrack *ct) { + nfct_attr_unset(ct, ATTR_TIMEOUT); + if (cache_add(STATE_STATS(cache), ct)) { debug_ct(ct, "cache new"); } else { @@ -153,6 +157,8 @@ static void event_new_stats(struct nf_conntrack *ct) static void event_update_stats(struct nf_conntrack *ct) { + nfct_attr_unset(ct, ATTR_TIMEOUT); + if (!cache_update_force(STATE_STATS(cache), ct)) { debug_ct(ct, "can't update"); return; @@ -162,8 +168,11 @@ static void event_update_stats(struct nf_conntrack *ct) static int event_destroy_stats(struct nf_conntrack *ct) { + nfct_attr_unset(ct, ATTR_TIMEOUT); + if (cache_del(STATE_STATS(cache), ct)) { debug_ct(ct, "cache destroy"); + dlog_ct(STATE(stats_log), ct); return 1; } else { debug_ct(ct, "can't destroy!"); diff --git a/src/sync-mode.c b/src/sync-mode.c index 7cd2b84..7c42c78 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -273,13 +273,14 @@ static int local_handler_sync(int fd, int type, void *data) case COMMIT: ret = fork(); if (ret == 0) { - dlog(STATE(log), LOG_INFO, "committing external cache"); + dlog(STATE(log), LOG_NOTICE, + "committing external cache"); cache_commit(STATE_SYNC(external)); exit(EXIT_SUCCESS); } break; case FLUSH_CACHE: - dlog(STATE(log), LOG_INFO, "flushing caches"); + dlog(STATE(log), LOG_NOTICE, "flushing caches"); cache_flush(STATE_SYNC(internal)); cache_flush(STATE_SYNC(external)); break; |