Race conditions fixed on config reload

Race conditions on logging and name resolution
This commit is contained in:
z3APA3A 2015-12-04 00:59:52 +03:00
parent 1220c504bd
commit bd37ffa2f7
7 changed files with 41 additions and 21 deletions

View File

@ -270,12 +270,13 @@ void cyclestep(void){
} }
if(conf.logname) { if(conf.logname) {
if(timechanged(conf.logtime, conf.time, conf.logtype)) { if(timechanged(conf.logtime, conf.time, conf.logtype)) {
FILE *fp, *fp1; FILE *fp;
fp = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a"); fp = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a");
if (fp) { if (fp) {
fp1 = conf.stdlog; pthread_mutex_lock(&log_mutex);
fclose(conf.stdlog);
conf.stdlog = fp; conf.stdlog = fp;
if(fp1) fclose(fp1); pthread_mutex_unlock(&log_mutex);
} }
fseek(stdout, 0L, SEEK_END); fseek(stdout, 0L, SEEK_END);
usleep(SLEEPTIME); usleep(SLEEPTIME);
@ -510,6 +511,9 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
return 1; return 1;
} }
pthread_mutex_init(&log_mutex, NULL);
logmutexinit = 1;
pthread_mutex_init(&config_mutex, NULL); pthread_mutex_init(&config_mutex, NULL);
pthread_mutex_init(&bandlim_mutex, NULL); pthread_mutex_init(&bandlim_mutex, NULL);
pthread_mutex_init(&hash_mutex, NULL); pthread_mutex_init(&hash_mutex, NULL);

View File

@ -1024,7 +1024,6 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
int j, k, len, flen; int j, k, len, flen;
SOCKET sock; SOCKET sock;
unsigned ttl; unsigned ttl;
time_t t;
#ifndef NOIPV6 #ifndef NOIPV6
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
#else #else

View File

@ -596,18 +596,25 @@ void lognone(struct clientparam * param, const unsigned char *s) {
if(param->trafcountfunc)(*param->trafcountfunc)(param); if(param->trafcountfunc)(*param->trafcountfunc)(param);
clearstat(param); clearstat(param);
} }
pthread_mutex_t log_mutex;
int logmutexinit = 0;
void logstdout(struct clientparam * param, const unsigned char *s) { void logstdout(struct clientparam * param, const unsigned char *s) {
unsigned char buf[4096]; unsigned char buf[4096];
FILE *log; FILE *log;
if(!logmutexinit){
pthread_mutex_init(&log_mutex, NULL);
logmutexinit = 1;
}
pthread_mutex_lock(&log_mutex);
log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout; log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout;
dobuf(param, buf, s, NULL); dobuf(param, buf, s, NULL);
if(!param->nolog)if(fprintf(log, "%s\n", buf) < 0) { if(!param->nolog)if(fprintf(log, "%s\n", buf) < 0) {
perror("printf()"); perror("printf()");
}; };
if(log != conf.stdlog)fflush(log); if(log != conf.stdlog)fflush(log);
pthread_mutex_unlock(&log_mutex);
} }
#ifndef _WIN32 #ifndef _WIN32
void logsyslog(struct clientparam * param, const unsigned char *s) { void logsyslog(struct clientparam * param, const unsigned char *s) {
@ -714,6 +721,7 @@ unsigned long getip(unsigned char *name){
int i; int i;
int ndots = 0; int ndots = 0;
struct hostent *hp=NULL; struct hostent *hp=NULL;
RESOLVFUNC tmpresolv;
#ifdef GETHOSTBYNAME_R #ifdef GETHOSTBYNAME_R
struct hostent he; struct hostent he;
@ -734,10 +742,10 @@ unsigned long getip(unsigned char *name){
return retval; return retval;
} }
} }
if(resolvfunc){ if((tmpresolv=resolvfunc)){
if((*resolvfunc)(AF_INET, name, &retval)) return retval; if((*tmpresolv)(AF_INET, name, (unsigned char *)&retval)) return retval;
if(conf.demanddialprog) system(conf.demanddialprog); if(conf.demanddialprog) system(conf.demanddialprog);
return (*resolvfunc)(AF_INET, name, &retval)?retval:0; return (*tmpresolv)(AF_INET, name, (unsigned char *)&retval)?retval:0;
} }
#if !defined(_WIN32) && !defined(GETHOSTBYNAME_R) #if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)
if(!ghbn_init){ if(!ghbn_init){
@ -767,6 +775,7 @@ unsigned long getip46(int family, unsigned char *name, struct sockaddr *sa){
int ndots=0, ncols=0, nhex=0; int ndots=0, ncols=0, nhex=0;
struct addrinfo *ai, hint; struct addrinfo *ai, hint;
int i; int i;
RESOLVFUNC tmpresolv;
if(!sa) return 0; if(!sa) return 0;
if(!family) { if(!family) {
@ -805,14 +814,14 @@ unsigned long getip46(int family, unsigned char *name, struct sockaddr *sa){
return inet_pton(AF_INET6, name, SAADDR(sa))?(family==4? 0:AF_INET6) : 0; return inet_pton(AF_INET6, name, SAADDR(sa))?(family==4? 0:AF_INET6) : 0;
} }
} }
if(resolvfunc){ if((tmpresolv = resolvfunc)){
int f = (family == 6 || family == 64)?AF_INET6:AF_INET; int f = (family == 6 || family == 64)?AF_INET6:AF_INET;
*SAFAMILY(sa) = f; *SAFAMILY(sa) = f;
if(resolvfunc(f, name, SAADDR(sa))) return f; if(tmpresolv(f, name, SAADDR(sa))) return f;
if(family == 4 || family == 6) return 0; if(family == 4 || family == 6) return 0;
f = (family == 46)? AF_INET6 : AF_INET; f = (family == 46)? AF_INET6 : AF_INET;
*SAFAMILY(sa) = f; *SAFAMILY(sa) = f;
if(resolvfunc(f, name, SAADDR(sa))) return f; if(tmpresolv(f, name, SAADDR(sa))) return f;
return 0; return 0;
} }
memset(&hint, 0, sizeof(hint)); memset(&hint, 0, sizeof(hint));

View File

@ -310,7 +310,7 @@ static int h_log(int argc, unsigned char ** argv){
} }
#endif #endif
else { else {
FILE *fp, *fp1; FILE *fp;
if(argc > 2) { if(argc > 2) {
conf.logtype = getrotate(*argv[2]); conf.logtype = getrotate(*argv[2]);
} }
@ -323,9 +323,10 @@ static int h_log(int argc, unsigned char ** argv){
return 1; return 1;
} }
else { else {
fp1 = conf.stdlog; pthread_mutex_lock(&log_mutex);
if(conf.stdlog)fclose(conf.stdlog);
conf.stdlog = fp; conf.stdlog = fp;
if(fp1) fclose(fp1); pthread_mutex_unlock(&log_mutex);
#ifdef _WINCE #ifdef _WINCE
freopen(tmpbuf, "w", stdout); freopen(tmpbuf, "w", stdout);
freopen(tmpbuf, "w", stderr); freopen(tmpbuf, "w", stderr);

View File

@ -315,6 +315,8 @@ extern pthread_mutex_t bandlim_mutex;
extern pthread_mutex_t hash_mutex; extern pthread_mutex_t hash_mutex;
extern pthread_mutex_t tc_mutex; extern pthread_mutex_t tc_mutex;
extern pthread_mutex_t pwl_mutex; extern pthread_mutex_t pwl_mutex;
extern pthread_mutex_t log_mutex;
extern int logmutexinit;
#ifndef NOODBC #ifndef NOODBC
extern pthread_mutex_t odbc_mutex; extern pthread_mutex_t odbc_mutex;
#endif #endif

View File

@ -207,7 +207,8 @@ int MODULEMAINFUNC (int argc, char** argv){
break; break;
case 'l': case 'l':
srv.logfunc = logstdout; srv.logfunc = logstdout;
srv.logtarget = (unsigned char*)argv[i] + 2; if(srv.logtarget) myfree(srv.logtarget);
srv.logtarget = mystrdup((unsigned char*)argv[i] + 2);
if(argv[i][2]) { if(argv[i][2]) {
if(argv[i][2]=='@'){ if(argv[i][2]=='@'){
@ -268,7 +269,8 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif #endif
#endif #endif
case 'f': case 'f':
srv.logformat = (unsigned char *)argv[i] + 2; if(srv.logformat)myfree(srv.logformat);
srv.logformat = mystrdup((unsigned char *)argv[i] + 2);
break; break;
case 't': case 't':
srv.silent = 1; srv.silent = 1;
@ -656,12 +658,14 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
memset(srv, 0, sizeof(struct srvparam)); memset(srv, 0, sizeof(struct srvparam));
srv->version = conf.paused; srv->version = conf.paused;
srv->logfunc = conf.logfunc; srv->logfunc = conf.logfunc;
srv->logformat = conf.logformat; if(srv->logformat)myfree(srv->logformat);
srv->logformat = mystrdup(conf.logformat);
srv->authfunc = conf.authfunc; srv->authfunc = conf.authfunc;
srv->usentlm = 0; srv->usentlm = 0;
srv->maxchild = conf.maxchild; srv->maxchild = conf.maxchild;
srv->time_start = time(NULL); srv->time_start = time(NULL);
srv->logtarget = conf.logtarget; if(srv->logtarget) myfree(srv->logtarget);
srv->logtarget = mystrdup(conf.logtarget);
srv->srvsock = INVALID_SOCKET; srv->srvsock = INVALID_SOCKET;
srv->logdumpsrv = conf.logdumpsrv; srv->logdumpsrv = conf.logdumpsrv;
srv->logdumpcli = conf.logdumpcli; srv->logdumpcli = conf.logdumpcli;
@ -682,15 +686,16 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
if(srv->logformat){ if(srv->logformat){
char *s; char *s;
if(*srv->logformat == '-' && (s = strchr((char *)srv->logformat + 1, '+')) && s[1]){ if(*srv->logformat == '-' && (s = strchr((char *)srv->logformat + 1, '+')) && s[1]){
char* logformat = srv->logformat;
*s = 0; *s = 0;
srv->nonprintable = (unsigned char *)mystrdup((char *)srv->logformat + 1); srv->nonprintable = (unsigned char *)mystrdup((char *)srv->logformat + 1);
srv->replace = s[1]; srv->replace = s[1];
srv->logformat = (unsigned char *)mystrdup(s + 2); srv->logformat = (unsigned char *)mystrdup(s + 2);
*s = '+'; *s = '+';
myfree(logformat);
} }
else srv->logformat = (unsigned char *)mystrdup((char *)srv->logformat);
} }
if(srv->logtarget) srv->logtarget = (unsigned char *)mystrdup((char *)srv->logtarget);
memset(&param->sinsl, 0, sizeof(param->sinsl)); memset(&param->sinsl, 0, sizeof(param->sinsl));
memset(&param->sinsr, 0, sizeof(param->sinsr)); memset(&param->sinsr, 0, sizeof(param->sinsr));
memset(&param->req, 0, sizeof(param->req)); memset(&param->req, 0, sizeof(param->req));

View File

@ -256,7 +256,7 @@ void * smtppchild(struct clientparam* param) {
if(!strncasecmp(command, "MAIL", 4) || !strncasecmp(command, "RCPT", 4) || !strncasecmp(command, "STARTTLS", 8) || !strncasecmp(command, "TURN", 4)){ if(!strncasecmp(command, "MAIL", 4) || !strncasecmp(command, "RCPT", 4) || !strncasecmp(command, "STARTTLS", 8) || !strncasecmp(command, "TURN", 4)){
res = (int)strlen(command); res = (int)strlen(command);
command[res] = 0; command[res] = 0;
res = handlehdrfilterscli(param, &command, &res, 0, &res); res = handlehdrfilterscli(param, (unsigned char **)&command, &res, 0, &res);
if(res != PASS) { if(res != PASS) {
if(res == HANDLED) res = 2; if(res == HANDLED) res = 2;
else RETURN(677); else RETURN(677);