Compare commits

...

4 Commits

Author SHA1 Message Date
jendis
b85a6b3862
Merge 983df6f7ae into 12c9039ea4 2026-02-11 02:54:29 +03:00
Vladimir Dubrovin
12c9039ea4 Fixed: crash on invalid configuration file
Some checks failed
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
2026-01-28 19:40:58 +03:00
Vladimir Dubrovin
1a970c5c98 Fixed: memory corruptions on config parsing 2026-01-28 19:13:41 +03:00
Jan Smutny
983df6f7ae 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.
2025-02-06 13:23:03 +01:00
6 changed files with 74 additions and 13 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

@ -526,16 +526,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;

View File

@ -105,6 +105,10 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign
struct tm *ts;
ts = localtime(&t);
if(strlen((char *)name) >= 4096){
*buf = 0;
return buf;
}
if(strchr((char *)name, '%')){
struct clientparam fakecli;
@ -905,7 +909,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
if(argc > 0 && strcmp("*", (char *)argv[0])) {
arg = argv[0];
arg = (unsigned char *)strtok((char *)arg, ",");
do {
if(arg) do {
if(!acl->users) {
acl->users = userl = myalloc(sizeof(struct userlist));
}
@ -924,7 +928,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
}
if(argc > 1 && strcmp("*", (char *)argv[1])) {
arg = (unsigned char *)strtok((char *)argv[1], ",");
do {
if(arg) do {
if(!acl->src) {
acl->src = ipl = myalloc(sizeof(struct iplist));
}
@ -945,7 +949,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
}
if(argc > 2 && strcmp("*", (char *)argv[2])) {
arg = (unsigned char *)strtok((char *)argv[2], ",");
do {
if(arg) do {
int arglen;
unsigned char *pattern;
struct iplist tmpip={NULL};
@ -1002,7 +1006,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
}
if(argc > 3 && strcmp("*", (char *)argv[3])) {
arg = (unsigned char *)strtok((char *)argv[3], ",");
do {
if(arg) do {
if(!acl->ports) {
acl->ports = portl = myalloc(sizeof(struct portlist));
}
@ -1025,7 +1029,7 @@ struct ace * make_ace (int argc, unsigned char ** argv){
}
if(argc > 4 && strcmp("*", (char *)argv[4])) {
arg = (unsigned char *)strtok((char *)argv[4], ",");
do {
if(arg) do {
if(!strcmp((char *)arg, "CONNECT")){
acl->operation |= CONNECT;
}
@ -1682,7 +1686,7 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
}
switch(*str){
case '\0':
if(comment) return -1;
if(comment || incbegin) return -1;
argm[argc] = 0;
return argc;
case '$':
@ -1709,14 +1713,14 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
argc--;
if((fd = open((char *)incbegin+1, O_RDONLY)) <= 0){
fprintf(stderr, "Failed to open %s\n", incbegin+1);
break;
return -1;
}
if((*bufsize - *inbuf) <STRINGBUF){
*bufsize += STRINGBUF;
if(!(buf = myrealloc(buf, *bufsize))){
fprintf(stderr, "Failed to allocate memory for %s\n", incbegin+1);
close(fd);
break;
return -1;
}
}
len = 0;
@ -1727,7 +1731,7 @@ int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned cha
if((res = read(fd, buf+*inbuf+len, STRINGBUF-(1+len))) <= 0) {
perror((char *)incbegin+1);
close(fd);
break;
return -1;
}
close(fd);
buf[*inbuf+res+len] = 0;

View File

@ -300,6 +300,8 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break;
}
case 0:
j--;
default:
buf[i++] = format[j];
}

View File

@ -288,6 +288,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"
@ -426,6 +429,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;
@ -815,6 +825,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()){
@ -990,6 +1001,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

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