Sfoglia il codice sorgente

Race conditions fixed on config reload

Race conditions on logging and name resolution
z3APA3A 10 anni fa
parent
commit
bd37ffa2f7
7 ha cambiato i file con 41 aggiunte e 21 eliminazioni
  1. 7 3
      src/3proxy.c
  2. 0 1
      src/auth.c
  3. 16 7
      src/common.c
  4. 4 3
      src/conf.c
  5. 2 0
      src/proxy.h
  6. 11 6
      src/proxymain.c
  7. 1 1
      src/smtpp.c

+ 7 - 3
src/3proxy.c

@@ -270,12 +270,13 @@ void cyclestep(void){
 	}
 	if(conf.logname) {
 		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");
 			if (fp) {
-				fp1 = conf.stdlog;
+				pthread_mutex_lock(&log_mutex);
+				fclose(conf.stdlog);
 				conf.stdlog = fp;
-				if(fp1) fclose(fp1);
+				pthread_mutex_unlock(&log_mutex);
 			}
 			fseek(stdout, 0L, SEEK_END);
 			usleep(SLEEPTIME);
@@ -510,6 +511,9 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
 	return 1;
   }
 
+  pthread_mutex_init(&log_mutex, NULL);
+  logmutexinit = 1;
+
   pthread_mutex_init(&config_mutex, NULL);
   pthread_mutex_init(&bandlim_mutex, NULL);
   pthread_mutex_init(&hash_mutex, NULL);

+ 0 - 1
src/auth.c

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

+ 16 - 7
src/common.c

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

+ 4 - 3
src/conf.c

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

+ 2 - 0
src/proxy.h

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

+ 11 - 6
src/proxymain.c

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

+ 1 - 1
src/smtpp.c

@@ -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)){
 		res = (int)strlen(command);
 		command[res] = 0;
-		res = handlehdrfilterscli(param, &command, &res, 0, &res);
+		res = handlehdrfilterscli(param, (unsigned char **)&command, &res, 0, &res);
 		if(res != PASS) {
 			if(res == HANDLED) res = 2;
 			else RETURN(677);