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:
Jan Smutny 2024-10-25 21:36:21 +02:00
parent cb6a4166b7
commit 983df6f7ae
4 changed files with 59 additions and 4 deletions

View File

@ -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

View File

@ -521,16 +521,48 @@ int doconnect(struct clientparam * param){
if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req);
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
if(SAISNULL(&param->sinsl)){
if (param->srv->keepip) {
#ifndef NOIPV6
if(*SAFAMILY(&param->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(&param->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
else
#endif
param->sinsl = param->srv->extsa;
}
}
*SAPORT(&param->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*)&param->sinsl, SASIZE(&param->sinsl))==-1) {
return 12;
}
if(param->operation >= 256 || (param->operation & CONNECT)){
if(connectwithpoll(param, param->remsock,(struct sockaddr *)&param->sinsr,SASIZE(&param->sinsr),CONNECT_TO)) {
return 13;

View File

@ -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

View File

@ -479,6 +479,7 @@ struct srvparam {
int paused, version;
int singlepacket;
int usentlm;
int keepip;
int needuser;
int silent;
int transparent;