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
This commit is contained in:
Vladimir Dubrovin 2026-04-12 00:30:35 +03:00
parent 77b0dc3397
commit c206349ee2
14 changed files with 153 additions and 135 deletions

View File

@ -2,7 +2,7 @@ name: C/C++ CI cmake
on: on:
push: push:
branches: [ "master" ] branches: [ "master", "unix_socket" ]
paths: [ '**.c', '**.h', '**.cmake', 'CMakeLists.txt', '.github/configs', '.github/workflows/c-cpp-cmake.yml' ] paths: [ '**.c', '**.h', '**.cmake', 'CMakeLists.txt', '.github/configs', '.github/workflows/c-cpp-cmake.yml' ]
pull_request: pull_request:
branches: [ "master" ] branches: [ "master" ]

View File

@ -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_POLL "Use poll() instead of select() (Unix only)" ON)
option(3PROXY_USE_WSAPOLL "Use WSAPoll instead of select() (Windows 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_NETFILTER "Enable Linux netfilter support (Linux only)" ON)
option(3PROXY_USE_UNIX_SOCKETS "Enable Unix domain socket support (Unix only)" ON)
# Output directory # Output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
@ -159,6 +160,10 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_compile_definitions(WITH_NETFILTER) add_compile_definitions(WITH_NETFILTER)
endif() endif()
if(3PROXY_USE_UNIX_SOCKETS)
add_compile_definitions(WITH_UN)
endif()
set(DEFAULT_PLUGINS set(DEFAULT_PLUGINS
StringsPlugin StringsPlugin
TrafficPlugin TrafficPlugin
@ -176,6 +181,10 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|Darwin|OpenBSD|NetBSD")
add_compile_options(-fno-strict-aliasing) add_compile_options(-fno-strict-aliasing)
endif() endif()
if(3PROXY_USE_UNIX_SOCKETS)
add_compile_definitions(WITH_UN)
endif()
set(DEFAULT_PLUGINS set(DEFAULT_PLUGINS
StringsPlugin StringsPlugin
TrafficPlugin TrafficPlugin
@ -188,6 +197,10 @@ else()
add_compile_options(-fno-strict-aliasing) add_compile_options(-fno-strict-aliasing)
endif() endif()
if(3PROXY_USE_UNIX_SOCKETS)
add_compile_definitions(WITH_UN)
endif()
set(DEFAULT_PLUGINS set(DEFAULT_PLUGINS
StringsPlugin StringsPlugin
TrafficPlugin TrafficPlugin

View File

@ -7,7 +7,7 @@
BUILDDIR = ../bin/ BUILDDIR = ../bin/
CC ?= cc 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 COUT = -o
LN ?= ${CC} LN ?= ${CC}
LDFLAGS += -pthread -fno-strict-aliasing LDFLAGS += -pthread -fno-strict-aliasing

View File

@ -7,7 +7,7 @@
BUILDDIR = ../bin/ BUILDDIR = ../bin/
CC ?= gcc 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 COUT = -o
LN ?= ${CC} LN ?= ${CC}
DCFLAGS ?= DCFLAGS ?=

View File

@ -9,7 +9,7 @@ BUILDDIR = ../bin/
CC ?= gcc CC ?= gcc
# you may need -L/usr/pkg/lib for older NetBSD versions # 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 COUT = -o
LN ?= $(CC) LN ?= $(CC)
LDFLAGS ?= -O2 -fno-strict-aliasing -pthread LDFLAGS ?= -O2 -fno-strict-aliasing -pthread

View File

@ -255,7 +255,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
if(!connected){ if(!connected){
if(cur->type == R_EXTIP){ if(cur->type == R_EXTIP){
param->sinsl = cur->addr; param->sinsl = cur->addr;
if(SAISNULL(&param->sinsl))param->sinsl = param->sincr; if(SAISNULL(&param->sinsl) && (*SAFAMILY(&param->sincr) == AF_INET || *SAFAMILY(&param->sincr) == AF_INET6))param->sinsl = param->sincr;
#ifndef NOIPV6 #ifndef NOIPV6
else if(cur->cidr && *SAFAMILY(&param->sinsl) == AF_INET6){ else if(cur->cidr && *SAFAMILY(&param->sinsl) == AF_INET6){
uint16_t c; uint16_t c;
@ -766,11 +766,8 @@ struct authcache {
char * username; char * username;
char * password; char * password;
time_t expires; time_t expires;
#ifndef NOIPV6 PROXYSOCKADDRTYPE sa;
struct sockaddr_in6 sa, sinsl; PROXYSOCKADDRTYPE sinsl;
#else
struct sockaddr_in sa, sinsl;
#endif
struct ace *acl; struct ace *acl;
struct authcache *next; struct authcache *next;
} *authc = NULL; } *authc = NULL;
@ -1209,13 +1206,8 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
int j, k, len, flen; int j, k, len, flen;
SOCKET sock; SOCKET sock;
uint32_t ttl; uint32_t ttl;
#ifndef NOIPV6 PROXYSOCKADDRTYPE addr;
struct sockaddr_in6 addr; PROXYSOCKADDRTYPE *sinsr, *sinsl;
struct sockaddr_in6 *sinsr, *sinsl;
#else
struct sockaddr_in addr;
struct sockaddr_in *sinsr, *sinsl;
#endif
int usetcp = 0; int usetcp = 0;
unsigned short serial = 1; unsigned short serial = 1;

View File

@ -306,11 +306,7 @@ int radsend(struct clientparam * param, int auth, int stop){
int total_length; int total_length;
int len; int len;
int op; int op;
#ifdef NOIPV6 PROXYSOCKADDRTYPE saremote;
struct sockaddr_in saremote;
#else
struct sockaddr_in6 saremote;
#endif
struct pollfd fds[1]; struct pollfd fds[1];
char vector[AUTH_VECTOR_LEN]; char vector[AUTH_VECTOR_LEN];
radius_packet_t packet, rpacket; radius_packet_t packet, rpacket;

View File

@ -63,6 +63,20 @@ int mutex_unlock(int *val)
#endif #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
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 #ifndef NOIPV6
if(af != AF_INET6){ if(af != AF_INET6){
#endif #endif

View File

@ -285,6 +285,15 @@ 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
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); getip46(46, argv[1], (struct sockaddr *)&conf.intsa);
return 0; return 0;
} }
@ -292,7 +301,7 @@ static int h_internal(int argc, unsigned char ** argv){
static int h_external(int argc, unsigned char ** argv){ static int h_external(int argc, unsigned char ** argv){
int res; int res;
#ifndef NOIPV6 #ifndef NOIPV6
struct sockaddr_in6 sa6; PROXYSOCKADDRTYPE sa6;
memset(&sa6, 0, sizeof(sa6)); memset(&sa6, 0, sizeof(sa6));
res = getip46(46, argv[1], (struct sockaddr *)&sa6); res = getip46(46, argv[1], (struct sockaddr *)&sa6);
if(!res) return 1; if(!res) return 1;
@ -687,11 +696,7 @@ static int h_nscache6(int argc, unsigned char **argv){
} }
static int h_nsrecord(int argc, unsigned char **argv){ static int h_nsrecord(int argc, unsigned char **argv){
#ifndef NOIPV6 PROXYSOCKADDRTYPE sa;
struct sockaddr_in6 sa;
#else
struct sockaddr_in sa;
#endif
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
if(!getip46(46, argv[2], (struct sockaddr *)&sa)) return 1; 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){ int scanipl(unsigned char *arg, struct iplist *dst){
#ifndef NOIPV6 PROXYSOCKADDRTYPE sa;
struct sockaddr_in6 sa;
#else
struct sockaddr_in sa;
#endif
char * slash, *dash; char * slash, *dash;
int masklen, addrlen; int masklen, addrlen;
int res; int res;
@ -1397,21 +1398,6 @@ static int h_delimchar(int argc, unsigned char **argv){
static int h_radius(int argc, unsigned char **argv){ static int h_radius(int argc, unsigned char **argv){
uint16_t port; 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)); memset(radiuslist, 0, sizeof(radiuslist));
if(strlen((char *)argv[1]) > 63) argv[1][63] = 0; if(strlen((char *)argv[1]) > 63) argv[1][63] = 0;
strcpy(radiussecret, (char *)argv[1]); strcpy(radiussecret, (char *)argv[1]);
@ -1427,11 +1413,6 @@ static int h_radius(int argc, unsigned char **argv){
port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr)); port = ntohs(*SAPORT(&radiuslist[nradservers].authaddr));
radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr; radiuslist[nradservers].logaddr = radiuslist[nradservers].authaddr;
*SAPORT(&radiuslist[nradservers].logaddr) = htons(port+1); *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; return 0;
} }

View File

@ -58,8 +58,10 @@ static FILTER_ACTION transparent_filter_client(void *fo, struct clientparam * pa
return REJECT; return REJECT;
#endif #endif
#else #else
if(*SAFAMILY(&param->sincl) == AF_INET || *SAFAMILY(&param->sincl) == AF_INET6){
param->req = param->sincl; param->req = param->sincl;
param->sincl = param->srv->intsa; param->sincl = param->srv->intsa;
}
#endif #endif
pl->myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)addrbuf, sizeof(addrbuf)); pl->myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)addrbuf, sizeof(addrbuf));
if(param->hostname) pl->freefunc(param->hostname); if(param->hostname) pl->freefunc(param->hostname);

View File

@ -328,14 +328,7 @@ extern struct commands commandhandlers[];
extern struct radserver { extern struct radserver {
#ifdef NOIPV6 PROXYSOCKADDRTYPE authaddr, logaddr, localaddr;
struct sockaddr_in authaddr, logaddr, localaddr;
#else
struct sockaddr_in6 authaddr, logaddr, localaddr;
#endif
/*
SOCKET logsock;
*/
} radiuslist[MAXRADIUS]; } radiuslist[MAXRADIUS];
extern char radiussecret[64]; extern char radiussecret[64];

View File

@ -252,11 +252,7 @@ int MODULEMAINFUNC (int argc, char** argv){
char *hostname=NULL; char *hostname=NULL;
int opt = 1, isudp = 0, iscbl = 0, iscbc = 0; int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
unsigned char *cbc_string = NULL, *cbl_string = NULL; unsigned char *cbc_string = NULL, *cbl_string = NULL;
#ifndef NOIPV6 PROXYSOCKADDRTYPE cbsa;
struct sockaddr_in6 cbsa;
#else
struct sockaddr_in cbsa;
#endif
FILE *fp = NULL; FILE *fp = NULL;
struct linger lg; struct linger lg;
int nlog = 5000; int nlog = 5000;
@ -409,12 +405,21 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
break; break;
case 'i': 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); getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.intsa);
break; break;
case 'e': case 'e':
{ {
#ifndef NOIPV6 #ifndef NOIPV6
struct sockaddr_in6 sa6; PROXYSOCKADDRTYPE sa6;
memset(&sa6, 0, sizeof(sa6)); memset(&sa6, 0, sizeof(sa6));
error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6); error = !getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&sa6);
if(!error) { if(!error) {
@ -654,6 +659,12 @@ 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, IPPROTO_TCP);
} }
@ -671,12 +682,17 @@ int MODULEMAINFUNC (int argc, char** argv){
fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL)); fcntl(sock,F_SETFL,O_NONBLOCK | fcntl(sock,F_GETFL));
#endif #endif
srv.srvsock = sock; srv.srvsock = sock;
#ifdef WITH_UN
if(*SAFAMILY(&srv.intsa) != AF_UNIX)
#endif
{
opt = 1; opt = 1;
if(srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()"); if(srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()");
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
opt = 1; opt = 1;
srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int)); srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(int));
#endif #endif
}
#if defined SO_BINDTODEVICE #if defined SO_BINDTODEVICE
if(srv.ibindtodevice && srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_BINDTODEVICE, srv.ibindtodevice, strlen(srv.ibindtodevice) + 1)) { 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"); dolog(&defparam, (unsigned char *)"failed to bind device");
@ -699,6 +715,12 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
#endif #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); 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)) { 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)); sprintf((char *)buf, "bind(): %s", strerror(errno));
@ -869,6 +891,9 @@ int MODULEMAINFUNC (int argc, char** argv){
if(!srv.silent)dolog(&defparam, buf); if(!srv.silent)dolog(&defparam, buf);
continue; continue;
} }
#ifdef WITH_UN
if(*SAFAMILY(&defparam.sincl) == AF_UNIX) defparam.sincr = defparam.sincl;
#endif
#ifdef _WIN32 #ifdef _WIN32
ioctlsocket(new_sock, FIONBIO, &ul); ioctlsocket(new_sock, FIONBIO, &ul);
#else #else

View File

@ -44,11 +44,7 @@ void * sockschild(struct clientparam* param) {
struct pollfd fds[3]; struct pollfd fds[3];
int ver=0; int ver=0;
int havepass = 0; int havepass = 0;
#ifndef NOIPV6 PROXYSOCKADDRTYPE sin;
struct sockaddr_in6 sin = {AF_INET6};
#else
struct sockaddr_in sin = {AF_INET};
#endif
int len; int len;

View File

@ -106,6 +106,9 @@ int
#endif #endif
#endif #endif
#ifdef WITH_UN
#include <sys/un.h>
#endif
#define ALLOW 0 #define ALLOW 0
#define DENY 1 #define DENY 1
@ -141,23 +144,52 @@ int
#define DNSRESOLVE 0x00100000 #define DNSRESOLVE 0x00100000
#define ADMIN 0x01000000 #define ADMIN 0x01000000
#ifdef NO_UN
#undef WITH_UN
#endif
#define SAFAMILY(sa) (&(((struct sockaddr_in *)sa)->sin_family)) #define SAFAMILY(sa) (&(((struct sockaddr_in *)sa)->sin_family))
#ifndef NOIPV6 #ifdef WITH_UN
#define SAPORT(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? &((struct sockaddr_in6 *)sa)->sin6_port : &((struct sockaddr_in *)sa)->sin_port) #define UN_SAPORT(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (uint16_t *)(((uint8_t *)(sa)) + sizeof(struct sockaddr_storage) - 2) :
#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 UN_SAADDR(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (unsigned char *)((struct sockaddr_un *)sa)->sun_path :
#define SAADDRLEN(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4) #define UN_SAADDRLEN(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (int)sizeof(((struct sockaddr_un *)sa)->sun_path) :
#define SASOCK(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? PF_INET6:PF_INET) #define UN_SASOCK(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? PF_UNIX :
#define SASIZE(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) #define UN_SASIZE(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? sizeof(struct sockaddr_un) :
#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))) #define UN_SAISNULL(sa) (((struct sockaddr_un *)sa)->sun_family == AF_UNIX)? (*((struct sockaddr_un *)sa)->sun_path == 0) :
#else #else
#define SAPORT(sa) (&((struct sockaddr_in *)sa)->sin_port) #define UN_SAPORT(sa)
#define SAADDR(sa) ((unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr) #define UN_SAADDR(sa)
#define SAADDRLEN(sa) (4) #define UN_SAADDRLEN(sa)
#define SASOCK(sa) (PF_INET) #define UN_SASOCK(sa)
#define SASIZE(sa) (sizeof(struct sockaddr_in)) #define UN_SASIZE(sa)
#define SAISNULL(sa) (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0) #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 #endif
extern char* NULLADDR; extern char* NULLADDR;
@ -230,13 +262,8 @@ struct auth {
struct iplist { struct iplist {
struct iplist *next; struct iplist *next;
int family; int family;
#ifndef NOIPV6 PROXYSOCKADDRTYPE ip_from;
struct in6_addr ip_from; PROXYSOCKADDRTYPE ip_to;
struct in6_addr ip_to;
#else
struct in_addr ip_from;
struct in_addr ip_to;
#endif
}; };
struct portlist { struct portlist {
@ -299,11 +326,7 @@ extern struct redirdesc redirs[];
struct chain { struct chain {
struct chain * next; struct chain * next;
int type; int type;
#ifndef NOIPV6 PROXYSOCKADDRTYPE addr;
struct sockaddr_in6 addr;
#else
struct sockaddr_in addr;
#endif
unsigned char * exthost; unsigned char * exthost;
unsigned char * extuser; unsigned char * extuser;
unsigned char * extpass; unsigned char * extpass;
@ -384,11 +407,7 @@ struct trafcount {
}; };
struct nserver { struct nserver {
#ifndef NOIPV6 PROXYSOCKADDRTYPE addr;
struct sockaddr_in6 addr;
#else
struct sockaddr_in addr;
#endif
int usetcp; int usetcp;
}; };
extern int numservers; extern int numservers;
@ -510,18 +529,11 @@ struct srvparam {
#endif #endif
unsigned bufsize; unsigned bufsize;
unsigned logdumpsrv, logdumpcli; unsigned logdumpsrv, logdumpcli;
PROXYSOCKADDRTYPE intsa, intNat, extNat;
#ifndef NOIPV6 #ifndef NOIPV6
struct sockaddr_in6 intsa; PROXYSOCKADDRTYPE extsa6;
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;
#endif #endif
PROXYSOCKADDRTYPE extsa;
pthread_mutex_t counter_mutex; pthread_mutex_t counter_mutex;
struct pollfd fds; struct pollfd fds;
FILE *stdlog; FILE *stdlog;
@ -613,11 +625,8 @@ struct clientparam {
uint64_t uint64_t
maxtrafin64, maxtrafin64,
maxtrafout64; maxtrafout64;
#ifndef NOIPV6 PROXYSOCKADDRTYPE sincl, sincr;
struct sockaddr_in6 sincl, sincr, sinsl, sinsr, req; PROXYSOCKADDRTYPE sinsl, sinsr, req;
#else
struct sockaddr_in sincl, sincr, sinsl, sinsr, req;
#endif
uint64_t statscli64, uint64_t statscli64,
statssrv64; statssrv64;
@ -662,14 +671,11 @@ struct extparam {
unsigned char *logname, **archiver; unsigned char *logname, **archiver;
ROTATION logtype, countertype; ROTATION logtype, countertype;
char * counterfile; char * counterfile;
PROXYSOCKADDRTYPE intsa;
#ifndef NOIPV6 #ifndef NOIPV6
struct sockaddr_in6 intsa; PROXYSOCKADDRTYPE extsa6;
struct sockaddr_in6 extsa6;
struct sockaddr_in6 extsa;
#else
struct sockaddr_in intsa;
struct sockaddr_in extsa;
#endif #endif
PROXYSOCKADDRTYPE extsa;
struct passwords *pwl; struct passwords *pwl;
struct auth * authenticate; struct auth * authenticate;
AUTHFUNC authfunc; AUTHFUNC authfunc;