Merge remote-tracking branch 'refs/remotes/origin/devel-logthread' into devel

This commit is contained in:
z3APA3A 2020-10-30 15:43:19 +03:00
commit 0f560a4725
30 changed files with 1178 additions and 800 deletions

View File

@ -8,7 +8,7 @@
BUILDDIR = ../bin/
CC = cl
CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:I386

View File

@ -8,7 +8,7 @@
BUILDDIR = ../bin64/
CC = cl
CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:x64

View File

@ -8,7 +8,7 @@
BUILDDIR = ../bin64/
CC = cl
CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
CFLAGS = /nologo /MT /W3 /Ox /EHs- /GS /GA /GF /D "MSVC" /D "WITH_STD_MALLOC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:arm64

View File

@ -8,7 +8,7 @@
BUILDDIR = ../bin/
CC = cl
CFLAGS = /DARM /D "NOODBC" /nologo /MT /W3 /Wp64 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "_WINCE" /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /Fp"proxy.pch" /FD /c
CFLAGS = /DARM /D "NOODBC" /nologo /MT /W3 /Wp64 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "_WINCE" /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no

View File

@ -8,7 +8,7 @@
BUILDDIR = ../bin/
CC = cl
CFLAGS = /nologo /Ox /MT /D "NOIPV6" /D "NODEBUG" /D "NOODBC" /D "NORADIUS" /D"WATCOM" /D "MSVC" /D "WITH_STD_MALLOC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /D "PRINTF_INT64_MODIFIER=\"I64\"" /c $(VERSION) $(BUILDDATE)
CFLAGS = /nologo /Ox /MT /D "NOIPV6" /D "NODEBUG" /D "NOODBC" /D "NORADIUS" /D"WATCOM" /D "MSVC" /D "WITH_STD_MALLOC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /c $(VERSION) $(BUILDDATE)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no

View File

@ -63,11 +63,6 @@ void __stdcall CommandHandler( DWORD dwCommand )
conf.paused++;
Sleep(2000);
SetStatus( SERVICE_STOPPED, 0, 0 );
#ifndef NOODBC
pthread_mutex_lock(&log_mutex);
close_sql();
pthread_mutex_unlock(&log_mutex);
#endif
break;
case SERVICE_CONTROL_PAUSE:
SetStatus( SERVICE_PAUSE_PENDING, 0, 1 );
@ -116,13 +111,7 @@ void mysigpause (int sig){
void mysigterm (int sig){
conf.paused++;
usleep(999*SLEEPTIME);
usleep(999*SLEEPTIME);
#ifndef NOODBC
pthread_mutex_lock(&log_mutex);
close_sql();
pthread_mutex_unlock(&log_mutex);
#endif
usleep(2000*SLEEPTIME);
conf.timetoexit = 1;
}
@ -200,11 +189,11 @@ void dumpcounters(struct trafcount *tlin, int counterd){
if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){
FILE * cfp;
cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
cfp = fopen((char *)dologname(tmpbuf, sizeof(tmpbuf), (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
if(cfp){
for(tl = tlin; cfp && tl; tl = tl->next){
if(tl->type >= conf.countertype)
fprintf(cfp, "%05d %020"PRINTF_INT64_MODIFIER"u%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
fprintf(cfp, "%05d %020" PRIu64 "%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
}
fclose(cfp);
}
@ -235,12 +224,12 @@ void dumpcounters(struct trafcount *tlin, int counterd){
void cyclestep(void){
struct tm *tm;
time_t minutecounter;
unsigned char tmpbuf[8192];
minutecounter = time(0);
for(;;){
usleep(SLEEPTIME*999);
flushlogs();
conf.time = time(0);
if(conf.needreload) {
doschedule();
@ -248,7 +237,6 @@ void cyclestep(void){
conf.needreload = 0;
}
doschedule();
if(conf.stdlog)fflush(conf.stdlog);
if(timechanged(minutecounter, conf.time, MINUTELY)) {
struct filemon *fm;
struct stat sb;
@ -269,55 +257,6 @@ void cyclestep(void){
tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
basetime = mktime(tm);
}
if(conf.logname) {
if(timechanged(conf.logtime, conf.time, conf.logtype)) {
if(conf.stdlog) conf.stdlog = freopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a", conf.stdlog);
else conf.stdlog = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a");
conf.logtime = conf.time;
if(conf.logtype != NONE && conf.rotate) {
int t;
t = 1;
switch(conf.logtype){
case ANNUALLY:
t = t * 12;
case MONTHLY:
t = t * 4;
case WEEKLY:
t = t * 7;
case DAILY:
t = t * 24;
case HOURLY:
t = t * 60;
case MINUTELY:
t = t * 60;
default:
break;
}
dologname (tmpbuf, conf.logname, (conf.archiver)?conf.archiver[1]:NULL, conf.logtype, (conf.logtime - t * conf.rotate));
remove ((char *) tmpbuf);
if(conf.archiver) {
int i;
*tmpbuf = 0;
for(i = 2; i < conf.archiverc && strlen((char *)tmpbuf) < 512; i++){
strcat((char *)tmpbuf, " ");
if(!strcmp((char *)conf.archiver[i], "%A")){
strcat((char *)tmpbuf, "\"");
dologname (tmpbuf + strlen((char *)tmpbuf), conf.logname, conf.archiver[1], conf.logtype, (conf.logtime - t));
strcat((char *)tmpbuf, "\"");
}
else if(!strcmp((char *)conf.archiver[i], "%F")){
strcat((char *)tmpbuf, "\"");
dologname (tmpbuf+strlen((char *)tmpbuf), conf.logname, NULL, conf.logtype, (conf.logtime-t));
strcat((char *)tmpbuf, "\"");
}
else
strcat((char *)tmpbuf, (char *)conf.archiver[i]);
}
system((char *)tmpbuf+1);
}
}
}
}
if(conf.counterd >= 0 && conf.trafcounter) {
if(timechanged(cheader.updated, conf.time, MINUTELY)){
dumpcounters(conf.trafcounter, conf.counterd);
@ -512,11 +451,10 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
pthread_mutex_init(&hash_mutex, NULL);
pthread_mutex_init(&tc_mutex, NULL);
pthread_mutex_init(&pwl_mutex, NULL);
pthread_mutex_init(&log_mutex, NULL);
#ifndef NORADIUS
pthread_mutex_init(&rad_mutex, NULL);
#endif
initlog();
freeconf(&conf);
res = readconfig(fp);
conf.version++;

View File

@ -26,50 +26,52 @@ ftp$(OBJSUFFICS): ftp.c proxy.h structures.h
sockgetchar$(OBJSUFFICS): sockgetchar.c proxy.h structures.h
$(CC) $(CFLAGS) sockgetchar.c
proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c
proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)ANONYMOUS proxy.c
pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c
pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP pop3p.c
smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c
smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP smtpp.c
ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c
ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP ftppr.c
tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c
tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP tcppm.c
socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c
socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c
udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c
udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c log.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP udppm.c
3proxy$(OBJSUFFICS): 3proxy.c proxy.h structures.h
$(CC) $(CFLAGS) 3proxy.c
$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
mainfunc$(OBJSUFFICS): proxy.h structures.h proxymain.c
$(CC) $(COUT)mainfunc$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)MODULEMAINFUNC=mainfunc proxymain.c

View File

@ -1370,155 +1370,3 @@ unsigned long fakeresolver (int af, unsigned char *name, unsigned char * value){
}
return 1;
}
#ifndef NOODBC
SQLHENV henv = NULL;
SQLHSTMT hstmt = NULL;
SQLHDBC hdbc = NULL;
char * sqlstring = NULL;
void close_sql(){
if(hstmt) {
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
hstmt = NULL;
}
if(hdbc){
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
hdbc = NULL;
}
if(henv) {
SQLFreeHandle(SQL_HANDLE_ENV, henv);
henv = NULL;
}
}
int attempt = 0;
time_t attempt_time = 0;
int init_sql(char * s){
SQLRETURN retcode;
char * datasource;
char * username;
char * password;
char * string;
if(!s) return 0;
if(!sqlstring || strcmp(sqlstring, s)){
string = sqlstring;
sqlstring=mystrdup(s);
if(string)myfree(string);
}
if(hstmt || hdbc || henv) close_sql();
attempt++;
attempt_time = time(0);
if(!henv){
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
henv = NULL;
return 0;
}
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
return 0;
}
}
if(!hdbc){
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
hdbc = NULL;
SQLFreeHandle(SQL_HANDLE_ENV, henv);
henv = NULL;
return 0;
}
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
}
string = mystrdup(sqlstring);
if(!string) return 0;
datasource = strtok(string, ",");
username = strtok(NULL, ",");
password = strtok(NULL, ",");
/* Connect to data source */
retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
(SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
(SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
myfree(string);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
hdbc = NULL;
SQLFreeHandle(SQL_HANDLE_ENV, henv);
henv = NULL;
return 0;
}
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
close_sql();
return 0;
}
return 1;
}
void sqlerr (char *buf){
if(conf.stdlog){
fprintf(conf.stdlog, "%s\n", buf);
fflush(conf.stdlog);
}
pthread_mutex_unlock(&log_mutex);
}
unsigned char statbuf[8192];
void logsql(struct clientparam * param, const unsigned char *s) {
SQLRETURN ret;
int len;
if(param->nolog) return;
pthread_mutex_lock(&log_mutex);
len = dobuf(param, statbuf, s, (unsigned char *)"\'");
if(attempt > 5){
time_t t;
t = time(0);
if (t - attempt_time < 180){
sqlerr((char *)statbuf);
return;
}
}
if(!hstmt){
if(!init_sql(sqlstring)) {
sqlerr((char *)statbuf);
return;
}
}
if(hstmt){
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
close_sql();
if(!init_sql(sqlstring)){
sqlerr((char *)statbuf);
return;
}
if(hstmt) {
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
sqlerr((char *)statbuf);
return;
}
attempt = 0;
}
}
attempt = 0;
}
pthread_mutex_unlock(&log_mutex);
}
#endif

View File

@ -293,14 +293,14 @@ typedef struct radius_packet_t {
uint8_t id;
uint16_t length;
uint8_t vector[AUTH_VECTOR_LEN];
uint8_t data[4096];
uint8_t data[2048];
} radius_packet_t;
#define RETURN(xxx) { res = xxx; goto CLEANRET; }
int radsend(struct clientparam * param, int auth, int stop){
#define packet (*((radius_packet_t *)inbuf))
int loop;
int radbuf(struct clientparam * param, unsigned char * inbuf, int auth, int stop){
int id;
int res = 4;
SOCKET sockfd = -1;
@ -308,29 +308,16 @@ int radsend(struct clientparam * param, int auth, int stop){
int total_length;
int len;
int op;
#ifdef NOIPV6
struct sockaddr_in saremote;
#else
struct sockaddr_in6 saremote;
#endif
struct pollfd fds[1];
char vector[AUTH_VECTOR_LEN];
radius_packet_t packet, rpacket;
SASIZETYPE salen;
int data_len;
uint8_t *vendor_len;
int count=0;
uint8_t *attr;
long vendor=0;
int vendorlen=0;
char buf[64];
if(!radiussecret || !nradservers) {
return 4;
return 0;
}
memset(&packet, 0, sizeof(packet));
memset(&packet, 0, sizeof(radius_packet_t));
pthread_mutex_lock(&rad_mutex);
@ -526,6 +513,39 @@ int radsend(struct clientparam * param, int auth, int stop){
md5_calc(packet.vector, (u_char *)&packet, total_length + len);
}
memcpy(vector, packet.vector, AUTH_VECTOR_LEN);
return total_length;
}
int radsend(const unsigned char *inbuf, int total_length, int auth,
#ifdef NOIPV6
struct sockaddr_in* sinsl
#else
struct sockaddr_in6* sinsl
#endif
){
int loop;
int res = 4;
SOCKET sockfd = -1;
int len;
#ifdef NOIPV6
struct sockaddr_in saremote;
#else
struct sockaddr_in6 saremote;
#endif
struct pollfd fds[1];
radius_packet_t rpacket;
SASIZETYPE salen;
int data_len;
uint8_t *vendor_len;
int count=0;
uint8_t *attr;
long vendor=0;
int vendorlen=0;
for (loop = 0; loop < nradservers && loop < MAXRADIUS; loop++) {
SOCKET remsock;
@ -554,7 +574,7 @@ int radsend(struct clientparam * param, int auth, int stop){
}
else remsock = radiuslist[loop].logsock;
*/
so._bind(param->remsock,(struct sockaddr *)&radiuslist[loop].localaddr,SASIZE(&radiuslist[loop].localaddr));
so._bind(remsock,(struct sockaddr *)&radiuslist[loop].localaddr,SASIZE(&radiuslist[loop].localaddr));
len = so._sendto(remsock, (char *)&packet, total_length, 0,
(struct sockaddr *)&saremote, sizeof(saremote));
if(len != ntohs(packet.length)){
@ -621,13 +641,13 @@ int radsend(struct clientparam * param, int auth, int stop){
}
if (!vendor && attr[0] == PW_FRAMED_IP_ADDRESS && attr[1] == 6) {
*SAFAMILY(&param->sinsl) = AF_INET;
memcpy(SAADDR(&param->sinsl), attr+2, 4);
*SAFAMILY(sinsl) = AF_INET;
memcpy(SAADDR(sinsl), attr+2, 4);
}
else if (!vendor && attr[0] == PW_FRAMED_IPV6_ADDRESS && attr[1] == 18) {
*SAFAMILY(&param->sinsl) = AF_INET6;
memcpy(SAADDR(&param->sinsl), attr+2, 16);
*SAFAMILY(sinsl) = AF_INET6;
memcpy(SAADDR(sinsl), attr+2, 16);
}
else if (!vendor && attr[0] == PW_REPLY_MESSAGE && attr[1] >= 3 && isdigit(attr[2])) {
res = 0;
@ -657,14 +677,20 @@ CLEANRET:
}
int radauth(struct clientparam * param){
radius_packet_t ppacket;
int len;
/*radsend(param, 0, 0);*/
return radsend(param, 1, 0);
len = radbuf(param, (unsigned char *)&ppacket, 1, 0);
return len?radsend((unsigned char *)&ppacket, len, 1, &param->sinsl):4;
}
void logradius(struct clientparam * param, const unsigned char *s) {
radsend(param, 0, 1);
if(param->trafcountfunc)(*param->trafcountfunc)(param);
clearstat(param);
int raddobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s){
return radbuf(param, buf, 0, 1);
}
void logradius(const unsigned char *buf, int len, struct LOGGER *logger){
if(len)radsend(buf, len, 0, NULL);
}

View File

@ -93,42 +93,46 @@ char *rotations[] = {
struct extparam conf = {
{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0},
NULL,
NULL,
NULL, NULL,
NULL,
NULL,
NULL,
0,
0, -1, 0, 0, 0, 0,
0, 500, 0, 0, 0, 0,
6, 600,
1048576,
NULL, NULL,
NONE, NONE,
NULL,
{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0}, /* int timeouts[12]; */
NULL, /*struct ace * acl; */
NULL, /* char * conffile; */
NULL, NULL, /* struct bandlim * bandlimiter, *bandlimiterout; */
NULL, /* struct connlim * connlimiter; */
NULL, /* struct trafcount * trafcounter; */
NULL, /* struct srvparam *services; */
0, /* int stacksize, */
0, -1, 0, 0, 0, 0, /* threadinit, counterd, haveerror, rotate, paused, archiverc, */
0, 500, 0, 0, 0, 0, /* demon, maxchild, needreload, timetoexit, version, noforce; */
6, 600, /* int authcachetype, authcachetime; */
1048576, /* int filtermaxsize; */
NULL, /* **archiver; */
NONE, NONE, /* ROTATION logtype, countertype; */
NULL, /* char * counterfile; */
#ifndef NOIPV6
{AF_INET},{AF_INET6},{AF_INET},
{AF_INET},{AF_INET6},{AF_INET}, /* struct sockaddr_in6 intsa;
struct sockaddr_in6 extsa6;
struct sockaddr_in6 extsa; */
#else
{AF_INET},{AF_INET},
{AF_INET},{AF_INET}, /* struct sockaddr_in intsa;
struct sockaddr_in extsa; */
#endif
NULL,
NULL,
doconnect,
lognone,
NULL,
NULL,
NULL, NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
(time_t)0, (time_t)0,
0,0,
'@',
NULL, /* struct passwords *pwl; */
NULL, /* struct auth * authenticate; */
doconnect, /* AUTHFUNC authfunc; */
NULL, /* BANDLIMFUNC bandlimfunc; */
NULL, /* TRAFCOUNTFUNC trafcountfunc; */
NULL, /* void (*prelog)(struct clientparam * param); */
NULL, NULL, /* unsigned char *logtarget, *logformat; */
NULL, /* struct filemon * fmon; */
NULL, /* struct filter * filters; */
NULL, /* struct auth *authfuncs; */
NULL, /* char* demanddialprog; */
NULL, /* unsigned char **stringtable; */
(time_t)0, /* time_t time; */
0,0, /* unsigned logdumpsrv, logdumpcli; */
'@', /* char delimchar; */
};
int numservers=0;
@ -519,7 +523,6 @@ unsigned long getip(unsigned char *name){
}
if((tmpresolv=resolvfunc)){
if((*tmpresolv)(AF_INET, name, (unsigned char *)&retval)) return retval;
if(conf.demanddialprog) system(conf.demanddialprog);
return (*tmpresolv)(AF_INET, name, (unsigned char *)&retval)?retval:0;
}
#if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)

View File

@ -101,49 +101,6 @@ int getrotate(char c){
}
unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) {
struct tm *ts;
ts = localtime(&t);
if(strchr((char *)name, '%')){
struct clientparam fakecli;
memset(&fakecli, 0, sizeof(fakecli));
dobuf2(&fakecli, buf, NULL, NULL, ts, (char *)name);
}
else switch(lt){
case NONE:
sprintf((char *)buf, "%s", name);
break;
case ANNUALLY:
sprintf((char *)buf, "%s.%04d", name, ts->tm_year+1900);
break;
case MONTHLY:
sprintf((char *)buf, "%s.%04d.%02d", name, ts->tm_year+1900, ts->tm_mon+1);
break;
case WEEKLY:
t = t - (ts->tm_wday * (60*60*24));
ts = localtime(&t);
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
break;
case DAILY:
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
break;
case HOURLY:
sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour);
break;
case MINUTELY:
sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
break;
default:
break;
}
if(ext){
strcat((char *)buf, ".");
strcat((char *)buf, (char *)ext);
}
return buf;
}
int start_proxy_thread(struct child * chp){
pthread_t thread;
@ -281,65 +238,12 @@ static int h_external(int argc, unsigned char ** argv){
static int h_log(int argc, unsigned char ** argv){
unsigned char tmpbuf[8192];
int notchanged = 0;
havelog = 1;
if(argc > 1 && conf.logtarget && !strcmp((char *)conf.logtarget, (char *)argv[1])) {
notchanged = 1;
myfree(conf.logtarget);
if(argc < 2) conf.logtarget = (unsigned char *)mystrdup("");
else conf.logtarget = (unsigned char *)mystrdup((char *)argv[1]);
if(argc > 2) {
conf.logtype = getrotate(*argv[2]);
}
if(!notchanged && conf.logtarget){
myfree(conf.logtarget);
conf.logtarget = NULL;
}
if(argc > 1) {
if(!strcmp((char *) argv[1], "/dev/null")) {
conf.logfunc = lognone;
return 0;
}
if(!notchanged) conf.logtarget = (unsigned char *)mystrdup((char *)argv[1]);
if(*argv[1]=='@'){
#ifndef _WIN32
conf.logfunc = logsyslog;
if(notchanged) return 0;
openlog((char *)conf.logtarget+1, LOG_PID, LOG_DAEMON);
#endif
}
#ifndef NOODBC
else if(*argv[1]=='&'){
if(notchanged) return 0;
conf.logfunc = logsql;
pthread_mutex_lock(&log_mutex);
close_sql();
init_sql((char *)argv[1]+1);
pthread_mutex_unlock(&log_mutex);
}
#endif
#ifndef NORADIUS
else if(!strcmp(argv[1],"radius")){
conf.logfunc = logradius;
}
#endif
else {
if(argc > 2) {
conf.logtype = getrotate(*argv[2]);
}
conf.logfunc = logstdout;
if(notchanged) return 0;
conf.logtime = time(0);
if(conf.logname)myfree(conf.logname);
conf.logname = (unsigned char *)mystrdup((char *)argv[1]);
if(conf.stdlog) conf.stdlog = freopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.logtime), "a", conf.stdlog);
else conf.stdlog = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.logtime), "a");
if(!conf.stdlog){
perror((char *)tmpbuf);
return 1;
}
}
}
else conf.logfunc = logstdout;
return 0;
}
@ -648,12 +552,6 @@ static int h_nsrecord(int argc, unsigned char **argv){
return 0;
}
static int h_dialer(int argc, unsigned char **argv){
if(conf.demanddialprog) myfree(conf.demanddialprog);
conf.demanddialprog = mystrdup((char *)argv[1]);
return 0;
}
static int h_system(int argc, unsigned char **argv){
int res;
@ -1535,36 +1433,35 @@ struct commands commandhandlers[]={
{commandhandlers+28, "nscache", h_nscache, 2, 2},
{commandhandlers+29, "nscache6", h_nscache6, 2, 2},
{commandhandlers+30, "nsrecord", h_nsrecord, 3, 3},
{commandhandlers+31, "dialer", h_dialer, 2, 2},
{commandhandlers+32, "system", h_system, 2, 2},
{commandhandlers+33, "pidfile", h_pidfile, 2, 2},
{commandhandlers+34, "monitor", h_monitor, 2, 2},
{commandhandlers+35, "parent", h_parent, 5, 0},
{commandhandlers+36, "allow", h_ace, 1, 0},
{commandhandlers+37, "deny", h_ace, 1, 0},
{commandhandlers+38, "redirect", h_ace, 3, 0},
{commandhandlers+39, "bandlimin", h_ace, 2, 0},
{commandhandlers+40, "bandlimout", h_ace, 2, 0},
{commandhandlers+41, "nobandlimin", h_ace, 1, 0},
{commandhandlers+42, "nobandlimout", h_ace, 1, 0},
{commandhandlers+43, "countin", h_ace, 4, 0},
{commandhandlers+44, "nocountin", h_ace, 1, 0},
{commandhandlers+45, "countout", h_ace, 4, 0},
{commandhandlers+46, "nocountout", h_ace, 1, 0},
{commandhandlers+47, "connlim", h_ace, 4, 0},
{commandhandlers+48, "noconnlim", h_ace, 1, 0},
{commandhandlers+49, "plugin", h_plugin, 3, 0},
{commandhandlers+50, "logdump", h_logdump, 2, 3},
{commandhandlers+51, "filtermaxsize", h_filtermaxsize, 2, 2},
{commandhandlers+52, "nolog", h_nolog, 1, 1},
{commandhandlers+53, "weight", h_nolog, 2, 2},
{commandhandlers+54, "authcache", h_authcache, 2, 3},
{commandhandlers+55, "smtpp", h_proxy, 1, 0},
{commandhandlers+56, "delimchar",h_delimchar, 2, 2},
{commandhandlers+57, "authnserver", h_authnserver, 2, 2},
{commandhandlers+58, "stacksize", h_stacksize, 2, 2},
{commandhandlers+59, "force", h_force, 1, 1},
{commandhandlers+60, "noforce", h_noforce, 1, 1},
{commandhandlers+31, "system", h_system, 2, 2},
{commandhandlers+32, "pidfile", h_pidfile, 2, 2},
{commandhandlers+33, "monitor", h_monitor, 2, 2},
{commandhandlers+34, "parent", h_parent, 5, 0},
{commandhandlers+35, "allow", h_ace, 1, 0},
{commandhandlers+36, "deny", h_ace, 1, 0},
{commandhandlers+37, "redirect", h_ace, 3, 0},
{commandhandlers+38, "bandlimin", h_ace, 2, 0},
{commandhandlers+39, "bandlimout", h_ace, 2, 0},
{commandhandlers+40, "nobandlimin", h_ace, 1, 0},
{commandhandlers+41, "nobandlimout", h_ace, 1, 0},
{commandhandlers+42, "countin", h_ace, 4, 0},
{commandhandlers+43, "nocountin", h_ace, 1, 0},
{commandhandlers+44, "countout", h_ace, 4, 0},
{commandhandlers+45, "nocountout", h_ace, 1, 0},
{commandhandlers+46, "connlim", h_ace, 4, 0},
{commandhandlers+47, "noconnlim", h_ace, 1, 0},
{commandhandlers+48, "plugin", h_plugin, 3, 0},
{commandhandlers+49, "logdump", h_logdump, 2, 3},
{commandhandlers+50, "filtermaxsize", h_filtermaxsize, 2, 2},
{commandhandlers+51, "nolog", h_nolog, 1, 1},
{commandhandlers+52, "weight", h_nolog, 2, 2},
{commandhandlers+53, "authcache", h_authcache, 2, 3},
{commandhandlers+54, "smtpp", h_proxy, 1, 0},
{commandhandlers+55, "delimchar",h_delimchar, 2, 2},
{commandhandlers+56, "authnserver", h_authnserver, 2, 2},
{commandhandlers+57, "stacksize", h_stacksize, 2, 2},
{commandhandlers+58, "force", h_force, 1, 1},
{commandhandlers+59, "noforce", h_noforce, 1, 1},
#ifndef NORADIUS
{commandhandlers+61, "radius", h_radius, 3, 0},
#endif
@ -1745,7 +1642,7 @@ void freeconf(struct extparam *confp){
struct ace *acl;
struct filemon *fm;
int counterd, archiverc;
unsigned char *logname, *logtarget;
unsigned char *logtarget;
unsigned char **archiver;
unsigned char * logformat;
@ -1781,18 +1678,13 @@ void freeconf(struct extparam *confp){
pthread_mutex_unlock(&pwl_mutex);
/*
logtarget = confp->logtarget;
confp->logtarget = NULL;
logname = confp->logname;
confp->logname = NULL;
*/
confp->logfunc = lognone;
logformat = confp->logformat;
confp->logformat = NULL;
confp->rotate = 0;
confp->logtype = NONE;
confp->logtime = confp->time = 0;
confp->time = 0;
archiverc = confp->archiverc;
confp->archiverc = 0;
@ -1840,22 +1732,12 @@ void freeconf(struct extparam *confp){
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);
}
myfree(logtarget);
myfree(logformat);
if(archiver) {
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
myfree(archiver);
}
havelog = 0;
}
int reload (void){

View File

@ -9,7 +9,7 @@
static void pr_unsigned64(struct node *node, CBFUNC cbf, void*cb){
char buf[32];
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRINTF_INT64_MODIFIER"u", *(uint64_t *)node->value));
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRIu64, *(uint64_t *)node->value));
}
static void pr_integer(struct node *node, CBFUNC cbf, void*cb){
@ -523,19 +523,8 @@ static void * ef_server_childcount(struct node * node){
}
static void * ef_server_log(struct node * node){
if(((struct srvparam *)node->value) -> logfunc == lognone) return "none";
#ifndef NORADIUS
else if(((struct srvparam *)node->value) -> logfunc == logradius) return "radius";
#endif
else if(((struct srvparam *)node->value) -> logfunc == logstdout)
return (((struct srvparam *)node->value) -> logtarget)?"file":"stdout";
#ifndef _WIN32
else if(((struct srvparam *)node->value) -> logfunc == logsyslog) return "syslog";
#endif
#ifndef NOODBC
else if(((struct srvparam *)node->value) -> logfunc == logsql) return "odbc";
#endif
return NULL;
if(((struct srvparam *)node->value) -> log == NULL) return "none";
return ((struct srvparam *)node->value) -> log -> selector;
}
static void * ef_server_logformat(struct node * node){
@ -551,11 +540,6 @@ static void * ef_server_replacement(struct node * node){
return NULL;
}
static void * ef_server_logtarget(struct node * node){
return ((struct srvparam *)node->value) -> logtarget;
}
static void * ef_server_target(struct node * node){
return ((struct srvparam *)node->value) -> target;
}
@ -763,18 +747,17 @@ static struct property prop_server[] = {
{prop_server + 7, "singlepacket", ef_server_singlepacket, TYPE_INTEGER, "is single packet redirection"},
{prop_server + 8, "usentlm", ef_server_usentlm, TYPE_INTEGER, "allow NTLM authentication"},
{prop_server + 9, "log", ef_server_log, TYPE_STRING, "type of logging"},
{prop_server + 10, "logtarget", ef_server_logtarget, TYPE_STRING, "log target options"},
{prop_server + 11, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
{prop_server + 12, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
{prop_server + 13, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
{prop_server + 14, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
{prop_server + 15, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
{prop_server + 16, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
{prop_server + 10, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
{prop_server + 11, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
{prop_server + 12, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
{prop_server + 13, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
{prop_server + 14, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
{prop_server + 15, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
#ifndef NOIPV6
{prop_server + 17, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
{prop_server + 18, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
#else
{prop_server + 16, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
{prop_server + 17, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
#else
{prop_server + 16, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
#endif
{NULL, "next", ef_server_next, TYPE_SERVER, "next"}
};

View File

@ -333,4 +333,5 @@ struct proxydef childdef = {
" -hdefault_host[:port] - use this host and port as default if no host specified\n"
};
#include "proxymain.c"
#include "log.c"
#endif

813
src/log.c
View File

@ -6,33 +6,467 @@
*/
#include "proxy.h"
pthread_mutex_t log_mutex;
int havelog = 0;
#ifdef _WIN32
HANDLE log_sem;
#else
sem_t log_sem;
#endif
#define MAXLOG 1024
#define EVENTSIZE (4096 - sizeof(void *))
#define LOGBUFSIZE (EVENTSIZE - sizeof(struct logevent))
#define MAX_SEM_COUNT 256
typedef enum {
REGISTER,
UNREGISTER,
LOG,
FLUSH,
FREEPARAM
} EVENTTYPE;
struct clientparam logparam;
struct srvparam logsrv;
struct LOGGER;
struct logevent {
struct logevent *next;
struct LOGGER *log;
EVENTTYPE event;
int inbuf;
struct clientparam *param;
char * logstring;
char buf[1];
} *logtail=NULL, *loghead=NULL;
static void delayflushlogs(void);
static void delayunregisterlog (struct LOGGER * log);
static void delayregisterlog (struct LOGGER * log);
static void delaydolog(struct logevent *evt);
static void delayfreeparam(struct clientparam *param);
void logpush(struct logevent *evt);
#ifdef WITHMAIN
#define HAVERADIUS 0
#define HAVESQL 0
#else
int raddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
void logradius(const char * buf, int len, struct LOGGER *logger);
#define HAVERADIUS 1
#ifndef NOODBC
#define HAVESQL 1
static int sqlinit(struct LOGGER *logger);
static int sqldobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
static void sqllog(const char * buf, int len, struct LOGGER *logger);
static void sqlrotate(struct LOGGER *logger);
static void sqlclose(struct LOGGER *logger);
#else
#define HAVESQL 0
#endif
#endif
#ifdef _WIN32
#define HAVESYSLOG 0
#else
#define HAVESYSLOG 1
static int sysloginit(struct LOGGER *logger);
static void logsyslog(const char * buf, int len, struct LOGGER *logger);
static void syslogrotate(struct LOGGER *logger);
static void syslogclose(struct LOGGER *logger);
#endif
static int stdloginit(struct LOGGER *logger);
static int stddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
static void stdlog(const char * buf, int len, struct LOGGER *logger);
static void stdlogrotate(struct LOGGER *logger);
static void stdlogclose(struct LOGGER *logger);
static void stdlogflush(struct LOGGER *logger);
struct LOGFUNC stdlogfuncs[] = {
#if HAVESYSLOG > 0
{stdlogfuncs+1, sysloginit, stddobuf, logsyslog, syslogrotate, NULL, syslogclose, "@"},
#endif
#if HAVERADIUS > 0
{stdlogfuncs+1+HAVESYSLOG, NULL, raddobuf, logradius, NULL, NULL, NULL, "radius"},
#endif
#if HAVESQL > 0
{stdlogfuncs+1+HAVESYSLOG+HAVERADIUS, sqlinit, sqldobuf, sqllog, sqlrotate, NULL, sqlclose, "&"},
#endif
{NULL, stdloginit, stddobuf, stdlog, stdlogrotate, stdlogflush, stdlogclose, ""}
};
struct LOGFUNC *logfuncs = stdlogfuncs;
struct stdlogdata{
FILE *fp;
} errld;
struct LOGGER errlogger = {NULL, NULL, "stderr", &errld, stdlogfuncs+1+HAVESYSLOG+HAVERADIUS+HAVESQL, 0, 0, 1};
struct LOGGER *loggers = &errlogger;
static void delayflushlogs(void){
struct LOGGER *log;
for(log = loggers; log; log=log->next){
if(log->logfunc && log->logfunc->flush)log->logfunc->flush(log);
#ifndef WITHMAIN
if(log->rotate && log->logfunc && log->logfunc->rotate && timechanged(log->rotated, conf.time, log->rotate)){
log->logfunc->rotate(log);
log->rotated = conf.time;
}
#endif
}
}
void flushlogs(void){
struct logevent * evt;
evt = malloc(sizeof(struct logevent));
evt->event = FLUSH;
logpush(evt);
}
void delayregisterlog(struct LOGGER *log){
struct LOGFUNC *funcs;
if(log->logfunc) return;
for(funcs = logfuncs; funcs; funcs=funcs->next){
if(!strncmp(log->selector, funcs->prefix, strlen(funcs->prefix))){
if(funcs->init && funcs->init(log)) break;
log->logfunc = funcs;
log->rotated = conf.time;
return;
}
}
}
struct LOGGER * registerlog(const char * logstring, int logtype){
struct LOGGER *log;
if(!logstring || !strcmp(logstring, "NUL") || !strcmp(logstring, "/dev/null")) return NULL;
pthread_mutex_lock(&log_mutex);
for(log = loggers; log; log=log->next){
if(!strcmp(logstring, log->selector)){
if(logtype >= 0) log->rotate = logtype;
log->registered++;
pthread_mutex_unlock(&log_mutex);
return log;
}
}
log = malloc(sizeof(struct LOGGER));
if(!log) {
pthread_mutex_unlock(&log_mutex);
return NULL;
}
memset (log, 0, sizeof(struct LOGGER));
log->selector = mystrdup(logstring);
if(log->selector){
struct logevent *evt;
if(logtype)log->rotate = logtype;
log->registered++;
log->next = loggers;
if (log->next)log->next->prev = log;
loggers = log;
pthread_mutex_unlock(&log_mutex);
evt = malloc(sizeof(struct logevent));
evt->event = REGISTER;
evt->log = log;
logpush(evt);
return log;
}
pthread_mutex_unlock(&log_mutex);
myfree(log);
return NULL;
}
static void delayunregisterlog (struct LOGGER * log){
if(log){
pthread_mutex_lock(&log_mutex);
log->registered--;
if(!log->registered){
if(log->prev)log->prev->next = log->next;
else loggers = log->next;
if(log->next)log->next->prev = log->prev;
pthread_mutex_unlock(&log_mutex);
if(log->logfunc){
if(log->logfunc->flush) log->logfunc->flush(log);
if(log->logfunc->close) log->logfunc->close(log);
}
myfree(log->selector);
myfree(log);
}
else pthread_mutex_unlock(&log_mutex);
}
}
void unregisterlog (struct LOGGER * log){
struct logevent *evt;
if(!log) return;
evt = malloc(sizeof(struct logevent));
evt->event = UNREGISTER;
evt->log = log;
logpush(evt);
}
#ifdef _WIN32
DWORD WINAPI logthreadfunc(LPVOID p) {
#else
void * logthreadfunc (void *p) {
#endif
for(;;){
struct logevent *evt;
#ifdef _WIN32
WaitForSingleObject(log_sem, INFINITE);
#else
sem_wait(&log_sem);
#endif
while(loghead){
pthread_mutex_lock(&log_mutex);
evt = loghead;
loghead = evt->next;
if(!loghead)logtail = NULL;
pthread_mutex_unlock(&log_mutex);
switch(evt->event){
case REGISTER:
delayregisterlog(evt->log);
break;
case UNREGISTER:
delayunregisterlog(evt->log);
break;
case FLUSH:
delayflushlogs();
break;
case LOG:
delaydolog(evt);
break;
case FREEPARAM:
delayfreeparam(evt->param);
break;
default:
break;
}
myfree(evt);
}
}
return 0;
}
void logpush(struct logevent *evt){
pthread_mutex_lock(&log_mutex);
if(logtail) logtail->next = evt;
logtail = evt;
evt->next = NULL;
if(!loghead)loghead = evt;
pthread_mutex_unlock(&log_mutex);
#ifdef _WIN32
ReleaseSemaphore(log_sem, 1, NULL);
#else
sem_post(&log_sem);
#endif
}
void initlog(void){
pthread_t thread;
srvinit(&logsrv, &logparam);
pthread_mutex_init(&log_mutex, NULL);
errld.fp = stdout;
#ifdef _WIN32
{
HANDLE h;
if(!(log_sem = CreateSemaphore(NULL, 0, MAX_SEM_COUNT, NULL))) exit(11);
#ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread);
#else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, 65536, (void *)logthreadfunc, NULL, 0, &thread);
#endif
if (h) {
CloseHandle(h);
}
else {
exit(10);
}
}
#else
{
pthread_attr_t pa;
pthread_attr_init(&pa);
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 1024*256);
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
if(sem_init(&log_sem, 0, 0)) exit(11);
if(pthread_create(&thread, &pa, logthreadfunc, NULL)) exit(10);
}
#endif
}
static void delaydolog(struct logevent *evt){
if(!evt->log->logfunc || !evt->log->logfunc->log) return;
if(evt->inbuf){
evt->log->logfunc->log(evt->buf, evt->inbuf, evt->log);
}
else if(evt->param && evt->log->logfunc->dobuf){
char buf[LOGBUFSIZE];
evt->log->logfunc->log(buf, evt->log->logfunc->dobuf(evt->param, buf, LOGBUFSIZE, evt->logstring), evt->log);
}
}
void dolog(struct clientparam * param, const unsigned char *s){
static int init = 0;
if(param)param->srv->logfunc(param, s);
else {
if(!init){
srvinit(&logsrv, &logparam);
init = 1;
}
logstdout(&logparam, s);
if(!param || !param->srv){
stdlog(s, strlen(s), &errlogger);
return;
}
if(conf.prelog)conf.prelog(param);
if(!param->nolog && param->srv->log) {
struct logevent *evt;
if(!param->srv->log->logfunc) {
int slen =0, hlen=0, ulen=0;
slen = s?strlen(s)+1 : 0;
hlen = param->hostname? strlen(param->hostname)+1 : 0;
ulen = param->username? strlen(param->username)+1 : 0;
if(!(evt = malloc(sizeof(struct logevent) + slen + ulen + hlen))) return;
evt->inbuf = 0;
evt->param=param;
evt->logstring = NULL;
if(slen){
memcpy(evt->buf,s, slen);
evt->logstring = evt->buf;
}
if(hlen){
memcpy(evt->buf+slen,param->hostname, hlen);
param->hostname = evt->buf + slen;
}
if(ulen){
memcpy(evt->buf+slen+hlen,param->username, ulen);
param->username = evt->buf + slen + hlen;
}
evt->event = LOG;
evt->log = param->srv->log;
logpush(evt);
}
else if (param->srv->log->logfunc->log){
if(!(evt = malloc(param->srv->log->logfunc->dobuf?EVENTSIZE:sizeof(struct logevent)))) return;
evt->inbuf = 0;
evt->param = NULL;
evt->logstring = NULL;
if(param->srv->log->logfunc->dobuf){
evt->inbuf = param->srv->log->logfunc->dobuf(param, evt->buf, LOGBUFSIZE, s);
}
evt->event = LOG;
evt->log = param->srv->log;
logpush(evt);
}
}
if(param->trafcountfunc)(*param->trafcountfunc)(param);
clearstat(param);
}
static void delayfreeparam(struct clientparam * param) {
if(param->res == 2) return;
if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
so._shutdown(param->ctrlsocksrv, SHUT_RDWR);
so._closesocket(param->ctrlsocksrv);
}
if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
so._shutdown(param->ctrlsock, SHUT_RDWR);
so._closesocket(param->ctrlsock);
}
if(param->remsock != INVALID_SOCKET) {
so._shutdown(param->remsock, SHUT_RDWR);
so._closesocket(param->remsock);
}
if(param->clisock != INVALID_SOCKET) {
so._shutdown(param->clisock, SHUT_RDWR);
so._closesocket(param->clisock);
}
myfree(param->clibuf);
myfree(param->srvbuf);
if(param->datfilterssrv) myfree(param->datfilterssrv);
#ifndef STDMAIN
if(param->reqfilters) myfree(param->reqfilters);
if(param->hdrfilterscli) myfree(param->hdrfilterscli);
if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
if(param->predatfilters) myfree(param->predatfilters);
if(param->datfilterscli) myfree(param->datfilterscli);
if(param->filters){
if(param->nfilters)while(param->nfilters--){
if(param->filters[param->nfilters].filter->filter_clear)
(*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
}
myfree(param->filters);
}
if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param);
#endif
if(param->srv){
pthread_mutex_lock(&param->srv->counter_mutex);
if(param->prev){
param->prev->next = param->next;
}
else
param->srv->child = param->next;
if(param->next){
param->next->prev = param->prev;
}
(param->srv->childcount)--;
if(param->srv->service == S_ZOMBIE && !param->srv->child)srvpostfree(param->srv);
pthread_mutex_unlock(&param->srv->counter_mutex);
}
if(param->hostname) myfree(param->hostname);
if(param->username) myfree(param->username);
if(param->password) myfree(param->password);
if(param->extusername) myfree(param->extusername);
if(param->extpassword) myfree(param->extpassword);
myfree(param);
}
void freeparam(struct clientparam * param) {
struct logevent *evt;
evt = malloc(sizeof(struct logevent));
evt->event = FREEPARAM;
evt->param = param;
logpush(evt);
}
void clearstat(struct clientparam * param) {
#ifdef _WIN32
@ -60,8 +494,48 @@ char months[12][4] = {
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
unsigned char * dologname (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) {
struct tm *ts;
int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){
ts = localtime(&t);
if(strchr((char *)name, '%')){
dobuf2(&logparam, buf, bufsize - (ext?strlen(ext):0), NULL, NULL, ts, (char *)name);
}
else switch(lt){
case NONE:
sprintf((char *)buf, "%s", name);
break;
case ANNUALLY:
sprintf((char *)buf, "%s.%04d", name, ts->tm_year+1900);
break;
case MONTHLY:
sprintf((char *)buf, "%s.%04d.%02d", name, ts->tm_year+1900, ts->tm_mon+1);
break;
case WEEKLY:
t = t - (ts->tm_wday * (60*60*24));
ts = localtime(&t);
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
break;
case DAILY:
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
break;
case HOURLY:
sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour);
break;
case MINUTELY:
sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
break;
default:
break;
}
if(ext){
strcat((char *)buf, ".");
strcat((char *)buf, (char *)ext);
}
return buf;
}
int dobuf2(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format){
int i, j;
int len;
time_t sec;
@ -96,7 +570,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
delay = param->time_start?((unsigned) ((sec - param->time_start))*1000 + msec) - param->msec_start : 0;
*buf = 0;
for(i=0, j=0; format[j] && i < 4040; j++){
for(i=0, j=0; format[j] && i < (bufsize-70); j++){
if(format[j] == '%' && format[j+1]){
j++;
switch(format[j]){
@ -158,7 +632,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
case 'U':
if(param->username && *param->username){
for(len = 0; i< 4000 && param->username[len]; len++){
for(len = 0; i< (bufsize - 3) && param->username[len]; len++){
buf[i] = param->username[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@ -174,7 +648,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
case 'n':
len = param->hostname? (int)strlen((char *)param->hostname) : 0;
if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < 256; len++, i++){
if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < (bufsize-3); len++, i++){
buf[i] = param->hostname[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@ -203,7 +677,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
case 'T':
if(s){
for(len = 0; i<4000 && s[len]; len++){
for(len = 0; i < (bufsize-3) && s[len]; len++){
buf[i] = s[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@ -246,15 +720,15 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
i += (int)strlen((char *)buf+i);
break;
case 'L':
sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->cycles);
sprintf((char *)buf+i, "%"PRIu64, param->cycles);
i += (int)strlen((char *)buf+i);
break;
case 'I':
sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statssrv64);
sprintf((char *)buf+i, "%"PRIu64, param->statssrv64);
i += (int)strlen((char *)buf+i);
break;
case 'O':
sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statscli64);
sprintf((char *)buf+i, "%"PRIu64, param->statscli64);
i += (int)strlen((char *)buf+i);
break;
case 'h':
@ -281,13 +755,13 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
j = k;
}
if(!s || format[k]!='T') break;
for(k = 0, len = 0; s[len] && i < 4000; len++){
for(k = 0, len = 0; s[len]; len++){
if(isspace(s[len])){
k++;
while(isspace(s[len+1]))len++;
if(k == pmin) continue;
}
if(k>=pmin && k<=pmax) {
if(k>=pmin && k<=pmax && i < (bufsize-3)) {
buf[i] = s[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) {
@ -310,7 +784,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
return i;
}
int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec){
int dobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec){
struct tm* tm;
int i;
char * format;
@ -318,37 +792,290 @@ int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *
time(&t);
if(!param) return 0;
if(param->trafcountfunc)(*param->trafcountfunc)(param);
format = param->srv->logformat?(char *)param->srv->logformat : DEFLOGFORMAT;
tm = (*format == 'G' || *format == 'g')?
gmtime(&t) : localtime(&t);
i = dobuf2(param, buf, s, doublec, tm, format + 1);
clearstat(param);
i = dobuf2(param, buf, bufsize, s, doublec, tm, format + 1);
return i;
}
void lognone(struct clientparam * param, const unsigned char *s) {
if(param->trafcountfunc)(*param->trafcountfunc)(param);
clearstat(param);
static int stdloginit(struct LOGGER *logger){
char tmpbuf[1024];
struct stdlogdata *lp;
lp = myalloc(sizeof(struct stdlogdata));
if(!lp) return 1;
logger->data = lp;
if(!*logger->selector || !strcmp(logger->selector, "stdout")){
logger->rotate = NONE;
lp->fp = stdout;
}
else if(!strcmp(logger->selector,"stderr")){
logger->rotate = NONE;
lp->fp = stderr;
}
else {
lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) - 1, logger->selector, NULL, logger->rotate, time(NULL)), "a");
if(!lp->fp){
myfree(lp);
return(2);
}
}
return 0;
}
void logstdout(struct clientparam * param, const unsigned char *s) {
FILE *log;
unsigned char tmpbuf[8192];
dobuf(param, tmpbuf, s, NULL);
log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout;
if(!param->nolog)if(fprintf(log, "%s\n", tmpbuf) < 0) {
perror("printf()");
};
if(log != conf.stdlog)fflush(log);
static int stddobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s){
return dobuf(param, buf, bufsize, s, NULL);
}
#ifndef _WIN32
void logsyslog(struct clientparam * param, const unsigned char *s) {
unsigned char tmpbuf[8192];
dobuf(param, tmpbuf, s, NULL);
if(!param->nolog)syslog(LOG_INFO, "%s", tmpbuf);
static void stdlog(const char * buf, int len, struct LOGGER *logger) {
FILE *log = ((struct stdlogdata *)logger->data)->fp;
fprintf(log, "%s\n", buf);
}
static void stdlogrotate(struct LOGGER *logger){
char tmpbuf[1024];
struct stdlogdata *lp = (struct stdlogdata *)logger->data;
if(lp->fp) lp->fp = freopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a", lp->fp);
else lp->fp = fopen((char *)dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, NULL, logger->rotate, conf.time), "a");
logger->rotated = conf.time;
if(logger->rotate) {
int t;
t = 1;
switch(logger->rotate){
case ANNUALLY:
t = t * 12;
case MONTHLY:
t = t * 4;
case WEEKLY:
t = t * 7;
case DAILY:
t = t * 24;
case HOURLY:
t = t * 60;
case MINUTELY:
t = t * 60;
default:
break;
}
/*
FIXME: move archiver to thread
*/
dologname (tmpbuf, sizeof(tmpbuf) -1, logger->selector, (conf.archiver)?conf.archiver[1]:NULL, logger->rotate, (logger->rotated - t * conf.rotate));
remove ((char *) tmpbuf);
if(conf.archiver) {
int i;
*tmpbuf = 0;
for(i = 2; i < conf.archiverc && strlen((char *)tmpbuf) < 512; i++){
strcat((char *)tmpbuf, " ");
if(!strcmp((char *)conf.archiver[i], "%A")){
strcat((char *)tmpbuf, "\"");
dologname (tmpbuf + strlen((char *)tmpbuf), sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1), logger->selector, conf.archiver[1], logger->rotate, (logger->rotated - t));
strcat((char *)tmpbuf, "\"");
}
else if(!strcmp((char *)conf.archiver[i], "%F")){
strcat((char *)tmpbuf, "\"");
dologname (tmpbuf+strlen((char *)tmpbuf), sizeof(tmpbuf) - (strlen((char *)tmpbuf) + 1), logger->selector, NULL, logger->rotate, (logger->rotated-t));
strcat((char *)tmpbuf, "\"");
}
else
strcat((char *)tmpbuf, (char *)conf.archiver[i]);
}
system((char *)tmpbuf+1);
}
}
}
static void stdlogflush(struct LOGGER *logger){
fflush(((struct stdlogdata *)logger->data)->fp);
}
static void stdlogclose(struct LOGGER *logger){
if(((struct stdlogdata *)logger->data)->fp != stdout && ((struct stdlogdata *)logger->data)->fp != stderr)
fclose(((struct stdlogdata *)logger->data)->fp);
myfree(logger->data);
}
#if HAVESYSLOG > 0
static int sysloginit(struct LOGGER *logger){
openlog(logger->selector, LOG_PID, LOG_DAEMON);
return 0;
}
static void logsyslog(const char * buf, int len, struct LOGGER *logger) {
syslog(LOG_INFO, "%s", buf);
}
static void syslogrotate(struct LOGGER *logger){
closelog();
openlog(logger->selector+1, LOG_PID, LOG_DAEMON);
}
static void syslogclose(struct LOGGER *logger){
closelog();
}
#endif
#if HAVESQL > 0
struct sqldata {
SQLHENV henv;
SQLHSTMT hstmt;
SQLHDBC hdbc;
int attempt;
time_t attempt_time;
};
static int sqlinit2(struct sqldata * sd, char * source){
SQLRETURN retcode;
char * datasource;
char * username;
char * password;
char * string;
int ret = 0;
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sd->henv);
if (!sd->henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
return 1;
}
retcode = SQLSetEnvAttr(sd->henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
ret = 2;
goto CLOSEENV;
}
retcode = SQLAllocHandle(SQL_HANDLE_DBC, sd->henv, &sd->hdbc);
if (!sd->hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
ret = 3;
goto CLOSEENV;
}
SQLSetConnectAttr(sd->hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
string = mystrdup(source);
if(!string) goto CLOSEHDBC;
datasource = strtok(string, ",");
username = strtok(NULL, ",");
password = strtok(NULL, ",");
/* Connect to data source */
retcode = SQLConnect(sd->hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
(SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
(SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
myfree(string);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
ret = 4;
goto CLOSEHDBC;
}
retcode = SQLAllocHandle(SQL_HANDLE_STMT, sd->hdbc, &sd->hstmt);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
sd->hstmt = 0;
ret = 5;
goto CLOSEHDBC;
}
return 0;
CLOSEHDBC:
SQLFreeHandle(SQL_HANDLE_DBC, sd->hdbc);
sd->hdbc = 0;
CLOSEENV:
SQLFreeHandle(SQL_HANDLE_ENV, sd->henv);
sd->henv = 0;
return ret;
}
static int sqlinit(struct LOGGER *logger){
struct sqldata *sd;
int res;
sd = (struct sqldata *)myalloc(sizeof(struct sqldata));
memset(sd, 0, sizeof(struct sqldata));
logger->data = sd;
if((res = sqlinit2(sd, logger->selector))) {
myfree(sd);
return res;
}
return 0;
}
static int sqldobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s){
return dobuf(param, buf, bufsize, s, (unsigned char *)"\'");
}
static void sqllog(const char * buf, int len, struct LOGGER *logger){
SQLRETURN ret;
struct sqldata *sd = (struct sqldata *)logger->data;
if(sd->attempt > 5){
if (conf.time - sd->attempt_time < 180){
return;
}
}
if(sd->attempt){
sd->attempt++;
sqlrotate(logger);
if(!sd->hstmt){
sd->attempt_time=conf.time;
return;
}
}
ret = SQLExecDirect(sd->hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
sqlrotate(logger);
if(sd->hstmt) {
ret = SQLExecDirect(sd->hstmt, (SQLCHAR *)buf, (SQLINTEGER)len);
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
sd->attempt++;
sd->attempt_time=conf.time;
return;
}
}
}
sd->attempt=0;
}
static void sqlrotate(struct LOGGER *logger){
struct sqldata * sd;
sqlclose(logger);
sd = (struct sqldata *)myalloc(sizeof(struct sqldata));
memset(sd, 0, sizeof(struct sqldata));
logger->data = sd;
sqlinit2(sd, logger->selector+1);
}
static void sqlclose(struct LOGGER *logger){
struct sqldata *sd = (struct sqldata *)logger->data;
if(sd->hstmt) {
SQLFreeHandle(SQL_HANDLE_STMT, sd->hstmt);
sd->hstmt = NULL;
}
if(sd->hdbc){
SQLDisconnect(sd->hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, sd->hdbc);
sd->hdbc = NULL;
}
if(sd->henv) {
SQLFreeHandle(SQL_HANDLE_ENV, sd->henv);
sd->henv = NULL;
}
myfree(sd);
}
#endif

View File

@ -75,6 +75,8 @@ struct symbol symbols[] = {
{symbols+48, "make_ace", (void *) make_ace},
{symbols+49, "freeacl", (void *) freeacl},
{symbols+50, "checkpreACL", (void *) checkpreACL},
{symbols+51, "dolog", (void *) dolog},
{symbols+52, "logfuncs", (void *) &logfuncs},
{NULL, "", NULL}
};

View File

@ -22,6 +22,9 @@ static struct commands ldap_trafgroup_handler;
static struct commands ldap_attrsgroup_handler;
static struct commands ldap_dircount_handler;
static void (*dolog)(struct clientparam * param, const unsigned char *s);
static char *attrs[] = { NULL, NULL};
static char *ldap_group_attr;
static char *ldap_access;
@ -109,7 +112,7 @@ static int ldapfunc(struct clientparam *param)
ld = ldap_init( ldap_serv, 389 );
if ( ld == NULL )
{
param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
dolog(param,"Error ldap_init: No init lib ldap");
/*ldap_perror( ld, "Error ldap_init" ); */
return 7;
}
@ -133,7 +136,7 @@ static int ldapfunc(struct clientparam *param)
if ( rc != LDAP_SUCCESS )
{
param->srv->logfunc(param,"Error ldap_bind: No connect ldap catalog");
dolog(param,"Error ldap_bind: No connect ldap catalog");
ldap_unbind_s(ld);
return 7;
}
@ -144,7 +147,7 @@ static int ldapfunc(struct clientparam *param)
if ( ld == NULL )
{
param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
dolog(param,"Error ldap_init: No init lib ldap");
/*ldap_perror( ld, "Error ldap_init" ); */
return 7;
}
@ -153,7 +156,7 @@ static int ldapfunc(struct clientparam *param)
if ( rc != LDAP_SUCCESS )
{
param->srv->logfunc(param, "Error ldap_bind: Not authorize in ldap\
dolog(param, "Error ldap_bind: Not authorize in ldap\
catalog, checked option \'ldapconnect\' ");
ldap_unbind_s(ld);
return 7;
@ -472,6 +475,9 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
return (0);
}
dolog=pluginlink->findbyname("dolog");
already_loaded = 1;
mypluginlink=pluginlink;

View File

@ -28,6 +28,7 @@ extern "C" {
#endif
PROXYFUNC tcppmfunc, proxyfunc, smtppfunc, ftpprfunc;
static void (*pdolog)(struct clientparam * param, const unsigned char *s);
static struct pluginlink * pl;
@ -238,25 +239,25 @@ int dossl(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientConn
ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, &ServerCert, &errSSL);
if ( ServerConn == NULL || ServerCert == NULL ) {
param->res = 8011;
param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed");
if(ServerConn == NULL) param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL");
if(ServerCert == NULL) param->srv->logfunc(param, (unsigned char *)"ServerCert is NULL");
if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
pdolog(param, (unsigned char *)"SSL handshake to server failed");
if(ServerConn == NULL) pdolog(param, (unsigned char *)"ServerConn is NULL");
if(ServerCert == NULL) pdolog(param, (unsigned char *)"ServerCert is NULL");
if(errSSL)pdolog(param, (unsigned char *)errSSL);
return 1;
}
FakeCert = ssl_copy_cert(ServerCert);
if ( FakeCert == NULL ) {
param->res = 8012;
_ssl_cert_free(ServerCert);
param->srv->logfunc(param, (unsigned char *)"Failed to create certificate copy");
pdolog(param, (unsigned char *)"Failed to create certificate copy");
ssl_conn_free(ServerConn);
return 2;
}
ClientConn = ssl_handshake_to_client(param->clisock, FakeCert, &errSSL);
if ( ClientConn == NULL ) {
param->res = 8012;
param->srv->logfunc(param, (unsigned char *)"Handshake to client failed");
if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
pdolog(param, (unsigned char *)"Handshake to client failed");
if(errSSL)pdolog(param, (unsigned char *)errSSL);
_ssl_cert_free(ServerCert);
_ssl_cert_free(FakeCert);
ssl_conn_free(ServerConn);
@ -382,6 +383,8 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
int argc, char** argv){
pl = pluginlink;
pdolog=pluginlink->findbyname("dolog");
if(!ssl_loaded){
ssl_loaded = 1;
pthread_mutex_init(&ssl_mutex, NULL);

View File

@ -4,4 +4,4 @@ TrafficPlugin$(OBJSUFFICS): TrafficPlugin.c
$(CC) $(DCFLAGS) $(CFLAGS) TrafficPlugin.c
$(BUILDDIR)TrafficPlugin$(DLSUFFICS): TrafficPlugin$(OBJSUFFICS)
$(LN) $(LNOUT)../../$(BUILDDIR)TrafficPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) TrafficPlugin$(OBJSUFFICS)
$(LN) $(LNOUT)../../$(BUILDDIR)TrafficPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) TrafficPlugin$(OBJSUFFICS) $(LIBS)

View File

@ -28,8 +28,8 @@ int DBGLEVEL = 0;
int already_loaded = 0;
typedef int (* handler)(int argc, unsigned char ** argv);
struct extparam * conf;
struct commands * commandhandlers;
struct extparam * sconfp;
struct commands * scommandhandlers;
struct pluginlink * pl;
typedef enum {
@ -169,12 +169,9 @@ int h_trafcorrect(int argc, unsigned char ** argv) {
return 1;
}
static unsigned short myhtons(unsigned short port) {
return (port << 8) | (port >> 8);
}
void(*origprelog)(struct clientparam * param) = NULL;
LOGFUNC origlogfunc;
void mylogfunc(struct clientparam * param, const unsigned char * pz) {
void mylogfunc(struct clientparam * param) {
PROXYSERVICE g_s = S_NOSERVICE;
int port;
int rule = 0;
@ -189,7 +186,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
port = starttrafcorrect->port;
g_s = starttrafcorrect->p_service;
if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service;
if (starttrafcorrect->port <= 0) port = myhtons(*SAPORT(&param->sinsr));
if (starttrafcorrect->port <= 0) port = htons(*SAPORT(&param->sinsr));
#ifndef NOPSTDINT
statssrv_before = param->statssrv64;
@ -199,7 +196,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
statscli_before = param->statscli;
#endif
rule++;
if (((g_s == param->service) && (port == myhtons(*SAPORT(&param->sinsr)))) ||
if (((g_s == param->service) && (port == htons(*SAPORT(&param->sinsr)))) ||
( ((starttrafcorrect->type == UDP) &&
((param->operation == UDPASSOC)||
(param->operation == DNSRESOLVE)||
@ -240,9 +237,9 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
}
if (DBGLEVEL == 1) {
#ifndef NOPSTDINT
fprintf(stdout, "Port=%hd; Before: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; After: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
fprintf(stdout, "Port=%hd; Before: srv=%"PRIu64", cli=%"PRIu64"; After: srv=%"PRIu64", cli=%"PRIu64"; nreads=%ld; nwrites=%ld; Rule=%d\n",htons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
#else
fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",htons(*SAPORT(&param->sins)), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
#endif
}
ok = 1;
@ -252,7 +249,7 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
if ((!ok) && (DBGLEVEL == 1)) {
fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, *SAPORT(&param->sinsr),param->operation);
}
origlogfunc(param, pz);
if(origprelog)origprelog(param);
}
#ifdef _WIN32
@ -277,8 +274,8 @@ BOOL WINAPI DllMain( HINSTANCE hModule,
PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char** argv) {
struct commands * starthandler;
conf = pluginlink->conf;
commandhandlers = pluginlink->commandhandlers;
sconfp = pluginlink->conf;
scommandhandlers = pluginlink->commandhandlers;
pl = pluginlink;
if (argc>1) {
@ -295,7 +292,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char**
}
already_loaded = 1;
/* äîáàâëÿåì êîìàíäó "trafcorrect" */
starthandler = commandhandlers;
starthandler = scommandhandlers;
for ( ; starthandler->next; starthandler = starthandler->next);
trafcorrect_handler.next = NULL;
trafcorrect_handler.minargs = 1;
@ -305,8 +302,8 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char**
starthandler->next = &trafcorrect_handler;
/* ïîäìåíÿåì conf->logfunc, ñ öåëüþ êîíòðîëèðîâàòü òðàôôèê */
origlogfunc = conf->logfunc;
conf->logfunc = mylogfunc;
origprelog = sconfp->prelog;
sconfp->prelog = mylogfunc;
return 0;
}

View File

@ -54,7 +54,6 @@ static FILTER_ACTION transparent_filter_client(void *fo, struct clientparam * pa
}
#else
#error No SO_ORIGINAL_DST defined
param->srv->logfunc(param, (unsigned char *)"transparent_plugin: No SO_ORIGINAL_DST defined");
return REJECT;
#endif
#else

View File

@ -69,4 +69,5 @@ struct proxydef childdef = {
};
#include "proxymain.c"
#include "log.c"
#endif

View File

@ -392,7 +392,7 @@ for(;;){
while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', conf.timeouts[STRING_S])) > 2){
if(i> 15 && (!strncasecmp((char *)(buf), "content-length", 14))){
buf[i]=0;
sscanf((char *)buf + 15, "%"PRINTF_INT64_MODIFIER"u", &contentlength64);
sscanf((char *)buf + 15, "%"PRIu64, &contentlength64);
}
}
while( contentlength64 > 0 && (i = sockgetlinebuf(param, CLIENT, buf, (BUFSIZE < contentlength64)? BUFSIZE - 1:(int)contentlength64, '\n', conf.timeouts[STRING_S])) > 0){
@ -502,7 +502,7 @@ for(;;){
if(!sb)continue;
++sb;
while(isspace(*sb))sb++;
sscanf((char *)sb, "%"PRINTF_INT64_MODIFIER"u",&contentlength64);
sscanf((char *)sb, "%"PRIu64,&contentlength64);
if(param->maxtrafout64 && (param->maxtrafout64 < param->statscli64 || contentlength64 > param->maxtrafout64 - param->statscli64)){
RETURN(10);
}
@ -549,7 +549,7 @@ for(;;){
contentlength64 = param->cliinbuf;
param->ndatfilterscli = 0;
}
sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRINTF_INT64_MODIFIER"u\r\n", contentlength64);
sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRIu64"\r\n", contentlength64);
}
#endif
@ -923,7 +923,7 @@ for(;;){
if(!sb)continue;
++sb;
while(isspace(*sb))sb++;
sscanf((char *)sb, "%"PRINTF_INT64_MODIFIER"u", &contentlength64);
sscanf((char *)sb, "%"PRIu64, &contentlength64);
hascontent = 1;
if(param->unsafefilter && param->ndatfilterssrv > 0) {
hascontent = 2;
@ -996,7 +996,7 @@ for(;;){
}
if(action != PASS) RETURN(517);
contentlength64 = param->srvinbuf;
sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRINTF_INT64_MODIFIER"u\r\n", contentlength64);
sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRIu64"\r\n", contentlength64);
hascontent = 1;
}
}
@ -1043,7 +1043,7 @@ for(;;){
}
smallbuf[i] = 0;
contentlength64 = 0;
sscanf((char *)smallbuf, "%"PRINTF_INT64_MODIFIER"x", &contentlength64);
sscanf((char *)smallbuf, "%"SCNx64, &contentlength64);
if(contentlength64 == 0) {
param->chunked = 2;
}
@ -1141,4 +1141,5 @@ struct proxydef childdef = {
"-a1 - anonymous proxy with random client IP spoofing\r\n"
};
#include "proxymain.c"
#include "log.c"
#endif

View File

@ -54,6 +54,7 @@
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <syslog.h>
#include <errno.h>
#endif
@ -166,21 +167,10 @@ int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char *
void initlog(void);
void dolog(struct clientparam * param, const unsigned char *s);
int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
extern FILE * stdlog;
void logstdout(struct clientparam * param, const unsigned char *s);
void logsyslog(struct clientparam * param, const unsigned char *s);
void lognone(struct clientparam * param, const unsigned char *s);
void logradius(struct clientparam * param, const unsigned char *s);
#ifndef NOSQL
void logsql(struct clientparam * param, const unsigned char *s);
int init_sql(char * s);
void close_sql();
#endif
int dobuf(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec);
int dobuf2(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
int doconnect(struct clientparam * param);
int alwaysauth(struct clientparam * param);
int ipauth(struct clientparam * param);
@ -202,11 +192,12 @@ unsigned long myresolver(int, unsigned char *, unsigned char *);
unsigned long fakeresolver (int, unsigned char *, unsigned char*);
int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
void freeparam(struct clientparam * param);
void srvpostfree(struct srvparam * srv);
void clearstat(struct clientparam * param);
void dumpcounters(struct trafcount *tl, int counterd);
int startconnlims (struct clientparam *param);
void stopconnlims (struct clientparam *param);
int timechanged (time_t oldtime, time_t newtime, ROTATION lt);
@ -274,7 +265,7 @@ FILTER_ACTION handledatfltsrv(struct clientparam *param, unsigned char ** buf_p,
void srvinit(struct srvparam * srv, struct clientparam *param);
void srvinit2(struct srvparam * srv, struct clientparam *param);
void srvfree(struct srvparam * srv);
unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
unsigned char * dologname (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
int readconfig(FILE * fp);
int connectwithpoll(SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);

View File

@ -8,6 +8,8 @@
#include "proxy.h"
void srvpostfree(struct srvparam * srv);
#define param ((struct clientparam *) p)
#ifdef _WIN32
DWORD WINAPI threadfunc(LPVOID p) {
@ -179,7 +181,7 @@ int MODULEMAINFUNC (int argc, char** argv){
SASIZETYPE size;
pthread_t thread;
struct clientparam defparam;
struct srvparam srv;
struct srvparam *srv;
struct clientparam * newparam;
int error = 0;
unsigned sleeptime;
@ -271,20 +273,21 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif
srvinit(&srv, &defparam);
srv.pf = childdef.pf;
srv = malloc(sizeof(struct srvparam));
srvinit(srv, &defparam);
srv->pf = childdef.pf;
isudp = childdef.isudp;
srv.service = defparam.service = childdef.service;
srv->service = defparam.service = childdef.service;
#ifndef STDMAIN
copyacl(conf.acl, &srv);
srv.authfuncs = copyauth(conf.authfuncs);
copyacl(conf.acl, srv);
srv->authfuncs = copyauth(conf.authfuncs);
if(!conf.services){
conf.services = &srv;
conf.services = srv;
}
else {
srv.next = conf.services;
conf.services = conf.services->prev = &srv;
srv->next = conf.services;
conf.services = conf.services->prev = srv;
}
#ifndef _WIN32
{
@ -294,8 +297,8 @@ int MODULEMAINFUNC (int argc, char** argv){
}
#endif
#else
srv.needuser = 0;
pthread_mutex_init(&log_mutex, NULL);
srv->needuser = 0;
initlog();
#endif
for (i=1; i<argc; i++) {
@ -307,37 +310,16 @@ int MODULEMAINFUNC (int argc, char** argv){
break;
#ifdef SO_BINDTODEVICE
case 'D':
if(argv[i][2] == 'i') srv.ibindtodevice = mystrdup(argv[i] + 3);
else srv.obindtodevice = mystrdup(argv[i] + 3);
if(argv[i][2] == 'i') srv->ibindtodevice = mystrdup(argv[i] + 3);
else srv->obindtodevice = mystrdup(argv[i] + 3);
break;
#endif
case 'l':
srv.logfunc = logstdout;
if(srv.logtarget) myfree(srv.logtarget);
srv.logtarget = (unsigned char *)mystrdup(argv[i] + 2);
if(argv[i][2]) {
if(argv[i][2]=='@'){
#ifdef STDMAIN
#ifndef _WIN32
openlog(argv[i]+3, LOG_PID, LOG_DAEMON);
srv.logfunc = logsyslog;
#endif
#endif
}
else {
fp = fopen(argv[i] + 2, "a");
if (fp) {
srv.stdlog = fp;
fseek(fp, 0L, SEEK_END);
}
}
}
myfree(srv->logtarget);
srv->logtarget = (unsigned char *)mystrdup(argv[i] + 2);
break;
case 'i':
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.intsa);
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->intsa);
break;
case 'e':
{
@ -346,29 +328,29 @@ int MODULEMAINFUNC (int argc, char** argv){
memset(&sa6, 0, sizeof(sa6));
error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6);
if(!error) {
if (*SAFAMILY(&sa6)==AF_INET) srv.extsa = sa6;
else srv.extsa6 = sa6;
if (*SAFAMILY(&sa6)==AF_INET) srv->extsa = sa6;
else srv->extsa6 = sa6;
}
#else
error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extsa);
error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->extsa);
#endif
}
break;
case 'N':
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv->extNat);
break;
case 'p':
*SAPORT(&srv.intsa) = htons(atoi(argv[i]+2));
*SAPORT(&srv->intsa) = htons(atoi(argv[i]+2));
break;
case '4':
case '6':
srv.family = atoi(argv[i]+1);
srv->family = atoi(argv[i]+1);
break;
case 'b':
srv.bufsize = atoi(argv[i]+2);
srv->bufsize = atoi(argv[i]+2);
break;
case 'n':
srv.usentlm = atoi(argv[i]+2);
srv->usentlm = atoi(argv[i]+2);
break;
#ifdef STDMAIN
#ifndef _WIN32
@ -382,11 +364,11 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif
#endif
case 'f':
if(srv.logformat)myfree(srv.logformat);
srv.logformat = (unsigned char *)mystrdup(argv[i] + 2);
if(srv->logformat)myfree(srv->logformat);
srv->logformat = (unsigned char *)mystrdup(argv[i] + 2);
break;
case 't':
srv.silent = 1;
srv->silent = 1;
break;
case 'h':
hostname = argv[i] + 2;
@ -400,44 +382,44 @@ int MODULEMAINFUNC (int argc, char** argv){
iscbl = 1;
break;
case 'u':
srv.needuser = 0;
if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2);
srv->needuser = 0;
if(*(argv[i] + 2)) srv->needuser = atoi(argv[i] + 2);
break;
case 'T':
srv.transparent = 1;
srv->transparent = 1;
break;
case 'S':
srv.stacksize = atoi(argv[i]+2);
srv->stacksize = atoi(argv[i]+2);
break;
case 'a':
srv.anonymous = 1 + atoi(argv[i]+2);
srv->anonymous = 1 + atoi(argv[i]+2);
break;
case 's':
#ifdef WITHSPLICE
if(isudp || srv.service == S_ADMIN)
if(isudp || srv->service == S_ADMIN)
#endif
srv.singlepacket = 1 + atoi(argv[i]+2);
srv->singlepacket = 1 + atoi(argv[i]+2);
#ifdef WITHSPLICE
else
if(*(argv[i]+2)) srv.usesplice = atoi(argv[i]+2);
if(*(argv[i]+2)) srv->usesplice = atoi(argv[i]+2);
#endif
break;
case 'o':
switch(argv[i][2]){
case 's':
srv.srvsockopts = getopts(argv[i]+3);
srv->srvsockopts = getopts(argv[i]+3);
break;
case 'c':
srv.clisockopts = getopts(argv[i]+3);
srv->clisockopts = getopts(argv[i]+3);
break;
case 'l':
srv.lissockopts = getopts(argv[i]+3);
srv->lissockopts = getopts(argv[i]+3);
break;
case 'r':
srv.cbcsockopts = getopts(argv[i]+3);
srv->cbcsockopts = getopts(argv[i]+3);
break;
case 'R':
srv.cbcsockopts = getopts(argv[i]+3);
srv->cbcsockopts = getopts(argv[i]+3);
break;
default:
error = 1;
@ -488,7 +470,7 @@ int MODULEMAINFUNC (int argc, char** argv){
else {
#endif
#ifndef NOPORTMAP
if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv->intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv->targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
#ifndef STDMAIN
haveerror = 1;
conf.threadinit = 0;
@ -514,7 +496,7 @@ int MODULEMAINFUNC (int argc, char** argv){
);
return (1);
}
srv.target = (unsigned char *)mystrdup(argv[i+1]);
srv->target = (unsigned char *)mystrdup(argv[i+1]);
#endif
#ifndef STDMAIN
}
@ -533,7 +515,7 @@ int MODULEMAINFUNC (int argc, char** argv){
return 2;
};
*newparam = defparam;
return((*srv.pf)((void *)newparam)? 1:0);
return((*srv->pf)((void *)newparam)? 1:0);
}
#endif
@ -542,19 +524,19 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif
srvinit2(&srv, &defparam);
if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET;
if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port);
*SAFAMILY(&srv.extsa) = AF_INET;
srvinit2(srv, &defparam);
if(!*SAFAMILY(&srv->intsa)) *SAFAMILY(&srv->intsa) = AF_INET;
if(!*SAPORT(&srv->intsa)) *SAPORT(&srv->intsa) = htons(childdef.port);
*SAFAMILY(&srv->extsa) = AF_INET;
#ifndef NOIPV6
*SAFAMILY(&srv.extsa6) = AF_INET6;
*SAFAMILY(&srv->extsa6) = AF_INET6;
#endif
if(hostname)parsehostname(hostname, &defparam, childdef.port);
#ifndef STDMAIN
copyfilter(conf.filters, &srv);
copyfilter(conf.filters, srv);
conf.threadinit = 0;
@ -563,27 +545,27 @@ int MODULEMAINFUNC (int argc, char** argv){
if (!iscbc) {
if(srv.srvsock == INVALID_SOCKET){
if(srv->srvsock == INVALID_SOCKET){
if(!isudp){
lg.l_onoff = 1;
lg.l_linger = conf.timeouts[STRING_L];
sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
sock=so._socket(SASOCK(&srv->intsa), SOCK_STREAM, IPPROTO_TCP);
}
else {
sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
sock=so._socket(SASOCK(&srv->intsa), SOCK_DGRAM, IPPROTO_UDP);
}
if( sock == INVALID_SOCKET) {
perror("socket()");
return -2;
}
setopts(sock, srv.lissockopts);
setopts(sock, srv->lissockopts);
#ifdef _WIN32
ioctlsocket(sock, FIONBIO, &ul);
#else
fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL));
#endif
srv.srvsock = sock;
srv->srvsock = sock;
opt = 1;
if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()");
#ifdef SO_REUSEPORT
@ -591,13 +573,13 @@ int MODULEMAINFUNC (int argc, char** argv){
so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
#endif
#ifdef SO_BINDTODEVICE
if(srv.ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1);
if(srv->ibindtodevice) so._setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, srv->ibindtodevice, strlen(srv->ibindtodevice) + 1);
#endif
}
size = sizeof(srv.intsa);
for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, SASIZE(&srv.intsa))==-1; usleep(sleeptime)) {
size = sizeof(srv->intsa);
for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv->intsa, SASIZE(&srv->intsa))==-1; usleep(sleeptime)) {
sprintf((char *)buf, "bind(): %s", strerror(errno));
if(!srv.silent)dolog(&defparam, buf);
if(!srv->silent)dolog(&defparam, buf);
sleeptime = (sleeptime<<1);
if(!sleeptime) {
so._closesocket(sock);
@ -605,69 +587,69 @@ int MODULEMAINFUNC (int argc, char** argv){
}
}
if(!isudp){
if(so._listen (sock, 1 + (srv.maxchild>>4))==-1) {
if(so._listen (sock, 1 + (srv->maxchild>>4))==-1) {
sprintf((char *)buf, "listen(): %s", strerror(errno));
if(!srv.silent)dolog(&defparam, buf);
if(!srv->silent)dolog(&defparam, buf);
return -4;
}
}
else
defparam.clisock = sock;
if(!srv.silent && !iscbc){
if(!srv->silent && !iscbc){
sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
dolog(&defparam, buf);
}
}
if(iscbl){
parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
parsehost(srv->family, cbl_string, (struct sockaddr *)&cbsa);
if((srv->cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
dolog(&defparam, (unsigned char *)"Failed to allocate connect back socket");
return -6;
}
opt = 1;
so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
so._setsockopt(srv->cbsock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
#ifdef SO_REUSEPORT
opt = 1;
so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
so._setsockopt(srv->cbsock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
#endif
setopts(srv.cbsock, srv.cbssockopts);
setopts(srv->cbsock, srv->cbssockopts);
if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
if(so._bind(srv->cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) {
dolog(&defparam, (unsigned char *)"Failed to bind connect back socket");
return -7;
}
if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
if(so._listen(srv->cbsock, 1 + (srv->maxchild>>4))==-1) {
dolog(&defparam, (unsigned char *)"Failed to listen connect back socket");
return -8;
}
}
srv.fds.fd = sock;
srv.fds.events = POLLIN;
srv->fds.fd = sock;
srv->fds.events = POLLIN;
#ifndef _WIN32
pthread_attr_init(&pa);
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv.stacksize));
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv->stacksize));
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
#endif
for (;;) {
for(;;){
while((conf.paused == srv.paused && srv.childcount >= srv.maxchild)){
while((conf.paused == srv->paused && srv->childcount >= srv->maxchild)){
nlog++;
if(!srv.silent && nlog > 5000) {
sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv.childcount, srv.maxchild);
if(!srv->silent && nlog > 5000) {
sprintf((char *)buf, "Warning: too many connected clients (%d/%d)", srv->childcount, srv->maxchild);
dolog(&defparam, buf);
nlog = 0;
}
usleep(SLEEPTIME);
}
if (iscbc) break;
if (conf.paused != srv.paused) break;
if (srv.fds.events & POLLIN) {
error = so._poll(&srv.fds, 1, 1000);
if (conf.paused != srv->paused) break;
if (srv->fds.events & POLLIN) {
error = so._poll(&srv->fds, 1, 1000);
}
else {
usleep(SLEEPTIME);
@ -677,20 +659,20 @@ int MODULEMAINFUNC (int argc, char** argv){
if (error == 0) continue;
if (errno != EAGAIN && errno != EINTR) {
sprintf((char *)buf, "poll(): %s/%d", strerror(errno), errno);
if(!srv.silent)dolog(&defparam, buf);
if(!srv->silent)dolog(&defparam, buf);
break;
}
}
if((conf.paused != srv.paused) || (error < 0)) break;
if((conf.paused != srv->paused) || (error < 0)) break;
error = 0;
if(!isudp){
size = sizeof(defparam.sincr);
if(iscbc){
new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
if(new_sock != INVALID_SOCKET){
setopts(new_sock, srv.cbcsockopts);
setopts(new_sock, srv->cbcsockopts);
parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
parsehost(srv->family, cbc_string, (struct sockaddr *)&defparam.sincr);
if(connectwithpoll(new_sock,(struct sockaddr *)&defparam.sincr,SASIZE(&defparam.sincr),CONNBACK_TO)) {
so._closesocket(new_sock);
new_sock = INVALID_SOCKET;
@ -748,7 +730,7 @@ int MODULEMAINFUNC (int argc, char** argv){
}
#endif
nlog++;
if(!srv.silent && (error || nlog > 5000)) {
if(!srv->silent && (error || nlog > 5000)) {
sprintf((char *)buf, "accept(): %s", strerror(errno));
dolog(&defparam, buf);
nlog = 0;
@ -756,11 +738,11 @@ int MODULEMAINFUNC (int argc, char** argv){
continue;
}
}
setopts(new_sock, srv.clisockopts);
setopts(new_sock, srv->clisockopts);
size = sizeof(defparam.sincl);
if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
sprintf((char *)buf, "getsockname(): %s", strerror(errno));
if(!srv.silent)dolog(&defparam, buf);
if(!srv->silent)dolog(&defparam, buf);
continue;
}
#ifdef _WIN32
@ -772,7 +754,7 @@ int MODULEMAINFUNC (int argc, char** argv){
so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
}
else {
srv.fds.events = 0;
srv->fds.events = 0;
}
#ifndef STDMAIN
@ -784,7 +766,7 @@ int MODULEMAINFUNC (int argc, char** argv){
if(! (newparam = myalloc (sizeof(defparam)))){
if(!isudp) so._closesocket(new_sock);
defparam.res = 21;
if(!srv.silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed");
if(!srv->silent)dolog(&defparam, (unsigned char *)"Memory Allocation Failed");
usleep(SLEEPTIME);
continue;
};
@ -794,68 +776,64 @@ int MODULEMAINFUNC (int argc, char** argv){
if(!isudp) newparam->clisock = new_sock;
#ifndef STDMAIN
if(makefilters(&srv, newparam) > CONTINUE){
if(makefilters(srv, newparam) > CONTINUE){
freeparam(newparam);
continue;
}
#endif
newparam->prev = newparam->next = NULL;
error = 0;
pthread_mutex_lock(&srv.counter_mutex);
if(!srv.child){
srv.child = newparam;
pthread_mutex_lock(&srv->counter_mutex);
if(!srv->child){
srv->child = newparam;
}
else {
newparam->next = srv.child;
srv.child = srv.child->prev = newparam;
newparam->next = srv->child;
srv->child = srv->child->prev = newparam;
}
#ifdef _WIN32
#ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
#else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv.stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
#endif
srv.childcount++;
srv->childcount++;
if (h) {
newparam->threadid = (unsigned)thread;
CloseHandle(h);
}
else {
sprintf((char *)buf, "_beginthreadex(): %s", _strerror(NULL));
if(!srv.silent)dolog(&defparam, buf);
if(!srv->silent)dolog(&defparam, buf);
error = 1;
}
#else
error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
srv.childcount++;
srv->childcount++;
if(error){
sprintf((char *)buf, "pthread_create(): %s", strerror(error));
if(!srv.silent)dolog(&defparam, buf);
if(!srv->silent)dolog(&defparam, buf);
}
else {
newparam->threadid = (unsigned)thread;
}
#endif
pthread_mutex_unlock(&srv.counter_mutex);
pthread_mutex_unlock(&srv->counter_mutex);
if(error) freeparam(newparam);
memset(&defparam.sincl, 0, sizeof(defparam.sincl));
memset(&defparam.sincr, 0, sizeof(defparam.sincr));
if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
if(isudp) while(!srv->fds.events)usleep(SLEEPTIME);
}
if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
if(!srv->silent) dolog(&defparam, (unsigned char *)"Exiting thread");
srvfree(&srv);
srvfree(srv);
pthread_mutex_lock(&srv->counter_mutex);
if(!srv->child)srvpostfree(srv);
pthread_mutex_unlock(&srv->counter_mutex);
#ifndef STDMAIN
pthread_mutex_lock(&config_mutex);
if(srv.next)srv.next->prev = srv.prev;
if(srv.prev)srv.prev->next = srv.next;
else conf.services = srv.next;
pthread_mutex_unlock(&config_mutex);
#endif
#ifndef _WIN32
pthread_attr_destroy(&pa);
@ -874,18 +852,16 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
memset(srv, 0, sizeof(struct srvparam));
srv->version = conf.version + 1;
srv->paused = conf.paused;
srv->logfunc = havelog?conf.logfunc:lognone;
srv->noforce = conf.noforce;
srv->logformat = conf.logformat? (unsigned char *)mystrdup((char *)conf.logformat) : NULL;
srv->logtarget = conf.logtarget? (unsigned char *)mystrdup((char *)conf.logtarget) : NULL;
srv->authfunc = conf.authfunc;
srv->usentlm = 0;
srv->maxchild = conf.maxchild;
srv->stacksize = conf.stacksize;
srv->time_start = time(NULL);
if(havelog && conf.logtarget){
srv->logtarget = (unsigned char *)mystrdup((char *)conf.logtarget);
}
srv->srvsock = INVALID_SOCKET;
srv->logtype = conf.logtype;
srv->logdumpsrv = conf.logdumpsrv;
srv->logdumpcli = conf.logdumpcli;
srv->cbsock = INVALID_SOCKET;
@ -921,6 +897,10 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
myfree(logformat);
}
}
if(srv->logtarget){
srv->log = registerlog(srv->logtarget, srv->logtype);
}
memset(&param->sinsl, 0, sizeof(param->sinsl));
memset(&param->sinsr, 0, sizeof(param->sinsr));
memset(&param->req, 0, sizeof(param->req));
@ -935,14 +915,15 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
param->sinsr = srv->extsa;
}
void srvfree(struct srvparam * srv){
if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
srv->srvsock = INVALID_SOCKET;
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
srv->cbsock = INVALID_SOCKET;
srv->service = S_ZOMBIE;
while(srv->child) usleep(SLEEPTIME * 100);
void srvpostfree(struct srvparam * srv){
unregisterlog(srv->log);
#ifndef STDMAIN
pthread_mutex_lock(&config_mutex);
if(srv->next)srv->next->prev = srv->prev;
if(srv->prev)srv->prev->next = srv->next;
else conf.services = srv->next;
pthread_mutex_unlock(&config_mutex);
if(srv->filter){
while(srv->nfilters){
srv->nfilters--;
@ -966,64 +947,15 @@ void srvfree(struct srvparam * srv){
if(srv->ibindtodevice) myfree(srv->ibindtodevice);
if(srv->obindtodevice) myfree(srv->obindtodevice);
#endif
myfree(srv);
}
void freeparam(struct clientparam * param) {
if(param->res == 2) return;
if(param->datfilterssrv) myfree(param->datfilterssrv);
#ifndef STDMAIN
if(param->reqfilters) myfree(param->reqfilters);
if(param->hdrfilterscli) myfree(param->hdrfilterscli);
if(param->hdrfilterssrv) myfree(param->hdrfilterssrv);
if(param->predatfilters) myfree(param->predatfilters);
if(param->datfilterscli) myfree(param->datfilterscli);
if(param->filters){
if(param->nfilters)while(param->nfilters--){
if(param->filters[param->nfilters].filter->filter_clear)
(*param->filters[param->nfilters].filter->filter_clear)(param->filters[param->nfilters].data);
}
myfree(param->filters);
}
if(conf.connlimiter && (param->res != 95 || param->remsock != INVALID_SOCKET)) stopconnlims(param);
#endif
if(param->clibuf) myfree(param->clibuf);
if(param->srvbuf) myfree(param->srvbuf);
if(param->srv){
pthread_mutex_lock(&param->srv->counter_mutex);
if(param->prev){
param->prev->next = param->next;
}
else
param->srv->child = param->next;
if(param->next){
param->next->prev = param->prev;
}
(param->srv->childcount)--;
pthread_mutex_unlock(&param->srv->counter_mutex);
}
if(param->hostname) myfree(param->hostname);
if(param->username) myfree(param->username);
if(param->password) myfree(param->password);
if(param->extusername) myfree(param->extusername);
if(param->extpassword) myfree(param->extpassword);
if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
so._shutdown(param->ctrlsocksrv, SHUT_RDWR);
so._closesocket(param->ctrlsocksrv);
}
if(param->ctrlsock != INVALID_SOCKET && param->ctrlsock != param->clisock) {
so._shutdown(param->ctrlsock, SHUT_RDWR);
so._closesocket(param->ctrlsock);
}
if(param->remsock != INVALID_SOCKET) {
so._shutdown(param->remsock, SHUT_RDWR);
so._closesocket(param->remsock);
}
if(param->clisock != INVALID_SOCKET) {
so._shutdown(param->clisock, SHUT_RDWR);
so._closesocket(param->clisock);
}
myfree(param);
void srvfree(struct srvparam * srv){
if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
srv->srvsock = INVALID_SOCKET;
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
srv->cbsock = INVALID_SOCKET;
srv->service = S_ZOMBIE;
}

View File

@ -313,4 +313,5 @@ struct proxydef childdef = {
};
#include "proxymain.c"
#include "log.c"
#endif

View File

@ -464,4 +464,5 @@ struct proxydef childdef = {
"-N(EXTERNAL_IP) External NAT address to report to client for BIND\n"
};
#include "proxymain.c"
#include "log.c"
#endif

View File

@ -15,9 +15,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#ifndef PRINTF_INT64_MODIFIER
#define PRINTF_INT64_MODIFIER "ll"
#endif
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -60,6 +58,15 @@ int mutex_unlock(int *val);
#ifdef MSVC
#pragma warning (disable : 4996)
#endif
#ifndef PRIu64
#define PRIu64 "I64u"
#endif
#ifndef PRIi64
#define PRIi64 "I64i"
#endif
#ifndef SCNx64
#define SCNx64 "I64x"
#endif
#endif
#define MAXBANDLIMS 10
@ -188,8 +195,8 @@ struct node;
struct symbol;
struct pluginlink;
struct srvparam;
typedef void (*LOGFUNC)(struct clientparam * param, const unsigned char *);
struct LOGFUNC;
struct LOGGER;
typedef int (*AUTHFUNC)(struct clientparam * param);
typedef void * (*REDIRECTFUNC)(struct clientparam * param);
typedef unsigned long (*RESOLVFUNC)(int af, unsigned char *name, unsigned char *value);
@ -365,6 +372,31 @@ struct trafcount {
time_t updated;
};
struct LOGFUNC {
struct LOGFUNC* next;
int (*init)(struct LOGGER *logger);
int (*dobuf)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s);
void (*log)(const char * buf, int len, struct LOGGER *logger);
void (*rotate)(struct LOGGER *logger);
void (*flush)(struct LOGGER *logger);
void (*close)(struct LOGGER *logger);
char* prefix;
};
extern struct LOGFUNC *logfuncs;
extern void(*prelog)(struct clientparam * param);
struct LOGGER {
struct LOGGER *next;
struct LOGGER *prev;
char * selector;
void * data;
struct LOGFUNC *logfunc;
int rotate;
time_t rotated;
int registered;
};
struct LOGGER * registerlog(const char * logstring, int logtype);
void unregisterlog (struct LOGGER * log);
void flushlogs(void);
struct nserver {
#ifndef NOIPV6
struct sockaddr_in6 addr;
@ -419,7 +451,6 @@ struct srvparam {
struct srvparam *prev;
struct clientparam *child;
PROXYSERVICE service;
LOGFUNC logfunc;
AUTHFUNC authfunc;
PROXYFUNC pf;
SOCKET srvsock, cbsock;
@ -436,6 +467,7 @@ struct srvparam {
int stacksize;
int noforce;
int anonymous;
int logtype;
int clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts;
#ifdef WITHSPLICE
int usesplice;
@ -465,9 +497,10 @@ struct srvparam {
struct ace *preacl, *acl;
struct auth *authfuncs;
struct filter *filter;
unsigned char * logformat;
unsigned char * logtarget;
unsigned char * logformat;
unsigned char * nonprintable;
struct LOGGER *log;
unsigned short targetport;
unsigned char replace;
time_t time_start;
@ -577,7 +610,7 @@ struct extparam {
demon, maxchild, needreload, timetoexit, version, noforce;
int authcachetype, authcachetime;
int filtermaxsize;
unsigned char *logname, **archiver;
unsigned char **archiver;
ROTATION logtype, countertype;
char * counterfile;
#ifndef NOIPV6
@ -591,17 +624,16 @@ struct extparam {
struct passwords *pwl;
struct auth * authenticate;
AUTHFUNC authfunc;
LOGFUNC logfunc;
BANDLIMFUNC bandlimfunc;
TRAFCOUNTFUNC trafcountfunc;
void (*prelog)(struct clientparam * param);
unsigned char *logtarget, *logformat;
struct filemon * fmon;
struct filter * filters;
struct auth *authfuncs;
FILE *stdlog;
char* demanddialprog;
unsigned char **stringtable;
time_t logtime, time;
time_t time;
unsigned logdumpsrv, logdumpcli;
char delimchar;
};
@ -738,8 +770,8 @@ struct pluginlink {
int (*sockgetcharsrv)(struct clientparam * param, int timeosec, int timeousec);
int (*sockgetlinebuf)(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to);
int (*myinet_ntop)(int af, void *src, char *dst, socklen_t size);
int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
int (*dobuf)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec);
int (*dobuf2)(struct clientparam * param, unsigned char * buf, int bufsize, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask);
unsigned long (*getip46)(int family, unsigned char *name, struct sockaddr *sa);
int (*sockmap)(struct clientparam * param, int timeo, int usesplice);
@ -772,7 +804,7 @@ struct pluginlink {
int (*parseusername)(char *username, struct clientparam *param, int extpasswd);
int (*parseconnusername)(char *username, struct clientparam *param, int extpasswd, unsigned short port);
struct sockfuncs *so;
unsigned char * (*dologname) (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
unsigned char * (*dologname) (unsigned char *buf, int bufsize, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
};
struct counter_header {

View File

@ -37,4 +37,5 @@ struct proxydef childdef = {
""
};
#include "proxymain.c"
#include "log.c"
#endif

View File

@ -116,4 +116,5 @@ struct proxydef childdef = {
" -s single packet UDP service for request/reply (DNS-like) services\n"
};
#include "proxymain.c"
#include "log.c"
#endif

View File

@ -474,9 +474,9 @@ void * adminchild(struct clientparam* param) {
}
else {
inbuf += sprintf(buf+inbuf,
"</td><td>%"PRINTF_INT64_MODIFIER"u</td>"
"</td><td>%"PRIu64"</td>"
"<td>MB%s</td>"
"<td>%"PRINTF_INT64_MODIFIER"u.%"PRINTF_INT64_MODIFIER"u</td>"
"<td>%"PRIu64".%"PRIu64"</td>"
"<td>%s</td>",
cp->traflim64 / (1024 * 1024),
rotations[cp->type],