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_WSAPOLL "Use WSAPoll instead of select() (Windows 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)
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
@ -185,6 +186,10 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
add_compile_definitions(WITH_NETFILTER)
|
||||
endif()
|
||||
|
||||
if(3PROXY_USE_LOCAL_PORT_RANGE)
|
||||
add_compile_definitions(WITH_LOCAL_PORT_RANGE)
|
||||
endif()
|
||||
|
||||
if(3PROXY_USE_UNIX_SOCKETS)
|
||||
add_compile_definitions(WITH_UN)
|
||||
endif()
|
||||
|
||||
@ -25,6 +25,10 @@ LDFLAGS += -fno-strict-aliasing -pthread
|
||||
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
||||
CFLAGS += $(EXTRA_CFLAGS)
|
||||
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||
LOCAL_PORT_RANGE ?= true
|
||||
ifeq ($(LOCAL_PORT_RANGE),true)
|
||||
CFLAGS += -DWITH_LOCAL_PORT_RANGE
|
||||
endif
|
||||
DLFLAGS ?= -shared
|
||||
DLSUFFICS = .ld.so
|
||||
# -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
|
||||
type is one of:
|
||||
.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
|
||||
\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
|
||||
|
||||
18
src/common.c
18
src/common.c
@ -10,6 +10,11 @@
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
#ifdef WITH_LOCAL_PORT_RANGE
|
||||
#ifndef IP_LOCAL_PORT_RANGE
|
||||
#define IP_LOCAL_PORT_RANGE 51
|
||||
#endif
|
||||
#endif
|
||||
|
||||
char * copyright = COPYRIGHT;
|
||||
|
||||
@ -680,6 +685,9 @@ int doconnect(struct clientparam * param){
|
||||
}
|
||||
*SAPORT(¶m->sinsl) = 0;
|
||||
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));
|
||||
#if defined SO_BINDTODEVICE
|
||||
@ -725,6 +733,16 @@ int doconnect(struct clientparam * param){
|
||||
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) {
|
||||
unsigned d1, d2, d3, d4, m;
|
||||
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);
|
||||
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
|
||||
if(!strncmp((char *)argv[3], "unix:", 5)){
|
||||
make_un(argv[3] + 5, (struct sockaddr_un*)&chains->addr);
|
||||
@ -838,7 +843,34 @@ static int h_parent(int argc, unsigned char **argv){
|
||||
*cidr = '/';
|
||||
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 > 6) chains->extpass = (unsigned char *)strdup((char *)argv[6]);
|
||||
if(!acl->chains) {
|
||||
@ -1696,7 +1728,7 @@ struct commands commandhandlers[]={
|
||||
{NULL, "system", h_system, 2, 2},
|
||||
{NULL, "pidfile", h_pidfile, 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, "deny", h_ace, 1, 0},
|
||||
{NULL, "redirect", h_ace, 3, 0},
|
||||
|
||||
@ -222,4 +222,3 @@ CLEANRET:
|
||||
#endif
|
||||
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);}
|
||||
*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 (pasv) {
|
||||
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);
|
||||
void initcommands(void);
|
||||
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);
|
||||
@ -428,4 +431,3 @@ extern char * ceargv[32];
|
||||
#define WEBBANNERS 35
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -502,8 +502,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':
|
||||
@ -1791,5 +1791,3 @@ FILTER_ACTION handledatfltsrv(struct clientparam *cparam, unsigned char ** buf_p
|
||||
}
|
||||
return PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -295,6 +295,9 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
||||
if(!connected){
|
||||
if(cur->type == R_EXTIP){
|
||||
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;
|
||||
#ifndef NOIPV6
|
||||
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;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,6 +250,9 @@ void * sockschild(struct clientparam* param) {
|
||||
}
|
||||
|
||||
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))) {
|
||||
*SAPORT(¶m->sinsl) = 0;
|
||||
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 short weight;
|
||||
unsigned short cidr;
|
||||
#ifdef WITH_LOCAL_PORT_RANGE
|
||||
uint32_t local_port_range;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct period {
|
||||
@ -666,6 +669,9 @@ struct clientparam {
|
||||
maxtrafout64;
|
||||
PROXYSOCKADDRTYPE sincl, sincr;
|
||||
PROXYSOCKADDRTYPE sinsl, sinsr, req;
|
||||
#ifdef WITH_LOCAL_PORT_RANGE
|
||||
uint32_t local_port_range;
|
||||
#endif
|
||||
|
||||
uint64_t statscli64,
|
||||
statssrv64;
|
||||
|
||||
@ -46,6 +46,9 @@ 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); }
|
||||
#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); }
|
||||
#ifdef _WIN32
|
||||
{ unsigned long ul2 = 1; ioctlsocket(param->remsock, FIONBIO, &ul2); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user