mirror of
https://github.com/3proxy/3proxy.git
synced 2026-05-13 13:30:12 +08:00
Fix UDP parent for SOCKSv5
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
This commit is contained in:
parent
07c1dc1462
commit
4068a6955f
@ -10,10 +10,10 @@ CRYPT_PREFIX ?= $(PREFIX)
|
||||
MANDIR ?= /usr/share/man
|
||||
CC ?= cc
|
||||
|
||||
CFLAGS := -c -fno-strict-aliasing -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_UN $(CFLAGS)
|
||||
CFLAGS := -c -O3 -fno-strict-aliasing -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_UN $(CFLAGS)
|
||||
COUT = -o
|
||||
LN ?= ${CC}
|
||||
LDFLAGS += -pthread -fno-strict-aliasing
|
||||
LDFLAGS += -g -flto -pthread -fno-strict-aliasing
|
||||
# -lpthreads may be reuiured on some platforms instead of -pthreads
|
||||
# -ldl or -lld may be required for some platforms
|
||||
DCFLAGS ?= -fPIC
|
||||
|
||||
@ -9,11 +9,11 @@ PREFIX ?= 3proxy_
|
||||
CRYPT_PREFIX ?= $(PREFIX)
|
||||
CC ?= gcc
|
||||
|
||||
CFLAGS := -g -fPIC -O2 -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER -D WITH_UN $(CFLAGS)
|
||||
CFLAGS := -g -fPIC -O3 -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER -D WITH_UN $(CFLAGS)
|
||||
COUT = -o
|
||||
LN ?= ${CC}
|
||||
DCFLAGS ?=
|
||||
LDFLAGS := -fPIC -O2 -fno-strict-aliasing -pthread $(LDFLAGS)
|
||||
LDFLAGS := -fPIC -O3 -fno-strict-aliasing -pthread $(LDFLAGS)
|
||||
DLFLAGS ?= -shared
|
||||
DLSUFFICS = .ld.so
|
||||
# -lpthreads may be reuqired on some platforms instead of -pthreads
|
||||
|
||||
@ -45,7 +45,7 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
|
||||
}
|
||||
if(!ipentry) return 0;
|
||||
}
|
||||
if((acentry->dst && (!SAISNULL(¶m->req) || param->operation == UDPASSOC || param->operation==BIND)) || (acentry->dstnames && param->hostname)) {
|
||||
if((acentry->dst && (!SAISNULL(¶m->req) || param->operation==BIND)) || (acentry->dstnames && param->hostname)) {
|
||||
for(ipentry = acentry->dst; ipentry; ipentry = ipentry->next)
|
||||
if(IPInentry((struct sockaddr *)¶m->req, ipentry)) {
|
||||
break;
|
||||
@ -93,7 +93,7 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
|
||||
}
|
||||
if(!ipentry && !hstentry) return 0;
|
||||
}
|
||||
if(acentry->ports && (*SAPORT(¶m->req) || param->operation == UDPASSOC || param->operation == BIND)) {
|
||||
if(acentry->ports && (*SAPORT(¶m->req) || param->operation == BIND)) {
|
||||
for (portentry = acentry->ports; portentry; portentry = portentry->next)
|
||||
if(ntohs(*SAPORT(¶m->req)) >= portentry->startport &&
|
||||
ntohs(*SAPORT(¶m->req)) <= portentry->endport) {
|
||||
@ -143,13 +143,14 @@ int checkACL(struct clientparam * param){
|
||||
struct ace dup;
|
||||
int res=60,i=0;
|
||||
|
||||
if(param->operation < 256 && !(param->operation & CONNECT)){
|
||||
|
||||
if(param->operation < 256 && !(param->operation & (CONNECT|UDPASSOC))){
|
||||
continue;
|
||||
}
|
||||
if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
|
||||
continue;
|
||||
}
|
||||
if(param->remsock != INVALID_SOCKET) {
|
||||
if(param->remsock != INVALID_SOCKET && (param->operation != UDPASSOC || param->ctrlsocksrv != INVALID_SOCKET)) {
|
||||
return 0;
|
||||
}
|
||||
for(; i < conf.parentretries; i++){
|
||||
|
||||
@ -557,9 +557,10 @@ int doconnect(struct clientparam * param){
|
||||
if (*SAFAMILY(¶m->sincl) == *SAFAMILY(¶m->req) && !memcmp(SAADDR(¶m->sincl), SAADDR(¶m->req), SAADDRLEN(¶m->req)) &&
|
||||
*SAPORT(¶m->sincl) == *SAPORT(¶m->req)) return 519;
|
||||
|
||||
if (param->operation == ADMIN || param->operation == DNSRESOLVE || param->operation == BIND || param->operation == UDPASSOC)
|
||||
if (param->operation == ADMIN || (( param->operation == DNSRESOLVE || param->operation == BIND || param->operation == UDPASSOC) && !param->redirected))
|
||||
return 0;
|
||||
if (param->remsock != INVALID_SOCKET){
|
||||
if(param->operation == UDPASSOC) return 0;
|
||||
size = sizeof(param->sinsr);
|
||||
if(param->srv->so._getpeername(param->sostate, param->remsock, (struct sockaddr *)¶m->sinsr, &size)==-1) {return (14);}
|
||||
}
|
||||
@ -632,7 +633,7 @@ int doconnect(struct clientparam * param){
|
||||
return 12;
|
||||
}
|
||||
|
||||
if(param->operation >= 256 || (param->operation & CONNECT)){
|
||||
if(param->operation >= 256 || (param->operation & CONNECT) || param->redirected){
|
||||
if(connectwithpoll(param, param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),conf.timeouts[CONNECT_TO])) {
|
||||
return 13;
|
||||
}
|
||||
@ -646,7 +647,6 @@ int doconnect(struct clientparam * param){
|
||||
action = handleconnectflt(param);
|
||||
if(action != PASS) return 19;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
#define _PASSWORD_LEN 256
|
||||
#define MAXNSERVERS 5
|
||||
|
||||
#define UDPBUFSIZE 16384
|
||||
#define TCPBUFSIZE 65536
|
||||
#define SRVBUFSIZE (param->srv->bufsize?param->srv->bufsize:((param->service == S_UDPPM)?UDPBUFSIZE:TCPBUFSIZE))
|
||||
|
||||
@ -231,7 +230,7 @@ void dumpcounters(struct trafcount *tl, int counterd);
|
||||
|
||||
int startconnlims (struct clientparam *param);
|
||||
void stopconnlims (struct clientparam *param);
|
||||
|
||||
int socks5_udp_build_hdr(unsigned char *buf, PROXYSOCKADDRTYPE *addr);
|
||||
|
||||
|
||||
extern struct auth authfuncs[];
|
||||
|
||||
@ -251,10 +251,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
unsigned char buf[256];
|
||||
char *hostname=NULL;
|
||||
int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
|
||||
#ifndef NOUDPMAIN
|
||||
unsigned char *udpbuf = NULL;
|
||||
int udplen = 0;
|
||||
#endif
|
||||
unsigned char *cbc_string = NULL, *cbl_string = NULL;
|
||||
PROXYSOCKADDRTYPE cbsa;
|
||||
FILE *fp = NULL;
|
||||
@ -343,7 +339,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
#ifndef NOUDPMAIN
|
||||
if(isudp) {
|
||||
if(!udp_table.ihashtable)inithashtable(&udp_table, 64, 256, 65536);
|
||||
if(!(udpbuf = myalloc(UDPBUFSIZE))) return 21;
|
||||
}
|
||||
#endif
|
||||
srv.service = defparam.service = childdef.service;
|
||||
@ -926,15 +921,26 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
#ifndef NOUDPMAIN
|
||||
else {
|
||||
struct clientparam *toparam;
|
||||
udplen = sockrecvfrom(NULL, srv.srvsock, (struct sockaddr *)&defparam.sincr, udpbuf, UDPBUFSIZE, 0);
|
||||
if(udplen <= 0) continue;
|
||||
|
||||
srv.udplen = sockrecvfrom(NULL, srv.srvsock, (struct sockaddr *)&defparam.sincr, srv.udpbuf, UDPBUFSIZE, 0);
|
||||
if(srv.udplen <= 0) continue;
|
||||
_3proxy_sem_lock(udpinit);
|
||||
if(hashresolv(&udp_table, &defparam, &toparam, NULL)) {
|
||||
srv.so._sendto(toparam->sostate, toparam->remsock, (char *)udpbuf, udplen, 0, (struct sockaddr *)&toparam->sinsr, SASIZE(&toparam->sinsr));
|
||||
_3proxy_sem_unlock(udpinit);
|
||||
toparam->statscli64 += udplen;
|
||||
toparam->nwrites++;
|
||||
continue;
|
||||
int i, len=0;
|
||||
|
||||
if(toparam->udp_nhops - 1){
|
||||
for(i=1; i < toparam->udp_nhops - 1; i++){
|
||||
len+=socks5_udp_build_hdr(srv.udpbuf2+len, &toparam->udp_relay[i-1]);
|
||||
}
|
||||
len += socks5_udp_build_hdr(srv.udpbuf2+len, &toparam->req);
|
||||
}
|
||||
memcpy(srv.udpbuf2+len, srv.udpbuf, srv.udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : srv.udplen);
|
||||
len += srv.udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : srv.udplen;
|
||||
srv.so._sendto(toparam->sostate, toparam->remsock, (char *)srv.udpbuf2, len, 0, (struct sockaddr *)&toparam->sinsr, SASIZE(&toparam->sinsr));
|
||||
toparam->statscli64 += srv.udplen;
|
||||
toparam->nwrites++;
|
||||
_3proxy_sem_unlock(udpinit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -964,18 +970,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifndef NOUDPMAIN
|
||||
if(isudp) {
|
||||
if(!(newparam->srvbuf = myalloc(UDPBUFSIZE))){
|
||||
freeparam(newparam);
|
||||
_3proxy_sem_unlock(udpinit);
|
||||
continue;
|
||||
}
|
||||
newparam->srvbufsize = UDPBUFSIZE;
|
||||
newparam->srvinbuf = udplen;
|
||||
memcpy(newparam->srvbuf, udpbuf, udplen);
|
||||
}
|
||||
#endif
|
||||
newparam->prev = newparam->next = NULL;
|
||||
error = 0;
|
||||
@ -1047,9 +1041,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
if(cbc_string)myfree(cbc_string);
|
||||
if(cbl_string)myfree(cbl_string);
|
||||
if(fp) fclose(fp);
|
||||
#ifndef NOUDPMAIN
|
||||
myfree(udpbuf);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
|
||||
int len=0;
|
||||
unsigned char * user, *pass;
|
||||
|
||||
|
||||
user = redir->extuser;
|
||||
pass = redir->extpass;
|
||||
if (!param->srvbufsize){
|
||||
@ -135,9 +134,9 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
|
||||
int atyp;
|
||||
int skip_port = 0;
|
||||
buf[0] = 5;
|
||||
buf[1] = 1;
|
||||
buf[2] = user? 2 : 0;
|
||||
if(socksend(param, param->remsock, buf, 3, conf.timeouts[CHAIN_TO]) != 3){
|
||||
buf[1] = user? 1 : 0;
|
||||
buf[2] = 2;
|
||||
if(socksend(param, param->remsock, buf, user?3:2, conf.timeouts[CHAIN_TO]) < 2){
|
||||
return 51;
|
||||
}
|
||||
param->statssrv64+=3;
|
||||
@ -172,9 +171,9 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
|
||||
}
|
||||
}
|
||||
buf[0] = 5;
|
||||
buf[1] = (param->operation == UDPASSOC && redir->type != R_SOCKS5B) ? 3 : 1;
|
||||
buf[1] = (param->operation == UDPASSOC) ? 3 : 1;
|
||||
buf[2] = 0;
|
||||
if (param->operation == UDPASSOC && redir->type != R_SOCKS5B) {
|
||||
if (param->operation == UDPASSOC) {
|
||||
buf[3] = 1;
|
||||
memset(buf + 4, 0, 6);
|
||||
len = 10;
|
||||
@ -219,7 +218,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
|
||||
return 59;
|
||||
case 3:
|
||||
if (sockgetlinebuf(param, SERVER, buf, 1, EOF, conf.timeouts[CHAIN_TO]) != 1) return 59;
|
||||
len = (unsigned char)buf[0];
|
||||
len = (unsigned char)buf[4];
|
||||
if (sockgetlinebuf(param, SERVER, buf, len + 2, EOF, conf.timeouts[CHAIN_TO]) != len + 2) return 59;
|
||||
break;
|
||||
case 4:
|
||||
@ -233,15 +232,17 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
|
||||
PROXYSOCKADDRTYPE *relay = ¶m->udp_relay[param->udp_nhops];
|
||||
memset(relay, 0, sizeof(*relay));
|
||||
if (atyp == 1) {
|
||||
((struct sockaddr_in *)relay)->sin_family = AF_INET;
|
||||
memcpy(&((struct sockaddr_in *)relay)->sin_addr, buf, 4);
|
||||
memcpy(&((struct sockaddr_in *)relay)->sin_port, buf + 4, 2);
|
||||
if (param->udp_nhops == 0) param->sinsr = *relay;
|
||||
*SAFAMILY(relay) = AF_INET;
|
||||
memcpy(SAADDR(relay), buf, 4);
|
||||
memcpy(SAPORT(relay), buf + 4, 2);
|
||||
if (param->udp_nhops == 0) {
|
||||
param->sinsr = *relay;
|
||||
}
|
||||
param->udp_nhops++;
|
||||
} else if (atyp == 4) {
|
||||
((struct sockaddr_in6 *)relay)->sin6_family = AF_INET6;
|
||||
memcpy(&((struct sockaddr_in6 *)relay)->sin6_addr, buf, 16);
|
||||
memcpy(&((struct sockaddr_in6 *)relay)->sin6_port, buf + 16, 2);
|
||||
*SAFAMILY(relay) = AF_INET6;
|
||||
memcpy(SAADDR(relay), buf, 16);
|
||||
memcpy(SAPORT(relay), buf + 16, 2);
|
||||
if (param->udp_nhops == 0) param->sinsr = *relay;
|
||||
param->udp_nhops++;
|
||||
}
|
||||
@ -265,9 +266,9 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
struct chain * cur;
|
||||
struct chain * redir = NULL;
|
||||
int r2;
|
||||
int saved = 0;
|
||||
|
||||
if(param->remsock != INVALID_SOCKET) {
|
||||
return 0;
|
||||
if(param->remsock != INVALID_SOCKET && param->operation != UDPASSOC) {
|
||||
}
|
||||
if((SAISNULL(¶m->req) || !*SAPORT(¶m->req)) && param->operation != UDPASSOC) {
|
||||
return 100;
|
||||
@ -352,7 +353,13 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
else {
|
||||
param->sinsr = cur->addr;
|
||||
}
|
||||
|
||||
if(param->operation == UDPASSOC){
|
||||
SOCKET s;
|
||||
s = param->remsock;
|
||||
param->remsock = INVALID_SOCKET;
|
||||
param->ctrlsocksrv = s;
|
||||
saved = 1;
|
||||
}
|
||||
if((res = alwaysauth(param))){
|
||||
return (res >= 10)? res : 60+res;
|
||||
}
|
||||
@ -397,5 +404,15 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
}
|
||||
|
||||
if(!connected || !redir) return 0;
|
||||
return clientnegotiate(redir, param, (struct sockaddr *)¶m->req, param->hostname);
|
||||
res = clientnegotiate(redir, param, (struct sockaddr *)¶m->req, param->hostname);
|
||||
if(saved){
|
||||
SOCKET s;
|
||||
|
||||
s = param->ctrlsocksrv;
|
||||
param->ctrlsocksrv = param->remsock;
|
||||
param->remsock = s;
|
||||
param->operation = UDPASSOC;
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
@ -314,6 +314,11 @@ log(logbuf);
|
||||
}
|
||||
else {
|
||||
FROMCLIENTPIPE = TOSERVER = 0;
|
||||
if(errno && errno != EINTR && errno != EAGAIN) {
|
||||
SERVERTERMREAD = 1;
|
||||
SERVERTERMWRITE = 1;
|
||||
HASERROR |= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(inserverpipe && !inserverbuf && FROMSERVERPIPE && TOCLIENT){
|
||||
@ -339,6 +344,11 @@ log(logbuf);
|
||||
}
|
||||
else {
|
||||
FROMSERVERPIPE = TOCLIENT = 0;
|
||||
if(errno && errno != EINTR && errno != EAGAIN) {
|
||||
CLIENTTERMREAD = 1;
|
||||
CLIENTTERMWRITE = 1;
|
||||
HASERROR |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(fromclient>inclientpipe && FROMCLIENT && TOCLIENTPIPE){
|
||||
@ -364,6 +374,11 @@ log(logbuf);
|
||||
CLIENTTERMREAD = 1;
|
||||
continue;
|
||||
}
|
||||
if(errno && errno != EINTR && errno != EAGAIN) {
|
||||
CLIENTTERMREAD = 1;
|
||||
CLIENTTERMWRITE = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITHLOG
|
||||
@ -401,6 +416,11 @@ log(logbuf);
|
||||
SERVERTERMREAD = 1;
|
||||
continue;
|
||||
}
|
||||
if(errno && errno != EINTR && errno != EAGAIN) {
|
||||
SERVERTERMREAD = 1;
|
||||
SERVERTERMWRITE = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef WITHLOG
|
||||
@ -499,11 +519,19 @@ log("done read from server to buf");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CLIENTTERMREAD && !inclientbuf && !SERVERTERMWRITE) {
|
||||
if (CLIENTTERMREAD && !inclientbuf
|
||||
#ifdef WITHSPLICE
|
||||
&& !inclientpipe
|
||||
#endif
|
||||
&& !SERVERTERMWRITE) {
|
||||
SERVERTERMWRITE = 1;
|
||||
param->srv->so._shutdown(param->sostate, param->remsock, SHUT_WR);
|
||||
}
|
||||
if (SERVERTERMREAD && !inserverbuf && !CLIENTTERMWRITE) {
|
||||
if (SERVERTERMREAD && !inserverbuf
|
||||
#ifdef WITHSPLICE
|
||||
&& !inserverpipe
|
||||
#endif
|
||||
&& !CLIENTTERMWRITE) {
|
||||
CLIENTTERMWRITE = 1;
|
||||
param->srv->so._shutdown(param->sostate, param->clisock, SHUT_WR);
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ void * sockschild(struct clientparam* param) {
|
||||
}
|
||||
if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) {
|
||||
RETURN(421);
|
||||
} /* version */
|
||||
}
|
||||
}
|
||||
if( (command = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) < 1 || command > 3){command = 0; RETURN(407);} /* command */
|
||||
if(ver == 5){
|
||||
|
||||
@ -183,7 +183,7 @@ int
|
||||
#endif
|
||||
|
||||
#define MAX_HASH_SIZE (16)
|
||||
|
||||
#define UDPBUFSIZE 16384
|
||||
|
||||
extern char* NULLADDR;
|
||||
typedef enum {
|
||||
@ -517,6 +517,11 @@ struct srvparam {
|
||||
AUTHFUNC authfunc;
|
||||
PROXYFUNC pf;
|
||||
SOCKET srvsock, cbsock;
|
||||
#ifndef NOUDPMAIN
|
||||
unsigned char udpbuf[UDPBUFSIZE];
|
||||
unsigned char udpbuf2[UDPBUFSIZE];
|
||||
int udplen;
|
||||
#endif
|
||||
int childcount;
|
||||
int maxchild;
|
||||
int backlog;
|
||||
|
||||
20
src/udppm.c
20
src/udppm.c
@ -29,11 +29,15 @@ static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash
|
||||
}
|
||||
|
||||
struct hashtable udp_table = {udpparam2hash, udpparam2hash, sizeof(struct clientparam *), 8};
|
||||
int socks5_udp_build_hdr(unsigned char *buf, PROXYSOCKADDRTYPE *addr);
|
||||
|
||||
void * udppmchild(struct clientparam* param) {
|
||||
int authres;
|
||||
int i;
|
||||
int len = 0;
|
||||
|
||||
if(parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) { RETURN(201) }
|
||||
|
||||
#ifndef NOIPV6
|
||||
memcpy(¶m->sinsl, *SAFAMILY(¶m->req) == AF_INET6 ? (struct sockaddr *)¶m->srv->extsa6 : (struct sockaddr *)¶m->srv->extsa, SASIZE(¶m->req));
|
||||
#else
|
||||
@ -53,13 +57,25 @@ void * udppmchild(struct clientparam* param) {
|
||||
authres = (*param->srv->authfunc)(param);
|
||||
if(authres) { RETURN(authres); }
|
||||
if(!param->srv->singlepacket)hashadd(&udp_table, param, ¶m, MAX_COUNTER_TIME);
|
||||
param->srv->so._sendto(param->sostate, param->remsock, (char *)param->srvbuf, param->srvinbuf, 0, (struct sockaddr *)¶m->sinsr, SASIZE(¶m->sinsr));
|
||||
if(!param->srvbuf){
|
||||
if(!(param->srvbuf = myalloc(UDPBUFSIZE)))RETURN(11);
|
||||
param->srvbufsize = UDPBUFSIZE;
|
||||
}
|
||||
if(param->udp_nhops){
|
||||
for(i=1; i < param->udp_nhops; i++){
|
||||
len+=socks5_udp_build_hdr(param->srvbuf+len, ¶m->udp_relay[i-1]);
|
||||
}
|
||||
len += socks5_udp_build_hdr(param->srvbuf+len, ¶m->req);
|
||||
}
|
||||
memcpy(param->srvbuf+len, param->srv->udpbuf, param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen);
|
||||
len += param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen;
|
||||
param->srv->so._sendto(param->sostate, param->remsock, (char *)param->srvbuf, len, 0, (struct sockaddr *)¶m->sinsr, SASIZE(¶m->sinsr));
|
||||
_3proxy_sem_unlock(udpinit);
|
||||
param->statscli64 += param->srvinbuf;
|
||||
param->srvinbuf = 0;
|
||||
param->nwrites++;
|
||||
param->clisock = param->srv->srvsock;
|
||||
param->udp_nhops = 1;
|
||||
param->udp_nhops++;
|
||||
param->waitserver64 = 0x7fffffffffffffff;
|
||||
param->res = udpsockmap(param, conf.timeouts[STRING_L]);
|
||||
_3proxy_sem_lock(udpinit);
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
static int socks5_udp_build_hdr(unsigned char *buf, PROXYSOCKADDRTYPE *addr)
|
||||
int socks5_udp_build_hdr(unsigned char *buf, PROXYSOCKADDRTYPE *addr)
|
||||
{
|
||||
buf[0] = buf[1] = buf[2] = 0;
|
||||
buf[3] = (*SAFAMILY(addr) == AF_INET) ? 1 : 4;
|
||||
@ -57,7 +57,6 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
int nhops = param->udp_nhops;
|
||||
int clisock_idx = -1, ctrlsock_idx = -1, ctrlsocksrv_idx = -1;
|
||||
int firstpacket = 1;
|
||||
|
||||
if (param->srvbufsize < UDPBUFSIZE) {
|
||||
unsigned char *newbuf = myrealloc(param->srvbuf, UDPBUFSIZE);
|
||||
if (!newbuf) return 21;
|
||||
@ -92,7 +91,7 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
|
||||
for (;;) {
|
||||
res = param->srv->so._poll(param->sostate, fds, nfds, timeo * 1000);
|
||||
if (res < 0) return 463;
|
||||
if (res < 0) return 481;
|
||||
if (res == 0) return 92;
|
||||
|
||||
/* datagram from client */
|
||||
@ -104,7 +103,7 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
len = param->srv->so._recvfrom(param->sostate, param->clisock,
|
||||
(char *)param->srvbuf + recvoff, UDPBUFSIZE - recvoff,
|
||||
0, (struct sockaddr *)&sin, &sasize);
|
||||
if (len <= 0) return 464;
|
||||
if (len <= 0) return 482;
|
||||
|
||||
if (SAADDRLEN(&sin) != SAADDRLEN(¶m->sincr) ||
|
||||
memcmp(SAADDR(&sin), SAADDR(¶m->sincr), SAADDRLEN(&sin)))
|
||||
@ -119,7 +118,7 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
if (nhops == 0) {
|
||||
int i;
|
||||
if (len < 10 || param->srvbuf[0] || param->srvbuf[1] || param->srvbuf[2])
|
||||
return 466;
|
||||
return 483;
|
||||
switch (param->srvbuf[3]) {
|
||||
case 1:
|
||||
*SAFAMILY(¶m->sinsr) = AF_INET;
|
||||
@ -127,14 +126,14 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
i = 8;
|
||||
break;
|
||||
case 4:
|
||||
if (len < 22) return 466;
|
||||
if (len < 22) return 484;
|
||||
*SAFAMILY(¶m->sinsr) = AF_INET6;
|
||||
memcpy(SAADDR(¶m->sinsr), param->srvbuf + 4, 16);
|
||||
i = 20;
|
||||
break;
|
||||
case 3: {
|
||||
int sz = param->srvbuf[4], j;
|
||||
if (len < 7 + sz) return 466;
|
||||
if (len < 7 + sz) return 485;
|
||||
for (j = 4; j < 4 + sz; j++) param->srvbuf[j] = param->srvbuf[j + 1];
|
||||
param->srvbuf[4 + sz] = 0;
|
||||
i = 5 + sz;
|
||||
@ -175,7 +174,7 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
len = param->srv->so._recvfrom(param->sostate, param->remsock,
|
||||
(char *)param->srvbuf + hdrsize, UDPBUFSIZE - hdrsize, 0,
|
||||
(struct sockaddr *)&from, &sasize);
|
||||
if (len <= 0) return 468;
|
||||
if (len <= 0) return 486;
|
||||
if (nhops >= 1) {
|
||||
if (!SAISNULL(¶m->sinsr) && *SAPORT(¶m->sinsr)) {
|
||||
if (SAADDRLEN(&from) != SAADDRLEN(¶m->sinsr) ||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user