diff --git a/src/proxymain.c b/src/proxymain.c index 9bdf340..d393a63 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -702,8 +702,10 @@ int MODULEMAINFUNC (int argc, char** argv){ freesrvstrings(&srv, cbc_string, cbl_string); 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 if (!iscbc) { @@ -805,27 +807,42 @@ int MODULEMAINFUNC (int argc, char** argv){ if(saved_nsfd != -1) { if(setns(saved_nsfd, CLONE_NEWNET)) { 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); freesrvstrings(&srv, cbc_string, cbl_string); return -14; } - close(saved_nsfd); - saved_nsfd = -1; + if(srv.service != S_SOCKS) { + close(saved_nsfd); + saved_nsfd = -1; + } } if(srv.onetns) { int nsfd = open(srv.onetns, O_RDONLY); if(nsfd == -1) { 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); return -14; } if(setns(nsfd, CLONE_NEWNET)) { dolog(&defparam, (unsigned char *)"failed to setns onetns"); 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); return -14; } - close(nsfd); + if(srv.service == S_SOCKS) srv.o_nsfd = nsfd; + else close(nsfd); } #endif if(iscbl){ @@ -1149,8 +1166,11 @@ void srvinit(struct srvparam * srv, struct clientparam *param){ srv->srvsock = INVALID_SOCKET; srv->logdumpsrv = conf.logdumpsrv; srv->logdumpcli = conf.logdumpcli; - srv->cbsock = INVALID_SOCKET; + srv->cbsock = INVALID_SOCKET; srv->needuser = 1; +#ifdef __linux__ + srv->saved_nsfd = srv->i_nsfd = srv->o_nsfd = -1; +#endif #ifdef WITHSPLICE srv->usesplice = 1; #endif @@ -1247,6 +1267,9 @@ void srvfree(struct srvparam * srv){ #ifdef __linux__ if(srv->inetns) free(srv->inetns); 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 if(srv->so.freefunc) srv->so.freefunc(srv->so.state); #ifndef NOUDPMAIN diff --git a/src/socks.c b/src/socks.c index 8802f61..be39cb6 100644 --- a/src/socks.c +++ b/src/socks.c @@ -7,6 +7,9 @@ */ #include "proxy.h" +#ifdef __linux__ +#include +#endif #define RETURN(xxx) { param->res = xxx; goto CLEANRET; } @@ -188,6 +191,12 @@ void * sockschild(struct clientparam* param) { param->sinsl = *SAFAMILY(¶m->req)==AF_INET6? param->srv->extsa6 : param->srv->extsa; #else 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 if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(¶m->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} param->operation = command == 2?BIND:UDPASSOC; @@ -242,6 +251,12 @@ fflush(stderr); param->srv->so._getsockname(param->sostate, param->remsock, (struct sockaddr *)¶m->sinsl, &sasize); if(command == 3) { 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(¶m->sincr), SOCK_DGRAM, IPPROTO_UDP); if(param->clisock == INVALID_SOCKET) {RETURN(11);} sin = param->sincl; diff --git a/src/structures.h b/src/structures.h index 31e3774..07fca16 100644 --- a/src/structures.h +++ b/src/structures.h @@ -557,6 +557,9 @@ struct srvparam { #ifdef __linux__ char * inetns; char * onetns; + int saved_nsfd; + int i_nsfd; + int o_nsfd; #endif struct auth *authenticate; struct pollfd * srvfds;