diff --git a/CMakeLists.txt b/CMakeLists.txt index 32d6a81..72bf6c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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} ) diff --git a/src/3proxy.c b/src/3proxy.c index ee11857..9b8e848 100644 --- a/src/3proxy.c +++ b/src/3proxy.c @@ -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 diff --git a/src/Makefile.inc b/src/Makefile.inc index ff8cb83..bf9a610 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -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 diff --git a/src/conf.c b/src/conf.c index a4105db..2ddf645 100644 --- a/src/conf.c +++ b/src/conf.c @@ -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; diff --git a/src/hash.c b/src/hash.c index eced1fe..2b95182 100644 --- a/src/hash.c +++ b/src/hash.c @@ -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(¶m->srv->intsa), SAADDRLEN(¶m->srv->intsa)); + blake2b_update(&S, SAPORT(¶m->srv->intsa), 2); + blake2b_update(&S, SAADDR(¶m->sincr), SAADDRLEN(¶m->sincr)); + blake2b_update(&S, SAPORT(¶m->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}; diff --git a/src/plugins.c b/src/plugins.c index 1f96b7d..8f33e35 100644 --- a/src/plugins.c +++ b/src/plugins.c @@ -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} }; diff --git a/src/proxy.h b/src/proxy.h index be17d31..4b2ffd4 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -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; diff --git a/src/proxymain.c b/src/proxymain.c index 323dfcf..0aa4e67 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -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(¶m->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(¶m->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(¶m->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(¶m->srv->counter_mutex); - } if(param->hostname) myfree(param->hostname); if(param->username) myfree(param->username); if(param->password) myfree(param->password); diff --git a/src/sockmap.c b/src/sockmap.c index b6c0056..b61182c 100644 --- a/src/sockmap.c +++ b/src/sockmap.c @@ -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; } diff --git a/src/structures.h b/src/structures.h index f189551..969ca07 100644 --- a/src/structures.h +++ b/src/structures.h @@ -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]; diff --git a/src/udppm.c b/src/udppm.c index aedad14..7cf02dc 100644 --- a/src/udppm.c +++ b/src/udppm.c @@ -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(¶m->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 *)¶m->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(¶m->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 *)¶m->sinsl, &size)) {RETURN(21);}; - if(param->srv->so._bind(param->sostate, param->clisock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) { - RETURN(822); - } -#else - param->clisock = param->srv->srvsock; -#endif - -#ifndef NOIPV6 - memcpy(¶m->sinsl, *SAFAMILY(¶m->req) == AF_INET? (struct sockaddr *)¶m->srv->extsa : (struct sockaddr *)¶m->srv->extsa6, SASIZE(¶m->req)); -#else - memcpy(¶m->sinsl, ¶m->srv->extsa, SASIZE(¶m->req)); -#endif - *SAPORT(¶m->sinsl) = 0; - if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(¶m->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} - if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->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(¶m->sinsr, ¶m->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); }