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