mirror of
				https://github.com/3proxy/3proxy.git
				synced 2025-11-04 07:42:39 +08:00 
			
		
		
		
	Race conditions fixed on config reload
Race conditions on logging and name resolution
This commit is contained in:
		
							parent
							
								
									1220c504bd
								
							
						
					
					
						commit
						bd37ffa2f7
					
				
							
								
								
									
										10
									
								
								src/3proxy.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/3proxy.c
									
									
									
									
									
								
							@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								src/common.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/common.c
									
									
									
									
									
								
							@ -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));
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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(¶m->sinsl, 0, sizeof(param->sinsl));
 | 
					 memset(¶m->sinsl, 0, sizeof(param->sinsl));
 | 
				
			||||||
 memset(¶m->sinsr, 0, sizeof(param->sinsr));
 | 
					 memset(¶m->sinsr, 0, sizeof(param->sinsr));
 | 
				
			||||||
 memset(¶m->req, 0, sizeof(param->req));
 | 
					 memset(¶m->req, 0, sizeof(param->req));
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user