From 48b330da7cc887d3e7d097ef2df76958e6b50863 Mon Sep 17 00:00:00 2001 From: z3APA3A <3APA3A@3proxy.ru> Date: Fri, 30 Oct 2020 11:17:28 +0300 Subject: [PATCH] intermediate commit for logging --- src/3proxy.c | 3 +- src/common.c | 1 - src/conf.c | 65 +++---- src/log.c | 477 +++++++++++++++++++++++++++++++++++++++-------- src/proxy.h | 7 +- src/proxymain.c | 292 ++++++++++++----------------- src/structures.h | 15 +- 7 files changed, 568 insertions(+), 292 deletions(-) diff --git a/src/3proxy.c b/src/3proxy.c index 550f917..2ccc3a8 100644 --- a/src/3proxy.c +++ b/src/3proxy.c @@ -189,7 +189,7 @@ void dumpcounters(struct trafcount *tlin, int counterd){ if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){ FILE * cfp; - cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w"); + cfp = fopen((char *)dologname(tmpbuf, sizeof(tmpbuf), (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w"); if(cfp){ for(tl = tlin; cfp && tl; tl = tl->next){ if(tl->type >= conf.countertype) @@ -229,6 +229,7 @@ void cyclestep(void){ for(;;){ usleep(SLEEPTIME*999); +// flushlogs(); conf.time = time(0); if(conf.needreload) { doschedule(); diff --git a/src/common.c b/src/common.c index 3ddeb43..3730ce2 100644 --- a/src/common.c +++ b/src/common.c @@ -522,7 +522,6 @@ unsigned long getip(unsigned char *name){ } if((tmpresolv=resolvfunc)){ if((*tmpresolv)(AF_INET, name, (unsigned char *)&retval)) return retval; - if(conf.demanddialprog) system(conf.demanddialprog); return (*tmpresolv)(AF_INET, name, (unsigned char *)&retval)?retval:0; } #if !defined(_WIN32) && !defined(GETHOSTBYNAME_R) diff --git a/src/conf.c b/src/conf.c index aada6f7..7a8c08d 100644 --- a/src/conf.c +++ b/src/conf.c @@ -552,12 +552,6 @@ static int h_nsrecord(int argc, unsigned char **argv){ return 0; } -static int h_dialer(int argc, unsigned char **argv){ - if(conf.demanddialprog) myfree(conf.demanddialprog); - conf.demanddialprog = mystrdup((char *)argv[1]); - return 0; -} - static int h_system(int argc, unsigned char **argv){ int res; @@ -1439,36 +1433,35 @@ struct commands commandhandlers[]={ {commandhandlers+28, "nscache", h_nscache, 2, 2}, {commandhandlers+29, "nscache6", h_nscache6, 2, 2}, {commandhandlers+30, "nsrecord", h_nsrecord, 3, 3}, - {commandhandlers+31, "dialer", h_dialer, 2, 2}, - {commandhandlers+32, "system", h_system, 2, 2}, - {commandhandlers+33, "pidfile", h_pidfile, 2, 2}, - {commandhandlers+34, "monitor", h_monitor, 2, 2}, - {commandhandlers+35, "parent", h_parent, 5, 0}, - {commandhandlers+36, "allow", h_ace, 1, 0}, - {commandhandlers+37, "deny", h_ace, 1, 0}, - {commandhandlers+38, "redirect", h_ace, 3, 0}, - {commandhandlers+39, "bandlimin", h_ace, 2, 0}, - {commandhandlers+40, "bandlimout", h_ace, 2, 0}, - {commandhandlers+41, "nobandlimin", h_ace, 1, 0}, - {commandhandlers+42, "nobandlimout", h_ace, 1, 0}, - {commandhandlers+43, "countin", h_ace, 4, 0}, - {commandhandlers+44, "nocountin", h_ace, 1, 0}, - {commandhandlers+45, "countout", h_ace, 4, 0}, - {commandhandlers+46, "nocountout", h_ace, 1, 0}, - {commandhandlers+47, "connlim", h_ace, 4, 0}, - {commandhandlers+48, "noconnlim", h_ace, 1, 0}, - {commandhandlers+49, "plugin", h_plugin, 3, 0}, - {commandhandlers+50, "logdump", h_logdump, 2, 3}, - {commandhandlers+51, "filtermaxsize", h_filtermaxsize, 2, 2}, - {commandhandlers+52, "nolog", h_nolog, 1, 1}, - {commandhandlers+53, "weight", h_nolog, 2, 2}, - {commandhandlers+54, "authcache", h_authcache, 2, 3}, - {commandhandlers+55, "smtpp", h_proxy, 1, 0}, - {commandhandlers+56, "delimchar",h_delimchar, 2, 2}, - {commandhandlers+57, "authnserver", h_authnserver, 2, 2}, - {commandhandlers+58, "stacksize", h_stacksize, 2, 2}, - {commandhandlers+59, "force", h_force, 1, 1}, - {commandhandlers+60, "noforce", h_noforce, 1, 1}, + {commandhandlers+31, "system", h_system, 2, 2}, + {commandhandlers+32, "pidfile", h_pidfile, 2, 2}, + {commandhandlers+33, "monitor", h_monitor, 2, 2}, + {commandhandlers+34, "parent", h_parent, 5, 0}, + {commandhandlers+35, "allow", h_ace, 1, 0}, + {commandhandlers+36, "deny", h_ace, 1, 0}, + {commandhandlers+37, "redirect", h_ace, 3, 0}, + {commandhandlers+38, "bandlimin", h_ace, 2, 0}, + {commandhandlers+39, "bandlimout", h_ace, 2, 0}, + {commandhandlers+40, "nobandlimin", h_ace, 1, 0}, + {commandhandlers+41, "nobandlimout", h_ace, 1, 0}, + {commandhandlers+42, "countin", h_ace, 4, 0}, + {commandhandlers+43, "nocountin", h_ace, 1, 0}, + {commandhandlers+44, "countout", h_ace, 4, 0}, + {commandhandlers+45, "nocountout", h_ace, 1, 0}, + {commandhandlers+46, "connlim", h_ace, 4, 0}, + {commandhandlers+47, "noconnlim", h_ace, 1, 0}, + {commandhandlers+48, "plugin", h_plugin, 3, 0}, + {commandhandlers+49, "logdump", h_logdump, 2, 3}, + {commandhandlers+50, "filtermaxsize", h_filtermaxsize, 2, 2}, + {commandhandlers+51, "nolog", h_nolog, 1, 1}, + {commandhandlers+52, "weight", h_nolog, 2, 2}, + {commandhandlers+53, "authcache", h_authcache, 2, 3}, + {commandhandlers+54, "smtpp", h_proxy, 1, 0}, + {commandhandlers+55, "delimchar",h_delimchar, 2, 2}, + {commandhandlers+56, "authnserver", h_authnserver, 2, 2}, + {commandhandlers+57, "stacksize", h_stacksize, 2, 2}, + {commandhandlers+58, "force", h_force, 1, 1}, + {commandhandlers+59, "noforce", h_noforce, 1, 1}, #ifndef NORADIUS {commandhandlers+61, "radius", h_radius, 3, 0}, #endif diff --git a/src/log.c b/src/log.c index a0bae9c..da03174 100644 --- a/src/log.c +++ b/src/log.c @@ -8,25 +8,24 @@ #include "proxy.h" pthread_mutex_t log_mutex; -/* #ifdef _WIN32 HANDLE log_sem; #else sem_t log_sem; #endif -*/ -#define MAXLOG 64 -#define MAXLOGGERS 64 -#define LOGBUFSIZE 4096 +#define MAXLOG 1024 +#define EVENTSIZE (4096 - sizeof(void *)) +#define LOGBUFSIZE (EVENTSIZE - sizeof(struct logevent)) +#define MAX_SEM_COUNT 256 -struct logqueue { - int event; - int inbuf; - char buf[LOGBUFSIZE]; -} logq[MAXLOG]; +typedef enum { + REGISTER, + UNREGISTER, + LOG, + FLUSH, + FREEPARAM +} EVENTTYPE; -int loghead=0; -int logtail=0; struct clientparam logparam; @@ -36,18 +35,39 @@ struct LOGGER; void(*prelog)(struct clientparam * param) = NULL; + +struct logevent { + struct logevent *next; + struct LOGGER *log; + EVENTTYPE event; + int inbuf; + struct clientparam *param; + char * logstring; + char buf[1]; +} *logtail=NULL, *loghead=NULL; + + + +static void delayflushlogs(void); +static void delayunregisterlog (struct LOGGER * log); +static void delayregisterlog (struct LOGGER * log); +static void delaydolog(struct logevent *evt); +static void delayfreeparam(struct clientparam *param); + +void logpush(struct logevent *evt); + #ifdef WITHMAIN #define HAVERADIUS 0 #define HAVESQL 0 #else -int raddobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s); +int raddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s); void logradius(const char * buf, int len, struct LOGGER *logger); #define HAVERADIUS 1 #ifndef NOODBC #define HAVESQL 1 static int sqlinit(struct LOGGER *logger); -static int sqldobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s); +static int sqldobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s); static void sqllog(const char * buf, int len, struct LOGGER *logger); static void sqlrotate(struct LOGGER *logger); static void sqlclose(struct LOGGER *logger); @@ -67,24 +87,24 @@ static void syslogclose(struct LOGGER *logger); #endif static int stdloginit(struct LOGGER *logger); -int stddobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s); +int stddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s); static void stdlog(const char * buf, int len, struct LOGGER *logger); static void stdlogrotate(struct LOGGER *logger); static void stdlogclose(struct LOGGER *logger); - +static void stdlogflush(struct LOGGER *logger); struct LOGFUNC stdlogfuncs[] = { #if HAVESYSLOG > 0 - {stdlogfuncs+1, sysloginit, stddobuf, logsyslog, syslogrotate, syslogclose, "@"}, + {stdlogfuncs+1, sysloginit, stddobuf, logsyslog, syslogrotate, NULL, syslogclose, "@"}, #endif #if HAVERADIUS > 0 - {stdlogfuncs+1+HAVESYSLOG, NULL, raddobuf, logradius, NULL, NULL, "radius"}, + {stdlogfuncs+1+HAVESYSLOG, NULL, raddobuf, logradius, NULL, NULL, NULL, "radius"}, #endif #if HAVESQL > 0 - {stdlogfuncs+1+HAVESYSLOG+HAVERADIUS, sqlinit, sqldobuf, sqllog, sqlrotate, sqlclose, "&"}, + {stdlogfuncs+1+HAVESYSLOG+HAVERADIUS, sqlinit, sqldobuf, sqllog, sqlrotate, NULL, sqlclose, "&"}, #endif - {NULL, stdloginit, stddobuf, stdlog, stdlogrotate, stdlogclose, ""} + {NULL, stdloginit, stddobuf, stdlog, stdlogrotate, stdlogflush, stdlogclose, ""} }; struct LOGFUNC *logfuncs = stdlogfuncs; @@ -93,43 +113,128 @@ struct stdlogdata{ FILE *fp; } errld; -struct LOGGER errlogger = {NULL, "stderr", &errld, stdlogfuncs+1+HAVESYSLOG+HAVERADIUS+HAVESQL, 0, 0, 1}; +struct LOGGER errlogger = {NULL, NULL, "stderr", &errld, stdlogfuncs+1+HAVESYSLOG+HAVERADIUS+HAVESQL, 0, 0, 1}; struct LOGGER *loggers = &errlogger; -struct LOGGER * registerlog(const char * logstring, int logtype){ + + +static void delayflushlogs(void){ struct LOGGER *log; + for(log = loggers; log; log=log->next){ + if(log->logfunc && log->logfunc->flush)log->logfunc->flush(log); + } +} + + + +void flushlogs(void){ + struct logevent * evt; + evt = malloc(sizeof(struct logevent)); + evt->event = FLUSH; + logpush(evt); +} + + +void delayregisterlog(struct LOGGER *log){ struct LOGFUNC *funcs; + +printf("delayregisterlog %s\n", log->selector); +fflush(stdout); + if(log->logfunc) return; + for(funcs = logfuncs; funcs; funcs=funcs->next){ + if(!strncmp(log->selector, funcs->prefix, strlen(funcs->prefix))){ + if(funcs->init && funcs->init(log)) break; + log->logfunc = funcs; +printf("new log initialised\n"); +fflush(stdout); + return; + } + } +} + + +struct LOGGER * registerlog(const char * logstring, int logtype){ + struct LOGGER *log; + +printf("registerlog %s\n", logstring); +fflush(stdout); if(!logstring || !strcmp(logstring, "NUL") || !strcmp(logstring, "/dev/null")) return NULL; + pthread_mutex_lock(&log_mutex); for(log = loggers; log; log=log->next){ if(!strcmp(logstring, log->selector)){ if(logtype >= 0) log->rotate = logtype; log->registered++; +printf("log registered\n"); +fflush(stdout); + pthread_mutex_unlock(&log_mutex); return log; } } log = malloc(sizeof(struct LOGGER)); - if(!log) return NULL; + if(!log) { + pthread_mutex_unlock(&log_mutex); + return NULL; + } memset (log, 0, sizeof(struct LOGGER)); log->selector = mystrdup(logstring); if(log->selector){ + struct logevent *evt; if(logtype)log->rotate = logtype; - for(funcs = logfuncs; funcs; funcs=funcs->next){ - if(!strncmp(logstring, funcs->prefix, strlen(funcs->prefix))){ - if(funcs->init && funcs->init(log)) break; - log->registered++; - return log; - } - } - myfree(log->selector); + log->registered++; + log->next = loggers; + if (log->next)log->next->prev = log; + loggers = log; + pthread_mutex_unlock(&log_mutex); + + evt = malloc(sizeof(struct logevent)); + evt->event = REGISTER; + evt->log = log; + logpush(evt); +printf("new log registered\n"); +fflush(stdout); + return log; } + pthread_mutex_unlock(&log_mutex); myfree(log); return NULL; } +static void delayunregisterlog (struct LOGGER * log){ + if(log){ + pthread_mutex_lock(&log_mutex); + log->registered--; + if(!log->registered){ + if(log->prev)log->prev->next = log->next; + else loggers = log->next; + if(log->next)log->next->prev = log->prev; + pthread_mutex_unlock(&log_mutex); + + if(log->logfunc){ + if(log->logfunc->flush) log->logfunc->flush(log); + if(log->logfunc->close) log->logfunc->close(log); + } + myfree(log->selector); + myfree(log); +printf("log closed\n"); +fflush(stdout); + } + else pthread_mutex_unlock(&log_mutex); + +printf("log unregistered\n"); +fflush(stdout); + } +} + void unregisterlog (struct LOGGER * log){ - if(log)log->registered--; + struct logevent *evt; + + if(!log) return; + evt = malloc(sizeof(struct logevent)); + evt->event = UNREGISTER; + evt->log = log; + logpush(evt); } #ifdef _WIN32 @@ -138,20 +243,102 @@ DWORD WINAPI logthreadfunc(LPVOID p) { void * logthreadfunc (void *p) { #endif +printf("enter logthreadfunc\n"); +fflush(stdout); + + + + for(;;){ + struct logevent *evt; +#ifdef _WIN32 + WaitForSingleObject(log_sem, INFINITE); +#else + sem_wait(&log_sem); +#endif +printf("got semaphore\n"); +fflush(stdout); + + while(loghead){ + pthread_mutex_lock(&log_mutex); + evt = loghead; + loghead = evt->next; + if(!loghead)logtail = NULL; + pthread_mutex_unlock(&log_mutex); + switch(evt->event){ + case REGISTER: +printf("got register\n"); +fflush(stdout); + delayregisterlog(evt->log); + break; + case UNREGISTER: +printf("got unregister\n"); +fflush(stdout); + delayunregisterlog(evt->log); + break; + case FLUSH: +printf("got flush\n"); +fflush(stdout); +// delayflushlogs(); + break; + case LOG: +printf("got log\n"); +fflush(stdout); + delaydolog(evt); + break; + case FREEPARAM: +printf("got freeparam\n"); +fflush(stdout); + delayfreeparam(evt->param); + break; + + default: + break; + } + myfree(evt); + } + + + + } + +printf("finish logthreadfunc\n"); +fflush(stdout); + return 0; +} + + + +void logpush(struct logevent *evt){ +printf("logpush\n"); +fflush(stdout); + pthread_mutex_lock(&log_mutex); + if(logtail) logtail->next = evt; + logtail = evt; + evt->next = NULL; + if(!loghead)loghead = evt; + + pthread_mutex_unlock(&log_mutex); +printf("sending post\n"); +fflush(stdout); +#ifdef _WIN32 + ReleaseSemaphore(log_sem, 1, NULL); +#else + sem_post(&log_sem); +#endif } void initlog(void){ pthread_t thread; +printf("initlog\n"); +fflush(stdout); srvinit(&logsrv, &logparam); pthread_mutex_init(&log_mutex, NULL); errld.fp = stdout; -/* #ifdef _WIN32 { HANDLE h; - log_sem = CreateSemaphore(NULL, 0, MAX_SEM_COUNT, NULL); - sem_init(&log_sem, 0, 0); + if(!(log_sem = CreateSemaphore(NULL, 0, MAX_SEM_COUNT, NULL))) exit(11); #ifndef _WINCE h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread); #else @@ -168,39 +355,94 @@ void initlog(void){ { pthread_attr_t pa; pthread_attr_init(&pa); + pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 1024*256); pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED); + if(sem_init(&log_sem, 0, 0)) exit(11); if(pthread_create(&thread, &pa, logthreadfunc, (void *)newparam)) exit(10); } #endif -*/ +} + +static void delaydolog(struct logevent *evt){ + +printf("delaylog\n"); +fflush(stdout); + if(!evt->log->logfunc || !evt->log->logfunc->log) return; + if(evt->inbuf){ +printf("havebuffer\n"); +fflush(stdout); + evt->log->logfunc->log(evt->buf, evt->inbuf, evt->log); + } + else if(evt->param && evt->log->logfunc->dobuf){ + char buf[LOGBUFSIZE]; + +printf("haveparam\n"); +fflush(stdout); + evt->log->logfunc->log(buf, evt->log->logfunc->dobuf(evt->param, buf, LOGBUFSIZE, evt->logstring), evt->log); + } } void dolog(struct clientparam * param, const unsigned char *s){ static int init = 0; -/* TODO: dobuf */ -/* TODO: spooling */ +printf("dolog\n"); +fflush(stdout); if(!param || !param->srv){ stdlog(s, strlen(s), &errlogger); + return; } - else if(!param->nolog && param->srv->logtarget){ - if(prelog)prelog(param); - if(param->srv->log && param->srv->log->logfunc && param->srv->log->logfunc->log){ - char buf[LOGBUFSIZE]; - int inbuf = 0; + if(prelog)prelog(param); + if(!param->nolog && param->srv->log) { + struct logevent *evt; - -/* - int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s); - int (*log)(const char * buf, int len, struct LOGGER *logger); -*/ - if(param->srv->log->logfunc->dobuf){ - param->srv->log->logfunc->dobuf(param, buf, s); + if(!param->srv->log->logfunc) { + int inbuf=0, len =0; + + if(!(evt = malloc(sizeof(struct logevent) + param->hostname?strlen(param->hostname)+1:0 + s? strlen(s)+1:0 + param->username?strlen(param->username):0))) return; + evt->inbuf = 0; + evt->param=param; + evt->logstring = NULL; + if(s){ + len = strlen(s); + memcpy(evt->buf,s, len); + inbuf+=len; + evt->logstring = evt->buf; } + if(param->hostname){ + len = strlen(param->hostname); + memcpy(evt->buf+inbuf,param->hostname, len); + param->hostname = evt->buf + inbuf; + inbuf+=len; + } + if(param->username){ + len = strlen(param->username); + memcpy(evt->buf+inbuf,param->username, len); + param->username = evt->buf + inbuf; + inbuf+=len; + } + evt->event = LOG; + evt->log = param->srv->log; + logpush(evt); + } + else if (param->srv->log->logfunc->log){ - param->srv->log->logfunc->log(buf, inbuf, param->srv->log); +printf("havelog\n"); +fflush(stdout); + if(!(evt = malloc(param->srv->log->logfunc->dobuf?EVENTSIZE:sizeof(struct logevent)))) return; + evt->inbuf = 0; + evt->param = NULL; + evt->logstring = NULL; + + if(param->srv->log->logfunc->dobuf){ + evt->inbuf = param->srv->log->logfunc->dobuf(param, evt->buf, LOGBUFSIZE, s); + } + evt->event = LOG; + evt->log = param->srv->log; +printf("pushing event\n"); +fflush(stdout); + logpush(evt); } } if(param->trafcountfunc)(*param->trafcountfunc)(param); @@ -208,6 +450,73 @@ void dolog(struct clientparam * param, const unsigned char *s){ } +static void delayfreeparam(struct clientparam * param) { + if(param->res == 2) return; + if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) { + so._shutdown(param->ctrlsocksrv, SHUT_RDWR); + so._closesocket(param->ctrlsocksrv); + } + if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) { + so._shutdown(param->ctrlsock, SHUT_RDWR); + so._closesocket(param->ctrlsock); + } + if(param->remsock != INVALID_SOCKET) { + so._shutdown(param->remsock, SHUT_RDWR); + so._closesocket(param->remsock); + } + if(param->clisock != INVALID_SOCKET) { + so._shutdown(param->clisock, SHUT_RDWR); + so._closesocket(param->clisock); + } + myfree(param->clibuf); + myfree(param->srvbuf); + if(param->datfilterssrv) myfree(param->datfilterssrv); +#ifndef STDMAIN + if(param->reqfilters) myfree(param->reqfilters); + if(param->hdrfilterscli) myfree(param->hdrfilterscli); + if(param->hdrfilterssrv) myfree(param->hdrfilterssrv); + if(param->predatfilters) myfree(param->predatfilters); + if(param->datfilterscli) myfree(param->datfilterscli); + if(param->filters){ + if(param->nfilters)while(param->nfilters--){ + if(param->filters[param->nfilters].filter->filter_clear) + (*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data); + } + myfree(param->filters); + } + if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param); +#endif + if(param->srv){ + pthread_mutex_lock(¶m->srv->counter_mutex); + if(param->prev){ + param->prev->next = param->next; + } + else + param->srv->child = param->next; + if(param->next){ + param->next->prev = param->prev; + } + (param->srv->childcount)--; + if(param->srv->service == S_ZOMBIE && !param->srv->child)srvpostfree(param->srv); + pthread_mutex_unlock(¶m->srv->counter_mutex); + } + if(param->hostname) myfree(param->hostname); + if(param->username) myfree(param->username); + if(param->password) myfree(param->password); + if(param->extusername) myfree(param->extusername); + if(param->extpassword) myfree(param->extpassword); + myfree(param); +} + +void freeparam(struct clientparam * param) { + struct logevent *evt; + + evt = malloc(sizeof(struct logevent)); + evt->event = FREEPARAM; + evt->param = param; + logpush(evt); +} + void clearstat(struct clientparam * param) { #ifdef _WIN32 @@ -235,7 +544,7 @@ char months[12][4] = { "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) { +unsigned char * dologname (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) { struct tm *ts; ts = localtime(&t); @@ -243,7 +552,7 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign struct clientparam fakecli; memset(&fakecli, 0, sizeof(fakecli)); - dobuf2(&fakecli, buf, NULL, NULL, ts, (char *)name); + dobuf2(&fakecli, buf, bufsize - strlen(ext), NULL, NULL, ts, (char *)name); } else switch(lt){ case NONE: @@ -279,7 +588,7 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign return buf; } -int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){ +int dobuf2(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){ int i, j; int len; time_t sec; @@ -314,7 +623,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char delay = param->time_start?((unsigned) ((sec - param->time_start))*1000 + msec) - param->msec_start : 0; *buf = 0; - for(i=0, j=0; format[j] && i < (LOGBUFSIZE-70); j++){ + for(i=0, j=0; format[j] && i < (bufsize-70); j++){ if(format[j] == '%' && format[j+1]){ j++; switch(format[j]){ @@ -376,7 +685,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char break; case 'U': if(param->username && *param->username){ - for(len = 0; i< (LOGBUFSIZE - 3) && param->username[len]; len++){ + for(len = 0; i< (bufsize - 3) && param->username[len]; len++){ buf[i] = param->username[len]; if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace; if(doublec && strchr((char *)doublec, buf[i])) { @@ -392,7 +701,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char break; case 'n': len = param->hostname? (int)strlen((char *)param->hostname) : 0; - if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < (LOGBUFSIZE-3); len++, i++){ + if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < (bufsize-3); len++, i++){ buf[i] = param->hostname[len]; if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace; if(doublec && strchr((char *)doublec, buf[i])) { @@ -421,7 +730,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char break; case 'T': if(s){ - for(len = 0; i < (LOGBUFSIZE-3) && s[len]; len++){ + for(len = 0; i < (bufsize-3) && s[len]; len++){ buf[i] = s[len]; if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace; if(doublec && strchr((char *)doublec, buf[i])) { @@ -505,7 +814,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char while(isspace(s[len+1]))len++; if(k == pmin) continue; } - if(k>=pmin && k<=pmax && i < (LOGBUFSIZE-3)) { + if(k>=pmin && k<=pmax && i < (bufsize-3)) { buf[i] = s[len]; if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace; if(doublec && strchr((char *)doublec, buf[i])) { @@ -528,7 +837,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char return i; } -int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec){ +int dobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec){ struct tm* tm; int i; char * format; @@ -539,7 +848,7 @@ int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char * format = param->srv->logformat?(char *)param->srv->logformat : DEFLOGFORMAT; tm = (*format == 'G' || *format == 'g')? gmtime(&t) : localtime(&t); - i = dobuf2(param, buf, s, doublec, tm, format + 1); + i = dobuf2(param, buf, bufsize, s, doublec, tm, format + 1); return i; } @@ -547,10 +856,13 @@ int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char * static int stdloginit(struct LOGGER *logger){ char tmpbuf[1024]; struct stdlogdata *lp; + +printf("stdloginit %s\n", logger->selector); +fflush(stdout); lp = myalloc(sizeof(struct stdlogdata)); if(!lp) return 1; logger->data = lp; - if(!*logger->selector || !strstr(logger->selector, "stdout")){ + if(!*logger->selector || !strcmp(logger->selector, "stdout")){ logger->rotate = NONE; lp->fp = stdout; } @@ -559,31 +871,38 @@ static int stdloginit(struct LOGGER *logger){ lp->fp = stderr; } else { - lp->fp = fopen((char *)dologname (tmpbuf, logger->selector, NULL, logger->rotate, time(NULL)), "a"); + lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) - 1, logger->selector, NULL, logger->rotate, time(NULL)), "a"); if(!lp->fp){ +printf("file not created: %s\n", tmpbuf); myfree(lp); return(2); } +printf("file created: %s\n", tmpbuf); +fflush(stdout); } return 0; } -static int stddobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s){ - return dobuf(param, buf, s, NULL); +static int stddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s){ +printf("stddobuf\n"); +fflush(stdout); + return dobuf(param, buf, bufsize, s, NULL); } static void stdlog(const char * buf, int len, struct LOGGER *logger) { FILE *log = ((struct stdlogdata *)logger->data)->fp; +printf("stdlog\n"); +fflush(stdout); fprintf(log, "%s\n", buf); - if(log == stdout || log == stderr)fflush(log); +fflush(log); } static void stdlogrotate(struct LOGGER *logger){ char tmpbuf[1024]; struct stdlogdata *lp = (struct stdlogdata *)logger->data; - if(lp->fp) lp->fp = freopen((char *)dologname (tmpbuf, logger->selector, NULL, logger->rotate, conf.time), "a", lp->fp); - else lp->fp = fopen((char *)dologname (tmpbuf, logger->selector, NULL, logger->rotate, conf.time), "a"); + if(lp->fp) lp->fp = freopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a", lp->fp); + else lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a"); logger->rotated = conf.time; if(logger->rotate) { int t; @@ -604,7 +923,10 @@ static void stdlogrotate(struct LOGGER *logger){ default: break; } - dologname (tmpbuf, logger->selector, (conf.archiver)?conf.archiver[1]:NULL, logger->rotate, (logger->rotated - t * conf.rotate)); +/* + FIXME: move archiver to thread +*/ + dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, (conf.archiver)?conf.archiver[1]:NULL, logger->rotate, (logger->rotated - t * conf.rotate)); remove ((char *) tmpbuf); if(conf.archiver) { int i; @@ -613,12 +935,12 @@ static void stdlogrotate(struct LOGGER *logger){ strcat((char *)tmpbuf, " "); if(!strcmp((char *)conf.archiver[i], "%A")){ strcat((char *)tmpbuf, "\""); - dologname (tmpbuf + strlen((char *)tmpbuf), logger->selector, conf.archiver[1], logger->rotate, (logger->rotated - t)); + dologname (tmpbuf + strlen((char *)tmpbuf), sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1), logger->selector, conf.archiver[1], logger->rotate, (logger->rotated - t)); strcat((char *)tmpbuf, "\""); } else if(!strcmp((char *)conf.archiver[i], "%F")){ strcat((char *)tmpbuf, "\""); - dologname (tmpbuf+strlen((char *)tmpbuf), logger->selector, NULL, logger->rotate, (logger->rotated-t)); + dologname (tmpbuf+strlen((char *)tmpbuf), sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1), logger->selector, NULL, logger->rotate, (logger->rotated-t)); strcat((char *)tmpbuf, "\""); } else @@ -629,9 +951,14 @@ static void stdlogrotate(struct LOGGER *logger){ } } +static void stdlogflush(struct LOGGER *logger){ + fflush(((struct stdlogdata *)logger->data)->fp); +} + static void stdlogclose(struct LOGGER *logger){ - fclose(((struct stdlogdata *)logger->data)->fp); - myfree(((struct stdlogdata *)logger->data)->fp); + if(((struct stdlogdata *)logger->data)->fp != stdout && ((struct stdlogdata *)logger->data)->fp != stderr) + fclose(((struct stdlogdata *)logger->data)->fp); + myfree(logger->data); } #if HAVESYSLOG > 0 @@ -748,8 +1075,8 @@ static int sqlinit(struct LOGGER *logger){ return 0; } -static int sqldobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s){ - return dobuf(param, buf, s, (unsigned char *)"\'"); +static int sqldobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s){ + return dobuf(param, buf, bufsize, s, (unsigned char *)"\'"); } diff --git a/src/proxy.h b/src/proxy.h index db37e3c..bc15068 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -169,8 +169,8 @@ int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char * void initlog(void); void dolog(struct clientparam * param, const unsigned char *s); -int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec); -int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format); +int dobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec); +int dobuf2(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format); int doconnect(struct clientparam * param); int alwaysauth(struct clientparam * param); int ipauth(struct clientparam * param); @@ -192,6 +192,7 @@ unsigned long myresolver(int, unsigned char *, unsigned char *); unsigned long fakeresolver (int, unsigned char *, unsigned char*); int inithashtable(struct hashtable *hashtable, unsigned nhashsize); void freeparam(struct clientparam * param); +void srvpostfree(struct srvparam * srv); void clearstat(struct clientparam * param); void dumpcounters(struct trafcount *tl, int counterd); int startconnlims (struct clientparam *param); @@ -263,7 +264,7 @@ FILTER_ACTION handledatfltsrv(struct clientparam *param, unsigned char ** buf_p, void srvinit(struct srvparam * srv, struct clientparam *param); void srvinit2(struct srvparam * srv, struct clientparam *param); void srvfree(struct srvparam * srv); -unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t); +unsigned char * dologname (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t); int readconfig(FILE * fp); int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to); diff --git a/src/proxymain.c b/src/proxymain.c index 3d0eabe..eac6491 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -8,6 +8,8 @@ #include "proxy.h" +void srvpostfree(struct srvparam * srv); + #define param ((struct clientparam *) p) #ifdef _WIN32 DWORD WINAPI threadfunc(LPVOID p) { @@ -179,7 +181,7 @@ int MODULEMAINFUNC (int argc, char** argv){ SASIZETYPE size; pthread_t thread; struct clientparam defparam; - struct srvparam srv; + struct srvparam *srv; struct clientparam * newparam; int error = 0; unsigned sleeptime; @@ -271,20 +273,21 @@ int MODULEMAINFUNC (int argc, char** argv){ #endif - srvinit(&srv, &defparam); - srv.pf = childdef.pf; + srv = malloc(sizeof(struct srvparam)); + srvinit(srv, &defparam); + srv->pf = childdef.pf; isudp = childdef.isudp; - srv.service = defparam.service = childdef.service; + srv->service = defparam.service = childdef.service; #ifndef STDMAIN - copyacl(conf.acl, &srv); - srv.authfuncs = copyauth(conf.authfuncs); + copyacl(conf.acl, srv); + srv->authfuncs = copyauth(conf.authfuncs); if(!conf.services){ - conf.services = &srv; + conf.services = srv; } else { - srv.next = conf.services; - conf.services = conf.services->prev = &srv; + srv->next = conf.services; + conf.services = conf.services->prev = srv; } #ifndef _WIN32 { @@ -294,7 +297,7 @@ int MODULEMAINFUNC (int argc, char** argv){ } #endif #else - srv.needuser = 0; + srv->needuser = 0; initlog(); #endif @@ -307,16 +310,16 @@ int MODULEMAINFUNC (int argc, char** argv){ break; #ifdef SO_BINDTODEVICE case 'D': - if(argv[i][2] == 'i') srv.ibindtodevice = mystrdup(argv[i] + 3); - else srv.obindtodevice = mystrdup(argv[i] + 3); + if(argv[i][2] == 'i') srv->ibindtodevice = mystrdup(argv[i] + 3); + else srv->obindtodevice = mystrdup(argv[i] + 3); break; #endif case 'l': - myfree(srv.logtarget); - srv.logtarget = (unsigned char *)mystrdup(argv[i] + 2); + myfree(srv->logtarget); + srv->logtarget = (unsigned char *)mystrdup(argv[i] + 2); break; case 'i': - getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.intsa); + getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->intsa); break; case 'e': { @@ -325,29 +328,29 @@ int MODULEMAINFUNC (int argc, char** argv){ memset(&sa6, 0, sizeof(sa6)); error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6); if(!error) { - if (*SAFAMILY(&sa6)==AF_INET) srv.extsa = sa6; - else srv.extsa6 = sa6; + if (*SAFAMILY(&sa6)==AF_INET) srv->extsa = sa6; + else srv->extsa6 = sa6; } #else - error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extsa); + error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->extsa); #endif } break; case 'N': - getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat); + getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->extNat); break; case 'p': - *SAPORT(&srv.intsa) = htons(atoi(argv[i]+2)); + *SAPORT(&srv->intsa) = htons(atoi(argv[i]+2)); break; case '4': case '6': - srv.family = atoi(argv[i]+1); + srv->family = atoi(argv[i]+1); break; case 'b': - srv.bufsize = atoi(argv[i]+2); + srv->bufsize = atoi(argv[i]+2); break; case 'n': - srv.usentlm = atoi(argv[i]+2); + srv->usentlm = atoi(argv[i]+2); break; #ifdef STDMAIN #ifndef _WIN32 @@ -361,11 +364,11 @@ int MODULEMAINFUNC (int argc, char** argv){ #endif #endif case 'f': - if(srv.logformat)myfree(srv.logformat); - srv.logformat = (unsigned char *)mystrdup(argv[i] + 2); + if(srv->logformat)myfree(srv->logformat); + srv->logformat = (unsigned char *)mystrdup(argv[i] + 2); break; case 't': - srv.silent = 1; + srv->silent = 1; break; case 'h': hostname = argv[i] + 2; @@ -379,44 +382,44 @@ int MODULEMAINFUNC (int argc, char** argv){ iscbl = 1; break; case 'u': - srv.needuser = 0; - if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2); + srv->needuser = 0; + if(*(argv[i] + 2)) srv->needuser = atoi(argv[i] + 2); break; case 'T': - srv.transparent = 1; + srv->transparent = 1; break; case 'S': - srv.stacksize = atoi(argv[i]+2); + srv->stacksize = atoi(argv[i]+2); break; case 'a': - srv.anonymous = 1 + atoi(argv[i]+2); + srv->anonymous = 1 + atoi(argv[i]+2); break; case 's': #ifdef WITHSPLICE - if(isudp || srv.service == S_ADMIN) + if(isudp || srv->service == S_ADMIN) #endif - srv.singlepacket = 1 + atoi(argv[i]+2); + srv->singlepacket = 1 + atoi(argv[i]+2); #ifdef WITHSPLICE else - if(*(argv[i]+2)) srv.usesplice = atoi(argv[i]+2); + if(*(argv[i]+2)) srv->usesplice = atoi(argv[i]+2); #endif break; case 'o': switch(argv[i][2]){ case 's': - srv.srvsockopts = getopts(argv[i]+3); + srv->srvsockopts = getopts(argv[i]+3); break; case 'c': - srv.clisockopts = getopts(argv[i]+3); + srv->clisockopts = getopts(argv[i]+3); break; case 'l': - srv.lissockopts = getopts(argv[i]+3); + srv->lissockopts = getopts(argv[i]+3); break; case 'r': - srv.cbcsockopts = getopts(argv[i]+3); + srv->cbcsockopts = getopts(argv[i]+3); break; case 'R': - srv.cbcsockopts = getopts(argv[i]+3); + srv->cbcsockopts = getopts(argv[i]+3); break; default: error = 1; @@ -467,7 +470,7 @@ int MODULEMAINFUNC (int argc, char** argv){ else { #endif #ifndef NOPORTMAP - if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) { + if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv->intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv->targetport = htons((unsigned short)atoi(argv[i+2])))==0) { #ifndef STDMAIN haveerror = 1; conf.threadinit = 0; @@ -493,7 +496,7 @@ int MODULEMAINFUNC (int argc, char** argv){ ); return (1); } - srv.target = (unsigned char *)mystrdup(argv[i+1]); + srv->target = (unsigned char *)mystrdup(argv[i+1]); #endif #ifndef STDMAIN } @@ -512,7 +515,7 @@ int MODULEMAINFUNC (int argc, char** argv){ return 2; }; *newparam = defparam; - return((*srv.pf)((void *)newparam)? 1:0); + return((*srv->pf)((void *)newparam)? 1:0); } #endif @@ -521,19 +524,19 @@ int MODULEMAINFUNC (int argc, char** argv){ #endif - srvinit2(&srv, &defparam); - if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET; - if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port); - *SAFAMILY(&srv.extsa) = AF_INET; + srvinit2(srv, &defparam); + if(!*SAFAMILY(&srv->intsa)) *SAFAMILY(&srv->intsa) = AF_INET; + if(!*SAPORT(&srv->intsa)) *SAPORT(&srv->intsa) = htons(childdef.port); + *SAFAMILY(&srv->extsa) = AF_INET; #ifndef NOIPV6 - *SAFAMILY(&srv.extsa6) = AF_INET6; + *SAFAMILY(&srv->extsa6) = AF_INET6; #endif if(hostname)parsehostname(hostname, &defparam, childdef.port); #ifndef STDMAIN - copyfilter(conf.filters, &srv); + copyfilter(conf.filters, srv); conf.threadinit = 0; @@ -542,27 +545,27 @@ int MODULEMAINFUNC (int argc, char** argv){ if (!iscbc) { - if(srv.srvsock == INVALID_SOCKET){ + if(srv->srvsock == INVALID_SOCKET){ if(!isudp){ lg.l_onoff = 1; lg.l_linger = conf.timeouts[STRING_L]; - sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP); + sock=so._socket(SASOCK(&srv->intsa), SOCK_STREAM, IPPROTO_TCP); } else { - sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP); + sock=so._socket(SASOCK(&srv->intsa), SOCK_DGRAM, IPPROTO_UDP); } if( sock == INVALID_SOCKET) { perror("socket()"); return -2; } - setopts(sock, srv.lissockopts); + setopts(sock, srv->lissockopts); #ifdef _WIN32 ioctlsocket(sock, FIONBIO, &ul); #else fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL)); #endif - srv.srvsock = sock; + srv->srvsock = sock; opt = 1; if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()"); #ifdef SO_REUSEPORT @@ -570,13 +573,13 @@ int MODULEMAINFUNC (int argc, char** argv){ so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int)); #endif #ifdef SO_BINDTODEVICE - if(srv.ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1); + if(srv->ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv->ibindtodevice, strlen(srv->ibindtodevice) + 1); #endif } - size = sizeof(srv.intsa); - for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, SASIZE(&srv.intsa))==-1; usleep(sleeptime)) { + size = sizeof(srv->intsa); + for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv->intsa, SASIZE(&srv->intsa))==-1; usleep(sleeptime)) { sprintf((char *)buf, "bind(): %s", strerror(errno)); - if(!srv.silent)dolog(&defparam, buf); + if(!srv->silent)dolog(&defparam, buf); sleeptime = (sleeptime<<1); if(!sleeptime) { so._closesocket(sock); @@ -584,69 +587,69 @@ int MODULEMAINFUNC (int argc, char** argv){ } } if(!isudp){ - if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) { + if(so._listen (sock, 1 + (srv->maxchild>>4))==-1) { sprintf((char *)buf, "listen(): %s", strerror(errno)); - if(!srv.silent)dolog(&defparam, buf); + if(!srv->silent)dolog(&defparam, buf); return -4; } } else defparam.clisock = sock; - if(!srv.silent && !iscbc){ + if(!srv->silent && !iscbc){ sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self()); dolog(&defparam, buf); } } if(iscbl){ - parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa); - if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) { + parsehost(srv->family, cbl_string, (struct sockaddr *)&cbsa); + if((srv->cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) { dolog(&defparam, (unsigned char *)"Failed to allocate connect back socket"); return -6; } opt = 1; - so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)); + so._setsockopt(srv->cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)); #ifdef SO_REUSEPORT opt = 1; - so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int)); + so._setsockopt(srv->cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int)); #endif - setopts(srv.cbsock, srv.cbssockopts); + setopts(srv->cbsock, srv->cbssockopts); - if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) { + if(so._bind(srv->cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) { dolog(&defparam, (unsigned char *)"Failed to bind connect back socket"); return -7; } - if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) { + if(so._listen(srv->cbsock, 1 + (srv->maxchild>>4))==-1) { dolog(&defparam, (unsigned char *)"Failed to listen connect back socket"); return -8; } } - srv.fds.fd = sock; - srv.fds.events = POLLIN; + srv->fds.fd = sock; + srv->fds.events = POLLIN; #ifndef _WIN32 pthread_attr_init(&pa); - pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv.stacksize)); + pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv->stacksize)); pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED); #endif for (;;) { for(;;){ - while((conf.paused == srv.paused && srv.childcount >= srv.maxchild)){ + while((conf.paused == srv->paused && srv->childcount >= srv->maxchild)){ nlog++; - if(!srv.silent && nlog > 5000) { - sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv.childcount, srv.maxchild); + if(!srv->silent && nlog > 5000) { + sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv->childcount, srv->maxchild); dolog(&defparam, buf); nlog = 0; } usleep(SLEEPTIME); } if (iscbc) break; - if (conf.paused != srv.paused) break; - if (srv.fds.events & POLLIN) { - error = so._poll(&srv.fds, 1, 1000); + if (conf.paused != srv->paused) break; + if (srv->fds.events & POLLIN) { + error = so._poll(&srv->fds, 1, 1000); } else { usleep(SLEEPTIME); @@ -656,20 +659,20 @@ int MODULEMAINFUNC (int argc, char** argv){ if (error == 0) continue; if (errno != EAGAIN && errno != EINTR) { sprintf((char *)buf, "poll(): %s/%d", strerror(errno), errno); - if(!srv.silent)dolog(&defparam, buf); + if(!srv->silent)dolog(&defparam, buf); break; } } - if((conf.paused != srv.paused) || (error < 0)) break; + if((conf.paused != srv->paused) || (error < 0)) break; error = 0; if(!isudp){ size = sizeof(defparam.sincr); if(iscbc){ new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP); if(new_sock != INVALID_SOCKET){ - setopts(new_sock, srv.cbcsockopts); + setopts(new_sock, srv->cbcsockopts); - parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr); + parsehost(srv->family, cbc_string, (struct sockaddr *)&defparam.sincr); if(connectwithpoll(new_sock,(struct sockaddr *)&defparam.sincr,SASIZE(&defparam.sincr),CONNBACK_TO)) { so._closesocket(new_sock); new_sock = INVALID_SOCKET; @@ -727,7 +730,7 @@ int MODULEMAINFUNC (int argc, char** argv){ } #endif nlog++; - if(!srv.silent && (error || nlog > 5000)) { + if(!srv->silent && (error || nlog > 5000)) { sprintf((char *)buf, "accept(): %s", strerror(errno)); dolog(&defparam, buf); nlog = 0; @@ -735,11 +738,11 @@ int MODULEMAINFUNC (int argc, char** argv){ continue; } } - setopts(new_sock, srv.clisockopts); + setopts(new_sock, srv->clisockopts); size = sizeof(defparam.sincl); if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){ sprintf((char *)buf, "getsockname(): %s", strerror(errno)); - if(!srv.silent)dolog(&defparam, buf); + if(!srv->silent)dolog(&defparam, buf); continue; } #ifdef _WIN32 @@ -751,7 +754,7 @@ int MODULEMAINFUNC (int argc, char** argv){ so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int)); } else { - srv.fds.events = 0; + srv->fds.events = 0; } #ifndef STDMAIN @@ -763,7 +766,7 @@ int MODULEMAINFUNC (int argc, char** argv){ if(! (newparam = myalloc (sizeof(defparam)))){ if(!isudp) so._closesocket(new_sock); defparam.res = 21; - if(!srv.silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed"); + if(!srv->silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed"); usleep(SLEEPTIME); continue; }; @@ -773,68 +776,64 @@ int MODULEMAINFUNC (int argc, char** argv){ if(!isudp) newparam->clisock = new_sock; #ifndef STDMAIN - if(makefilters(&srv, newparam) > CONTINUE){ + if(makefilters(srv, newparam) > CONTINUE){ freeparam(newparam); continue; } #endif newparam->prev = newparam->next = NULL; error = 0; - pthread_mutex_lock(&srv.counter_mutex); - if(!srv.child){ - srv.child = newparam; + pthread_mutex_lock(&srv->counter_mutex); + if(!srv->child){ + srv->child = newparam; } else { - newparam->next = srv.child; - srv.child = srv.child->prev = newparam; + newparam->next = srv->child; + srv->child = srv->child->prev = newparam; } #ifdef _WIN32 #ifndef _WINCE - h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread); + h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread); #else - h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread); + h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread); #endif - srv.childcount++; + srv->childcount++; if (h) { newparam->threadid = (unsigned)thread; CloseHandle(h); } else { sprintf((char *)buf, "_beginthreadex(): %s", _strerror(NULL)); - if(!srv.silent)dolog(&defparam, buf); + if(!srv->silent)dolog(&defparam, buf); error = 1; } #else error = pthread_create(&thread, &pa, threadfunc, (void *)newparam); - srv.childcount++; + srv->childcount++; if(error){ sprintf((char *)buf, "pthread_create(): %s", strerror(error)); - if(!srv.silent)dolog(&defparam, buf); + if(!srv->silent)dolog(&defparam, buf); } else { newparam->threadid = (unsigned)thread; } #endif - pthread_mutex_unlock(&srv.counter_mutex); + pthread_mutex_unlock(&srv->counter_mutex); if(error) freeparam(newparam); memset(&defparam.sincl, 0, sizeof(defparam.sincl)); memset(&defparam.sincr, 0, sizeof(defparam.sincr)); - if(isudp) while(!srv.fds.events)usleep(SLEEPTIME); + if(isudp) while(!srv->fds.events)usleep(SLEEPTIME); } - if(!srv.silent) dolog(&defparam, (unsigned char *)"Exiting thread"); + if(!srv->silent) dolog(&defparam, (unsigned char *)"Exiting thread"); - srvfree(&srv); + srvfree(srv); + pthread_mutex_lock(&srv->counter_mutex); + if(!srv->child)srvpostfree(srv); + pthread_mutex_unlock(&srv->counter_mutex); -#ifndef STDMAIN - pthread_mutex_lock(&config_mutex); - if(srv.next)srv.next->prev = srv.prev; - if(srv.prev)srv.prev->next = srv.next; - else conf.services = srv.next; - pthread_mutex_unlock(&config_mutex); -#endif #ifndef _WIN32 pthread_attr_destroy(&pa); @@ -916,15 +915,15 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){ param->sinsr = srv->extsa; } -void srvfree(struct srvparam * srv){ - if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock); - srv->srvsock = INVALID_SOCKET; - if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock); - srv->cbsock = INVALID_SOCKET; - srv->service = S_ZOMBIE; - while(srv->child) usleep(SLEEPTIME * 100); + +void srvpostfree(struct srvparam * srv){ unregisterlog(srv->log); #ifndef STDMAIN + pthread_mutex_lock(&config_mutex); + if(srv->next)srv->next->prev = srv->prev; + if(srv->prev)srv->prev->next = srv->next; + else conf.services = srv->next; + pthread_mutex_unlock(&config_mutex); if(srv->filter){ while(srv->nfilters){ srv->nfilters--; @@ -948,64 +947,15 @@ void srvfree(struct srvparam * srv){ if(srv->ibindtodevice) myfree(srv->ibindtodevice); if(srv->obindtodevice) myfree(srv->obindtodevice); #endif + myfree(srv); } - -void freeparam(struct clientparam * param) { - if(param->res == 2) return; - if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) { - so._shutdown(param->ctrlsocksrv, SHUT_RDWR); - so._closesocket(param->ctrlsocksrv); - } - if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) { - so._shutdown(param->ctrlsock, SHUT_RDWR); - so._closesocket(param->ctrlsock); - } - if(param->remsock != INVALID_SOCKET) { - so._shutdown(param->remsock, SHUT_RDWR); - so._closesocket(param->remsock); - } - if(param->clisock != INVALID_SOCKET) { - so._shutdown(param->clisock, SHUT_RDWR); - so._closesocket(param->clisock); - } - myfree(param->clibuf); - myfree(param->srvbuf); - if(param->datfilterssrv) myfree(param->datfilterssrv); -#ifndef STDMAIN - if(param->reqfilters) myfree(param->reqfilters); - if(param->hdrfilterscli) myfree(param->hdrfilterscli); - if(param->hdrfilterssrv) myfree(param->hdrfilterssrv); - if(param->predatfilters) myfree(param->predatfilters); - if(param->datfilterscli) myfree(param->datfilterscli); - if(param->filters){ - if(param->nfilters)while(param->nfilters--){ - if(param->filters[param->nfilters].filter->filter_clear) - (*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data); - } - myfree(param->filters); - } - if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param); -#endif - if(param->srv){ - pthread_mutex_lock(¶m->srv->counter_mutex); - if(param->prev){ - param->prev->next = param->next; - } - else - param->srv->child = param->next; - if(param->next){ - param->next->prev = param->prev; - } - (param->srv->childcount)--; - pthread_mutex_unlock(¶m->srv->counter_mutex); - } - if(param->hostname) myfree(param->hostname); - if(param->username) myfree(param->username); - if(param->password) myfree(param->password); - if(param->extusername) myfree(param->extusername); - if(param->extpassword) myfree(param->extpassword); - myfree(param); +void srvfree(struct srvparam * srv){ + if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock); + srv->srvsock = INVALID_SOCKET; + if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock); + srv->cbsock = INVALID_SOCKET; + srv->service = S_ZOMBIE; } diff --git a/src/structures.h b/src/structures.h index 218cf87..04bfd45 100644 --- a/src/structures.h +++ b/src/structures.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { #endif @@ -195,6 +196,7 @@ struct symbol; struct pluginlink; struct srvparam; struct LOGFUNC; +struct LOGGER; typedef int (*AUTHFUNC)(struct clientparam * param); typedef void * (*REDIRECTFUNC)(struct clientparam * param); typedef unsigned long (*RESOLVFUNC)(int af, unsigned char *name, unsigned char *value); @@ -373,15 +375,18 @@ struct trafcount { struct LOGFUNC { struct LOGFUNC* next; int (*init)(struct LOGGER *logger); - int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s); + int (*dobuf)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s); void (*log)(const char * buf, int len, struct LOGGER *logger); void (*rotate)(struct LOGGER *logger); + void (*flush)(struct LOGGER *logger); void (*close)(struct LOGGER *logger); char* prefix; }; extern struct LOGFUNC *logfuncs; +extern void(*prelog)(struct clientparam * param); struct LOGGER { struct LOGGER *next; + struct LOGGER *prev; char * selector; void * data; struct LOGFUNC *logfunc; @@ -389,9 +394,9 @@ struct LOGGER { time_t rotated; int registered; }; -extern void(*prelog)(struct clientparam * param); struct LOGGER * registerlog(const char * logstring, int logtype); void unregisterlog (struct LOGGER * log); +void flushlogs(void); struct nserver { #ifndef NOIPV6 struct sockaddr_in6 addr; @@ -764,8 +769,8 @@ struct pluginlink { int (*sockgetcharsrv)(struct clientparam * param, int timeosec, int timeousec); int (*sockgetlinebuf)(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to); int (*myinet_ntop)(int af, void *src, char *dst, socklen_t size); - int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec); - int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format); + int (*dobuf)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec); + int (*dobuf2)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format); int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask); unsigned long (*getip46)(int family, unsigned char *name, struct sockaddr *sa); int (*sockmap)(struct clientparam * param, int timeo, int usesplice); @@ -798,7 +803,7 @@ struct pluginlink { int (*parseusername)(char *username, struct clientparam *param, int extpasswd); int (*parseconnusername)(char *username, struct clientparam *param, int extpasswd, unsigned short port); struct sockfuncs *so; - unsigned char * (*dologname) (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t); + unsigned char * (*dologname) (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t); }; struct counter_header {