udppm switched to hashtable and supports multiple connections; no standalone udppm

This commit is contained in:
Vladimir Dubrovin 2026-04-27 15:12:39 +03:00
parent 7ddea44ffd
commit d52701518d
11 changed files with 203 additions and 198 deletions

View File

@ -416,7 +416,7 @@ target_include_directories(3proxy_crypt PRIVATE
target_link_libraries(3proxy_crypt PRIVATE Threads::Threads)
# Build standalone proxy executables
foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm tlspr)
if(PROXY_NAME STREQUAL "ftppr" OR PROXY_NAME STREQUAL "proxy")
# ftppr and proxy use ftp_obj
add_executable(${PROXY_NAME}
@ -500,7 +500,7 @@ if(PAM_FOUND)
endif()
# Installation rules
install(TARGETS 3proxy 3proxy_crypt proxy socks pop3p smtpp ftppr tcppm udppm tlspr
install(TARGETS 3proxy 3proxy_crypt proxy socks pop3p smtpp ftppr tcppm tlspr
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View File

@ -511,7 +511,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
pthread_mutex_init(&config_mutex, NULL);
pthread_mutex_init(&bandlim_mutex, NULL);
pthread_mutex_init(&connlim_mutex, NULL);
pthread_mutex_init(&hash_mutex, NULL);
pthread_mutex_init(&tc_mutex, NULL);
pthread_mutex_init(&log_mutex, NULL);
#ifndef NORADIUS

View File

@ -2,7 +2,7 @@
# 3 proxy common Makefile
#
all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)3proxy_crypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)tlspr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)3proxy_crypt$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)tlspr$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
@ -48,9 +48,6 @@ tlspr$(OBJSUFFICS): tlspr.c proxy.h structures.h proxymain.c
socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c
udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP udppm.c
3proxy$(OBJSUFFICS): 3proxy.c proxy.h structures.h
$(CC) $(CFLAGS) 3proxy.c
@ -75,14 +72,9 @@ $(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcp
$(BUILDDIR)tlspr$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tlspr$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)tlspr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tlspr$(OBJSUFFICS) log$(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)
mainfunc$(OBJSUFFICS): proxy.h structures.h proxymain.c
$(CC) $(COUT)mainfunc$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)MODULEMAINFUNC=mainfunc proxymain.c
srvproxy$(OBJSUFFICS): proxy.c proxy.h structures.h
$(CC) $(COUT)srvproxy$(OBJSUFFICS) $(CFLAGS) proxy.c

View File

@ -23,7 +23,6 @@
pthread_mutex_t bandlim_mutex;
pthread_mutex_t connlim_mutex;
pthread_mutex_t tc_mutex;
pthread_mutex_t hash_mutex;
pthread_mutex_t config_mutex;
int haveerror = 0;
@ -445,18 +444,6 @@ static int h_counter(int argc, unsigned char **argv){
fprintf(stderr, "Not a counter file %s, line %d\n", argv[1], linenum);
return 2;
}
#ifdef _TIME64_T_DEFINED
#ifdef _MAX__TIME64_T
#define MAX_COUNTER_TIME (_MAX__TIME64_T)
#elif defined (MAX__TIME64_T)
#define MAX_COUNTER_TIME (MAX__TIME64_T)
#else
#define MAX_COUNTER_TIME (0x793406fff)
#endif
#else
#define MAX_COUNTER_TIME ((sizeof(time_t)>4)?(time_t)0x793406fff:(time_t)0x7fffffff)
#endif
if(ch1.updated < 0 || ch1.updated >= MAX_COUNTER_TIME){
fprintf(stderr, "Invalid or corrupted counter file %s. Use countersutil utility to convert from older version\n", argv[1]);
return 3;

View File

@ -1,7 +1,6 @@
#include "proxy.h"
#include "libs/blake2.h"
struct hashentry {
time_t expires;
uint32_t inext;
@ -14,7 +13,7 @@ static uint32_t hashindex(unsigned tablesize, const uint8_t* hash){
void destroyhashtable(struct hashtable *ht){
pthread_mutex_lock(&hash_mutex);
pthread_mutex_lock(&ht->hash_mutex);
if(ht->ihashtable){
myfree(ht->ihashtable);
ht->ihashtable = NULL;
@ -30,7 +29,8 @@ void destroyhashtable(struct hashtable *ht){
ht->poolsize = 0;
ht->tablesize = 0;
ht->ihashempty = 0;
pthread_mutex_unlock(&hash_mutex);
pthread_mutex_unlock(&ht->hash_mutex);
pthread_mutex_destroy(&ht->hash_mutex);
}
#define hvalue(ht,I) ((struct hashentry *)(ht->hashvalues + (I-1)*(sizeof(struct hashentry) + ht->recsize - 4)))
@ -53,21 +53,27 @@ int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, u
c = clock();
if(tablesize < 2 || poolsize < tablesize || growlimit < poolsize) return 1;
pthread_mutex_lock(&hash_mutex);
if(ht->ihashtable){
myfree(ht->ihashtable);
ht->ihashtable = NULL;
pthread_mutex_lock(&ht->hash_mutex);
if(ht->ihashtable){
myfree(ht->ihashtable);
ht->ihashtable = NULL;
}
if(ht->hashvalues){
myfree(ht->hashvalues);
ht->hashvalues = NULL;
}
if(ht->hashhashvalues){
myfree(ht->hashhashvalues);
ht->hashhashvalues = NULL;
}
ht->poolsize = 0;
ht->tablesize = 0;
}
if(ht->hashvalues){
myfree(ht->hashvalues);
ht->hashvalues = NULL;
else {
pthread_mutex_init(&ht->hash_mutex, NULL);
pthread_mutex_lock(&ht->hash_mutex);
}
if(ht->hashhashvalues){
myfree(ht->hashhashvalues);
ht->hashhashvalues = NULL;
}
ht->poolsize = 0;
ht->tablesize = 0;
if(!(ht->ihashtable = myalloc(tablesize * sizeof(uint32_t)))
|| !(ht->hashvalues = myalloc(poolsize * (sizeof(struct hashentry) + (ht->recsize-4))))
|| !(ht->hashhashvalues = myalloc(poolsize * ht->hash_size))
@ -76,7 +82,7 @@ int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, u
ht->ihashtable = NULL;
myfree(ht->hashvalues);
ht->hashvalues = NULL;
pthread_mutex_unlock(&hash_mutex);
pthread_mutex_unlock(&ht->hash_mutex);
return 3;
}
ht->poolsize = poolsize;
@ -89,7 +95,7 @@ int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, u
hvalue(ht,i)->inext = i+1;
}
ht->ihashempty = 1;
pthread_mutex_unlock(&hash_mutex);
pthread_mutex_unlock(&ht->hash_mutex);
return 0;
}
@ -174,7 +180,7 @@ void hashadd(struct hashtable *ht, void* name, void* value, time_t expires){
}
ht->index2hash_add(ht, name, hash);
pthread_mutex_lock(&hash_mutex);
pthread_mutex_lock(&ht->hash_mutex);
index = hashindex(ht->tablesize, hash);
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
@ -209,7 +215,7 @@ void hashadd(struct hashtable *ht, void* name, void* value, time_t expires){
hvalue(ht,hen)->expires = expires;
}
pthread_mutex_unlock(&hash_mutex);
pthread_mutex_unlock(&ht->hash_mutex);
}
int hashresolv(struct hashtable *ht, void* name, void* value, uint32_t *ttl){
@ -222,7 +228,7 @@ int hashresolv(struct hashtable *ht, void* name, void* value, uint32_t *ttl){
return 0;
}
ht->index2hash_search(ht,name, hash);
pthread_mutex_lock(&hash_mutex);
pthread_mutex_lock(&ht->hash_mutex);
index = hashindex(ht->tablesize, hash);
for(hep = ht->ihashtable + index; (he = *hep)!=0; ){
if(hvalue(ht, he)->expires < conf.time) {
@ -234,15 +240,39 @@ int hashresolv(struct hashtable *ht, void* name, void* value, uint32_t *ttl){
else if(!memcmp(hash, hhash(ht,he), ht->hash_size)){
if(ttl) *ttl = (uint32_t)(hvalue(ht,he)->expires - conf.time);
memcpy(value, hvalue(ht,he)->value, ht->recsize);
pthread_mutex_unlock(&hash_mutex);
pthread_mutex_unlock(&ht->hash_mutex);
return 1;
}
else hep=&(hvalue(ht,he)->inext);
}
pthread_mutex_unlock(&hash_mutex);
pthread_mutex_unlock(&ht->hash_mutex);
return 0;
}
void hashdelete(struct hashtable *ht, void *name){
uint8_t hash[MAX_HASH_SIZE];
uint32_t *hep;
uint32_t he;
uint32_t index;
if(!ht || !ht->ihashtable || !name) {
return;
}
ht->index2hash_search(ht, name, hash);
pthread_mutex_lock(&ht->hash_mutex);
index = hashindex(ht->tablesize, hash);
for(hep = ht->ihashtable + index; (he = *hep) != 0; ){
if((hvalue(ht, he)->expires && hvalue(ht, he)->expires < conf.time) || !memcmp(hash, hhash(ht, he), ht->hash_size)) {
(*hep) = hvalue(ht, he)->inext;
hvalue(ht, he)->expires = 0;
hvalue(ht, he)->inext = ht->ihashempty;
ht->ihashempty = he;
}
else hep = &(hvalue(ht, he)->inext);
}
pthread_mutex_unlock(&ht->hash_mutex);
}
static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *hash){
char* name = index;
@ -269,6 +299,28 @@ static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *has
memcpy(param->hash, hash, ht->hash_size);
}
void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
memcpy(hash, param->hash, ht->hash_size);
}
static void user2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
blake2b(hash, ht->hash_size, param->username, strlen((const char *)param->username), NULL, 0);
}
static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
blake2b_state S;
blake2b_init(&S, ht->hash_size);
blake2b_update(&S, SAADDR(&param->srv->intsa), SAADDRLEN(&param->srv->intsa));
blake2b_update(&S, SAPORT(&param->srv->intsa), 2);
blake2b_update(&S, SAADDR(&param->sincr), SAADDRLEN(&param->sincr));
blake2b_update(&S, SAPORT(&param->sincr), 2);
blake2b_final(&S, hash, ht->hash_size);
}
static void pw2hash_add(const struct hashtable *ht, void *index, uint8_t *hash){
char ** pw = (char **)index;
blake2b_state S;
@ -308,18 +360,7 @@ static void pwnt2hash_search(const struct hashtable *ht, void *index, uint8_t *h
pwnt2hash_add(ht, pw, hash);
}
void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
memcpy(hash, param->hash, ht->hash_size);
}
static void user2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
blake2b(hash, ht->hash_size, param->username, strlen((const char *)param->username), NULL, 0);
}
struct hashtable dns_table = {char_index2hash, char_index2hash, 4, 12};
struct hashtable dns6_table = {char_index2hash, char_index2hash, 16, 12};
@ -327,3 +368,4 @@ struct hashtable auth_table = {param2hash_add, param2hash_search, sizeof(struct
struct hashtable pw_table = {pw2hash_add, pw2hash_search, 0, 12};
struct hashtable pwnt_table = {pwnt2hash_add, pwnt2hash_search, 0, 12};
struct hashtable pwcr_table = {char_index2hash, user2hash_search, 64, 12};
struct hashtable udp_table = {udpparam2hash, udpparam2hash, sizeof(struct clientparam *), 12};

View File

@ -47,31 +47,30 @@ struct symbol symbols[] = {
{symbols+22, "udpresolve", (void *) udpresolve},
{symbols+23, "bandlim_mutex", (void *) &bandlim_mutex},
{symbols+24, "tc_mutex", (void *) &tc_mutex},
{symbols+25, "hash_mutex", (void *) &hash_mutex},
{symbols+26, "linenum", (void *) &linenum},
{symbols+27, "proxy_stringtable", (void *) proxy_stringtable},
{symbols+28, "en64", (void *) en64},
{symbols+29, "de64", (void *) de64},
{symbols+30, "tohex", (void *) tohex},
{symbols+31, "fromhex", (void *) fromhex},
{symbols+32, "dnspr", (void *) dnsprchild},
{symbols+33, "pop3p", (void *) pop3pchild},
{symbols+34, "proxy", (void *) proxychild},
{symbols+35, "socks", (void *) sockschild},
{symbols+36, "tcppm", (void *) tcppmchild},
{symbols+37, "udppm", (void *) udppmchild},
{symbols+38, "admin", (void *) adminchild},
{symbols+39, "ftppr", (void *) ftpprchild},
{symbols+40, "smtpp", (void *) smtppchild},
{symbols+41, "auto", (void *) smtppchild},
{symbols+42, "tlspr", (void *) smtppchild},
{symbols+43, "authfuncs", (void *) &authfuncs},
{symbols+44, "commandhandlers", (void *) &commandhandlers},
{symbols+45, "decodeurl", (void *) decodeurl},
{symbols+46, "parsestr", (void *) parsestr},
{symbols+47, "make_ace", (void *) make_ace},
{symbols+48, "freeacl", (void *) freeacl},
{symbols+49, "handleredirect", (void *) handleredirect},
{symbols+25, "linenum", (void *) &linenum},
{symbols+26, "proxy_stringtable", (void *) proxy_stringtable},
{symbols+27, "en64", (void *) en64},
{symbols+28, "de64", (void *) de64},
{symbols+29, "tohex", (void *) tohex},
{symbols+30, "fromhex", (void *) fromhex},
{symbols+31, "dnspr", (void *) dnsprchild},
{symbols+32, "pop3p", (void *) pop3pchild},
{symbols+33, "proxy", (void *) proxychild},
{symbols+34, "socks", (void *) sockschild},
{symbols+35, "tcppm", (void *) tcppmchild},
{symbols+36, "udppm", (void *) udppmchild},
{symbols+37, "admin", (void *) adminchild},
{symbols+38, "ftppr", (void *) ftpprchild},
{symbols+39, "smtpp", (void *) smtppchild},
{symbols+40, "auto", (void *) smtppchild},
{symbols+41, "tlspr", (void *) smtppchild},
{symbols+42, "authfuncs", (void *) &authfuncs},
{symbols+43, "commandhandlers", (void *) &commandhandlers},
{symbols+44, "decodeurl", (void *) decodeurl},
{symbols+45, "parsestr", (void *) parsestr},
{symbols+46, "make_ace", (void *) make_ace},
{symbols+47, "freeacl", (void *) freeacl},
{symbols+48, "handleredirect", (void *) handleredirect},
{NULL, "", NULL}
};

View File

@ -146,6 +146,18 @@ void daemonize(void);
#define myrealloc realloc
#define mystrdup strdup
#ifdef _TIME64_T_DEFINED
#ifdef _MAX__TIME64_T
#define MAX_COUNTER_TIME (_MAX__TIME64_T)
#elif defined (MAX__TIME64_T)
#define MAX_COUNTER_TIME (MAX__TIME64_T)
#else
#define MAX_COUNTER_TIME (0x793406fff)
#endif
#else
#define MAX_COUNTER_TIME ((sizeof(time_t)>4)?(time_t)0x793406fff:(time_t)0x7fffffff)
#endif
extern RESOLVFUNC resolvfunc;
extern int wday;
@ -246,6 +258,7 @@ void mschap(const unsigned char *win_password,
void destroyhashtable(struct hashtable *ht);
int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, unsigned growlimit);
void hashadd(struct hashtable *ht, void* name, void* value, time_t expires);
void hashdelete(struct hashtable *ht, void* name);
int hashresolv(struct hashtable *ht, void* name, void* value, uint32_t *ttl);
int parsehost(int family, unsigned char *host, struct sockaddr *sa);
@ -312,7 +325,6 @@ struct property;
extern pthread_mutex_t config_mutex;
extern pthread_mutex_t bandlim_mutex;
extern pthread_mutex_t connlim_mutex;
extern pthread_mutex_t hash_mutex;
extern pthread_mutex_t tc_mutex;
extern pthread_mutex_t log_mutex;
extern pthread_mutex_t rad_mutex;

View File

@ -251,6 +251,8 @@ int MODULEMAINFUNC (int argc, char** argv){
unsigned char buf[256];
char *hostname=NULL;
int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
unsigned char udpbuf[UDPBUFSIZE];
int udplen = 0;
unsigned char *cbc_string = NULL, *cbl_string = NULL;
PROXYSOCKADDRTYPE cbsa;
FILE *fp = NULL;
@ -336,6 +338,11 @@ int MODULEMAINFUNC (int argc, char** argv){
srvinit(&srv, &defparam);
srv.pf = childdef.pf;
isudp = childdef.isudp;
#ifndef STDMAIN
if(isudp) {
if(!udp_table.ihashtable)inithashtable(&udp_table, 64, 256, 65536);
}
#endif
srv.service = defparam.service = childdef.service;
#ifndef STDMAIN
@ -900,9 +907,22 @@ int MODULEMAINFUNC (int argc, char** argv){
srv.so._setsockopt(srv.so.state, new_sock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
srv.so._setsockopt(srv.so.state, new_sock, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
}
#ifndef STDMAIN
else {
srv.fds.events = 0;
struct clientparam *toparam;
udplen = sockrecvfrom(NULL, srv.srvsock, (struct sockaddr *)&defparam.sincr, udpbuf, UDPBUFSIZE, 0);
if(udplen <= 0) continue;
pthread_mutex_lock(&srv.counter_mutex);
if(hashresolv(&udp_table, &defparam, &toparam, NULL)) {
socksendto(toparam, toparam->remsock, (struct sockaddr *)&toparam->sinsr, udpbuf, udplen, 0);
toparam->statscli64 += udplen;
toparam->nwrites++;
pthread_mutex_unlock(&srv.counter_mutex);
continue;
}
pthread_mutex_unlock(&srv.counter_mutex);
}
#endif
if(! (newparam = myalloc (sizeof(defparam)))){
if(!isudp) srv.so._closesocket(srv.so.state, new_sock);
defparam.res = 21;
@ -916,9 +936,36 @@ int MODULEMAINFUNC (int argc, char** argv){
if(!isudp) newparam->clisock = new_sock;
#ifndef STDMAIN
if(makefilters(&srv, newparam) > CONTINUE){
freeparam(newparam);
freeparam(newparam);
continue;
}
if(isudp) {
int authres;
if(parsehostname((char *)srv.target, newparam, ntohs(srv.targetport))) { freeparam(newparam); continue; }
#ifndef NOIPV6
memcpy(&newparam->sinsl, *SAFAMILY(&newparam->req) == AF_INET6 ? (struct sockaddr *)&srv.extsa6 : (struct sockaddr *)&srv.extsa, SASIZE(&newparam->req));
#else
memcpy(&newparam->sinsl, (struct sockaddr *)&srv.extsa, SASIZE(&newparam->req));
#endif
*SAPORT(&newparam->sinsl) = 0;
newparam->remsock = srv.so._socket(srv.so.state, SASOCK(&newparam->sinsl), SOCK_DGRAM, IPPROTO_UDP);
if(newparam->remsock == INVALID_SOCKET) { freeparam(newparam); continue; }
if(srv.so._bind(srv.so.state, newparam->remsock, (struct sockaddr *)&newparam->sinsl, SASIZE(&newparam->sinsl))) { freeparam(newparam); continue; }
#ifdef _WIN32
{ unsigned long ul2 = 1; ioctlsocket(newparam->remsock, FIONBIO, &ul2); }
#else
fcntl(newparam->remsock, F_SETFL, O_NONBLOCK | fcntl(newparam->remsock, F_GETFL));
#endif
memcpy(&newparam->sinsr, &newparam->req, sizeof(newparam->req));
newparam->operation = UDPASSOC;
authres = (*srv.authfunc)(newparam);
if(authres) { freeparam(newparam); continue; }
if(!srv.singlepacket)hashadd(&udp_table, newparam, &newparam, MAX_COUNTER_TIME);
socksendto(newparam, newparam->remsock, (struct sockaddr *)&newparam->sinsr, udpbuf, udplen, 0);
newparam->statscli64 += udplen;
newparam->nwrites++;
}
#endif
newparam->prev = newparam->next = NULL;
error = 0;
@ -963,7 +1010,6 @@ int MODULEMAINFUNC (int argc, char** argv){
memset(&defparam.sincl, 0, sizeof(defparam.sincl));
memset(&defparam.sincr, 0, sizeof(defparam.sincr));
if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
}
@ -1101,6 +1147,23 @@ void srvfree(struct srvparam * srv){
void freeparam(struct clientparam * param) {
if(param->res == 2) return;
if(param->srv){
if(param->srv->so.freefunc) param->srv->so.freefunc(param->sostate);
pthread_mutex_lock(&param->srv->counter_mutex);
#ifndef STDMAIN
if(param->srv->service == S_UDPPM) hashdelete(&udp_table, param);
#endif
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->clibuf) myfree(param->clibuf);
if(param->srvbuf) myfree(param->srvbuf);
if(param->ctrlsocksrv != INVALID_SOCKET && param->ctrlsocksrv != param->remsock) {
@ -1137,20 +1200,6 @@ void freeparam(struct clientparam * param) {
}
if(param->connlim) stopconnlims(param);
#endif
if(param->srv){
if(param->srv->so.freefunc) param->srv->so.freefunc(param->sostate);
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);

View File

@ -95,10 +95,6 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
TOSERVER = 0;
FROMCLIENT = 0;
}
if(param->operation == UDPASSOC && param->srv->singlepacket){
fromclient = inclientbuf;
FROMCLIENT = 0;
}
if(inserverbuf >= fromserver) FROMSERVER = 0;
if(inclientbuf >= fromclient) FROMCLIENT = 0;
#ifdef WITHSPLICE
@ -279,6 +275,7 @@ log("done send to client from buf");
if(param->srvoffset == param->srvinbuf)param->srvoffset = param->srvinbuf =0;
if(param->srvinbuf < param->srvbufsize) TOSERVERBUF = 1;
needaction = 0;
if(param->srv->singlepacket) RETURN(0);
continue;
}
}
@ -417,10 +414,6 @@ log("done read from server to pipe\n");
sl1 = (*param->bandlimfunc)(param, res, 0);
if(sl1 > sleeptime) sleeptime = sl1;
}
if(param->operation == UDPASSOC && param->srv->singlepacket){
fromserver = inserverpipe;
FROMSERVER = 0;
}
needaction = 0;
continue;
}
@ -487,10 +480,6 @@ log("done read from server to buf");
if(sl1 > sleeptime) sleeptime = sl1;
}
if(param->srvbufsize == param->srvinbuf) TOSERVERBUF = 0;
if(param->operation == UDPASSOC && param->srv->singlepacket){
fromserver = inserverbuf;
FROMSERVER = 0;
}
needaction = 0;
continue;
}

View File

@ -500,6 +500,23 @@ struct sockfuncs {
extern struct sockfuncs so;
struct hashtable {
void (*index2hash_add)(const struct hashtable *ht, void *index, uint8_t *hash);
void (*index2hash_search)(const struct hashtable *ht, void *index, uint8_t *hash);
unsigned recsize;
unsigned hash_size;
unsigned poolsize;
unsigned tablesize;
unsigned growlimit;
uint32_t * ihashtable;
uint8_t * hashvalues;
uint8_t * hashhashvalues;
pthread_mutex_t hash_mutex;
time_t compacted;
uint32_t ihashhashempty;
uint32_t ihashempty;
};
struct srvparam {
struct sockfuncs so;
struct srvparam *next;
@ -760,28 +777,13 @@ struct child {
};
struct hashtable {
void (*index2hash_add)(const struct hashtable *ht, void *index, uint8_t *hash);
void (*index2hash_search)(const struct hashtable *ht, void *index, uint8_t *hash);
unsigned recsize;
unsigned hash_size;
unsigned poolsize;
unsigned tablesize;
unsigned growlimit;
uint32_t * ihashtable;
uint8_t * hashvalues;
uint8_t * hashhashvalues;
time_t compacted;
uint32_t ihashhashempty;
uint32_t ihashempty;
};
extern struct hashtable dns_table;
extern struct hashtable dns6_table;
extern struct hashtable auth_table;
extern struct hashtable pw_table;
extern struct hashtable pwnt_table;
extern struct hashtable pwcr_table;
extern struct hashtable udp_table;
struct authcache {
unsigned char username[64];

View File

@ -18,81 +18,15 @@
void * udppmchild(struct clientparam* param) {
unsigned char *buf = NULL;
int res, i;
#ifdef _WIN32
SASIZETYPE size;
unsigned long ul = 1;
#endif
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);
}
if(!param->clibuf && (!(param->clibuf=myalloc(UDPBUFSIZE)) || !(param->clibufsize = UDPBUFSIZE))){
param->srv->fds.events = POLLIN;
RETURN (21);
}
param->cliinbuf = param->clioffset = 0;
i = sockrecvfrom(param, param->srv->srvsock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, 0);
if(i<=0){
param->srv->fds.events = POLLIN;
RETURN (214);
}
param->cliinbuf = i;
#ifdef _WIN32
if((param->clisock=param->srv->so._socket(param->sostate, SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
RETURN(818);
}
if(param->srv->so._setsockopt(param->sostate, param->clisock, SOL_SOCKET, SO_REUSEADDR, (char *)&ul, sizeof(int))) {RETURN(820);};
ul = 1;
ioctlsocket(param->clisock, FIONBIO, &ul);
size = sizeof(param->sinsl);
if(param->srv->so._getsockname(param->sostate, param->srv->srvsock, (struct sockaddr *)&param->sinsl, &size)) {RETURN(21);};
if(param->srv->so._bind(param->sostate, param->clisock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {
RETURN(822);
}
#else
param->clisock = param->srv->srvsock;
#endif
#ifndef NOIPV6
memcpy(&param->sinsl, *SAFAMILY(&param->req) == AF_INET? (struct sockaddr *)&param->srv->extsa : (struct sockaddr *)&param->srv->extsa6, SASIZE(&param->req));
#else
memcpy(&param->sinsl, &param->srv->extsa, SASIZE(&param->req));
#endif
*SAPORT(&param->sinsl) = 0;
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {RETURN (12);}
#ifdef _WIN32
ul = 1;
ioctlsocket(param->remsock, FIONBIO, &ul);
#else
fcntl(param->remsock,F_SETFL,O_NONBLOCK | fcntl(param->remsock,F_GETFL));
#endif
memcpy(&param->sinsr, &param->req, sizeof(param->req));
param->operation = UDPASSOC;
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
if(param->srv->singlepacket) {
param->srv->fds.events = POLLIN;
}
param->res = mapsocket(param, conf.timeouts[(param->srv->singlepacket)?SINGLEBYTE_L:STRING_L]);
if(!param->srv->singlepacket) {
param->srv->fds.events = POLLIN;
}
param->clisock = param->srv->srvsock;
param->waitserver64 = 0x7fffffffffffffff;
param->res = mapsocket(param, conf.timeouts[STRING_L]);
CLEANRET:
if(buf)myfree(buf);
dolog(param, NULL);
#ifndef _WIN32
param->clisock = INVALID_SOCKET;
#endif
freeparam(param);
return (NULL);
}