Reorganize service config parsing / main loop

This commit is contained in:
Vladimir Dubrovin 2026-10-12 13:08:55 +03:00
parent b00e3b9a9c
commit 89d2131094
6 changed files with 1040 additions and 931 deletions

View File

@ -729,12 +729,12 @@ foreach(PROXY_NAME proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr)
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src
) )
target_compile_definitions(${PROXY_NAME} PRIVATE target_compile_definitions(${PROXY_NAME} PRIVATE WITHMAIN)
WITHMAIN
NOPORTMAP
)
if(NOT PROXY_NAME STREQUAL "udppm") # each takes the main loop of its kind only: udppm UDP, the others TCP
if(PROXY_NAME STREQUAL "udppm")
target_compile_definitions(${PROXY_NAME} PRIVATE NOTCPMAIN)
else()
target_compile_definitions(${PROXY_NAME} PRIVATE NOUDPMAIN) target_compile_definitions(${PROXY_NAME} PRIVATE NOUDPMAIN)
endif() endif()
@ -744,8 +744,12 @@ foreach(PROXY_NAME proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr)
target_compile_definitions(${PROXY_NAME} PRIVATE ANONYMOUS) target_compile_definitions(${PROXY_NAME} PRIVATE ANONYMOUS)
endif() endif()
# port mappers take port, host and port as arguments, the others options
# only; one of the two is defined, as in src/Makefile.inc
if(PROXY_NAME STREQUAL "tcppm" OR PROXY_NAME STREQUAL "udppm" OR PROXY_NAME STREQUAL "tlspr") if(PROXY_NAME STREQUAL "tcppm" OR PROXY_NAME STREQUAL "udppm" OR PROXY_NAME STREQUAL "tlspr")
target_compile_definitions(${PROXY_NAME} PRIVATE PORTMAP) target_compile_definitions(${PROXY_NAME} PRIVATE PORTMAP)
else()
target_compile_definitions(${PROXY_NAME} PRIVATE NOPORTMAP)
endif() endif()
if(WIN32) if(WIN32)

View File

@ -558,7 +558,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
#ifndef NORADIUS #ifndef NORADIUS
_3proxy_mutex_init(&rad_mutex); _3proxy_mutex_init(&rad_mutex);
#endif #endif
if(_3proxy_sem_init(conf.threadinit, 1, 1) || _3proxy_sem_init_timed(serviceexited, 0, 0x7fffffff)){ if(_3proxy_sem_init_timed(serviceexited, 0, 0x7fffffff)){
fprintf(stderr, "semaphore init failed\n"); fprintf(stderr, "semaphore init failed\n");
return 1; return 1;
} }
@ -581,7 +581,9 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
res = readconfig(fp); res = readconfig(fp);
conf.version++; conf.version++;
if(res) RETURN(res); /* readconfig() names the failing line, which an exit status would cut
to 8 bits: a failed configuration exits with 1 */
if(res) RETURN(1);
fclose(fp); fp = NULL; fclose(fp); fp = NULL;
#ifdef _WIN32 #ifdef _WIN32
@ -614,6 +616,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
CLEARRETURN: CLEARRETURN:
if(fp && fp != stdin) {fclose(fp); fp = NULL;} if(fp && fp != stdin) {fclose(fp); fp = NULL;}
return 0; return res;
} }

View File

@ -47,7 +47,7 @@ tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP $(DEFINEOPTION)NOUDPMAIN tcppm.c $(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP $(DEFINEOPTION)NOUDPMAIN tcppm.c
udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP udppm.c $(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP $(DEFINEOPTION)NOTCPMAIN udppm.c
tlspr$(OBJSUFFICS): tlspr.c proxy.h structures.h proxymain.c tlspr$(OBJSUFFICS): tlspr.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP $(DEFINEOPTION)NOUDPMAIN tlspr.c $(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP $(DEFINEOPTION)NOUDPMAIN tlspr.c

View File

@ -42,13 +42,14 @@ int runningservices = 0;
_3proxy_mutex_t runningservices_mutex; _3proxy_mutex_t runningservices_mutex;
_3proxy_sem_t serviceexited; _3proxy_sem_t serviceexited;
int haveerror = 0;
int linenum = 0; int linenum = 0;
struct counter_header cheader = {"3CF", (time_t)0}; struct counter_header cheader = {"3CF", (time_t)0};
struct counter_record crecord; struct counter_record crecord;
int mainfunc (int argc, char** argv); int mainprepare(int argc, char** argv, void **service);
int mainrun(void *service);
void maindrop(void *service);
struct proxydef childdef = {NULL, 0, 0, S_NOSERVICE, ""}; struct proxydef childdef = {NULL, 0, 0, S_NOSERVICE, ""};
@ -78,15 +79,8 @@ DWORD WINAPI startsrv(LPVOID data) {
#else #else
void * startsrv(void * data) { void * startsrv(void * data) {
#endif #endif
struct child *d = (struct child *)data; /* counted by start_proxy_thread() before the thread is created */
mainrun(data);
/* counted here rather than where the service is listed, so every way
out of it is counted too; start_proxy_thread() waits for the service
to start, so it is counted by the time that returns */
_3proxy_mutex_lock(&runningservices_mutex);
runningservices++;
_3proxy_mutex_unlock(&runningservices_mutex);
mainfunc(d->argc, (char **)d->argv);
_3proxy_mutex_lock(&runningservices_mutex); _3proxy_mutex_lock(&runningservices_mutex);
runningservices--; runningservices--;
_3proxy_mutex_unlock(&runningservices_mutex); _3proxy_mutex_unlock(&runningservices_mutex);
@ -156,36 +150,45 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign
return buf; return buf;
} }
/* The service is set up here, in the thread reading the configuration, so
an error in its options stops the configuration; its own thread then
listens and serves. */
int start_proxy_thread(struct child * chp){ int start_proxy_thread(struct child * chp){
pthread_t thread; pthread_t thread;
void *service;
int res;
#ifdef _WIN32 #ifdef _WIN32
HANDLE h; HANDLE h;
#endif #endif
_3proxy_sem_lock(conf.threadinit); if((res = mainprepare(chp->argc, (char **)chp->argv, &service))) {
fprintf(stderr, "Service not started on line: %d%s\n", linenum, res == 2? ": insufficient memory":"");
return(40);
}
_3proxy_mutex_lock(&runningservices_mutex);
runningservices++;
_3proxy_mutex_unlock(&runningservices_mutex);
#ifdef _WIN32 #ifdef _WIN32
#ifndef _WINCE #ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 16384+conf.stacksize, (void *)startsrv, (void *) chp, (DWORD)0, &thread); h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 16384+conf.stacksize, (void *)startsrv, service, (DWORD)0, &thread);
#else #else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, 16384+conf.stacksize, (void *)startsrv, (void *) chp, (DWORD)0, &thread); h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, 16384+conf.stacksize, (void *)startsrv, service, (DWORD)0, &thread);
#endif #endif
if(h)CloseHandle(h); if(h)CloseHandle(h);
else {
#else #else
pthread_attr_init(&pa); pthread_attr_init(&pa);
pthread_attr_setstacksize(&pa,threadstacksize(conf.stacksize)); pthread_attr_setstacksize(&pa,threadstacksize(conf.stacksize));
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
if(pthread_create(&thread, &pa, startsrv, (void *)chp)){ res = pthread_create(&thread, &pa, startsrv, service);
pthread_attr_destroy(&pa);
fprintf(stderr, "Failed to create service thread on line %d, try to set larger stacksize\n", linenum);
_3proxy_sem_unlock(conf.threadinit);
return(40);
}
pthread_attr_destroy(&pa); pthread_attr_destroy(&pa);
if(res){
#endif #endif
_3proxy_sem_lock(conf.threadinit); _3proxy_mutex_lock(&runningservices_mutex);
_3proxy_sem_unlock(conf.threadinit); runningservices--;
if(haveerror) { _3proxy_mutex_unlock(&runningservices_mutex);
fprintf(stderr, "Service not started on line: %d%s\n", linenum, haveerror == 2? ": insufficient memory":""); maindrop(service);
fprintf(stderr, "Failed to create service thread on line %d, try to set larger stacksize\n", linenum);
return(40); return(40);
} }
return 0; return 0;

File diff suppressed because it is too large Load Diff

View File

@ -801,7 +801,6 @@ struct filemon {
struct extparam { struct extparam {
_3proxy_sem_t threadinit;
int *timeouts; int *timeouts;
struct ace * acl; struct ace * acl;
#ifdef WITH_HTTPSRV #ifdef WITH_HTTPSRV