mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-13 12:19:17 +08:00
Merge 4bf9eecddf into eca362af81
This commit is contained in:
commit
8e86183787
@ -55,6 +55,7 @@ option(3PROXY_USE_SPLICE "Build Linux splice() support, slower than read/write f
|
|||||||
option(3PROXY_USE_POLL "Use poll() instead of select() (Unix only)" ON)
|
option(3PROXY_USE_POLL "Use poll() instead of select() (Unix only)" ON)
|
||||||
option(3PROXY_USE_WSAPOLL "Use WSAPoll instead of select() (Windows only)" ON)
|
option(3PROXY_USE_WSAPOLL "Use WSAPoll instead of select() (Windows only)" ON)
|
||||||
option(3PROXY_USE_NETFILTER "Enable Linux netfilter support (Linux only)" ON)
|
option(3PROXY_USE_NETFILTER "Enable Linux netfilter support (Linux only)" ON)
|
||||||
|
option(3PROXY_USE_LOCAL_PORT_RANGE "Enable per-connection local port ranges (Linux 6.3+ only)" ON)
|
||||||
option(3PROXY_USE_UNIX_SOCKETS "Enable Unix domain socket support (Unix only)" ON)
|
option(3PROXY_USE_UNIX_SOCKETS "Enable Unix domain socket support (Unix only)" ON)
|
||||||
|
|
||||||
if(NOT WIN32 AND NOT APPLE)
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
@ -185,6 +186,10 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||||||
add_compile_definitions(WITH_NETFILTER)
|
add_compile_definitions(WITH_NETFILTER)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(3PROXY_USE_LOCAL_PORT_RANGE)
|
||||||
|
add_compile_definitions(WITH_LOCAL_PORT_RANGE)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(3PROXY_USE_UNIX_SOCKETS)
|
if(3PROXY_USE_UNIX_SOCKETS)
|
||||||
add_compile_definitions(WITH_UN)
|
add_compile_definitions(WITH_UN)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -25,6 +25,10 @@ LDFLAGS += -fno-strict-aliasing -pthread
|
|||||||
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
||||||
CFLAGS += $(EXTRA_CFLAGS)
|
CFLAGS += $(EXTRA_CFLAGS)
|
||||||
LDFLAGS += $(EXTRA_LDFLAGS)
|
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||||
|
LOCAL_PORT_RANGE ?= true
|
||||||
|
ifeq ($(LOCAL_PORT_RANGE),true)
|
||||||
|
CFLAGS += -DWITH_LOCAL_PORT_RANGE
|
||||||
|
endif
|
||||||
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
|
||||||
|
|||||||
@ -817,7 +817,7 @@ with probability of 0.7) for outgoing web connections. Chains are only applied t
|
|||||||
.br
|
.br
|
||||||
type is one of:
|
type is one of:
|
||||||
.br
|
.br
|
||||||
\fBextip\fR does not actually redirect the request; it sets the external address for this request to \fI<ip>\fR. It can be chained with another parent type. It's useful to set the external IP based on ACL or make it random.
|
\fBextip\fR does not actually redirect the request; it sets the external address for this request to \fI<ip>\fR. It can be chained with another parent type. It's useful to set the external IP based on ACL or make it random. Its \fI<port>\fR argument is optional and defaults to 0. When built with \fBWITH_LOCAL_PORT_RANGE\fR on Linux 6.3 or newer, \fI<port>\fR may be an inclusive IPv4 local port range \fIFIRST-LAST\fR. The range is applied to outgoing sockets for requests matching this parent; DNS resolver traffic is not affected. For example, \fBparent 1000 extip 192.0.2.10 20000-30000\fR.
|
||||||
.br
|
.br
|
||||||
\fBtcp\fR simply redirect connection. TCP is always last in chain. This type of proxy is a simple TCP redirection, it does not support parent authentication.
|
\fBtcp\fR simply redirect connection. TCP is always last in chain. This type of proxy is a simple TCP redirection, it does not support parent authentication.
|
||||||
.br
|
.br
|
||||||
|
|||||||
18
src/common.c
18
src/common.c
@ -10,6 +10,11 @@
|
|||||||
|
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
|
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
#ifndef IP_LOCAL_PORT_RANGE
|
||||||
|
#define IP_LOCAL_PORT_RANGE 51
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
char * copyright = COPYRIGHT;
|
char * copyright = COPYRIGHT;
|
||||||
|
|
||||||
@ -680,6 +685,9 @@ int doconnect(struct clientparam * param){
|
|||||||
}
|
}
|
||||||
*SAPORT(¶m->sinsl) = 0;
|
*SAPORT(¶m->sinsl) = 0;
|
||||||
setopts(param->remsock, param->srv->srvsockopts);
|
setopts(param->remsock, param->srv->srvsockopts);
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
if(set_local_port_range(param, param->remsock, (struct sockaddr *)¶m->sinsl)) return 12;
|
||||||
|
#endif
|
||||||
|
|
||||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||||
#if defined SO_BINDTODEVICE
|
#if defined SO_BINDTODEVICE
|
||||||
@ -725,6 +733,16 @@ int doconnect(struct clientparam * param){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
int set_local_port_range(struct clientparam *param, SOCKET sock, const struct sockaddr *sa){
|
||||||
|
if(param->local_port_range && sa->sa_family == AF_INET &&
|
||||||
|
((const struct sockaddr_in *)sa)->sin_port == 0 &&
|
||||||
|
param->srv->so._setsockopt(param->srv->so.state, sock, IPPROTO_IP, IP_LOCAL_PORT_RANGE,
|
||||||
|
(char *)¶m->local_port_range, sizeof(param->local_port_range))) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int scanaddr(const unsigned char *s, uint32_t * ip, uint32_t * mask) {
|
int scanaddr(const unsigned char *s, uint32_t * ip, uint32_t * mask) {
|
||||||
unsigned d1, d2, d3, d4, m;
|
unsigned d1, d2, d3, d4, m;
|
||||||
int res;
|
int res;
|
||||||
|
|||||||
36
src/conf.c
36
src/conf.c
@ -814,6 +814,11 @@ static int h_parent(int argc, unsigned char **argv){
|
|||||||
free(chains);
|
free(chains);
|
||||||
return(4);
|
return(4);
|
||||||
}
|
}
|
||||||
|
if(argc < 5 && chains->type != R_EXTIP) {
|
||||||
|
fprintf(stderr, "Chaining error: port is required for parent type %s\n", argv[2]);
|
||||||
|
free(chains);
|
||||||
|
return(3);
|
||||||
|
}
|
||||||
#ifdef WITH_UN
|
#ifdef WITH_UN
|
||||||
if(!strncmp((char *)argv[3], "unix:", 5)){
|
if(!strncmp((char *)argv[3], "unix:", 5)){
|
||||||
make_un(argv[3] + 5, (struct sockaddr_un*)&chains->addr);
|
make_un(argv[3] + 5, (struct sockaddr_un*)&chains->addr);
|
||||||
@ -838,7 +843,34 @@ static int h_parent(int argc, unsigned char **argv){
|
|||||||
*cidr = '/';
|
*cidr = '/';
|
||||||
chains->cidr = atoi(cidr + 1);
|
chains->cidr = atoi(cidr + 1);
|
||||||
}
|
}
|
||||||
*SAPORT(&chains->addr) = htons((uint16_t)atoi((char *)argv[4]));
|
if(argc > 4) {
|
||||||
|
char *end;
|
||||||
|
unsigned long port;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
port = strtoul((char *)argv[4], &end, 10);
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
if(chains->type == R_EXTIP && *end == '-') {
|
||||||
|
unsigned long last;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
last = strtoul(end + 1, &end, 10);
|
||||||
|
if(errno || *end || !port || !last || port > last || last > 65535) {
|
||||||
|
free(chains->exthost);
|
||||||
|
free(chains);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
chains->local_port_range = ((uint32_t)last << 16) | (uint32_t)port;
|
||||||
|
port = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(errno || *end || port > 65535) {
|
||||||
|
free(chains->exthost);
|
||||||
|
free(chains);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
*SAPORT(&chains->addr) = htons((uint16_t)port);
|
||||||
|
}
|
||||||
if(argc > 5) chains->extuser = (unsigned char *)strdup((char *)argv[5]);
|
if(argc > 5) chains->extuser = (unsigned char *)strdup((char *)argv[5]);
|
||||||
if(argc > 6) chains->extpass = (unsigned char *)strdup((char *)argv[6]);
|
if(argc > 6) chains->extpass = (unsigned char *)strdup((char *)argv[6]);
|
||||||
if(!acl->chains) {
|
if(!acl->chains) {
|
||||||
@ -1696,7 +1728,7 @@ struct commands commandhandlers[]={
|
|||||||
{NULL, "system", h_system, 2, 2},
|
{NULL, "system", h_system, 2, 2},
|
||||||
{NULL, "pidfile", h_pidfile, 2, 2},
|
{NULL, "pidfile", h_pidfile, 2, 2},
|
||||||
{NULL, "monitor", h_monitor, 2, 2},
|
{NULL, "monitor", h_monitor, 2, 2},
|
||||||
{NULL, "parent", h_parent, 5, 0},
|
{NULL, "parent", h_parent, 4, 0},
|
||||||
{NULL, "allow", h_ace, 1, 0},
|
{NULL, "allow", h_ace, 1, 0},
|
||||||
{NULL, "deny", h_ace, 1, 0},
|
{NULL, "deny", h_ace, 1, 0},
|
||||||
{NULL, "redirect", h_ace, 3, 0},
|
{NULL, "redirect", h_ace, 3, 0},
|
||||||
|
|||||||
@ -222,4 +222,3 @@ CLEANRET:
|
|||||||
#endif
|
#endif
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -121,6 +121,9 @@ void * ftpprchild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
if ((clidatasock=socket(SASOCK(¶m->sincl), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
|
if ((clidatasock=socket(SASOCK(¶m->sincl), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
|
||||||
*SAPORT(¶m->sincl) = 0;
|
*SAPORT(¶m->sincl) = 0;
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
if(set_local_port_range(param, clidatasock, (struct sockaddr *)¶m->sincl)){RETURN(822);}
|
||||||
|
#endif
|
||||||
if(param->srv->so._bind(param->sostate, clidatasock, (struct sockaddr *)¶m->sincl, SASIZE(¶m->sincl))){RETURN(822);}
|
if(param->srv->so._bind(param->sostate, clidatasock, (struct sockaddr *)¶m->sincl, SASIZE(¶m->sincl))){RETURN(822);}
|
||||||
if (pasv) {
|
if (pasv) {
|
||||||
if(param->srv->so._listen(param->sostate, clidatasock, 1)) {RETURN(823);}
|
if(param->srv->so._listen(param->sostate, clidatasock, 1)) {RETURN(823);}
|
||||||
|
|||||||
@ -347,6 +347,9 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign
|
|||||||
int readconfig(FILE * fp);
|
int readconfig(FILE * fp);
|
||||||
void initcommands(void);
|
void initcommands(void);
|
||||||
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
|
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
int set_local_port_range(struct clientparam *param, SOCKET sock, const struct sockaddr *sa);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint32_t myrand(void);
|
uint32_t myrand(void);
|
||||||
@ -428,4 +431,3 @@ extern char * ceargv[32];
|
|||||||
#define WEBBANNERS 35
|
#define WEBBANNERS 35
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -502,8 +502,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
if(argv[i][3] == 'e') getip46(46, (unsigned char *)argv[i]+3, (struct sockaddr *)&srv.extNat);
|
if(argv[i][2] == '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);
|
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);
|
else getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -1791,5 +1791,3 @@ FILTER_ACTION handledatfltsrv(struct clientparam *cparam, unsigned char ** buf_p
|
|||||||
}
|
}
|
||||||
return PASS;
|
return PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -295,6 +295,9 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
|||||||
if(!connected){
|
if(!connected){
|
||||||
if(cur->type == R_EXTIP){
|
if(cur->type == R_EXTIP){
|
||||||
param->sinsl = cur->addr;
|
param->sinsl = cur->addr;
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
param->local_port_range = cur->local_port_range;
|
||||||
|
#endif
|
||||||
if(SAISNULL(¶m->sinsl) && (*SAFAMILY(¶m->sincr) == AF_INET || *SAFAMILY(¶m->sincr) == AF_INET6))param->sinsl = param->sincr;
|
if(SAISNULL(¶m->sinsl) && (*SAFAMILY(¶m->sincr) == AF_INET || *SAFAMILY(¶m->sincr) == AF_INET6))param->sinsl = param->sincr;
|
||||||
#ifndef NOIPV6
|
#ifndef NOIPV6
|
||||||
else if(cur->cidr && *SAFAMILY(¶m->sinsl) == AF_INET6){
|
else if(cur->cidr && *SAFAMILY(¶m->sinsl) == AF_INET6){
|
||||||
|
|||||||
@ -198,4 +198,4 @@ uint32_t fakeresolver (int af, unsigned char *name, unsigned char * value){
|
|||||||
value[3] = 2;
|
value[3] = 2;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -250,6 +250,9 @@ void * sockschild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(command > 1) {
|
if(command > 1) {
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
if(set_local_port_range(param, param->remsock, (struct sockaddr *)¶m->sinsl)) RETURN(12);
|
||||||
|
#endif
|
||||||
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {
|
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {
|
||||||
*SAPORT(¶m->sinsl) = 0;
|
*SAPORT(¶m->sinsl) = 0;
|
||||||
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl)))RETURN (12);
|
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl)))RETURN (12);
|
||||||
|
|||||||
@ -335,6 +335,9 @@ struct chain {
|
|||||||
unsigned char * extpass;
|
unsigned char * extpass;
|
||||||
unsigned short weight;
|
unsigned short weight;
|
||||||
unsigned short cidr;
|
unsigned short cidr;
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
uint32_t local_port_range;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct period {
|
struct period {
|
||||||
@ -666,6 +669,9 @@ struct clientparam {
|
|||||||
maxtrafout64;
|
maxtrafout64;
|
||||||
PROXYSOCKADDRTYPE sincl, sincr;
|
PROXYSOCKADDRTYPE sincl, sincr;
|
||||||
PROXYSOCKADDRTYPE sinsl, sinsr, req;
|
PROXYSOCKADDRTYPE sinsl, sinsr, req;
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
uint32_t local_port_range;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint64_t statscli64,
|
uint64_t statscli64,
|
||||||
statssrv64;
|
statssrv64;
|
||||||
|
|||||||
@ -46,6 +46,9 @@ void * udppmchild(struct clientparam* param) {
|
|||||||
*SAPORT(¶m->sinsl) = 0;
|
*SAPORT(¶m->sinsl) = 0;
|
||||||
param->remsock = param->srv->so._socket(param->srv->so.state, SASOCK(¶m->sinsl), SOCK_DGRAM, IPPROTO_UDP);
|
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(param->remsock == INVALID_SOCKET) { RETURN(202); }
|
||||||
|
#ifdef WITH_LOCAL_PORT_RANGE
|
||||||
|
if(set_local_port_range(param, param->remsock, (struct sockaddr *)¶m->sinsl)) { RETURN(203); }
|
||||||
|
#endif
|
||||||
if(param->srv->so._bind(param->srv->so.state, param->remsock, (struct sockaddr *)¶m->sinsl, SASIZE(¶m->sinsl))) { RETURN(203); }
|
if(param->srv->so._bind(param->srv->so.state, param->remsock, (struct sockaddr *)¶m->sinsl, SASIZE(¶m->sinsl))) { RETURN(203); }
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
{ unsigned long ul2 = 1; ioctlsocket(param->remsock, FIONBIO, &ul2); }
|
{ unsigned long ul2 = 1; ioctlsocket(param->remsock, FIONBIO, &ul2); }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user