mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 18:45:40 +08:00
race condition fixed on configuration reload
Race condition on service free'ing
This commit is contained in:
parent
0e4a507dd8
commit
62775da1d5
119
src/3proxy.c
119
src/3proxy.c
@ -24,6 +24,7 @@ pthread_mutex_t bandlim_mutex;
|
|||||||
pthread_mutex_t tc_mutex;
|
pthread_mutex_t tc_mutex;
|
||||||
pthread_mutex_t pwl_mutex;
|
pthread_mutex_t pwl_mutex;
|
||||||
pthread_mutex_t hash_mutex;
|
pthread_mutex_t hash_mutex;
|
||||||
|
pthread_mutex_t config_mutex;
|
||||||
|
|
||||||
#ifndef NOODBC
|
#ifndef NOODBC
|
||||||
pthread_mutex_t odbc_mutex;
|
pthread_mutex_t odbc_mutex;
|
||||||
@ -84,6 +85,113 @@ FILE * confopen(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void freeconf(struct extparam *confp){
|
||||||
|
struct bandlim * bl;
|
||||||
|
struct bandlim * blout;
|
||||||
|
struct trafcount * tc;
|
||||||
|
struct passwords *pw;
|
||||||
|
struct ace *acl;
|
||||||
|
struct filemon *fm;
|
||||||
|
int counterd, archiverc;
|
||||||
|
unsigned char *logname, *logtarget;
|
||||||
|
unsigned char **archiver;
|
||||||
|
unsigned char * logformat;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pthread_mutex_lock(&tc_mutex);
|
||||||
|
confp->trafcountfunc = NULL;
|
||||||
|
tc = confp->trafcounter;
|
||||||
|
confp->trafcounter = NULL;
|
||||||
|
counterd = confp->counterd;
|
||||||
|
confp->counterd = -1;
|
||||||
|
pthread_mutex_unlock(&tc_mutex);
|
||||||
|
if(tc)dumpcounters(tc,counterd);
|
||||||
|
for(; tc; tc = (struct trafcount *) itfree(tc, tc->next)){
|
||||||
|
if(tc->comment)myfree(tc->comment);
|
||||||
|
freeacl(tc->ace);
|
||||||
|
}
|
||||||
|
confp->countertype = NONE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
logtarget = confp->logtarget;
|
||||||
|
confp->logtarget = NULL;
|
||||||
|
logformat = confp->logformat;
|
||||||
|
confp->logformat = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bandlim_mutex);
|
||||||
|
bl = confp->bandlimiter;
|
||||||
|
blout = confp->bandlimiterout;
|
||||||
|
confp->bandlimiter = NULL;
|
||||||
|
confp->bandlimiterout = NULL;
|
||||||
|
confp->bandlimfunc = NULL;
|
||||||
|
pthread_mutex_unlock(&bandlim_mutex);
|
||||||
|
|
||||||
|
logname = confp->logname;
|
||||||
|
confp->logname = NULL;
|
||||||
|
archiverc = confp->archiverc;
|
||||||
|
confp->archiverc = 0;
|
||||||
|
archiver = confp->archiver;
|
||||||
|
confp->archiver = NULL;
|
||||||
|
fm = confp->fmon;
|
||||||
|
confp->fmon = NULL;
|
||||||
|
pw = confp->pwl;
|
||||||
|
confp->pwl = NULL;
|
||||||
|
confp->rotate = 0;
|
||||||
|
confp->logtype = NONE;
|
||||||
|
confp->authfunc = ipauth;
|
||||||
|
confp->bandlimfunc = NULL;
|
||||||
|
memset(&confp->intsa, 0, sizeof(confp->intsa));
|
||||||
|
memset(&confp->extsa, 0, sizeof(confp->extsa));
|
||||||
|
#ifndef NOIPV6
|
||||||
|
memset(&confp->extsa6, 0, sizeof(confp->extsa6));
|
||||||
|
*SAFAMILY(&confp->extsa6) = AF_INET6;
|
||||||
|
#endif
|
||||||
|
*SAFAMILY(&confp->intsa) = AF_INET;
|
||||||
|
*SAFAMILY(&confp->extsa) = AF_INET;
|
||||||
|
confp->singlepacket = 0;
|
||||||
|
confp->maxchild = 100;
|
||||||
|
resolvfunc = NULL;
|
||||||
|
numservers = 0;
|
||||||
|
acl = confp->acl;
|
||||||
|
confp->acl = NULL;
|
||||||
|
confp->logtime = confp->time = 0;
|
||||||
|
|
||||||
|
usleep(SLEEPTIME);
|
||||||
|
|
||||||
|
|
||||||
|
freeacl(acl);
|
||||||
|
freepwl(pw);
|
||||||
|
for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace);
|
||||||
|
for(; blout; blout = (struct bandlim *) itfree(blout, blout->next))freeacl(blout->ace);
|
||||||
|
|
||||||
|
if(counterd != -1) {
|
||||||
|
close(counterd);
|
||||||
|
}
|
||||||
|
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
|
||||||
|
if(fm->path) myfree(fm->path);
|
||||||
|
}
|
||||||
|
if(logtarget) {
|
||||||
|
myfree(logtarget);
|
||||||
|
}
|
||||||
|
if(logname) {
|
||||||
|
myfree(logname);
|
||||||
|
}
|
||||||
|
if(logformat) {
|
||||||
|
myfree(logformat);
|
||||||
|
}
|
||||||
|
if(archiver) {
|
||||||
|
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
|
||||||
|
myfree(archiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void clearall(){
|
void clearall(){
|
||||||
freeconf(&conf);
|
freeconf(&conf);
|
||||||
}
|
}
|
||||||
@ -135,15 +243,7 @@ void __stdcall CommandHandler( DWORD dwCommand )
|
|||||||
break;
|
break;
|
||||||
case SERVICE_CONTROL_CONTINUE:
|
case SERVICE_CONTROL_CONTINUE:
|
||||||
SetStatus( SERVICE_CONTINUE_PENDING, 0, 1 );
|
SetStatus( SERVICE_CONTINUE_PENDING, 0, 1 );
|
||||||
clearall();
|
conf.needreload = 1;
|
||||||
fp = confopen();
|
|
||||||
if(fp){
|
|
||||||
error = readconfig(fp);
|
|
||||||
if(error) {
|
|
||||||
clearall();
|
|
||||||
}
|
|
||||||
if(!writable)fclose(fp);
|
|
||||||
}
|
|
||||||
SetStatus( SERVICE_RUNNING, 0, 0 );
|
SetStatus( SERVICE_RUNNING, 0, 0 );
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
@ -2087,6 +2187,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
pthread_mutex_init(&tc_mutex, NULL);
|
pthread_mutex_init(&tc_mutex, NULL);
|
||||||
|
@ -246,6 +246,7 @@ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, un
|
|||||||
|
|
||||||
struct ace * copyacl (struct ace *ac);
|
struct ace * copyacl (struct ace *ac);
|
||||||
struct auth * copyauth (struct auth *);
|
struct auth * copyauth (struct auth *);
|
||||||
|
void * itfree(void *data, void * retval);
|
||||||
void freeacl(struct ace *ac);
|
void freeacl(struct ace *ac);
|
||||||
void freeauth(struct auth *);
|
void freeauth(struct auth *);
|
||||||
void freefilter(struct filter *filter);
|
void freefilter(struct filter *filter);
|
||||||
@ -308,6 +309,7 @@ struct dictionary;
|
|||||||
struct node;
|
struct node;
|
||||||
struct property;
|
struct property;
|
||||||
|
|
||||||
|
extern pthread_mutex_t config_mutex;
|
||||||
extern pthread_mutex_t bandlim_mutex;
|
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;
|
||||||
|
124
src/proxymain.c
124
src/proxymain.c
@ -632,18 +632,21 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
|
|
||||||
if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
|
if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
|
||||||
if(fp) fclose(fp);
|
if(fp) fclose(fp);
|
||||||
|
|
||||||
srvfree(&srv);
|
srvfree(&srv);
|
||||||
if(defparam.hostname)myfree(defparam.hostname);
|
|
||||||
if(cbc_string)myfree(cbc_string);
|
|
||||||
if(cbl_string)myfree(cbc_string);
|
|
||||||
|
|
||||||
#ifndef STDMAIN
|
#ifndef STDMAIN
|
||||||
|
pthread_mutex_lock(&config_mutex);
|
||||||
if(srv.next)srv.next->prev = srv.prev;
|
if(srv.next)srv.next->prev = srv.prev;
|
||||||
if(srv.prev)srv.prev->next = srv.next;
|
if(srv.prev)srv.prev->next = srv.next;
|
||||||
else conf.services = srv.next;
|
else conf.services = srv.next;
|
||||||
freeacl(srv.acl);
|
pthread_mutex_unlock(&config_mutex);
|
||||||
freeauth(srv.authfuncs);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(defparam.hostname)myfree(defparam.hostname);
|
||||||
|
if(cbc_string)myfree(cbc_string);
|
||||||
|
if(cbl_string)myfree(cbl_string);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,6 +723,9 @@ void srvfree(struct srvparam * srv){
|
|||||||
}
|
}
|
||||||
myfree(srv->filter);
|
myfree(srv->filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(srv->acl)freeacl(srv->acl);
|
||||||
|
if(srv->authfuncs)freeauth(srv->authfuncs);
|
||||||
#endif
|
#endif
|
||||||
pthread_mutex_destroy(&srv->counter_mutex);
|
pthread_mutex_destroy(&srv->counter_mutex);
|
||||||
if(srv->target) myfree(srv->target);
|
if(srv->target) myfree(srv->target);
|
||||||
@ -903,7 +909,7 @@ FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * itfree(void *data, void * retval){
|
void * itfree(void *data, void * retval){
|
||||||
myfree(data);
|
myfree(data);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -944,112 +950,6 @@ void freeacl(struct ace *ac){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeconf(struct extparam *confp){
|
|
||||||
struct bandlim * bl;
|
|
||||||
struct bandlim * blout;
|
|
||||||
struct trafcount * tc;
|
|
||||||
struct passwords *pw;
|
|
||||||
struct ace *acl;
|
|
||||||
struct filemon *fm;
|
|
||||||
int counterd, archiverc;
|
|
||||||
unsigned char *logname, *logtarget;
|
|
||||||
unsigned char **archiver;
|
|
||||||
unsigned char * logformat;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pthread_mutex_lock(&tc_mutex);
|
|
||||||
confp->trafcountfunc = NULL;
|
|
||||||
tc = confp->trafcounter;
|
|
||||||
confp->trafcounter = NULL;
|
|
||||||
counterd = confp->counterd;
|
|
||||||
confp->counterd = -1;
|
|
||||||
pthread_mutex_unlock(&tc_mutex);
|
|
||||||
if(tc)dumpcounters(tc,counterd);
|
|
||||||
for(; tc; tc = (struct trafcount *) itfree(tc, tc->next)){
|
|
||||||
if(tc->comment)myfree(tc->comment);
|
|
||||||
freeacl(tc->ace);
|
|
||||||
}
|
|
||||||
confp->countertype = NONE;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
logtarget = confp->logtarget;
|
|
||||||
confp->logtarget = NULL;
|
|
||||||
logformat = confp->logformat;
|
|
||||||
confp->logformat = NULL;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&bandlim_mutex);
|
|
||||||
bl = confp->bandlimiter;
|
|
||||||
blout = confp->bandlimiterout;
|
|
||||||
confp->bandlimiter = NULL;
|
|
||||||
confp->bandlimiterout = NULL;
|
|
||||||
confp->bandlimfunc = NULL;
|
|
||||||
pthread_mutex_unlock(&bandlim_mutex);
|
|
||||||
|
|
||||||
logname = confp->logname;
|
|
||||||
confp->logname = NULL;
|
|
||||||
archiverc = confp->archiverc;
|
|
||||||
confp->archiverc = 0;
|
|
||||||
archiver = confp->archiver;
|
|
||||||
confp->archiver = NULL;
|
|
||||||
fm = confp->fmon;
|
|
||||||
confp->fmon = NULL;
|
|
||||||
pw = confp->pwl;
|
|
||||||
confp->pwl = NULL;
|
|
||||||
confp->rotate = 0;
|
|
||||||
confp->logtype = NONE;
|
|
||||||
confp->authfunc = ipauth;
|
|
||||||
confp->bandlimfunc = NULL;
|
|
||||||
memset(&confp->intsa, 0, sizeof(confp->intsa));
|
|
||||||
memset(&confp->extsa, 0, sizeof(confp->extsa));
|
|
||||||
#ifndef NOIPV6
|
|
||||||
memset(&confp->extsa6, 0, sizeof(confp->extsa6));
|
|
||||||
*SAFAMILY(&confp->extsa6) = AF_INET6;
|
|
||||||
#endif
|
|
||||||
*SAFAMILY(&confp->intsa) = AF_INET;
|
|
||||||
*SAFAMILY(&confp->extsa) = AF_INET;
|
|
||||||
confp->singlepacket = 0;
|
|
||||||
confp->maxchild = 100;
|
|
||||||
resolvfunc = NULL;
|
|
||||||
numservers = 0;
|
|
||||||
acl = confp->acl;
|
|
||||||
confp->acl = NULL;
|
|
||||||
confp->logtime = confp->time = 0;
|
|
||||||
|
|
||||||
usleep(SLEEPTIME);
|
|
||||||
|
|
||||||
|
|
||||||
freeacl(acl);
|
|
||||||
freepwl(pw);
|
|
||||||
for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace);
|
|
||||||
for(; blout; blout = (struct bandlim *) itfree(blout, blout->next))freeacl(blout->ace);
|
|
||||||
|
|
||||||
if(counterd != -1) {
|
|
||||||
close(counterd);
|
|
||||||
}
|
|
||||||
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
|
|
||||||
if(fm->path) myfree(fm->path);
|
|
||||||
}
|
|
||||||
if(logtarget) {
|
|
||||||
myfree(logtarget);
|
|
||||||
}
|
|
||||||
if(logname) {
|
|
||||||
myfree(logname);
|
|
||||||
}
|
|
||||||
if(logformat) {
|
|
||||||
myfree(logformat);
|
|
||||||
}
|
|
||||||
if(archiver) {
|
|
||||||
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
|
|
||||||
myfree(archiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||||
FILTER_ACTION action;
|
FILTER_ACTION action;
|
||||||
int i;
|
int i;
|
||||||
|
Loading…
Reference in New Issue
Block a user