mirror of
https://github.com/3proxy/3proxy.git
synced 2026-04-19 18:50:12 +08:00
Support unix socket for parent and tcppm; abstract (fileless) unix sockets for linux support
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
Use unix:/path/to/socket, e.g. tcppm 1234 unix:/path/to/socket 1234 Under linux abstract sockets are supported with '@' prefix, e.g. parent 1000 http unix:@virtual.3proxy.socket 1111 Destination port numbers are not used in tcppm/parent, but you must specify any positive value to match the syntaxis.
This commit is contained in:
parent
3f92dc7355
commit
878a432481
41
src/common.c
41
src/common.c
@ -62,17 +62,34 @@ int mutex_unlock(int *val)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_UN
|
||||||
|
void make_un(const unsigned char *path, struct sockaddr_un * sun){
|
||||||
|
memset(sun, 0, sizeof(*sun));
|
||||||
|
sun->sun_family = AF_UNIX;
|
||||||
|
strncpy(sun->sun_path, (char *)path, sizeof(sun->sun_path) - 1);
|
||||||
|
if(*path == '@')*sun->sun_path = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int myinet_ntop(int af, void *src, char *dst, socklen_t size){
|
int myinet_ntop(int af, void *src, char *dst, socklen_t size){
|
||||||
#ifdef WITH_UN
|
#ifdef WITH_UN
|
||||||
if(af == AF_UNIX){
|
if(af == AF_UNIX){
|
||||||
struct sockaddr_un *sun = (struct sockaddr_un *)src;
|
struct sockaddr_un *sun = (struct sockaddr_un *)src;
|
||||||
|
int ephemeral = 0;
|
||||||
char *path = sun->sun_path;
|
char *path = sun->sun_path;
|
||||||
char *basename = strrchr(path, '/');
|
char *basename;
|
||||||
|
if(!path[0] && path[1]){
|
||||||
|
ephemeral = 1;
|
||||||
|
*dst++ = '@';
|
||||||
|
path++;
|
||||||
|
}
|
||||||
|
basename = strrchr(path, '/');
|
||||||
if(basename) basename++;
|
if(basename) basename++;
|
||||||
else basename = path;
|
else basename = path;
|
||||||
if(size > 0){
|
if(size > 0){
|
||||||
strncpy(dst, basename, (size > 40) ? 40 : size - 1);
|
strncpy(dst, basename, (size > 40) ? 40 : size - (ephemeral + 1));
|
||||||
dst[((size > 40) ? 40 : size - 1)] = 0;
|
dst[((size > 40) ? 40 : size - (ephemeral + 1))] = 0;
|
||||||
}
|
}
|
||||||
return (int)strlen(dst);
|
return (int)strlen(dst);
|
||||||
}
|
}
|
||||||
@ -538,14 +555,14 @@ int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa,
|
|||||||
fcntl(sock,F_SETFL, O_NONBLOCK | fcntl(sock,F_GETFL));
|
fcntl(sock,F_SETFL, O_NONBLOCK | fcntl(sock,F_GETFL));
|
||||||
#endif
|
#endif
|
||||||
if(param?param->srv->so._connect(param->sostate, sock,sa,size) : so._connect(so.state, sock,sa,size)) {
|
if(param?param->srv->so._connect(param->sostate, sock,sa,size) : so._connect(so.state, sock,sa,size)) {
|
||||||
if(errno != EAGAIN && errno != EINPROGRESS) return (13);
|
if(errno != EAGAIN && errno != EINPROGRESS) return 13;
|
||||||
}
|
}
|
||||||
if(!errno) return 0;
|
if(!errno) return 0;
|
||||||
memset(fds, 0, sizeof(fds));
|
memset(fds, 0, sizeof(fds));
|
||||||
fds[0].fd = sock;
|
fds[0].fd = sock;
|
||||||
fds[0].events = POLLOUT;
|
fds[0].events = POLLOUT;
|
||||||
if((param?param->srv->so._poll(param->sostate, fds, 1, to*1000):so._poll(so.state, fds, 1, to*1000)) <= 0 || !(fds[0].revents & POLLOUT) || (fds[0].revents & (POLLERR|POLLHUP))) {
|
if((param?param->srv->so._poll(param->sostate, fds, 1, to*1000):so._poll(so.state, fds, 1, to*1000)) <= 0 || !(fds[0].revents & POLLOUT) || (fds[0].revents & (POLLERR|POLLHUP))) {
|
||||||
return (13);
|
return 13;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -575,8 +592,17 @@ int doconnect(struct clientparam * param){
|
|||||||
memcpy(SAADDR(¶m->sinsr), SAADDR(¶m->req), SAADDRLEN(¶m->req));
|
memcpy(SAADDR(¶m->sinsr), SAADDR(¶m->req), SAADDRLEN(¶m->req));
|
||||||
}
|
}
|
||||||
if(!*SAPORT(¶m->sinsr))*SAPORT(¶m->sinsr) = *SAPORT(¶m->req);
|
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 ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(¶m->sinsr), SOCK_STREAM,
|
||||||
|
#ifdef WITH_UN
|
||||||
|
*SAFAMILY(¶m->sinsr) == AF_UNIX? 0 :
|
||||||
|
#endif
|
||||||
|
IPPROTO_TCP
|
||||||
|
)) == INVALID_SOCKET) {return (11);}
|
||||||
if(SAISNULL(¶m->sinsl)){
|
if(SAISNULL(¶m->sinsl)){
|
||||||
|
#ifdef WITH_UN
|
||||||
|
if(*SAFAMILY(¶m->sinsr) == AF_UNIX) param->sinsl = param->sinsr;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
#ifndef NOIPV6
|
#ifndef NOIPV6
|
||||||
if(*SAFAMILY(¶m->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
|
if(*SAFAMILY(¶m->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
|
||||||
else
|
else
|
||||||
@ -616,6 +642,9 @@ int doconnect(struct clientparam * param){
|
|||||||
if(*SAFAMILY(¶m->sinsl) == AF_INET6 && param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx))) return 12;
|
if(*SAFAMILY(¶m->sinsl) == AF_INET6 && param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx))) return 12;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_UN
|
||||||
|
if(*SAFAMILY(¶m->sinsl) != AF_UNIX)
|
||||||
#endif
|
#endif
|
||||||
if(param->srv->so._bind(param->sostate, param->remsock, (struct sockaddr*)¶m->sinsl, SASIZE(¶m->sinsl))==-1) {
|
if(param->srv->so._bind(param->sostate, param->remsock, (struct sockaddr*)¶m->sinsl, SASIZE(¶m->sinsl))==-1) {
|
||||||
return 12;
|
return 12;
|
||||||
|
|||||||
16
src/conf.c
16
src/conf.c
@ -287,10 +287,7 @@ static int h_proxy(int argc, unsigned char ** argv){
|
|||||||
static int h_internal(int argc, unsigned char ** argv){
|
static int h_internal(int argc, unsigned char ** argv){
|
||||||
#ifdef WITH_UN
|
#ifdef WITH_UN
|
||||||
if(!strncmp((char *)argv[1], "unix:", 5)){
|
if(!strncmp((char *)argv[1], "unix:", 5)){
|
||||||
struct sockaddr_un *sun = (struct sockaddr_un *)&conf.intsa;
|
make_un(argv[1] +5, (struct sockaddr_un *)&conf.intsa);
|
||||||
memset(sun, 0, sizeof(*sun));
|
|
||||||
sun->sun_family = AF_UNIX;
|
|
||||||
strncpy(sun->sun_path, (char *)argv[1] + 5, sizeof(sun->sun_path) - 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -776,7 +773,7 @@ struct redirdesc redirs[] = {
|
|||||||
static int h_parent(int argc, unsigned char **argv){
|
static int h_parent(int argc, unsigned char **argv){
|
||||||
struct ace *acl = NULL;
|
struct ace *acl = NULL;
|
||||||
struct chain *chains;
|
struct chain *chains;
|
||||||
char * cidr;
|
char * cidr = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
acl = conf.acl;
|
acl = conf.acl;
|
||||||
@ -807,9 +804,18 @@ static int h_parent(int argc, unsigned char **argv){
|
|||||||
fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]);
|
fprintf(stderr, "Chaining error: bad chain type (%s)\n", argv[2]);
|
||||||
return(4);
|
return(4);
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_UN
|
||||||
|
if(!strncmp((char *)argv[3], "unix:", 5)){
|
||||||
|
make_un(argv[3] + 5, (struct sockaddr_un*)&chains->addr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#endif
|
||||||
cidr = strchr((char *)argv[3], '/');
|
cidr = strchr((char *)argv[3], '/');
|
||||||
if(cidr) *cidr = 0;
|
if(cidr) *cidr = 0;
|
||||||
if(!getip46(46, argv[3], (struct sockaddr *)&chains->addr)) return (5);
|
if(!getip46(46, argv[3], (struct sockaddr *)&chains->addr)) return (5);
|
||||||
|
#ifdef WITH_UN
|
||||||
|
}
|
||||||
|
#endif
|
||||||
chains->exthost = (unsigned char *)mystrdup((char *)argv[3]);
|
chains->exthost = (unsigned char *)mystrdup((char *)argv[3]);
|
||||||
if(!chains->exthost) return 21;
|
if(!chains->exthost) return 21;
|
||||||
if(cidr){
|
if(cidr){
|
||||||
|
|||||||
@ -326,6 +326,10 @@ extern struct commands commandhandlers[];
|
|||||||
#define mapsocket(a,b) sockmap(a,b, 0)
|
#define mapsocket(a,b) sockmap(a,b, 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_UN
|
||||||
|
void make_un(const unsigned char *path, struct sockaddr_un * sun);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern struct radserver {
|
extern struct radserver {
|
||||||
PROXYSOCKADDRTYPE authaddr, logaddr, localaddr;
|
PROXYSOCKADDRTYPE authaddr, logaddr, localaddr;
|
||||||
|
|||||||
@ -407,10 +407,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
case 'i':
|
case 'i':
|
||||||
#ifdef WITH_UN
|
#ifdef WITH_UN
|
||||||
if(!strncmp((char *)argv[i]+2, "unix:", 5)){
|
if(!strncmp((char *)argv[i]+2, "unix:", 5)){
|
||||||
struct sockaddr_un *sun = (struct sockaddr_un *)&srv.intsa;
|
make_un((unsigned char *)argv[i] + 7, (struct sockaddr_un *)&srv.intsa);
|
||||||
memset(sun, 0, sizeof(*sun));
|
|
||||||
sun->sun_family = AF_UNIX;
|
|
||||||
strncpy(sun->sun_path, (char *)argv[i] + 7, sizeof(sun->sun_path) - 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -658,15 +655,13 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
|
|
||||||
if (!iscbc) {
|
if (!iscbc) {
|
||||||
if(srv.srvsock == INVALID_SOCKET){
|
if(srv.srvsock == INVALID_SOCKET){
|
||||||
|
|
||||||
#ifdef WITH_UN
|
|
||||||
if(*SAFAMILY(&srv.intsa) == AF_UNIX){
|
|
||||||
sock=srv.so._socket(srv.so.state, PF_UNIX, SOCK_STREAM, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if(!isudp){
|
if(!isudp){
|
||||||
sock=srv.so._socket(srv.so.state, SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
|
sock=srv.so._socket(srv.so.state, SASOCK(&srv.intsa), SOCK_STREAM,
|
||||||
|
#ifdef WITH_UN
|
||||||
|
*SAFAMILY(&srv.intsa) == AF_UNIX? 0 :
|
||||||
|
#endif
|
||||||
|
IPPROTO_TCP
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sock=srv.so._socket(srv.so.state, SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
|
sock=srv.so._socket(srv.so.state, SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
|
||||||
@ -718,7 +713,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
#ifdef WITH_UN
|
#ifdef WITH_UN
|
||||||
if(*SAFAMILY(&srv.intsa) == AF_UNIX){
|
if(*SAFAMILY(&srv.intsa) == AF_UNIX){
|
||||||
struct sockaddr_un *sun = (struct sockaddr_un *)&srv.intsa;
|
struct sockaddr_un *sun = (struct sockaddr_un *)&srv.intsa;
|
||||||
unlink(sun->sun_path);
|
if(*sun->sun_path)unlink(sun->sun_path);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
size = sizeof(srv.intsa);
|
size = sizeof(srv.intsa);
|
||||||
@ -1064,7 +1059,12 @@ void srvinit2(struct srvparam * srv, struct clientparam *param){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void srvfree(struct srvparam * srv){
|
void srvfree(struct srvparam * srv){
|
||||||
if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->so.state, srv->srvsock);
|
if(srv->srvsock != INVALID_SOCKET) {
|
||||||
|
so._closesocket(srv->so.state, srv->srvsock);
|
||||||
|
#ifdef WITH_UN
|
||||||
|
if(*SAFAMILY(&srv->intsa) == AF_UNIX && *SAADDR(&srv->intsa))unlink((char *)SAADDR(&srv->intsa));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
srv->srvsock = INVALID_SOCKET;
|
srv->srvsock = INVALID_SOCKET;
|
||||||
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->so.state, srv->cbsock);
|
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->so.state, srv->cbsock);
|
||||||
srv->cbsock = INVALID_SOCKET;
|
srv->cbsock = INVALID_SOCKET;
|
||||||
|
|||||||
@ -156,7 +156,7 @@ int
|
|||||||
#define UN_SAADDRLEN(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (int)sizeof(((struct sockaddr_un *)sa)->sun_path) :
|
#define UN_SAADDRLEN(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (int)sizeof(((struct sockaddr_un *)sa)->sun_path) :
|
||||||
#define UN_SASOCK(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? PF_UNIX :
|
#define UN_SASOCK(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? PF_UNIX :
|
||||||
#define UN_SASIZE(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? sizeof(struct sockaddr_un) :
|
#define UN_SASIZE(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? sizeof(struct sockaddr_un) :
|
||||||
#define UN_SAISNULL(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (*((struct sockaddr_un *)sa)->sun_path == 0) :
|
#define UN_SAISNULL(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (((struct sockaddr_un *)sa)->sun_path[0] == 0 && ((struct sockaddr_un *)sa)->sun_path[1] == 0) :
|
||||||
#else
|
#else
|
||||||
#define UN_SAPORT(sa)
|
#define UN_SAPORT(sa)
|
||||||
#define UN_SAADDR(sa)
|
#define UN_SAADDR(sa)
|
||||||
|
|||||||
13
src/tcppm.c
13
src/tcppm.c
@ -16,7 +16,18 @@
|
|||||||
void * tcppmchild(struct clientparam* param) {
|
void * tcppmchild(struct clientparam* param) {
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if(!param->hostname && parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))) RETURN(100);
|
if(!param->hostname){
|
||||||
|
#ifdef WITH_UN
|
||||||
|
if(!strncmp((char *)param->srv->target, "unix:", 5)){
|
||||||
|
make_un(param->srv->target + 5, (struct sockaddr_un *)¶m->sinsr);
|
||||||
|
make_un(param->srv->target + 5, (struct sockaddr_un *)¶m->req);
|
||||||
|
param->hostname = (unsigned char *)mystrdup((char *)param->srv->target);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if(
|
||||||
|
parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport))
|
||||||
|
) RETURN(100);
|
||||||
|
}
|
||||||
param->operation = CONNECT;
|
param->operation = CONNECT;
|
||||||
res = (*param->srv->authfunc)(param);
|
res = (*param->srv->authfunc)(param);
|
||||||
if(res) {RETURN(res);}
|
if(res) {RETURN(res);}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user