From c206349ee25f3fb69b5901396ac98fdf15039290 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 12 Apr 2026 00:30:35 +0300 Subject: [PATCH] Support unix sockets for internal and -i Example configuration: log auto -iunix:/path/to/3proxy.sock test with curl --unix-socket /path/to/3proxy.sock https://3proxy.ru --- .github/workflows/c-cpp-cmake.yml | 2 +- CMakeLists.txt | 13 +++ Makefile.FreeBSD | 2 +- Makefile.Linux | 2 +- Makefile.unix | 2 +- src/auth.c | 18 +-- src/authradius.c | 6 +- src/common.c | 22 +++- src/conf.c | 47 +++----- .../TransparentPlugin/transparent_plugin.c | 6 +- src/proxy.h | 9 +- src/proxymain.c | 45 ++++++-- src/socks.c | 6 +- src/structures.h | 108 +++++++++--------- 14 files changed, 153 insertions(+), 135 deletions(-) diff --git a/.github/workflows/c-cpp-cmake.yml b/.github/workflows/c-cpp-cmake.yml index 8f736d0..4f4030a 100644 --- a/.github/workflows/c-cpp-cmake.yml +++ b/.github/workflows/c-cpp-cmake.yml @@ -2,7 +2,7 @@ name: C/C++ CI cmake on: push: - branches: [ "master" ] + branches: [ "master", "unix_socket" ] paths: [ '**.c', '**.h', '**.cmake', 'CMakeLists.txt', '.github/configs', '.github/workflows/c-cpp-cmake.yml' ] pull_request: branches: [ "master" ] diff --git a/CMakeLists.txt b/CMakeLists.txt index 001a8cc..a12fa6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ option(3PROXY_USE_SPLICE "Use Linux splice() for zero-copy (Linux only)" ON) option(3PROXY_USE_POLL "Use poll() instead of select() (Unix only)" ON) option(3PROXY_USE_WSAPOLL "Use WSAPoll instead of select() (Windows only)" ON) option(3PROXY_USE_NETFILTER "Enable Linux netfilter support (Linux only)" ON) +option(3PROXY_USE_UNIX_SOCKETS "Enable Unix domain socket support (Unix only)" ON) # Output directory set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) @@ -159,6 +160,10 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_compile_definitions(WITH_NETFILTER) endif() + if(3PROXY_USE_UNIX_SOCKETS) + add_compile_definitions(WITH_UN) + endif() + set(DEFAULT_PLUGINS StringsPlugin TrafficPlugin @@ -176,6 +181,10 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|Darwin|OpenBSD|NetBSD") add_compile_options(-fno-strict-aliasing) endif() + if(3PROXY_USE_UNIX_SOCKETS) + add_compile_definitions(WITH_UN) + endif() + set(DEFAULT_PLUGINS StringsPlugin TrafficPlugin @@ -188,6 +197,10 @@ else() add_compile_options(-fno-strict-aliasing) endif() + if(3PROXY_USE_UNIX_SOCKETS) + add_compile_definitions(WITH_UN) + endif() + set(DEFAULT_PLUGINS StringsPlugin TrafficPlugin diff --git a/Makefile.FreeBSD b/Makefile.FreeBSD index 3edaf42..99037bb 100644 --- a/Makefile.FreeBSD +++ b/Makefile.FreeBSD @@ -7,7 +7,7 @@ BUILDDIR = ../bin/ CC ?= cc -CFLAGS := -c -fno-strict-aliasing -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL $(CFLAGS) +CFLAGS := -c -fno-strict-aliasing -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_UN $(CFLAGS) COUT = -o LN ?= ${CC} LDFLAGS += -pthread -fno-strict-aliasing diff --git a/Makefile.Linux b/Makefile.Linux index c8bdc05..3276a3d 100644 --- a/Makefile.Linux +++ b/Makefile.Linux @@ -7,7 +7,7 @@ BUILDDIR = ../bin/ CC ?= gcc -CFLAGS := -g -fPIC -O2 -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER $(CFLAGS) +CFLAGS := -g -fPIC -O2 -fno-strict-aliasing -c -pthread -DWITHSPLICE -D_GNU_SOURCE -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_NETFILTER -D WITH_UN $(CFLAGS) COUT = -o LN ?= ${CC} DCFLAGS ?= diff --git a/Makefile.unix b/Makefile.unix index 5a0057a..c849046 100644 --- a/Makefile.unix +++ b/Makefile.unix @@ -9,7 +9,7 @@ BUILDDIR = ../bin/ CC ?= gcc # you may need -L/usr/pkg/lib for older NetBSD versions -CFLAGS := -g -O2 -fno-strict-aliasing -c -pthread -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL $(CFLAGS) +CFLAGS := -g -O2 -fno-strict-aliasing -c -pthread -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DFD_SETSIZE=4096 -DWITH_POLL -DWITH_UN $(CFLAGS) COUT = -o LN ?= $(CC) LDFLAGS ?= -O2 -fno-strict-aliasing -pthread diff --git a/src/auth.c b/src/auth.c index c133694..3758308 100644 --- a/src/auth.c +++ b/src/auth.c @@ -255,7 +255,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){ if(!connected){ if(cur->type == R_EXTIP){ param->sinsl = cur->addr; - if(SAISNULL(¶m->sinsl))param->sinsl = param->sincr; + if(SAISNULL(¶m->sinsl) && (*SAFAMILY(¶m->sincr) == AF_INET || *SAFAMILY(¶m->sincr) == AF_INET6))param->sinsl = param->sincr; #ifndef NOIPV6 else if(cur->cidr && *SAFAMILY(¶m->sinsl) == AF_INET6){ uint16_t c; @@ -766,11 +766,8 @@ struct authcache { char * username; char * password; time_t expires; -#ifndef NOIPV6 - struct sockaddr_in6 sa, sinsl; -#else - struct sockaddr_in sa, sinsl; -#endif + PROXYSOCKADDRTYPE sa; + PROXYSOCKADDRTYPE sinsl; struct ace *acl; struct authcache *next; } *authc = NULL; @@ -1209,13 +1206,8 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_ int j, k, len, flen; SOCKET sock; uint32_t ttl; -#ifndef NOIPV6 - struct sockaddr_in6 addr; - struct sockaddr_in6 *sinsr, *sinsl; -#else - struct sockaddr_in addr; - struct sockaddr_in *sinsr, *sinsl; -#endif + PROXYSOCKADDRTYPE addr; + PROXYSOCKADDRTYPE *sinsr, *sinsl; int usetcp = 0; unsigned short serial = 1; diff --git a/src/authradius.c b/src/authradius.c index f0ee54c..405639c 100644 --- a/src/authradius.c +++ b/src/authradius.c @@ -306,11 +306,7 @@ int radsend(struct clientparam * param, int auth, int stop){ int total_length; int len; int op; -#ifdef NOIPV6 - struct sockaddr_in saremote; -#else - struct sockaddr_in6 saremote; -#endif + PROXYSOCKADDRTYPE saremote; struct pollfd fds[1]; char vector[AUTH_VECTOR_LEN]; radius_packet_t packet, rpacket; diff --git a/src/common.c b/src/common.c index b60bce7..e705c19 100644 --- a/src/common.c +++ b/src/common.c @@ -63,12 +63,26 @@ int mutex_unlock(int *val) #endif int myinet_ntop(int af, void *src, char *dst, socklen_t size){ +#ifdef WITH_UN + if(af == AF_UNIX){ + struct sockaddr_un *sun = (struct sockaddr_un *)src; + char *path = sun->sun_path; + char *basename = strrchr(path, '/'); + if(basename) basename++; + else basename = path; + if(size > 0){ + strncpy(dst, basename, (size > 40) ? 40 : size - 1); + dst[((size > 40) ? 40 : size - 1)] = 0; + } + return (int)strlen(dst); + } +#endif #ifndef NOIPV6 if(af != AF_INET6){ -#endif +#endif unsigned u = ntohl(((struct in_addr *)src)->s_addr); - return sprintf(dst, "%u.%u.%u.%u", - ((u&0xFF000000)>>24), + return sprintf(dst, "%u.%u.%u.%u", + ((u&0xFF000000)>>24), ((u&0x00FF0000)>>16), ((u&0x0000FF00)>>8), ((u&0x000000FF))); @@ -77,7 +91,7 @@ int myinet_ntop(int af, void *src, char *dst, socklen_t size){ *dst = 0; inet_ntop(af, src, dst, size); return (int)strlen(dst); -#endif +#endif } char *rotations[] = { diff --git a/src/conf.c b/src/conf.c index a525136..f9c44c0 100644 --- a/src/conf.c +++ b/src/conf.c @@ -285,17 +285,26 @@ static int h_proxy(int argc, unsigned char ** argv){ } static int h_internal(int argc, unsigned char ** argv){ - getip46(46, argv[1], (struct sockaddr *)&conf.intsa); +#ifdef WITH_UN + if(!strncmp((char *)argv[1], "unix:", 5)){ + struct sockaddr_un *sun = (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 +#endif + getip46(46, argv[1], (struct sockaddr *)&conf.intsa); return 0; } static int h_external(int argc, unsigned char ** argv){ int res; #ifndef NOIPV6 - struct sockaddr_in6 sa6; + PROXYSOCKADDRTYPE sa6; memset(&sa6, 0, sizeof(sa6)); res = getip46(46, argv[1], (struct sockaddr *)&sa6); - if(!res) return 1; + if(!res) return 1; if (*SAFAMILY(&sa6)==AF_INET) conf.extsa = sa6; else conf.extsa6 = sa6; #else @@ -687,11 +696,7 @@ static int h_nscache6(int argc, unsigned char **argv){ } static int h_nsrecord(int argc, unsigned char **argv){ -#ifndef NOIPV6 - struct sockaddr_in6 sa; -#else - struct sockaddr_in sa; -#endif + PROXYSOCKADDRTYPE sa; memset(&sa, 0, sizeof(sa)); if(!getip46(46, argv[2], (struct sockaddr *)&sa)) return 1; @@ -842,11 +847,7 @@ static int h_nolog(int argc, unsigned char **argv){ } int scanipl(unsigned char *arg, struct iplist *dst){ -#ifndef NOIPV6 - struct sockaddr_in6 sa; -#else - struct sockaddr_in sa; -#endif + PROXYSOCKADDRTYPE sa; char * slash, *dash; int masklen, addrlen; int res; @@ -1397,21 +1398,6 @@ static int h_delimchar(int argc, unsigned char **argv){ static int h_radius(int argc, unsigned char **argv){ uint16_t port; -/* - int oldrad; -#ifdef NOIPV6 - struct sockaddr_in bindaddr; -#else - struct sockaddr_in6 bindaddr; -#endif - - oldrad = nradservers; - nradservers = 0; - for(; oldrad; oldrad--){ - if(radiuslist[oldrad].logsock >= 0) so._closesocket(radiuslist[oldrad].logsock); - radiuslist[oldrad].logsock = -1; - } -*/ memset(radiuslist, 0, sizeof(radiuslist)); if(strlen((char *)argv[1]) > 63) argv[1][63] = 0; strcpy(radiussecret, (char *)argv[1]); @@ -1427,11 +1413,6 @@ static int h_radius(int argc, unsigned char **argv){ port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr)); radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr; *SAPORT(&radiuslist[nradservers].logaddr) = htons(port+1); -/* - bindaddr = radiuslist[nradservers].localaddr; - if ((radiuslist[nradservers].logsock = so._socket(SASOCK(&radiuslist[nradservers].logaddr), SOCK_DGRAM, 0)) < 0) return 2; - if (so._bind(radiuslist[nradservers].logsock, (struct sockaddr *)&bindaddr, SASIZE(&bindaddr))) return 3; -*/ } return 0; } diff --git a/src/plugins/TransparentPlugin/transparent_plugin.c b/src/plugins/TransparentPlugin/transparent_plugin.c index f46eb7d..f191f17 100644 --- a/src/plugins/TransparentPlugin/transparent_plugin.c +++ b/src/plugins/TransparentPlugin/transparent_plugin.c @@ -58,8 +58,10 @@ static FILTER_ACTION transparent_filter_client(void *fo, struct clientparam * pa return REJECT; #endif #else - param->req = param->sincl; - param->sincl = param->srv->intsa; + if(*SAFAMILY(¶m->sincl) == AF_INET || *SAFAMILY(¶m->sincl) == AF_INET6){ + param->req = param->sincl; + param->sincl = param->srv->intsa; + } #endif pl->myinet_ntop(*SAFAMILY(¶m->req), SAADDR(¶m->req), (char *)addrbuf, sizeof(addrbuf)); if(param->hostname) pl->freefunc(param->hostname); diff --git a/src/proxy.h b/src/proxy.h index e96a17e..d932654 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -328,14 +328,7 @@ extern struct commands commandhandlers[]; extern struct radserver { -#ifdef NOIPV6 - struct sockaddr_in authaddr, logaddr, localaddr; -#else - struct sockaddr_in6 authaddr, logaddr, localaddr; -#endif -/* - SOCKET logsock; -*/ + PROXYSOCKADDRTYPE authaddr, logaddr, localaddr; } radiuslist[MAXRADIUS]; extern char radiussecret[64]; diff --git a/src/proxymain.c b/src/proxymain.c index 9bd58b5..7ffaeec 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -252,11 +252,7 @@ int MODULEMAINFUNC (int argc, char** argv){ char *hostname=NULL; int opt = 1, isudp = 0, iscbl = 0, iscbc = 0; unsigned char *cbc_string = NULL, *cbl_string = NULL; -#ifndef NOIPV6 - struct sockaddr_in6 cbsa; -#else - struct sockaddr_in cbsa; -#endif + PROXYSOCKADDRTYPE cbsa; FILE *fp = NULL; struct linger lg; int nlog = 5000; @@ -409,18 +405,27 @@ int MODULEMAINFUNC (int argc, char** argv){ } break; case 'i': +#ifdef WITH_UN + if(!strncmp((char *)argv[i]+2, "unix:", 5)){ + struct sockaddr_un *sun = (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 +#endif getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.intsa); break; case 'e': { #ifndef NOIPV6 - struct sockaddr_in6 sa6; + PROXYSOCKADDRTYPE sa6; memset(&sa6, 0, sizeof(sa6)); error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6); if(!error) { if (*SAFAMILY(&sa6)==AF_INET) srv.extsa = sa6; else srv.extsa6 = sa6; - } + } #else error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extsa); #endif @@ -654,6 +659,12 @@ int MODULEMAINFUNC (int argc, char** argv){ if (!iscbc) { 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){ sock=srv.so._socket(srv.so.state, SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP); } @@ -671,12 +682,17 @@ int MODULEMAINFUNC (int argc, char** argv){ fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL)); #endif srv.srvsock = sock; +#ifdef WITH_UN + if(*SAFAMILY(&srv.intsa) != AF_UNIX) +#endif + { opt = 1; if(srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()"); #ifdef SO_REUSEPORT opt = 1; srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int)); #endif + } #if defined SO_BINDTODEVICE if(srv.ibindtodevice && srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1)) { dolog(&defparam, (unsigned char *)"failed to bind device"); @@ -699,11 +715,17 @@ int MODULEMAINFUNC (int argc, char** argv){ } #endif } +#ifdef WITH_UN + if(*SAFAMILY(&srv.intsa) == AF_UNIX){ + struct sockaddr_un *sun = (struct sockaddr_un *)&srv.intsa; + unlink(sun->sun_path); + } +#endif size = sizeof(srv.intsa); for(sleeptime = SLEEPTIME * 100; srv.so._bind(srv.so.state, sock, (struct sockaddr*)&srv.intsa, SASIZE(&srv.intsa))==-1; usleep(sleeptime)) { sprintf((char *)buf, "bind(): %s", strerror(errno)); - if(!srv.silent)dolog(&defparam, buf); - sleeptime = (sleeptime<<1); + if(!srv.silent)dolog(&defparam, buf); + sleeptime = (sleeptime<<1); if(!sleeptime) { srv.so._closesocket(srv.so.state, sock); return -3; @@ -716,7 +738,7 @@ int MODULEMAINFUNC (int argc, char** argv){ return -4; } } - else + else defparam.clisock = sock; if(!srv.silent && !iscbc){ @@ -869,6 +891,9 @@ int MODULEMAINFUNC (int argc, char** argv){ if(!srv.silent)dolog(&defparam, buf); continue; } +#ifdef WITH_UN + if(*SAFAMILY(&defparam.sincl) == AF_UNIX) defparam.sincr = defparam.sincl; +#endif #ifdef _WIN32 ioctlsocket(new_sock, FIONBIO, &ul); #else diff --git a/src/socks.c b/src/socks.c index aee6d38..b233d82 100644 --- a/src/socks.c +++ b/src/socks.c @@ -44,11 +44,7 @@ void * sockschild(struct clientparam* param) { struct pollfd fds[3]; int ver=0; int havepass = 0; -#ifndef NOIPV6 - struct sockaddr_in6 sin = {AF_INET6}; -#else - struct sockaddr_in sin = {AF_INET}; -#endif + PROXYSOCKADDRTYPE sin; int len; diff --git a/src/structures.h b/src/structures.h index d3da058..9d6d006 100644 --- a/src/structures.h +++ b/src/structures.h @@ -106,6 +106,9 @@ int #endif #endif +#ifdef WITH_UN +#include +#endif #define ALLOW 0 #define DENY 1 @@ -141,23 +144,52 @@ int #define DNSRESOLVE 0x00100000 #define ADMIN 0x01000000 +#ifdef NO_UN +#undef WITH_UN +#endif #define SAFAMILY(sa) (&(((struct sockaddr_in *)sa)->sin_family)) -#ifndef NOIPV6 -#define SAPORT(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? &((struct sockaddr_in6 *)sa)->sin6_port : &((struct sockaddr_in *)sa)->sin_port) -#define SAADDR(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)&((struct sockaddr_in6 *)sa)->sin6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr) -#define SAADDRLEN(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4) -#define SASOCK(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? PF_INET6:PF_INET) -#define SASIZE(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) -#define SAISNULL(sa) (!memcmp(((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)&((struct sockaddr_in6 *)sa)->sin6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr, NULLADDR, (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4))) +#ifdef WITH_UN +#define UN_SAPORT(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (uint16_t *)(((uint8_t *)(sa)) + sizeof(struct sockaddr_storage) - 2) : +#define UN_SAADDR(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (unsigned char *)((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_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) : #else -#define SAPORT(sa) (&((struct sockaddr_in *)sa)->sin_port) -#define SAADDR(sa) ((unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr) -#define SAADDRLEN(sa) (4) -#define SASOCK(sa) (PF_INET) -#define SASIZE(sa) (sizeof(struct sockaddr_in)) -#define SAISNULL(sa) (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0) +#define UN_SAPORT(sa) +#define UN_SAADDR(sa) +#define UN_SAADDRLEN(sa) +#define UN_SASOCK(sa) +#define UN_SASIZE(sa) +#define UN_SAISNULL(sa) +#endif + +#ifndef NOIPV6 +#define SAPORT(sa) ( UN_SAPORT(sa) ((struct sockaddr_in *)sa)->sin_family == AF_INET6? &((struct sockaddr_in6 *)sa)->sin6_port : &((struct sockaddr_in *)sa)->sin_port) +#define SAADDR(sa) ( UN_SAADDR(sa) ((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)&((struct sockaddr_in6 *)sa)->sin6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr) +#define SAADDRLEN(sa) ( UN_SAADDRLEN(sa) ((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4) +#define SASOCK(sa) ( UN_SASOCK(sa) ((struct sockaddr_in *)sa)->sin_family == AF_INET6? PF_INET6:PF_INET) +#define SASIZE(sa) ( UN_SASIZE(sa) ((struct sockaddr_in *)sa)->sin_family == AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) +#define SAISNULL(sa) ( UN_SAISNULL(sa) !memcmp(((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)&((struct sockaddr_in6 *)sa)->sin6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr, NULLADDR, (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4))) +#else +#define SAPORT(sa) ( UN_SAPORT(sa) &((struct sockaddr_in *)sa)->sin_port) +#define SAADDR(sa) ( UN_SAADDR(sa) (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr) +#define SAADDRLEN(sa) ( UN_SAADDRLEN(sa) 4) +#define SASOCK(sa) ( UN_SASOCK(sa) PF_INET) +#define SASIZE(sa) ( UN_SASIZE(sa) sizeof(struct sockaddr_in)) +#define SAISNULL(sa) ( UN_SAISNULL(sa) ((struct sockaddr_in *)sa)->sin_addr.s_addr == 0) +#endif + +#ifdef WITH_UN +#define PROXYSOCKADDRTYPE struct sockaddr_storage +#else +#ifndef NOIPv6 +#define PROXYSOCKADDRTYPE struct sockaddr_in6 +#else +#define PROXYSOCKADDRTYPE struct sockaddr_in +#endif #endif extern char* NULLADDR; @@ -230,13 +262,8 @@ struct auth { struct iplist { struct iplist *next; int family; -#ifndef NOIPV6 - struct in6_addr ip_from; - struct in6_addr ip_to; -#else - struct in_addr ip_from; - struct in_addr ip_to; -#endif + PROXYSOCKADDRTYPE ip_from; + PROXYSOCKADDRTYPE ip_to; }; struct portlist { @@ -299,11 +326,7 @@ extern struct redirdesc redirs[]; struct chain { struct chain * next; int type; -#ifndef NOIPV6 - struct sockaddr_in6 addr; -#else - struct sockaddr_in addr; -#endif + PROXYSOCKADDRTYPE addr; unsigned char * exthost; unsigned char * extuser; unsigned char * extpass; @@ -384,11 +407,7 @@ struct trafcount { }; struct nserver { -#ifndef NOIPV6 - struct sockaddr_in6 addr; -#else - struct sockaddr_in addr; -#endif + PROXYSOCKADDRTYPE addr; int usetcp; }; extern int numservers; @@ -510,18 +529,11 @@ struct srvparam { #endif unsigned bufsize; unsigned logdumpsrv, logdumpcli; + PROXYSOCKADDRTYPE intsa, intNat, extNat; #ifndef NOIPV6 - struct sockaddr_in6 intsa; - struct sockaddr_in6 extsa6; - struct sockaddr_in6 extsa; - struct sockaddr_in6 extNat; - struct sockaddr_in6 intNat; -#else - struct sockaddr_in intsa; - struct sockaddr_in extsa; - struct sockaddr_in extNat; - struct sockaddr_in intNat; + PROXYSOCKADDRTYPE extsa6; #endif + PROXYSOCKADDRTYPE extsa; pthread_mutex_t counter_mutex; struct pollfd fds; FILE *stdlog; @@ -613,11 +625,8 @@ struct clientparam { uint64_t maxtrafin64, maxtrafout64; -#ifndef NOIPV6 - struct sockaddr_in6 sincl, sincr, sinsl, sinsr, req; -#else - struct sockaddr_in sincl, sincr, sinsl, sinsr, req; -#endif + PROXYSOCKADDRTYPE sincl, sincr; + PROXYSOCKADDRTYPE sinsl, sinsr, req; uint64_t statscli64, statssrv64; @@ -662,14 +671,11 @@ struct extparam { unsigned char *logname, **archiver; ROTATION logtype, countertype; char * counterfile; + PROXYSOCKADDRTYPE intsa; #ifndef NOIPV6 - struct sockaddr_in6 intsa; - struct sockaddr_in6 extsa6; - struct sockaddr_in6 extsa; -#else - struct sockaddr_in intsa; - struct sockaddr_in extsa; + PROXYSOCKADDRTYPE extsa6; #endif + PROXYSOCKADDRTYPE extsa; struct passwords *pwl; struct auth * authenticate; AUTHFUNC authfunc;