mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 02:25:40 +08:00
Extend SOCKS for AnyIP utilization
Introduce '-k' parameter that overwrites the -e parameter (if given) and uses the IP for the external connection that corresponds to the current client connection. The benefit arises when the parameter '-i0.0.0.0' or '-i::' in case of IPv6 is set. This allows the entire range configured as local on the system to receive connections and establish connections to the target server using the IP address to which the client connected. Note: This feature is not applicable for Windows.
This commit is contained in:
parent
cb6a4166b7
commit
983df6f7ae
10
man/socks.8
10
man/socks.8
@ -42,6 +42,16 @@ of IP-IP NAT (will not work for PAT)
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -k
|
||||
External address given by
|
||||
.B -e
|
||||
is ignored and the internal address or generally the address client conected to is used instead.
|
||||
This allows to utilize AnyIP Linux feature when
|
||||
.B -i0.0.0.0
|
||||
or in case of IPv6
|
||||
.B -i::
|
||||
is set. Not available for Windows platform.
|
||||
.TP
|
||||
.B -p
|
||||
Port. Port proxy listens for incoming connections. Default is 1080.
|
||||
.TP
|
||||
|
40
src/common.c
40
src/common.c
@ -521,16 +521,48 @@ int doconnect(struct clientparam * param){
|
||||
if(!*SAPORT(¶m->sinsr))*SAPORT(¶m->sinsr) = *SAPORT(¶m->req);
|
||||
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(¶m->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
|
||||
if(SAISNULL(¶m->sinsl)){
|
||||
if (param->srv->keepip) {
|
||||
#ifndef NOIPV6
|
||||
if(*SAFAMILY(¶m->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
|
||||
else
|
||||
struct sockaddr_in6 local_addr;
|
||||
socklen_t local_addr_len = sizeof(local_addr);
|
||||
getsockname(param->clisock, (struct sockaddr *)&local_addr, &local_addr_len);
|
||||
|
||||
if(*SAFAMILY(&local_addr) == AF_INET6) {
|
||||
if (IN6_IS_ADDR_V4MAPPED(&local_addr.sin6_addr)) {
|
||||
struct sockaddr_in6 local_addr2;
|
||||
memset(&local_addr2, 0, sizeof(local_addr2));
|
||||
local_addr2.sin6_family = AF_INET;
|
||||
local_addr2.sin6_port = local_addr.sin6_port;
|
||||
param->sinsl = local_addr2;
|
||||
} else {
|
||||
param->sinsl = local_addr;
|
||||
}
|
||||
} else {
|
||||
param->sinsl = local_addr;
|
||||
}
|
||||
#else
|
||||
struct sockaddr_in local_addr;
|
||||
socklen_t local_addr_len = sizeof(local_addr);
|
||||
getsockname(new_sock, (struct sockaddr *)&local_addr, &local_addr_len);
|
||||
param->sinsl = local_addr;
|
||||
#endif
|
||||
param->sinsl = param->srv->extsa;
|
||||
} else {
|
||||
#ifndef NOIPV6
|
||||
if(*SAFAMILY(¶m->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
|
||||
else
|
||||
#endif
|
||||
param->sinsl = param->srv->extsa;
|
||||
}
|
||||
}
|
||||
*SAPORT(¶m->sinsl) = 0;
|
||||
setopts(param->remsock, param->srv->srvsockopts);
|
||||
|
||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||
|
||||
if (param->srv->keepip) {
|
||||
int opt = 1;
|
||||
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_IP, IP_FREEBIND, (char *)&opt, sizeof(int));
|
||||
}
|
||||
#ifdef REUSE
|
||||
{
|
||||
int opt;
|
||||
@ -564,7 +596,7 @@ int doconnect(struct clientparam * param){
|
||||
if(param->srv->so._bind(param->sostate, param->remsock, (struct sockaddr*)¶m->sinsl, SASIZE(¶m->sinsl))==-1) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
|
||||
if(param->operation >= 256 || (param->operation & CONNECT)){
|
||||
if(connectwithpoll(param, param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->sinsr),CONNECT_TO)) {
|
||||
return 13;
|
||||
|
@ -239,6 +239,9 @@ 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"
|
||||
#ifndef _WIN32
|
||||
" -k outgoing connection will have local IP where client connected, thus ignores -e (useful in AnyIP case)\n"
|
||||
#endif
|
||||
" -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"
|
||||
@ -377,6 +380,13 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#ifndef _WIN32
|
||||
case 'k':
|
||||
{
|
||||
srv.keepip = 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'N':
|
||||
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
|
||||
break;
|
||||
@ -763,6 +773,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
||||
}
|
||||
else {
|
||||
new_sock = srv.so._accept(srv.so.state, sock, (struct sockaddr*)&defparam.sincr, &size);
|
||||
|
||||
if(new_sock == INVALID_SOCKET){
|
||||
#ifdef _WIN32
|
||||
switch(WSAGetLastError()){
|
||||
@ -938,6 +949,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
|
||||
srv->logdumpcli = conf.logdumpcli;
|
||||
srv->cbsock = INVALID_SOCKET;
|
||||
srv->needuser = 1;
|
||||
srv->keepip = 0;
|
||||
#ifdef WITHSPLICE
|
||||
srv->usesplice = 1;
|
||||
#endif
|
||||
|
@ -479,6 +479,7 @@ struct srvparam {
|
||||
int paused, version;
|
||||
int singlepacket;
|
||||
int usentlm;
|
||||
int keepip;
|
||||
int needuser;
|
||||
int silent;
|
||||
int transparent;
|
||||
|
Loading…
Reference in New Issue
Block a user