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

# Conflicts:
#	src/plugins.c
#	src/proxymain.c
#	src/sockmap.c
This commit is contained in:
z3APA3A 2020-10-24 11:35:47 +03:00
commit fa4322afee
19 changed files with 215 additions and 81 deletions

View File

@ -2,8 +2,8 @@
1 VERSIONINFO
FILEVERSION 0,9,0,0
PRODUCTVERSION 0,9,0,0
FILEVERSION 10,0,0,0
PRODUCTVERSION 10,0,0,0
FILETYPE 1
FILESUBTYPE 0x0L
BEGIN
@ -14,12 +14,12 @@ BEGIN
VALUE "Comments", "3proxy - tiny proxy server, http://3proxy.org/\0"
VALUE "CompanyName", "Vladimir Dubrovin\0"
VALUE "FileDescription", "3proxy - tiny proxy server\0"
VALUE "FileVersion", "0.9-devel-" BUILDDATE "\0"
VALUE "FileVersion", "10-devel-" BUILDDATE "\0"
VALUE "InternalName", "3proxy\0"
VALUE "LegalCopyright", "Copyright (C) 2002-2019 Vladimir Dubrovin\0"
VALUE "LegalCopyright", "Copyright (C) 2002-2020 Vladimir Dubrovin\0"
VALUE "OriginalFilename", "3proxy.exe\0"
VALUE "ProductName", "3proxy\0"
VALUE "ProductVersion", "0.9-devel-" BUILDDATE "\0"
VALUE "ProductVersion", "10-devel-" BUILDDATE "\0"
END
END
BLOCK "VarFileInfo"

20
README
View File

@ -1,5 +1,11 @@
# 3APA3A 3proxy tiny proxy server
(c) 2002-2019 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
(c) 2002-2020 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
Branches:
Master (stable) branch - 3proxy 0.9
Devel branch - 3proxy 10
Download:
https://github.com/z3APA3A/3proxy/releases
@ -58,7 +64,7 @@ Please read doc/html/index.html and man pages.
+ Threaded application (no child process).
+ Web administration and statistics
+ Plugins for functionality extension
+ Native 64 bit application
+ Native 32/64 bit application
2. Proxy chaining and network connections
+ Can be used as a bridge between client and different proxy type
(e.g. convert incoming HTTP proxy request from client to SOCKSv5
@ -78,9 +84,8 @@ Please read doc/html/index.html and man pages.
+ syslog logging (Unix)
+ ODBC logging
+ RADIUS accounting
+ log file rotation (hourly, daily, weekly, monthly)
+ automatic log file comperssion with external archiver (for files)
+ automatic removal of older log files
+ log file rotation
+ automatic log file processing with external archiver (for files)
+ Character filtering for log files
+ different log files for different servces are supported
4. Access control
@ -89,12 +94,13 @@ Please read doc/html/index.html and man pages.
(POST, PUT, GET, etc), weekday and daytime.
+ ACL-driven (user/source/destination/protocol/weekday/daytime or
combined) bandwith limitation for incoming and (!)outgoing trafic.
+ ACL-driven (user/source/destination/protocol/weekday/daytime or
combined) traffic limitation per day, week or month for incoming and
+ ACL-driven traffic limitation per day, week or month for incoming and
outgoing traffic
+ Connection limitation and ratelimting
+ User authentication by username / password
+ RADIUS Authentication and Authorization
+ User authentication by DNS hostname
+ Authentication cache with possibility to limit user to single IP address
+ Access control by username/password for SOCKSv5 and HTTP/HTTPS/FTP
+ Cleartext or encrypted (crypt/MD5 or NT) passwords.
+ Connection redirection

View File

@ -873,12 +873,12 @@ You can control 3proxy service via "Services" administration ot via "net" comman
<li>since 0.9
<li>90 - unexpected system error (should not happen)
<li>91 - unexpected poll error (should not happen)
<li>92 - connection terminated by timeout
<li>93 - dirty connection termination by server or client (or network issue) with unsent data
<li>94 - clear connection termination by server or client with unsent data
<li>95 - dirty connection termination by client (or network issue)
<li>96 - dirty connection termination by server (or network issue)
<li>97 - dirty connection termination by both client and server (probably network issue)
<li>92 - connection terminated by timeout (see timeouts)
<li>93 - connection terminated by ratelimit-related timeout or due to errors limit
<li>94 - connection termination by server or client with unsent data
<li>95 - dirty connection termination by client (or networking issue)
<li>96 - dirty connection termination by server (or networking issue)
<li>97 - dirty connection termination by both client and server (probably networking issue)
<li>prior to 0.9:
<li>90 - socket error or connection broken
<li>91 - TCP/IP common failure

View File

@ -1049,9 +1049,9 @@
<li>с версии 0.9
<li>90 - неожиданная системная ошибка (не должно происходить)
<li>91 - ошибка poll (не должно происходить)
<li>92 - соединение прервано по таймауту
<li>93 - клиент или сервер &quot;грязно&quot; закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
<li>94 - клиент или сервер &quot;чисто&quot; закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
<li>92 - соединение прервано по таймауту на сетевую операцию (см. timeouts)
<li>93 - соединение прервано по таймауту связанному с рейтлимитом или из-за превышения числа ошибок
<li>94 - клиент или сервер закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
<li>95 - клиент "грязно" закрыл соединение или сетевая ошибка
<li>96 - сервер "грязно" закрыл соединение или сетевая ошибка
<li>97 - клиент и сервер "грязно" закрыли соединение или сетевая ошибка

View File

@ -240,6 +240,8 @@ alternate config file. Think twice before using it.
@ (for Unix) use syslog, filename is used as ident name
.br
& use ODBC, filename consists of comma-delimited datasource,username,password (username and password are optional)
.br
radius - use RADIUS for logging
.br
LOGTYPE is one of:
.br
@ -388,6 +390,28 @@ can use %A as produced archive name and %F as filename.
.br
default timeouts 1 5 30 60 180 1800 15 60 15 5
.br
.B radius
<NAS_SECRET> <radius_server_1[:port][/local_address_1]> <radius_server_2[:port][/local_address_2]>
.br
Configures RADIUS servers to be used for logging and authentication (log and auth types
must be set to radius). port and local address to use with given server may be specified.
.br
Attributes within request: User-Name, Password: (username and password if presented by client),
Service Type: Authenticate-Only,
NAS-Port-Type: NAS-Port-Virtual,
NAS-Port-ID: (proxy service port, e.g. 1080),
NAS-IPv6-Address / NAS-IP-Address: (proxy interface accessed by client),
NAS-Identifier: (text identifing proxy, e.g. PROXY or SOCKSv5),
Framed-IPv6-Address / Framed-IP-Address: (IP address of the client),
Called-Station-ID: (requested Hostname, if presents),
Login-Service: (type of request, e.g. 1001 - SOCKS CONNECT, 1010 - HTTP GET, 1013 - HTTP CONNECT),
Login-TCP-Port: (requested port),
Login-IPv6-Host / Login-IP-Host: (requested IP).
.br
Supported reply attributes for authentication:
Framed-IP-Address / Framed-IPv6-Address (IP to assign to user), Reply-Message.
Use authcache to speedup authentication. RADIUS feature is currently experimental.
.br
.B nserver
@ -503,6 +527,8 @@ NB: there is no any password check, name may be spoofed.
SOCKSv5, FTP, POP3 and HTTP proxy.
.br
cache - cached authentication, may be used with \'authcache\'.
.br
radius - authentication with RADIUS.
.br
Plugins may add additional authentication types.

View File

@ -676,14 +676,16 @@ int alwaysauth(struct clientparam * param){
return res;
}
int checkACL(struct clientparam * param){
int checkACL2(struct clientparam * param, int pre){
struct ace* acentry;
if(!param->srv->acl) {
acentry = pre?param->srv->preacl:param->srv->acl;
if(!acentry) {
return 0;
}
for(acentry = param->srv->acl; acentry; acentry = acentry->next) {
for(; acentry; acentry = acentry->next) {
if(ACLmatches(acentry, param)) {
if(!pre){
param->nolog = acentry->nolog;
param->weight = acentry->weight;
if(acentry->action == 2) {
@ -698,12 +700,26 @@ int checkACL(struct clientparam * param){
dup = *acentry;
return handleredirect(param, &dup);
}
}
return acentry->action;
}
}
return 3;
}
int checkACL(struct clientparam * param){
int res;
res = checkACL2(param, 1);
if(res < 2) return res;
return checkACL2(param, 0);
}
int checkpreACL(struct clientparam * param){
return checkACL2(param, 1);
}
struct authcache {
char * username;
char * password;
@ -771,6 +787,16 @@ int cacheauth(struct clientparam * param){
return 4;
}
int dopreauth(struct clientparam * param){
int res = 0;
if(param->srv && param->srv->authfuncs && param->srv->authfuncs->preauthorize){
res = param->srv->authfuncs->preauthorize(param);
param->preauthorized = !res;
if(res != 1) res = 0;
}
return res;
}
int doauth(struct clientparam * param){
int res = 0;
struct auth *authfuncs;
@ -781,7 +807,8 @@ int doauth(struct clientparam * param){
for(authfuncs=param->srv->authfuncs; authfuncs; authfuncs=authfuncs->next){
res = authfuncs->authenticate?(*authfuncs->authenticate)(param):0;
if(!res) {
if(authfuncs->authorize &&
if(!param->preauthorized && authfuncs->authorize &&
(res = (*authfuncs->authorize)(param)))
return res;
if(conf.authcachetype && authfuncs->authenticate && authfuncs->authenticate != cacheauth && param->username && (!(conf.authcachetype&4) || (!param->pwtype && param->password))){
@ -847,9 +874,11 @@ int doauth(struct clientparam * param){
int ipauth(struct clientparam * param){
int res;
unsigned char *username;
if(param->preauthorized) return (0);
username = param->username;
param->username = NULL;
res = checkACL(param);
res = checkACL2(param,0);
param->username = username;
return res;
}
@ -960,20 +989,20 @@ int strongauth(struct clientparam * param){
int radauth(struct clientparam * param);
struct auth authfuncs[] = {
{authfuncs+1, NULL, NULL, ""},
{authfuncs+2, ipauth, NULL, "iponly"},
{authfuncs+3, userauth, checkACL, "useronly"},
{authfuncs+4, dnsauth, checkACL, "dnsname"},
{authfuncs+5, strongauth, checkACL, "strong"},
{authfuncs+6, cacheauth, checkACL, "cache"},
{authfuncs+1, NULL,NULL, NULL, ""},
{authfuncs+2, checkpreACL, ipauth, NULL, "iponly"},
{authfuncs+3, checkpreACL, userauth, checkACL, "useronly"},
{authfuncs+4, checkpreACL, dnsauth, checkACL, "dnsname"},
{authfuncs+5, checkpreACL, strongauth, checkACL, "strong"},
{authfuncs+6, checkpreACL, cacheauth, checkACL, "cache"},
#ifndef NORADIUS
#define AUTHOFFSET 1
{authfuncs+7, radauth, checkACL, "radius"},
{authfuncs+7, checkpreACL, radauth, checkACL, "radius"},
#else
#define AUTHOFFSET 0
#endif
{authfuncs+7+AUTHOFFSET, NULL, NULL, "none"},
{NULL, NULL, NULL, ""}
{authfuncs+7+AUTHOFFSET, NULL, NULL, NULL, "none"},
{NULL, NULL, NULL, NULL, ""}
};

View File

@ -578,6 +578,7 @@ int radsend(const char *buf, int total_length, int auth){
}
else remsock = radiuslist[loop].logsock;
*/
so._bind(param->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)){

View File

@ -292,7 +292,10 @@ int parsehostname(char *hostname, struct clientparam *param, unsigned short port
if(!hostname || !*hostname)return 2;
if(*hostname == '[') se=strchr(hostname, ']');
if ( (sp = strchr(se?se:hostname, ':')) && !strchr(sp+1, ':')) *sp = 0;
if (sp = strchr(se?se:hostname, ':')) {
if(strchr(sp+1, ':'))sp = NULL;
else *sp = 0;
}
if(se){
*se = 0;
}

View File

@ -481,6 +481,7 @@ static int h_auth(int argc, unsigned char **argv){
newau->next = conf.authfuncs;
conf.authfuncs = newau;
conf.authfuncs->desc = au->desc;
conf.authfuncs->preauthorize = au->preauthorize;
conf.authfuncs->authenticate = au->authenticate;
conf.authfuncs->authorize = au->authorize;
break;
@ -1329,13 +1330,19 @@ static int h_radius(int argc, unsigned char **argv){
if(strlen(argv[1]) > 63) argv[1][63] = 0;
strcpy(radiussecret, argv[1]);
for( nradservers=0; nradservers < MAXRADIUS && nradservers < argc -2; nradservers++){
char *s = 0;
if(strchr(argv[nradservers + 2], '/')){
*s = 0;
s++;
}
if( !getip46(46, argv[nradservers + 2], (struct sockaddr *)&radiuslist[nradservers].authaddr)) return 1;
if( s && !getip46(46, s, (struct sockaddr *)&radiuslist[nradservers].localaddr)) return 2;
if(!*SAPORT(&radiuslist[nradservers].authaddr))*SAPORT(&radiuslist[nradservers].authaddr) = htons(1812);
port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr));
radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr;
*SAPORT(&radiuslist[nradservers].logaddr) = htons(port+1);
/*
bindaddr = conf.intsa;
bindaddr = radiuslist[nradservers].localaddr;
if ((radiuslist[nradservers].logsock = so._socket(SASOCK(&radiuslist[nradservers].logaddr), SOCK_DGRAM, 0)) < 0) return 2;
if (so._bind(radiuslist[nradservers].logsock, (struct sockaddr *)&bindaddr, SASIZE(&bindaddr))) return 3;
*/

View File

@ -74,9 +74,10 @@ struct symbol symbols[] = {
{symbols+47, "parsestr", (void *) parsestr},
{symbols+48, "make_ace", (void *) make_ace},
{symbols+49, "freeacl", (void *) freeacl}
{symbols+50, "dolog", (void *) dolog},
{symbols+50, "logfuncs", (void *) logfuncs},
{symbols+50, "prelog", (void *) prelog},
{symbols+50, "checkpreACL", (void *) checkpreACL},
{symbols+51, "dolog", (void *) dolog},
{symbols+52, "logfuncs", (void *) logfuncs},
{symbols+53, "prelog", (void *) prelog},
{NULL, "", NULL}
};
@ -111,6 +112,7 @@ struct pluginlink pluginlink = {
ACLmatches,
alwaysauth,
checkACL,
checkpreACL,
nametohash,
hashindex,
en64,

View File

@ -494,6 +494,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink,
myalwaysauth.preauthorize = pluginlink->checkpreACL;
myalwaysauth.authenticate = ldapfunc;
myalwaysauth.authorize = pluginlink->checkACL;
myalwaysauth.desc = "ldap";

View File

@ -139,6 +139,7 @@ PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, unsigne
already_loaded = 1;
pthread_mutex_init(&pam_mutex, NULL);
pamauth.preauthorize = pluginlink->checkpreACL;
pamauth.authenticate = pamfunc;
pamauth.authorize = pluginlink->checkACL;
pamauth.desc = "pam";

View File

@ -78,6 +78,7 @@ PLUGINAPI int PLUGINCALL WindowsAuthentication(struct pluginlink * pluginlink, i
(LPTSTR) tmpbuf, &dlen, &snu)) return 100000 + (int)GetLastError();
if(snu != SidTypeGroup && snu != SidTypeAlias && snu != SidTypeWellKnownGroup) return 12;
if(!loaded){
alwaysauth.preauthorize = pluginlink->checkpreACL;
alwaysauth.authenticate = windowsfunc;
alwaysauth.authorize = pluginlink->checkACL;
alwaysauth.desc = "windows";

View File

@ -173,6 +173,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
int doconnect(struct clientparam * param);
int alwaysauth(struct clientparam * param);
int ipauth(struct clientparam * param);
int dopreauth(struct clientparam * param);
int doauth(struct clientparam * param);
int strongauth(struct clientparam * param);
void trafcountfunc(struct clientparam *param);
@ -236,10 +237,11 @@ int parseusername(char *username, struct clientparam *param, int extpasswd);
int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port);
int ACLmatches(struct ace* acentry, struct clientparam * param);
int checkACL(struct clientparam * param);
int checkpreACL(struct clientparam * param);
extern int havelog;
unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth);
struct ace * copyacl (struct ace *ac);
void copyacl (struct ace *ac, struct srvparam *srv);
struct auth * copyauth (struct auth *);
void * itfree(void *data, void * retval);
void freeacl(struct ace *ac);
@ -308,9 +310,9 @@ extern struct commands commandhandlers[];
extern struct radserver {
#ifdef NOIPV6
struct sockaddr_in authaddr, logaddr;
struct sockaddr_in authaddr, logaddr, localaddr;
#else
struct sockaddr_in6 authaddr, logaddr;
struct sockaddr_in6 authaddr, logaddr, localaddr;
#endif
/*
SOCKET logsock;

View File

@ -34,7 +34,7 @@ void * threadfunc (void *p) {
}
#ifndef WITHMAIN
param->req = param->sinsr;
if(param->srv->acl) param->res = checkACL(param);
if(param->srv->preacl) param->res = checkpreACL(param);
if(param->res){
dolog(param, (unsigned char *)"Connect back ACL failed");
so._closesocket(param->remsock);
@ -61,7 +61,7 @@ void * threadfunc (void *p) {
#ifndef _WIN32
sigset_t mask;
sigfillset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
if(param->srv->service != S_UDPPM)pthread_sigmask(SIG_SETMASK, &mask, NULL);
#endif
((struct clientparam *) p)->srv->pf((struct clientparam *)p);
@ -277,7 +277,7 @@ int MODULEMAINFUNC (int argc, char** argv){
srv.service = defparam.service = childdef.service;
#ifndef STDMAIN
srv.acl = copyacl(conf.acl);
copyacl(conf.acl, &srv);
srv.authfuncs = copyauth(conf.authfuncs);
if(!conf.services){
conf.services = &srv;
@ -286,11 +286,6 @@ int MODULEMAINFUNC (int argc, char** argv){
srv.next = conf.services;
conf.services = conf.services->prev = &srv;
}
#else
srv.needuser = 0;
initlog();
#endif
#ifndef _WIN32
{
sigset_t mask;
@ -298,6 +293,10 @@ int MODULEMAINFUNC (int argc, char** argv){
pthread_sigmask(SIG_SETMASK, &mask, NULL);
}
#endif
#else
srv.needuser = 0;
initlog();
#endif
for (i=1; i<argc; i++) {
if(*argv[i]=='-') {
@ -774,6 +773,13 @@ int MODULEMAINFUNC (int argc, char** argv){
else {
srv.fds.events = 0;
}
#ifndef STDMAIN
if((dopreauth(&defparam)) != 0){
if(!isudp) so._closesocket(new_sock);
continue;
}
#endif
if(! (newparam = myalloc (sizeof(defparam)))){
if(!isudp) so._closesocket(new_sock);
defparam.res = 21;
@ -784,6 +790,7 @@ int MODULEMAINFUNC (int argc, char** argv){
*newparam = defparam;
if(defparam.hostname)newparam->hostname=(unsigned char *)mystrdup((char *)defparam.hostname);
clearstat(newparam);
if(!isudp) newparam->clisock = new_sock;
#ifndef STDMAIN
if(makefilters(&srv, newparam) > CONTINUE){
@ -946,6 +953,7 @@ void srvfree(struct srvparam * srv){
}
if(srv->acl)freeacl(srv->acl);
if(srv->preacl)freeacl(srv->preacl);
if(srv->authfuncs)freeauth(srv->authfuncs);
#endif
pthread_mutex_destroy(&srv->counter_mutex);
@ -1036,16 +1044,17 @@ struct auth * copyauth (struct auth * authfuncs){
return newauth;
}
struct ace * copyacl (struct ace *ac){
struct ace * ret = NULL;
void copyacl (struct ace *ac, struct srvparam *srv){
struct iplist *ipl;
struct portlist *pl;
struct userlist *ul;
struct chain *ch;
struct period *pel;
struct hostname *hst;
int preacl = 1;
struct ace *acc;
ret = ac = itcopy(ac, sizeof(struct ace));
ac = itcopy(ac, sizeof(struct ace));
for( ; ac; ac = ac->next = itcopy(ac->next, sizeof(struct ace))){
ac->src = itcopy(ac->src, sizeof(struct iplist));
for(ipl = ac->src; ipl; ipl = ipl->next = itcopy(ipl->next, sizeof(struct iplist)));
@ -1069,8 +1078,21 @@ struct ace * copyacl (struct ace *ac){
if(ch->extpass)ch->extpass = (unsigned char*)mystrdup((char *)ch->extpass);
if(ch->exthost)ch->exthost = (unsigned char*)mystrdup((char *)ch->exthost);
}
if(preacl){
if(ac->dst || ac->ports || ac->users || ac->dstnames || ac->chains|| ac->action>1){
preacl = 0;
for(acc = srv->preacl; acc; acc=acc->next)if(acc->next == ac) {
acc->next = NULL;
break;
}
srv->acl = ac;
}
else {
if(!srv->preacl) srv->preacl = ac;
}
}
}
return ret;
}

View File

@ -8,6 +8,8 @@
#include "proxy.h"
#define MAXFAILATTEMPT 10
#ifdef WITHLOG
#if WITHLOG > 1
char logbuf[1024];
@ -57,6 +59,7 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
FILTER_ACTION action;
int res;
SASIZETYPE sasize;
int needaction = 0;
#ifdef WITHSPLICE
uint64_t inclientpipe = 0, inserverpipe = 0;
@ -120,17 +123,17 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
if(action != PASS) RETURN(19);
while(
((!CLIENTTERM) && (inserverbuf
((!CLIENTTERM) && fromserver && (inserverbuf
#ifdef WITHSPLICE
|| inserverpipe
#endif
|| (!SERVERTERM && fromserver)))
|| (!SERVERTERM )))
||
((!SERVERTERM) && (inclientbuf
((!SERVERTERM) && fromclient && (inclientbuf
#ifdef WITHSPLICE
|| inclientpipe
#endif
|| (!CLIENTTERM && fromclient)))
|| (!CLIENTTERM )))
){
@ -155,8 +158,12 @@ sprintf(logbuf, "int FROMCLIENT = %d, TOCLIENTBUF = %d, FROMCLIENTBUF = %d, TOSE
log(logbuf);
#endif
if(needaction > 2 && !sleeptime){
if(needaction > (MAXFAILATTEMPT+1)){RETURN (93);}
sleeptime = (1<<(needaction-2));
}
if(sleeptime > 0) {
if(sleeptime > (timeo * 1000)){RETURN (92);}
if(sleeptime > (timeo * 1000)){RETURN (93);}
memset(fds, 0, sizeof(fds));
fds[0].fd = param->clisock;
fds[1].fd = param->remsock;
@ -216,6 +223,7 @@ log("done send to server from buf");
sl1 = (*param->bandlimfunc)(param, 0, res);
if(sl1 > sleeptime) sleeptime = sl1;
}
needaction = 0;
continue;
}
}
@ -247,6 +255,7 @@ log("done send to client from buf");
param->srvoffset += res;
if(param->srvoffset == param->srvinbuf)param->srvoffset = param->srvinbuf =0;
if(param->srvinbuf < param->srvbufsize) TOSERVERBUF = 1;
needaction = 0;
continue;
}
}
@ -270,6 +279,7 @@ log("done send to server from pipe");
sl1 = (*param->bandlimfunc)(param, 0, res);
if(sl1 > sleeptime) sleeptime = sl1;
}
needaction = 0;
continue;
}
else {
@ -288,6 +298,7 @@ log("done send to client from pipe");
inserverpipe -= res;
fromserver -= res;
if(fromserver)TOSERVERPIPE = 1;
needaction = 0;
continue;
}
else {
@ -306,6 +317,10 @@ log("read from client to pipe");
log("read failed");
#endif
FROMCLIENT = TOCLIENTPIPE = 0;
if(res == 0) {
CLIENTTERM = 1;
continue;
}
}
else {
#ifdef WITHLOG
@ -313,6 +328,7 @@ log("done read from client to pipe");
#endif
inclientpipe += res;
if(inclientpipe >= MAXSPLICE) TOCLIENTPIPE = 0;
needaction = 0;
continue;
}
}
@ -328,6 +344,10 @@ log("splice finished\n");
#endif
if(res <= 0) {
FROMSERVER = TOSERVERPIPE = 0;
if(res == 0 || !errno) {
SERVERTERM = 1;
continue;
}
}
else {
#ifdef WITHLOG
@ -346,10 +366,11 @@ log("done read from server to pipe\n");
fromserver = inserverpipe;
FROMSERVER = 0;
}
}
needaction = 0;
continue;
}
}
}
else
#endif
{
@ -360,8 +381,11 @@ log("read from client to buf");
sasize = sizeof(param->sincr);
res = so._recvfrom(param->clisock, (char *)param->clibuf + param->cliinbuf, (int)MIN((uint64_t)param->clibufsize - param->cliinbuf, fromclient-inclientbuf), 0, (struct sockaddr *)&param->sincr, &sasize);
if(res <= 0) {
if(!errno)CLIENTTERM = 1;
FROMCLIENT = 0;
if(res == 0){
CLIENTTERM = 1;
continue;
}
}
else {
#ifdef WITHLOG
@ -370,6 +394,7 @@ log("done read from client to buf");
inclientbuf += res;
param->cliinbuf += res;
if(param->clibufsize == param->cliinbuf) TOCLIENTBUF = 0;
needaction = 0;
continue;
}
}
@ -381,8 +406,11 @@ log("read from server to buf");
sasize = sizeof(param->sinsr);
res = so._recvfrom(param->remsock, (char *)param->srvbuf + param->srvinbuf, (int)MIN((uint64_t)param->srvbufsize - param->srvinbuf, fromserver-inserverbuf), 0, (struct sockaddr *)&param->sinsr, &sasize);
if(res <= 0) {
if(!errno) SERVERTERM = 1;
FROMSERVER = 0;
if(res == 0) {
SERVERTERM = 1;
continue;
}
}
else {
#ifdef WITHLOG
@ -402,6 +430,7 @@ log("done read from server to buf");
fromserver = inserverbuf;
FROMSERVER = 0;
}
needaction = 0;
continue;
}
}
@ -639,7 +668,7 @@ log("leaving poll");
#ifdef WITHLOG
log("poll error");
#endif
if(errno != EAGAIN && errno != EINTR) RETURN(91);
if(errno != EINTR) RETURN(91);
break;
}
if(res < 1){
@ -650,14 +679,15 @@ log("timeout");
}
}
}
needaction++;
}
res = 0;
if(!fromserver && param->waitserver64) res = 98;
else if(!fromclient && param->waitclient64) res = 99;
else if((inclientbuf || inserverbuf)) res = HASERROR?93:94;
else if((inclientbuf || inserverbuf)) res = 94;
#ifdef WITHSPLICE
else if(inclientpipe || inserverpipe) res = HASERROR?93:94;
else if(inclientpipe || inserverpipe) res = 94;
#endif
else if(HASERROR) res = 94+HASERROR;

View File

@ -215,6 +215,7 @@ typedef int (*PLUGINFUNC)(struct pluginlink *pluginlink, int argc, char** argv);
struct auth {
struct auth *next;
AUTHFUNC preauthorize;
AUTHFUNC authenticate;
AUTHFUNC authorize;
char * desc;
@ -477,7 +478,7 @@ struct srvparam {
#endif
struct auth *authenticate;
struct pollfd * srvfds;
struct ace *acl;
struct ace *preacl, *acl;
struct auth *authfuncs;
struct filter *filter;
unsigned char * logformat;
@ -519,6 +520,7 @@ struct clientparam {
operation,
nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv,
unsafefilter,
preauthorized,
bandlimver;
int res,
@ -759,6 +761,7 @@ struct pluginlink {
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
int (*alwaysauth)(struct clientparam * param);
int (*checkACL)(struct clientparam * param);
int (*checkpreACL)(struct clientparam * param);
void (*nametohash)(const unsigned char * name, unsigned char *hash);
unsigned (*hashindex)(const unsigned char* hash);
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);

View File

@ -16,7 +16,7 @@
void * tcppmchild(struct clientparam* param) {
int res;
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
if(!param->hostname && parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) RETURN(100);
param->operation = CONNECT;
res = (*param->srv->authfunc)(param);
if(res) {RETURN(res);}

View File

@ -38,7 +38,7 @@ void * udppmchild(struct clientparam* param) {
struct pollfd fds[256];
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
if(!param->hostname && parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) RETURN(100);
if (SAISNULL(&param->req)) {
param->srv->fds.events = POLLIN;
RETURN (100);