mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-13 20:29:15 +08:00
Merge adc6319ea4 into c31fe8367f
This commit is contained in:
commit
f6b1578126
@ -176,6 +176,9 @@ listen on given local HOST:port for incoming connections instead of making remot
|
||||
.B -r\fIHOST\fB:\fIport\fR
|
||||
connect to given remote HOST:port instead of listening local connection on -p or default port. Can be used with another 3proxy service running -R option for connect back functionality. Most commonly used with proxy or socks. HOST can be given as IP or hostname, useful in case of dynamic DNS.
|
||||
.br
|
||||
.B -Tr\fIFIRST\fB-\fILAST\fR, -Ur\fIFIRST\fB-\fILAST\fR, -UAr\fIFIRST\fB-\fILAST\fR
|
||||
(Linux) use the inclusive local ephemeral port range FIRST-LAST for outgoing IPv4 TCP (-Tr) or UDP (-Ur) sockets of this service. -UAr applies only to the UDP relay socket returned to a SOCKS5 UDP ASSOCIATE client. Use it when this port range must be forwarded by NAT and allowed by a firewall. Requires kernel support for IP_LOCAL_PORT_RANGE (Linux 6.3 or newer). The option is applied before bind(2); no system-wide sysctl is changed. For example, \fBsocks -p1080 -Ur20000-30000 -UAr30000-31000\fR.
|
||||
.br
|
||||
.B -oc\fIOPTIONS\fB, -os\fIOPTIONS\fB, -ol\fIOPTIONS\fB, -or\fIOPTIONS\fB, -oR\fIOPTIONS\fR
|
||||
options for proxy-to-client (\fB-oc\fR), proxy-to-server (\fB-os\fR), proxy listening (\fB-ol\fR), connect back client (\fB-or\fR), connect back listening (\fB-oR\fR) sockets.
|
||||
Options like TCP_CORK, TCP_NODELAY, TCP_DEFER_ACCEPT, TCP_QUICKACK, TCP_TIMESTAMPS, TCP_FASTOPEN, SO_REUSEADDR, SO_REUSEPORT, SO_EXCLUSIVEADDRUSE, SO_PORT_SCALABILITY, SO_REUSE_UNICASTPORT, SO_KEEPALIVE, SO_DONTROUTE may be supported depending on OS.
|
||||
|
||||
24
src/common.c
24
src/common.c
@ -10,6 +10,11 @@
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef IP_LOCAL_PORT_RANGE
|
||||
#define IP_LOCAL_PORT_RANGE 51
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char * copyright = COPYRIGHT;
|
||||
|
||||
@ -679,6 +684,7 @@ int doconnect(struct clientparam * param){
|
||||
}
|
||||
*SAPORT(¶m->sinsl) = 0;
|
||||
setopts(param->remsock, param->srv->srvsockopts);
|
||||
if(set_local_port_range(param->srv, param->remsock, (struct sockaddr *)¶m->sinsl, LOCAL_PORT_RANGE_TCP)) return 12;
|
||||
|
||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||
#if defined SO_BINDTODEVICE
|
||||
@ -724,6 +730,24 @@ int doconnect(struct clientparam * param){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_local_port_range(struct srvparam *srv, SOCKET sock, const struct sockaddr *sa, int range_type){
|
||||
#ifdef __linux__
|
||||
uint32_t range = range_type == LOCAL_PORT_RANGE_TCP ? srv->tcp_local_port_range :
|
||||
range_type == LOCAL_PORT_RANGE_UDP ? srv->udp_local_port_range : srv->udp_associate_port_range;
|
||||
|
||||
if(range && sa->sa_family == AF_INET &&
|
||||
((const struct sockaddr_in *)sa)->sin_port == 0 &&
|
||||
srv->so._setsockopt(srv->so.state, sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
|
||||
(char *)&range, sizeof(range))) return -1;
|
||||
#else
|
||||
(void)srv;
|
||||
(void)sock;
|
||||
(void)sa;
|
||||
(void)range_type;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scanaddr(const unsigned char *s, uint32_t * ip, uint32_t * mask) {
|
||||
unsigned d1, d2, d3, d4, m;
|
||||
int res;
|
||||
|
||||
@ -149,6 +149,10 @@ void * dnsprchild(struct clientparam* param) {
|
||||
}
|
||||
memset(¶m->sinsl, 0, sizeof(param->sinsl));
|
||||
*SAFAMILY(¶m->sinsl) = *SAFAMILY(&nservers[0].addr);
|
||||
if(set_local_port_range(param->srv, param->remsock, (struct sockaddr *)¶m->sinsl,
|
||||
nservers[0].usetcp ? LOCAL_PORT_RANGE_TCP : LOCAL_PORT_RANGE_UDP)) {
|
||||
RETURN(819);
|
||||
}
|
||||
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {
|
||||
RETURN(819);
|
||||
}
|
||||
@ -222,4 +226,3 @@ CLEANRET:
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -121,6 +121,7 @@ void * ftpprchild(struct clientparam* param) {
|
||||
}
|
||||
if ((clidatasock=socket(SASOCK(¶m->sincl), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
|
||||
*SAPORT(¶m->sincl) = 0;
|
||||
if(set_local_port_range(param->srv, clidatasock, (struct sockaddr *)¶m->sincl, LOCAL_PORT_RANGE_TCP)){RETURN(822);}
|
||||
if(param->srv->so._bind(param->sostate, clidatasock, (struct sockaddr *)¶m->sincl, SASIZE(¶m->sincl))){RETURN(822);}
|
||||
if (pasv) {
|
||||
if(param->srv->so._listen(param->sostate, clidatasock, 1)) {RETURN(823);}
|
||||
|
||||
@ -347,6 +347,10 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign
|
||||
int readconfig(FILE * fp);
|
||||
void initcommands(void);
|
||||
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
|
||||
#define LOCAL_PORT_RANGE_TCP 1
|
||||
#define LOCAL_PORT_RANGE_UDP 2
|
||||
#define LOCAL_PORT_RANGE_UDP_ASSOCIATE 3
|
||||
int set_local_port_range(struct srvparam *srv, SOCKET sock, const struct sockaddr *sa, int range_type);
|
||||
|
||||
|
||||
uint32_t myrand(void);
|
||||
@ -428,4 +432,3 @@ extern char * ceargv[32];
|
||||
#define WEBBANNERS 35
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -342,6 +342,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
"\n"
|
||||
" -iIP ip address or internal interface (clients are expected to connect)\n"
|
||||
" -eIP ip address or external interface (outgoing connection will have this)\n"
|
||||
" -TrFIRST-LAST, -UrFIRST-LAST, -UArFIRST-LAST Linux: local TCP, UDP or UDP ASSOCIATE ranges\n"
|
||||
" -rHOST:PORT Use IP:port for connect back proxy instead of listen port\n"
|
||||
" -RHOST:PORT Use PORT to listen connect back proxy connection to pass data to\n"
|
||||
" -4 Use IPv4 for outgoing connections\n"
|
||||
@ -502,8 +503,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
if(argv[i][3] == 'e') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.extNat);
|
||||
else if(argv[i][3] == 'i') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.intNat);
|
||||
if(argv[i][2] == 'e') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.extNat);
|
||||
else if(argv[i][2] == 'i') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.intNat);
|
||||
else getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
|
||||
break;
|
||||
case 'n':
|
||||
@ -565,6 +566,35 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
srv.needuser = 0;
|
||||
if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2);
|
||||
break;
|
||||
case 'U':
|
||||
#ifdef __linux__
|
||||
{
|
||||
char *end;
|
||||
const char *range_arg;
|
||||
unsigned long first, last;
|
||||
uint32_t *range;
|
||||
|
||||
if(argv[i][2] == 'r') {
|
||||
range_arg = argv[i] + 3;
|
||||
range = &srv.udp_local_port_range;
|
||||
}
|
||||
else if(argv[i][2] == 'A' && argv[i][3] == 'r') {
|
||||
range_arg = argv[i] + 4;
|
||||
range = &srv.udp_associate_port_range;
|
||||
}
|
||||
else { error = 1; break; }
|
||||
errno = 0;
|
||||
first = strtoul(range_arg, &end, 10);
|
||||
if(errno || end == range_arg || *end != '-') { error = 1; break; }
|
||||
errno = 0;
|
||||
last = strtoul(end + 1, &end, 10);
|
||||
if(errno || *end || !first || !last || first > last || last > 65535) { error = 1; break; }
|
||||
*range = ((uint32_t)last << 16) | (uint32_t)first;
|
||||
}
|
||||
#else
|
||||
error = 1;
|
||||
#endif
|
||||
break;
|
||||
case 'x':
|
||||
srv.nostarttls = 1;
|
||||
break;
|
||||
@ -587,7 +617,27 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
srv.transparent = 1;
|
||||
if(!argv[i][2]) {
|
||||
srv.transparent = 1;
|
||||
break;
|
||||
}
|
||||
#ifdef __linux__
|
||||
{
|
||||
char *end;
|
||||
unsigned long first, last;
|
||||
|
||||
if(argv[i][2] != 'r') { error = 1; break; }
|
||||
errno = 0;
|
||||
first = strtoul(argv[i] + 3, &end, 10);
|
||||
if(errno || end == argv[i] + 3 || *end != '-') { error = 1; break; }
|
||||
errno = 0;
|
||||
last = strtoul(end + 1, &end, 10);
|
||||
if(errno || *end || !first || !last || first > last || last > 65535) { error = 1; break; }
|
||||
srv.tcp_local_port_range = ((uint32_t)last << 16) | (uint32_t)first;
|
||||
}
|
||||
#else
|
||||
error = 1;
|
||||
#endif
|
||||
break;
|
||||
case 'S':
|
||||
srv.stacksize = atoi(argv[i]+2);
|
||||
@ -1791,5 +1841,3 @@ FILTER_ACTION handledatfltsrv(struct clientparam *cparam, unsigned char ** buf_p
|
||||
}
|
||||
return PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -44,6 +44,10 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
|
||||
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
|
||||
}
|
||||
if((sock=so._socket(so.state, SASOCK(sinsl), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
||||
if(param && set_local_port_range(param->srv, sock, (struct sockaddr *)sinsl, usetcp ? LOCAL_PORT_RANGE_TCP : LOCAL_PORT_RANGE_UDP)) {
|
||||
so._closesocket(so.state, sock);
|
||||
break;
|
||||
}
|
||||
if(so._bind(so.state, sock,(struct sockaddr *)sinsl,SASIZE(sinsl))){
|
||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||
so._closesocket(so.state, sock);
|
||||
@ -198,4 +202,4 @@ uint32_t fakeresolver (int af, unsigned char *name, unsigned char * value){
|
||||
value[3] = 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,6 +250,8 @@ void * sockschild(struct clientparam* param) {
|
||||
}
|
||||
|
||||
if(command > 1) {
|
||||
if(set_local_port_range(param->srv, param->remsock, (struct sockaddr *)¶m->sinsl,
|
||||
command == 2 ? LOCAL_PORT_RANGE_TCP : LOCAL_PORT_RANGE_UDP)) RETURN(12);
|
||||
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {
|
||||
*SAPORT(¶m->sinsl) = 0;
|
||||
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl)))RETURN (12);
|
||||
@ -274,6 +276,7 @@ fflush(stderr);
|
||||
#endif
|
||||
sin = param->sincl;
|
||||
*SAPORT(&sin) = 0;
|
||||
if(set_local_port_range(param->srv, param->clisock, (struct sockaddr *)&sin, LOCAL_PORT_RANGE_UDP_ASSOCIATE)) {RETURN (12);}
|
||||
if(param->srv->so._bind(param->sostate, param->clisock,(struct sockaddr *)&sin,SASIZE(&sin))) {RETURN (12);}
|
||||
sasize = SASIZE(&sin);
|
||||
param->srv->so._getsockname(param->sostate, param->clisock, (struct sockaddr *)&sin, &sasize);
|
||||
|
||||
@ -589,6 +589,9 @@ struct srvparam {
|
||||
unsigned char *udpbuf;
|
||||
unsigned char *udpbuf2;
|
||||
int udplen;
|
||||
uint32_t tcp_local_port_range;
|
||||
uint32_t udp_local_port_range;
|
||||
uint32_t udp_associate_port_range;
|
||||
};
|
||||
|
||||
struct clientparam {
|
||||
|
||||
@ -46,6 +46,7 @@ void * udppmchild(struct clientparam* param) {
|
||||
*SAPORT(¶m->sinsl) = 0;
|
||||
param->remsock = param->srv->so._socket(param->srv->so.state, SASOCK(¶m->sinsl), SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(param->remsock == INVALID_SOCKET) { RETURN(202); }
|
||||
if(set_local_port_range(param->srv, param->remsock, (struct sockaddr *)¶m->sinsl, LOCAL_PORT_RANGE_UDP)) { RETURN(203); }
|
||||
if(param->srv->so._bind(param->srv->so.state, param->remsock, (struct sockaddr *)¶m->sinsl, SASIZE(¶m->sinsl))) { RETURN(203); }
|
||||
#ifdef _WIN32
|
||||
{ unsigned long ul2 = 1; ioctlsocket(param->remsock, FIONBIO, &ul2); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user