Support namespaces for UDP in socks

This commit is contained in:
Vladimir Dubrovin 2026-05-08 20:21:04 +03:00
parent ff15a8d480
commit 7871279fae
3 changed files with 46 additions and 5 deletions

View File

@ -702,8 +702,10 @@ int MODULEMAINFUNC (int argc, char** argv){
freesrvstrings(&srv, cbc_string, cbl_string); freesrvstrings(&srv, cbc_string, cbl_string);
return -13; return -13;
} }
close(nsfd); if(srv.service == S_SOCKS) srv.i_nsfd = nsfd;
else close(nsfd);
} }
if(srv.service == S_SOCKS) srv.saved_nsfd = saved_nsfd;
} }
#endif #endif
if (!iscbc) { if (!iscbc) {
@ -805,27 +807,42 @@ int MODULEMAINFUNC (int argc, char** argv){
if(saved_nsfd != -1) { if(saved_nsfd != -1) {
if(setns(saved_nsfd, CLONE_NEWNET)) { if(setns(saved_nsfd, CLONE_NEWNET)) {
dolog(&defparam, (unsigned char *)"failed to restore netns"); dolog(&defparam, (unsigned char *)"failed to restore netns");
if(srv.service == S_SOCKS) {
if(srv.i_nsfd >= 0) { close(srv.i_nsfd); srv.i_nsfd = -1; }
srv.saved_nsfd = -1;
}
close(saved_nsfd); close(saved_nsfd);
freesrvstrings(&srv, cbc_string, cbl_string); freesrvstrings(&srv, cbc_string, cbl_string);
return -14; return -14;
} }
close(saved_nsfd); if(srv.service != S_SOCKS) {
saved_nsfd = -1; close(saved_nsfd);
saved_nsfd = -1;
}
} }
if(srv.onetns) { if(srv.onetns) {
int nsfd = open(srv.onetns, O_RDONLY); int nsfd = open(srv.onetns, O_RDONLY);
if(nsfd == -1) { if(nsfd == -1) {
dolog(&defparam, (unsigned char *)"failed to open onetns"); dolog(&defparam, (unsigned char *)"failed to open onetns");
if(srv.service == S_SOCKS) {
if(srv.saved_nsfd >= 0) { close(srv.saved_nsfd); srv.saved_nsfd = -1; }
if(srv.i_nsfd >= 0) { close(srv.i_nsfd); srv.i_nsfd = -1; }
}
freesrvstrings(&srv, cbc_string, cbl_string); freesrvstrings(&srv, cbc_string, cbl_string);
return -14; return -14;
} }
if(setns(nsfd, CLONE_NEWNET)) { if(setns(nsfd, CLONE_NEWNET)) {
dolog(&defparam, (unsigned char *)"failed to setns onetns"); dolog(&defparam, (unsigned char *)"failed to setns onetns");
close(nsfd); close(nsfd);
if(srv.service == S_SOCKS) {
if(srv.saved_nsfd >= 0) { close(srv.saved_nsfd); srv.saved_nsfd = -1; }
if(srv.i_nsfd >= 0) { close(srv.i_nsfd); srv.i_nsfd = -1; }
}
freesrvstrings(&srv, cbc_string, cbl_string); freesrvstrings(&srv, cbc_string, cbl_string);
return -14; return -14;
} }
close(nsfd); if(srv.service == S_SOCKS) srv.o_nsfd = nsfd;
else close(nsfd);
} }
#endif #endif
if(iscbl){ if(iscbl){
@ -1149,8 +1166,11 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
srv->srvsock = INVALID_SOCKET; srv->srvsock = INVALID_SOCKET;
srv->logdumpsrv = conf.logdumpsrv; srv->logdumpsrv = conf.logdumpsrv;
srv->logdumpcli = conf.logdumpcli; srv->logdumpcli = conf.logdumpcli;
srv->cbsock = INVALID_SOCKET; srv->cbsock = INVALID_SOCKET;
srv->needuser = 1; srv->needuser = 1;
#ifdef __linux__
srv->saved_nsfd = srv->i_nsfd = srv->o_nsfd = -1;
#endif
#ifdef WITHSPLICE #ifdef WITHSPLICE
srv->usesplice = 1; srv->usesplice = 1;
#endif #endif
@ -1247,6 +1267,9 @@ void srvfree(struct srvparam * srv){
#ifdef __linux__ #ifdef __linux__
if(srv->inetns) free(srv->inetns); if(srv->inetns) free(srv->inetns);
if(srv->onetns) free(srv->onetns); if(srv->onetns) free(srv->onetns);
if(srv->saved_nsfd >= 0) { close(srv->saved_nsfd); srv->saved_nsfd = -1; }
if(srv->i_nsfd >= 0) { close(srv->i_nsfd); srv->i_nsfd = -1; }
if(srv->o_nsfd >= 0) { close(srv->o_nsfd); srv->o_nsfd = -1; }
#endif #endif
if(srv->so.freefunc) srv->so.freefunc(srv->so.state); if(srv->so.freefunc) srv->so.freefunc(srv->so.state);
#ifndef NOUDPMAIN #ifndef NOUDPMAIN

View File

@ -7,6 +7,9 @@
*/ */
#include "proxy.h" #include "proxy.h"
#ifdef __linux__
#include <sched.h>
#endif
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; } #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
@ -188,6 +191,12 @@ void * sockschild(struct clientparam* param) {
param->sinsl = *SAFAMILY(&param->req)==AF_INET6? param->srv->extsa6 : param->srv->extsa; param->sinsl = *SAFAMILY(&param->req)==AF_INET6? param->srv->extsa6 : param->srv->extsa;
#else #else
param->sinsl = param->srv->extsa; param->sinsl = param->srv->extsa;
#endif
#ifdef __linux__
if(command == 3 && param->srv->o_nsfd >= 0) {
if(param->srv->saved_nsfd >= 0 && setns(param->srv->saved_nsfd, CLONE_NEWNET)) {RETURN(11);}
if(setns(param->srv->o_nsfd, CLONE_NEWNET)) {RETURN(11);}
}
#endif #endif
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
param->operation = command == 2?BIND:UDPASSOC; param->operation = command == 2?BIND:UDPASSOC;
@ -242,6 +251,12 @@ fflush(stderr);
param->srv->so._getsockname(param->sostate, param->remsock, (struct sockaddr *)&param->sinsl, &sasize); param->srv->so._getsockname(param->sostate, param->remsock, (struct sockaddr *)&param->sinsl, &sasize);
if(command == 3) { if(command == 3) {
param->ctrlsock = param->clisock; param->ctrlsock = param->clisock;
#ifdef __linux__
if(param->srv->i_nsfd >= 0) {
if(param->srv->saved_nsfd >= 0 && setns(param->srv->saved_nsfd, CLONE_NEWNET)) {RETURN(11);}
if(setns(param->srv->i_nsfd, CLONE_NEWNET)) {RETURN(11);}
}
#endif
param->clisock = param->srv->so._socket(param->sostate, SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP); param->clisock = param->srv->so._socket(param->sostate, SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP);
if(param->clisock == INVALID_SOCKET) {RETURN(11);} if(param->clisock == INVALID_SOCKET) {RETURN(11);}
sin = param->sincl; sin = param->sincl;

View File

@ -557,6 +557,9 @@ struct srvparam {
#ifdef __linux__ #ifdef __linux__
char * inetns; char * inetns;
char * onetns; char * onetns;
int saved_nsfd;
int i_nsfd;
int o_nsfd;
#endif #endif
struct auth *authenticate; struct auth *authenticate;
struct pollfd * srvfds; struct pollfd * srvfds;