- feature: remote TCP logging facility

This commit is contained in:
Thomas Ries
2004-12-30 12:54:29 +00:00
parent d9fc1ab0f8
commit afed495c87
11 changed files with 305 additions and 40 deletions
+229 -17
View File
@@ -20,7 +20,7 @@
#include "config.h"
//#include "log.h"
#include "log.h"
#include <pthread.h>
#include <stdio.h>
@@ -30,19 +30,35 @@
#include <time.h>
#include <syslog.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
static char const ident[]="$Id$";
static int log_to_stdout=0;
/* module local variables */
static int log_to_stderr=0;
static int debug_pattern=0;
static int debug_listen_port=0;
static int debug_listen_fd=0;
static int debug_fd=0;
static char outbuf[512];
/*
* What shall I log to syslog?
* 0 - DEBUGs, INFOs, WARNINGs and ERRORs (this is the default)
* 1 - INFOs, WARNINGs and ERRORs
* 0 - DEBUGs, INFOs, WARNINGs and ERRORs
* 1 - INFOs, WARNINGs and ERRORs (this is the default)
* 2 - WARNINGs and ERRORs
* 3 - only ERRORs
* 4 - absolutely nothing
*/
static int silence_level=0;
static int silence_level=1;
/*
* Mutex for threat synchronization when writing log data
@@ -53,18 +69,137 @@ static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
void log_set_pattern(int pattern) {
debug_pattern=pattern;
return;
}
int log_get_pattern(void) {
return debug_pattern;
}
void log_set_stdout(int tostdout) {
log_to_stdout=tostdout;
void log_set_stderr(int tostdout) {
log_to_stderr=tostdout;
return;
}
void log_set_silence(int level) {
silence_level=level;
return;
}
/*
* TCP logging
*/
void log_set_listen_port(int port){
debug_listen_port = port;
log_tcp_listen();
return;
}
void log_tcp_listen(void) {
struct sockaddr_in my_addr;
int sts, on=1;
int flags;
/* disabled in configuration? */
if (debug_listen_port == 0) {
debug_listen_fd=-1;
return;
}
/* ignore SIGPIPE of lost TCP connection */
signal (SIGPIPE, SIG_IGN);
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(debug_listen_port);
debug_listen_fd=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
INFO("DEBUG listener on TCP port %i",debug_listen_port);
if (debug_listen_fd < 0) {
ERROR("socket returned error [%i:%s]",errno, strerror(errno));
return;
}
if (setsockopt(debug_listen_fd, SOL_SOCKET, SO_REUSEADDR, &on , sizeof(on)) < 0) {
ERROR("socket returned error [%i:%s]",errno, strerror(errno));
return;
}
sts=bind(debug_listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (sts != 0) {
ERROR("bind returned error [%i:%s]",errno, strerror(errno));
close(debug_listen_fd);
debug_listen_fd=-1;
return;
}
/* set non-blocking */
flags = fcntl(debug_listen_fd, F_GETFL);
if (flags < 0) {
ERROR("fcntl returned error [%i:%s]",errno, strerror(errno));
close(debug_listen_fd);
debug_listen_fd=-1;
return;
}
if (fcntl(debug_listen_fd, F_SETFL, (long) flags | O_NONBLOCK) < 0) {
ERROR("fcntl returned error [%i:%s]",errno, strerror(errno));
close(debug_listen_fd);
debug_listen_fd=-1;
return;
}
listen (debug_listen_fd, 1);
return;
}
void log_tcp_connect(void) {
int sts;
fd_set fdset;
struct timeval timeout;
int tmpfd;
if (debug_listen_fd <= 0) return;
timeout.tv_sec=0;
timeout.tv_usec=0;
FD_ZERO(&fdset);
FD_SET (debug_listen_fd, &fdset);
sts=select(debug_listen_fd+1, &fdset, NULL, NULL, &timeout);
if (sts > 0) {
if (debug_fd != 0) {
tmpfd=accept(debug_listen_fd, NULL, NULL);
close(tmpfd);
INFO("Rejected DEBUG TCP connection");
} else {
debug_fd=accept(debug_listen_fd, NULL, NULL);
INFO("Accepted DEBUG TCP connection [fd=%i]", debug_fd);
}
}
/* check the TCP connection */
if (debug_fd > 0) {
timeout.tv_sec=0;
timeout.tv_usec=0;
FD_ZERO(&fdset);
FD_SET (debug_fd, &fdset);
sts=select(debug_fd+1, &fdset, NULL, NULL, &timeout);
if (sts > 0) {
char buf[32];
sts = recv(debug_fd, buf, sizeof(buf), 0);
/* got disconnected? */
if (sts == 0) {
close(debug_fd);
INFO("Disconnected DEBUG TCP connection [fd=%i]", debug_fd);
debug_fd=0;
}
}
}
return;
}
@@ -80,7 +215,6 @@ void log_debug(int class, char *file, int line, const char *format, ...) {
struct tm *tim;
char string[128];
if ((debug_pattern & class) == 0) return;
va_start(ap, format);
@@ -89,7 +223,7 @@ void log_debug(int class, char *file, int line, const char *format, ...) {
/*
* DEBUG output is either STDOUT or SYSLOG, but not both
*/
if (log_to_stdout) {
if (log_to_stderr) {
/* not running as daemon - log to STDERR */
time(&t);
tim=localtime(&t);
@@ -103,6 +237,21 @@ void log_debug(int class, char *file, int line, const char *format, ...) {
vsnprintf(string, sizeof(string), format, ap);
syslog(LOG_USER|LOG_DEBUG, "%s:%i %s", file, line, string);
}
/*
* Log to TCP
*/
if (debug_fd > 0) {
/* log to TCP socket */
time(&t);
tim=localtime(&t);
snprintf(outbuf, sizeof(outbuf) ,"%2.2i:%2.2i:%2.2i %s:%i ",
tim->tm_hour, tim->tm_min, tim->tm_sec, file, line);
write(debug_fd, outbuf, strlen(outbuf));
vsnprintf(outbuf, sizeof(outbuf) , format, ap);
write(debug_fd, outbuf, strlen(outbuf));
snprintf(outbuf, sizeof(outbuf) ,"\n");
write(debug_fd, outbuf, strlen(outbuf));
}
pthread_mutex_unlock(&log_mutex);
va_end(ap);
@@ -124,7 +273,7 @@ void log_error(char *file, int line, const char *format, ...) {
* INFO, WARN, ERROR output is always to syslog and if not daemonized
* st STDOUT as well.
*/
if (log_to_stdout) {
if (log_to_stderr) {
/* not running as daemon - log to STDERR */
time(&t);
tim=localtime(&t);
@@ -139,6 +288,21 @@ void log_error(char *file, int line, const char *format, ...) {
vsnprintf(string, sizeof(string), format, ap);
syslog(LOG_USER|LOG_WARNING, "%s:%i ERROR:%s", file, line, string);
}
/*
* Log to TCP
*/
if (debug_fd > 0) {
/* log to TCP socket */
time(&t);
tim=localtime(&t);
snprintf(outbuf, sizeof(outbuf) ,"%2.2i:%2.2i:%2.2i ERROR:%s:%i ",
tim->tm_hour, tim->tm_min, tim->tm_sec, file, line);
write(debug_fd, outbuf, strlen(outbuf));
vsnprintf(outbuf, sizeof(outbuf) , format, ap);
write(debug_fd, outbuf, strlen(outbuf));
snprintf(outbuf, sizeof(outbuf) ,"\n");
write(debug_fd, outbuf, strlen(outbuf));
}
pthread_mutex_unlock(&log_mutex);
va_end(ap);
@@ -160,7 +324,7 @@ void log_warn(char *file, int line, const char *format, ...) {
* INFO, WARN, ERROR output is always to syslog and if not daemonized
* st STDOUT as well.
*/
if (log_to_stdout) {
if (log_to_stderr) {
/* not running as daemon - log to STDERR */
time(&t);
tim=localtime(&t);
@@ -175,6 +339,21 @@ void log_warn(char *file, int line, const char *format, ...) {
vsnprintf(string, sizeof(string), format, ap);
syslog(LOG_USER|LOG_NOTICE, "%s:%i WARNING:%s", file, line, string);
}
/*
* Log to TCP
*/
if (debug_fd > 0) {
/* log to TCP socket */
time(&t);
tim=localtime(&t);
snprintf(outbuf, sizeof(outbuf) ,"%2.2i:%2.2i:%2.2i WARNING:%s:%i ",
tim->tm_hour, tim->tm_min, tim->tm_sec, file, line);
write(debug_fd, outbuf, strlen(outbuf));
vsnprintf(outbuf, sizeof(outbuf) , format, ap);
write(debug_fd, outbuf, strlen(outbuf));
snprintf(outbuf, sizeof(outbuf) ,"\n");
write(debug_fd, outbuf, strlen(outbuf));
}
pthread_mutex_unlock(&log_mutex);
va_end(ap);
@@ -196,7 +375,7 @@ void log_info(char *file, int line, const char *format, ...) {
* INFO, WARN, ERROR output is always to syslog and if not daemonized
* st STDOUT as well.
*/
if (log_to_stdout) {
if (log_to_stderr) {
/* not running as daemon - log to STDERR */
time(&t);
tim=localtime(&t);
@@ -211,6 +390,21 @@ void log_info(char *file, int line, const char *format, ...) {
vsnprintf(string, sizeof(string), format, ap);
syslog(LOG_USER|LOG_NOTICE, "%s:%i INFO:%s", file, line, string);
}
/*
* Log to TCP
*/
if (debug_fd > 0) {
/* log to TCP socket */
time(&t);
tim=localtime(&t);
snprintf(outbuf, sizeof(outbuf) ,"%2.2i:%2.2i:%2.2i INFO:%s:%i ",
tim->tm_hour, tim->tm_min, tim->tm_sec, file, line);
write(debug_fd, outbuf, strlen(outbuf));
vsnprintf(outbuf, sizeof(outbuf) , format, ap);
write(debug_fd, outbuf, strlen(outbuf));
snprintf(outbuf, sizeof(outbuf) ,"\n");
write(debug_fd, outbuf, strlen(outbuf));
}
pthread_mutex_unlock(&log_mutex);
va_end(ap);
@@ -225,10 +419,14 @@ void log_dump_buffer(int class, char *file, int line,
char tmp[8], tmplin1[80], tmplin2[80];
if ((debug_pattern & class) == 0) return;
if (!log_to_stdout) return;
if ((!log_to_stderr) && (debug_fd <= 0)) return;
pthread_mutex_lock(&log_mutex);
fprintf(stderr,"---BUFFER DUMP follows---\n");
if (log_to_stderr) fprintf(stderr, "---BUFFER DUMP follows---\n");
if (debug_fd > 0) {
snprintf(outbuf, sizeof(outbuf) ,"---BUFFER DUMP follows---\n");
write(debug_fd, outbuf, strlen(outbuf));
}
for (i=0; i<length; i+=16) {
strcpy(tmplin1,"");
@@ -239,12 +437,26 @@ void log_dump_buffer(int class, char *file, int line,
sprintf(tmp, "%c",(isprint((int)buffer[i+j]))? buffer[i+j]: '.');
strcat(tmplin2, tmp);
}
fprintf(stderr, " %-47.47s %-16.16s\n",tmplin1, tmplin2);
if (log_to_stderr) {
fprintf(stderr, " %-47.47s %-16.16s\n",tmplin1, tmplin2);
}
if (debug_fd > 0) {
snprintf(outbuf, sizeof(outbuf) ," %-47.47s %-16.16s\n",
tmplin1, tmplin2);
write(debug_fd, outbuf, strlen(outbuf));
}
}
fprintf(stderr,"\n---end of BUFFER DUMP---\n");
fflush(stderr);
if (log_to_stderr) {
fprintf(stderr,"\n---end of BUFFER DUMP---\n");
fflush(stderr);
}
if (debug_fd > 0) {
snprintf(outbuf, sizeof(outbuf) ,"---end of BUFFER DUMP---\n");
write(debug_fd, outbuf, strlen(outbuf));
}
pthread_mutex_unlock(&log_mutex);
return;
}
+4 -1
View File
@@ -38,8 +38,11 @@
void log_set_pattern(int pattern);
int log_get_pattern(void);
void log_set_stdout(int tostdout);
void log_set_stderr(int tostdout);
void log_set_silence(int level);
void log_set_listen_port(int port);
void log_tcp_listen(void);
void log_tcp_connect(void);
#undef DEBUG
#define DEBUG(F...) log_debug(1,__FILE__, __LINE__,F)
+1
View File
@@ -144,6 +144,7 @@ static int parse_config (FILE *configfile) {
void *dest;
} configoptions[] = {
{ "debug_level", TYP_INT4, &configuration.debuglevel },
{ "debug_port", TYP_INT4, &configuration.debugport },
{ "sip_listen_port", TYP_INT4, &configuration.sip_listen_port },
{ "daemonize", TYP_INT4, &configuration.daemonize },
{ "silence_log", TYP_INT4, &configuration.silence_log },
+8 -4
View File
@@ -88,7 +88,7 @@ int main (int argc, char *argv[])
char *pidfilename=NULL;
struct sigaction act;
log_set_stdout(1);
log_set_stderr(1);
/*
* setup signal handlers
@@ -191,6 +191,7 @@ int main (int argc, char *argv[])
/* set debug level as desired */
log_set_pattern(configuration.debuglevel);
log_set_listen_port(configuration.debugport);
/* change user and group IDs */
secure_enviroment();
@@ -202,7 +203,7 @@ int main (int argc, char *argv[])
setsid();
if (fork()!=0) exit(0);
log_set_stdout(0);
log_set_stderr(0);
INFO("daemonized, pid=%i", getpid());
}
@@ -255,11 +256,14 @@ int main (int argc, char *argv[])
*/
while (!exit_program) {
DEBUGC(DBCLASS_BABBLE,"going into sip_wait\n");
DEBUGC(DBCLASS_BABBLE,"going into sipsock_wait\n");
while (sipsock_wait()<=0) {
/* got no input, here by timeout. do aging */
register_agemap();
/* TCP log: check for a connection */
log_tcp_connect();
/* dump memory stats if requested to do so */
if (dmalloc_dump) {
dmalloc_dump=0;
@@ -276,7 +280,7 @@ int main (int argc, char *argv[])
}
/* got input, process */
DEBUGC(DBCLASS_BABBLE,"back from sip_wait");
DEBUGC(DBCLASS_BABBLE,"back from sipsock_wait");
i=sipsock_read(&buff, sizeof(buff)-1, &ticket.from, &ticket.protocol);
buff[i]='\0';
+1
View File
@@ -57,6 +57,7 @@ typedef struct {
*/
struct siproxd_config {
int debuglevel;
int debugport;
char *inbound_if;
char *outbound_if;
int sip_listen_port;
+2 -2
View File
@@ -68,7 +68,7 @@ int sipsock_listen (void) {
}
/*
* Wait for incoming SIP message. After a 5 sec timeout
* Wait for incoming SIP message. After a 2 sec timeout
* this function returns with sts=0
*
* RETURNS >0 if data received, =0 if nothing received /T/O), -1 on error
@@ -78,7 +78,7 @@ int sipsock_wait(void) {
fd_set fdset;
struct timeval timeout;
timeout.tv_sec=5;
timeout.tv_sec=2;
timeout.tv_usec=0;
FD_ZERO(&fdset);