diff --git a/Makefile.am b/Makefile.am index 4a58eec7e..d1fcbcb6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,7 +43,7 @@ install-data-hook: $(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-hssd $(MKDIR_P) $(DESTDIR)/$(localstatedir)/run/nextepc-epcd -CLEANFILES = symtbl.c +CLEANFILES = -R data DISTCLEANFILES = $(DIST_ARCHIVES) MAINTAINERCLEANFILES = \ configure config.in \ diff --git a/debian/control b/debian/control index a998cfe7c..e94acc2e0 100644 --- a/debian/control +++ b/debian/control @@ -69,7 +69,7 @@ Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, nextepc-core (= ${binary:Version}), - iproute2 + ifupdown Description: Open Source based 3GPP EPC PGW (Packet Data Network Gateway) NextEPC is a C-language Open Source implementation of the 3GPP Evolved Packet Core, i.e. the core network of an LTE network. diff --git a/debian/nextepc-pgw.postinst b/debian/nextepc-pgw.postinst index 9eeb0e489..7cb9d480f 100644 --- a/debian/nextepc-pgw.postinst +++ b/debian/nextepc-pgw.postinst @@ -21,9 +21,7 @@ set -e case "$1" in configure) if ! grep "pgwtun" /proc/net/dev > /dev/null; then - ip tuntap add name pgwtun mode tun - ip addr add 45.45.0.1/16 dev pgwtun - ip link set pgwtun up + ifup pgwtun fi ;; diff --git a/lib/base/context.c b/lib/base/context.c index 5e46a72b3..a027d711c 100644 --- a/lib/base/context.c +++ b/lib/base/context.c @@ -110,6 +110,8 @@ status_t context_parse_config() d_assert(config, return CORE_ERROR, ); + self.log.console = -1; + if (!bson_iter_init(&iter, config->bson)) { d_error("bson_iter_init failed in this document"); @@ -129,10 +131,15 @@ status_t context_parse_config() while(bson_iter_next(&child1_iter)) { const char *child1_key = bson_iter_key(&child1_iter); - if (!strcmp(child1_key, "FILE") && + if (!strcmp(child1_key, "CONSOLE") && + BSON_ITER_HOLDS_INT32(&child1_iter)) + { + self.log.console = bson_iter_int32(&child1_iter); + } + else if (!strcmp(child1_key, "SYSLOG") && BSON_ITER_HOLDS_UTF8(&child1_iter)) { - self.log.file = bson_iter_utf8(&child1_iter, &length); + self.log.syslog = bson_iter_utf8(&child1_iter, &length); } else if (!strcmp(child1_key, "SOCKET") && BSON_ITER_HOLDS_DOCUMENT(&iter)) @@ -154,7 +161,11 @@ status_t context_parse_config() bson_iter_utf8(&child2_iter, &length); } } - + } + else if (!strcmp(child1_key, "FILE") && + BSON_ITER_HOLDS_UTF8(&child1_iter)) + { + self.log.file = bson_iter_utf8(&child1_iter, &length); } } } diff --git a/lib/base/context.h b/lib/base/context.h index 952d633cb..7fc52f2d7 100644 --- a/lib/base/context.h +++ b/lib/base/context.h @@ -30,11 +30,13 @@ typedef struct _context_t { void *database; struct { - const char *file; + int console; + const char *syslog; struct { const char *unix_domain; const char *file; } socket; + const char *file; } log; struct { diff --git a/lib/core/include/core_debug.h b/lib/core/include/core_debug.h index d9d9a205f..de59d2313 100644 --- a/lib/core/include/core_debug.h +++ b/lib/core/include/core_debug.h @@ -26,8 +26,10 @@ extern int g_trace_mask; #define D_MSG_TO_STDOUT 0x00000002 #define D_MSG_TO_SYSLOG 0x00000004 #define D_MSG_TO_SOCKET 0x00000008 +#define D_MSG_TO_FILE 0x00000010 #define D_MSG_TO_ALL (D_MSG_TO_CONSOLE | D_MSG_TO_STDOUT | \ - D_MSG_TO_SYSLOG | D_MSG_TO_SOCKET) + D_MSG_TO_SYSLOG | D_MSG_TO_SOCKET | \ + D_MSG_TO_FILE ) #define D_LOG_LEVEL_NONE 0 #define D_LOG_LEVEL_FATAL 1 @@ -138,12 +140,17 @@ CORE_DECLARE(int) d_msg(int tp, int lv, c_time_t t, char *fn, int ln, expr; \ } -void d_msg_register_syslog(const char *name); -void d_msg_deregister_syslog(); -void d_msg_register_socket(const char *name, const char *log_file); -void d_msg_deregister_socket(); -void d_msg_register_console(int console_fd); -void d_msg_deregister_console(); +status_t d_msg_console_init(int console_fd); +void d_msg_console_final(); +void d_msg_syslog_init(const char *name); +void d_msg_syslog_final(); +status_t d_msg_socket_init(const char *name); +void d_msg_socket_final(); +status_t d_msg_socket_start(const char *file); +void d_msg_socket_stop(); +void d_msg_socket_final(); +status_t d_msg_file_init(const char *file); +void d_msg_file_final(); void d_msg_to(int to, int on_off); diff --git a/lib/core/src/debug.c b/lib/core/src/debug.c index fba1d9adc..af8174af6 100644 --- a/lib/core/src/debug.c +++ b/lib/core/src/debug.c @@ -15,11 +15,13 @@ int g_msg_to = D_MSG_TO_STDOUT; int g_console_connected = 0; int g_syslog_connected = 0; int g_socket_connected = 0; +int g_file_connected = 0; int g_log_level_console = D_LOG_LEVEL_FULL; int g_log_level_stdout = D_LOG_LEVEL_FULL; int g_log_level_syslog = D_LOG_LEVEL_FULL; int g_log_level_socket = D_LOG_LEVEL_FULL; +int g_log_level_file = D_LOG_LEVEL_FULL; static int g_console_fd = -1; static int g_socket_fd = -1; @@ -29,7 +31,26 @@ static thread_id socket_thread = 0; static void *THREAD_FUNC socket_main(thread_id id, void *data); static int socket_handler(const char *path); -void d_msg_register_syslog(const char *name) +static file_t *g_file = NULL; + +status_t d_msg_console_init(int console_fd) +{ + d_assert(console_fd >= 0, return CORE_ERROR, + "param 'console_fd' is invalid"); + + g_console_fd = console_fd; + g_console_connected = 1; + + return CORE_OK; +} + +void d_msg_console_final() +{ + g_console_connected = 0; + g_console_fd = -1; +} + +void d_msg_syslog_init(const char *name) { d_assert(name, return, ); @@ -37,39 +58,53 @@ void d_msg_register_syslog(const char *name) g_syslog_connected = 1; } -void d_msg_deregister_syslog() +void d_msg_syslog_final() { g_syslog_connected = 0; closelog(); } -void d_msg_register_socket(const char *name, const char *log_file) +status_t d_msg_socket_init(const char *name) { - status_t rv; - - d_assert(name, return, ); + d_assert(name, return CORE_ERROR, ); g_socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0); - d_assert(g_socket_fd >= 0, return, + d_assert(g_socket_fd >= 0, return CORE_ERROR, "socket() failed. (%d:%s)\n", errno, strerror(errno)); g_socket_addr.sun_family = AF_UNIX; strcpy(g_socket_addr.sun_path, name); - rv = thread_create(&socket_thread, NULL, socket_main, (void*)log_file); - d_assert(rv == CORE_OK, return, "socket thread creation failed"); + return CORE_OK; +} + +status_t d_msg_socket_start(const char *file) +{ + status_t rv; + + d_assert(file, return CORE_ERROR, ); + + rv = thread_create(&socket_thread, NULL, socket_main, (void*)file); + d_assert(rv == CORE_OK, return CORE_ERROR, + "socket thread creation failed"); g_socket_connected = 1; d_msg_to(D_MSG_TO_SOCKET, 1); + + return CORE_OK; } -void d_msg_deregister_socket() +void d_msg_socket_stop() { d_msg_to(D_MSG_TO_SOCKET, 0); g_socket_connected = 0; - thread_delete(socket_thread); + if (socket_thread) + thread_delete(socket_thread); +} +void d_msg_socket_final() +{ close(g_socket_fd); g_socket_fd = -1; } @@ -99,7 +134,7 @@ static int socket_handler(const char *path) fd_set readfd; struct timeval timer_val; struct sockaddr_un svaddr; - file_t *g_file = NULL; + file_t *file = NULL; char g_buffer[1024]; us = socket(AF_UNIX, SOCK_DGRAM, 0); @@ -136,7 +171,7 @@ static int socket_handler(const char *path) } } - rv = file_open(&g_file, path, + rv = file_open(&file, path, FILE_CREATE | FILE_WRITE| FILE_APPEND, FILE_UREAD | FILE_UWRITE | FILE_GREAD); if (rv != CORE_OK) @@ -180,7 +215,7 @@ static int socket_handler(const char *path) continue; nbytes = r; - rv = file_write(g_file, g_buffer, &nbytes); + rv = file_write(file, g_buffer, &nbytes); if (rv != CORE_OK || r != nbytes) { d_error("Cannot write %ld bytes to log file (%ld written)", @@ -189,7 +224,7 @@ static int socket_handler(const char *path) } } - file_close(g_file); + file_close(file); close(us); @@ -198,18 +233,33 @@ static int socket_handler(const char *path) return 0; } -void d_msg_register_console(int console_fd) +status_t d_msg_file_init(const char *file) { - d_assert(console_fd >= 0, return, "param 'console_fd' is invalid"); + status_t rv; - g_console_fd = console_fd; - g_console_connected = 1; + d_assert(file, return CORE_ERROR, ); + + rv = file_open(&g_file, file, + FILE_CREATE | FILE_WRITE| FILE_APPEND, + FILE_UREAD | FILE_UWRITE | FILE_GREAD); + if (rv != CORE_OK) + { + d_error("Cannot open log file '%s'", file); + return CORE_ERROR; + } + + g_file_connected = 1; + d_msg_to(D_MSG_TO_FILE, 1); + + return CORE_OK; } -void d_msg_deregister_console() +void d_msg_file_final() { - g_console_connected = 0; - g_console_fd = -1; + d_msg_to(D_MSG_TO_FILE, 0); + g_file_connected = 0; + + file_close(g_file); } void d_msg_to(int to, int on_off) @@ -236,6 +286,11 @@ void d_msg_to(int to, int on_off) g_msg_to | D_MSG_TO_SOCKET : g_msg_to & ~D_MSG_TO_SOCKET; break; + case D_MSG_TO_FILE: + g_msg_to = on_off ? + g_msg_to | D_MSG_TO_FILE : + g_msg_to & ~D_MSG_TO_FILE; + break; case D_MSG_TO_ALL: g_msg_to = on_off ? D_MSG_TO_ALL : 0; break; @@ -265,6 +320,9 @@ void d_log_set_level(int to, int level) case D_MSG_TO_SOCKET: g_log_level_socket = level; break; + case D_MSG_TO_FILE: + g_log_level_socket = level; + break; case D_MSG_TO_ALL: g_log_level_console = level; g_log_level_stdout = level; @@ -288,6 +346,8 @@ int d_log_get_level(int to) return g_log_level_syslog; case D_MSG_TO_SOCKET: return g_log_level_socket; + case D_MSG_TO_FILE: + return g_log_level_socket; default: break; } @@ -311,6 +371,9 @@ void d_log_full(int to) case D_MSG_TO_SOCKET: g_log_level_socket = D_LOG_LEVEL_FULL; break; + case D_MSG_TO_FILE: + g_log_level_socket = D_LOG_LEVEL_FULL; + break; case D_MSG_TO_ALL: g_log_level_console = D_LOG_LEVEL_FULL; g_log_level_stdout = D_LOG_LEVEL_FULL; @@ -338,6 +401,9 @@ void d_log_off(int to) case D_MSG_TO_SOCKET: g_log_level_socket = D_LOG_LEVEL_NONE; break; + case D_MSG_TO_FILE: + g_log_level_socket = D_LOG_LEVEL_NONE; + break; case D_MSG_TO_ALL: g_log_level_console = D_LOG_LEVEL_NONE; g_log_level_stdout = D_LOG_LEVEL_NONE; @@ -436,6 +502,11 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...) sendto(g_socket_fd, fstr, n, 0, (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr)); } + if (g_file_connected && (g_msg_to & D_MSG_TO_FILE)) + { + size_t nbytes = n; + file_write(g_file, fstr, &nbytes); + } if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE)) { if (fstr[n-1] == '\n') @@ -463,6 +534,11 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...) sendto(g_socket_fd, fstr, n, 0, (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr)); } + if (g_file_connected && (g_msg_to & D_MSG_TO_FILE)) + { + size_t nbytes = n; + file_write(g_file, fstr, &nbytes); + } if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE)) { if (fstr[n-1] == '\n') @@ -508,6 +584,14 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...) sendto(g_socket_fd, fstr, n, 0, (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr)); } + if (g_file_connected && (g_msg_to & D_MSG_TO_FILE)) + { + size_t nbytes; + + fstr[n++] = '\n'; + nbytes = n; + file_write(g_file, fstr, &nbytes); + } if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE) && lv <= g_log_level_console) { @@ -538,6 +622,14 @@ int d_msg(int tp, int lv, c_time_t t, char *fn, int ln, char *fmt, ...) sendto(g_socket_fd, fstr, n, 0, (struct sockaddr *)&g_socket_addr, sizeof(g_socket_addr)); } + if (g_file_connected && (g_msg_to & D_MSG_TO_FILE)) + { + size_t nbytes; + + fstr[n++] = '\n'; + nbytes = n; + file_write(g_file, fstr, &nbytes); + } if (g_console_connected && (g_msg_to & D_MSG_TO_CONSOLE)) { fstr[n++] = '\r'; /* fstr[n++] = '\n'; FIXME: */ diff --git a/main.c b/main.c index 6682cf172..4c509d009 100644 --- a/main.c +++ b/main.c @@ -49,7 +49,7 @@ static int check_signal(int signum) case SIGHUP: { d_info("SIGHUP received"); - logger_restart(); + app_logger_restart(); break; } case SIGUSR1: diff --git a/src/app.h b/src/app.h index fdc790315..c7068b2fe 100644 --- a/src/app.h +++ b/src/app.h @@ -21,7 +21,7 @@ CORE_DECLARE(void) app_did_terminate(void); CORE_DECLARE(status_t) config_initialize(char *config_path); CORE_DECLARE(void) config_terminate(void); -CORE_DECLARE(status_t) logger_restart(void); +CORE_DECLARE(status_t) app_logger_restart(void); CORE_DECLARE(status_t) app_log_pid(const char *file); CORE_DECLARE(status_t) mme_initialize(); diff --git a/src/init.c b/src/init.c index 77d790566..56c54e60f 100644 --- a/src/init.c +++ b/src/init.c @@ -11,8 +11,10 @@ #define DEFAULT_RUNTIME_DIR_PATH LOCALSTATE_DIR "run/" #define DEFAULT_CONFIG_FILE_PATH SYSCONF_DIR PACKAGE "/nextepc.conf" -status_t app_socket_log_start(); -status_t app_socket_log_stop(); +static status_t app_logger_init(); +static status_t app_logger_final(); +static status_t app_logger_start(); +static status_t app_logger_stop(); status_t app_will_initialize(char *config_path, char *log_path) { @@ -36,6 +38,9 @@ status_t app_will_initialize(char *config_path, char *log_path) { d_trace_level(&_app_init, others); } + + rv = app_logger_init(); + if (rv != CORE_OK) return rv; if (context_self()->db_uri) { @@ -48,14 +53,15 @@ status_t app_will_initialize(char *config_path, char *log_path) status_t app_did_initialize(char *config_path, char *log_path) { - app_socket_log_start(); + status_t rv = app_logger_start(); + if (rv != CORE_OK) return rv; return CORE_OK; } void app_will_terminate(void) { - app_socket_log_stop(); + app_logger_stop(); } void app_did_terminate(void) @@ -65,42 +71,11 @@ void app_did_terminate(void) context_db_final(); } + app_logger_final(); + context_final(); } -status_t app_socket_log_start() -{ - if (context_self()->log.socket.file && - context_self()->log.socket.unix_domain) - { - d_msg_register_socket( - context_self()->log.socket.unix_domain, - context_self()->log.socket.file); - d_print(" Logging '%s'\n", context_self()->log.socket.file); - } - - return CORE_OK; -} - -status_t app_socket_log_stop() -{ - if (context_self()->log.socket.file && - context_self()->log.socket.unix_domain) - { - d_msg_deregister_socket(); - } - - return CORE_OK; -} - -status_t logger_restart() -{ - app_socket_log_stop(); - app_socket_log_start(); - - return CORE_OK; -} - status_t app_log_pid(const char *name) { file_t *pid_file = NULL; @@ -137,3 +112,120 @@ status_t app_log_pid(const char *name) return CORE_OK; } + +status_t app_logger_restart() +{ + app_logger_stop(); + app_logger_final(); + + app_logger_init(); + app_logger_start(); + + return CORE_OK; +} + +static status_t app_logger_init() +{ + status_t rv; + + if (context_self()->log.console >= 0) + { + rv = d_msg_console_init(context_self()->log.console); + if (rv != CORE_OK) + { + d_error("console logger init failed : (file:%d)", + context_self()->log.console); + return rv; + } + d_print(" Console Logging '%d'\n", context_self()->log.console); + } + if (context_self()->log.syslog) + { + d_msg_syslog_init(context_self()->log.syslog); + d_print(" Syslog Logging '%s'\n", context_self()->log.syslog); + } + if (context_self()->log.socket.file && + context_self()->log.socket.unix_domain) + { + rv = d_msg_socket_init(context_self()->log.socket.unix_domain); + if (rv != CORE_OK) + { + d_error("socket logger init failed : (unix_domain:%s, file:%s)", + context_self()->log.socket.unix_domain, + context_self()->log.socket.file); + return rv; + } + d_print(" Socket Logging '%s' on %s\n", + context_self()->log.socket.file, + context_self()->log.socket.unix_domain); + } + if (context_self()->log.file) + { + rv = d_msg_file_init(context_self()->log.file); + if (rv != CORE_OK) + { + d_error("file logger init failed : (file:%s)", + context_self()->log.file); + return rv; + } + d_print(" File Logging '%s'\n", context_self()->log.file); + } + + return CORE_OK; +} + + +static status_t app_logger_start() +{ + status_t rv; + + if (context_self()->log.socket.file && + context_self()->log.socket.unix_domain) + { + rv = d_msg_socket_start(context_self()->log.socket.file); + if (rv != CORE_OK) + { + d_error("socket logger start failed : (unix_domain:%s, file:%s)", + context_self()->log.socket.unix_domain, + context_self()->log.socket.file); + return rv; + } + } + + return CORE_OK; +} + +static status_t app_logger_stop() +{ + if (context_self()->log.socket.file && + context_self()->log.socket.unix_domain) + { + d_msg_socket_stop(); + } + + return CORE_OK; +} + +static status_t app_logger_final() +{ + if (context_self()->log.console >= 0) + { + d_msg_console_final(); + } + if (context_self()->log.syslog) + { + d_msg_syslog_final(); + } + if (context_self()->log.socket.file && + context_self()->log.socket.unix_domain) + { + d_msg_socket_final(); + } + if (context_self()->log.file) + { + d_msg_file_final(); + } + + return CORE_OK; +} + diff --git a/support/config/hss.conf.in b/support/config/hss.conf.in index 658eb2549..267e1e72c 100644 --- a/support/config/hss.conf.in +++ b/support/config/hss.conf.in @@ -2,10 +2,11 @@ "DB_URI" : "mongodb://localhost/nextepc", "LOG" : { + "FILE" : "@LOCALSTATE_DIR@/log/nextepc/hss.log", "SOCKET" : { - "FILE" : "@LOCALSTATE_DIR@/log/nextepc/hss.log", - "UNIX_DOMAIN" : "/tmp/nextepc-hssd.sock" + "UNIX_DOMAIN" : "/tmp/nextepc-hssd.sock", + "FILE" : 0 } }, "TRACE" : diff --git a/support/config/mme.conf.in b/support/config/mme.conf.in index 09431df7f..c4a0ea7fa 100644 --- a/support/config/mme.conf.in +++ b/support/config/mme.conf.in @@ -1,10 +1,11 @@ { "LOG" : { + "FILE" : "@LOCALSTATE_DIR@/log/nextepc/mme.log", "SOCKET" : { - "FILE" : "@LOCALSTATE_DIR@/log/nextepc/mme.log", - "UNIX_DOMAIN" : "/tmp/nextepc-mmed.sock" + "UNIX_DOMAIN" : "/tmp/nextepc-mmed.sock", + "FILE" : 0 } }, "TRACE" : diff --git a/support/config/nextepc.conf.in b/support/config/nextepc.conf.in index d6003bb47..234da864d 100644 --- a/support/config/nextepc.conf.in +++ b/support/config/nextepc.conf.in @@ -2,10 +2,11 @@ "DB_URI" : "mongodb://localhost/nextepc", "LOG" : { + "FILE" : "@LOCALSTATE_DIR@/log/nextepc/nextepc.log", "SOCKET" : { - "FILE" : "@LOCALSTATE_DIR@/log/nextepc/nextepc.log", - "UNIX_DOMAIN" : "/tmp/nextepc-epcd.sock" + "UNIX_DOMAIN" : "/tmp/nextepc-epcd.sock", + "FILE" : 0 } }, "TRACE" : diff --git a/support/config/pcrf.conf.in b/support/config/pcrf.conf.in index 3c315c90d..e179cd623 100644 --- a/support/config/pcrf.conf.in +++ b/support/config/pcrf.conf.in @@ -2,10 +2,11 @@ "DB_URI" : "mongodb://localhost/nextepc", "LOG" : { + "FILE" : "@LOCALSTATE_DIR@/log/nextepc/pcrf.log", "SOCKET" : { - "FILE" : "@LOCALSTATE_DIR@/log/nextepc/pcrf.log", - "UNIX_DOMAIN" : "/tmp/nextepc-pcrfd.sock" + "UNIX_DOMAIN" : "/tmp/nextepc-pcrfd.sock", + "FILE" : 0 } }, "TRACE" : diff --git a/support/config/pgw.conf.in b/support/config/pgw.conf.in index 5bbad725e..ab337ebab 100644 --- a/support/config/pgw.conf.in +++ b/support/config/pgw.conf.in @@ -1,10 +1,11 @@ { "LOG" : { + "FILE" : "@LOCALSTATE_DIR@/log/nextepc/pgw.log", "SOCKET" : { - "FILE" : "@LOCALSTATE_DIR@/log/nextepc/pgw.log", - "UNIX_DOMAIN" : "/tmp/nextepc-pgwd.sock" + "UNIX_DOMAIN" : "/tmp/nextepc-pgwd.sock", + "FILE" : 0 } }, "TRACE" : diff --git a/support/config/sgw.conf.in b/support/config/sgw.conf.in index c55cdb30b..5070082f2 100644 --- a/support/config/sgw.conf.in +++ b/support/config/sgw.conf.in @@ -1,10 +1,11 @@ { "LOG" : { + "FILE" : "@LOCALSTATE_DIR@/log/nextepc/sgw.log", "SOCKET" : { - "FILE" : "@LOCALSTATE_DIR@/log/nextepc/sgw.log", - "UNIX_DOMAIN" : "/tmp/nextepc-sgwd.sock" + "UNIX_DOMAIN" : "/tmp/nextepc-sgwd.sock", + "FILE" : 0 } }, "TRACE" :