diff -ur stunnel-4.34/src/common.h stunnel-4.34.unixsockets/src/common.h --- stunnel-4.34/src/common.h 2010-09-14 17:00:36.000000000 +0200 +++ stunnel-4.34.unixsockets/src/common.h 2010-10-19 15:09:39.125265992 +0200 @@ -238,6 +238,10 @@ #define ioctlsocket(a,b,c) ioctl((a),(b),(c)) #endif +#if defined(USE_UNIXSOCK) +#define UNIXSOCK_DIR "/var/run" +#endif + /* OpenVMS compatibility */ #ifdef __vms #define libdir "__NA__" @@ -295,6 +299,9 @@ #include /* struct sockaddr_in */ #include /* getpeername */ +#if defined(USE_UNIXSOCK) +#include /* unix socket */ +#endif #include /* inet_ntoa */ #include /* select */ #include /* ioctl */ @@ -404,12 +411,23 @@ if(!isalnum((int)*p)) *p='.';} while(0) /* some definitions for IPv6 support */ +#if defined(USE_UNIXSOCK) +#if defined(USE_IPv6) +#define addr_len(x) ((x).sa.sa_family==AF_INET ? \ + sizeof(struct sockaddr_in) : ((x).sa.sa_family==AF_INET6 ? \ + sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_un))) +#else +#define addr_len(x) ((x).sa.sa_family==AF_INET ? \ + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_un)) +#endif +#else #if defined(USE_IPv6) #define addr_len(x) ((x).sa.sa_family==AF_INET ? \ sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) #else #define addr_len(x) (sizeof(struct sockaddr_in)) #endif +#endif /* always use IPv4 defaults! */ #define DEFAULT_LOOPBACK "127.0.0.1" diff -ur stunnel-4.34/src/network.c stunnel-4.34.unixsockets/src/network.c --- stunnel-4.34/src/network.c 2010-09-14 17:12:22.000000000 +0200 +++ stunnel-4.34.unixsockets/src/network.c 2010-10-19 15:09:39.125265992 +0200 @@ -538,7 +538,12 @@ extern SOCK_OPT sock_opts[]; static char *type_str[3]={"accept", "local", "remote"}; int opt_size; +#if defined(USE_UNIXSOCK) + int stype = AF_UNSPEC; + socklen_t stype_len = sizeof(stype); + getsockopt(s, SOL_SOCKET, SO_TYPE, &stype, &stype_len); +#endif for(ptr=sock_opts;ptr->opt_str;ptr++) { if(!ptr->opt_val[type]) continue; /* default */ @@ -552,6 +557,10 @@ default: opt_size=sizeof(int); break; } +#if defined(USE_UNIXSOCK) + if (stype==AF_UNIX && ptr->opt_level!=SOL_SOCKET) + continue; +#endif if(setsockopt(s, ptr->opt_level, ptr->opt_name, (void *)ptr->opt_val[type], opt_size)) { sockerror(ptr->opt_str); diff -ur stunnel-4.34/src/options.c stunnel-4.34.unixsockets/src/options.c --- stunnel-4.34/src/options.c 2010-09-14 17:09:36.000000000 +0200 +++ stunnel-4.34.unixsockets/src/options.c 2010-10-19 15:09:39.125265992 +0200 @@ -312,6 +312,26 @@ } #endif +#if defined(USE_UNIXSOCK) + /* Unix sockets base dir */ + switch(cmd) { + case CMD_INIT: + new_global_options.unix_sockets_dir=UNIXSOCK_DIR; + break; + case CMD_EXEC: + if(strcasecmp(opt, "unix-sockets-dir")) + break; + new_global_options.unix_sockets_dir=stralloc(arg); + return NULL; /* OK */ + case CMD_DEFAULT: + s_log(LOG_NOTICE, "%-15s = %s", "unix-sockets-dir", UNIXSOCK_DIR); + break; + case CMD_HELP: + s_log(LOG_NOTICE, "%-15s = base directory for unix sockets", "unix-sockets-dir"); + break; + } +#endif + /* RNDbytes */ switch(cmd) { case CMD_INIT: diff -ur stunnel-4.34/src/prototypes.h stunnel-4.34.unixsockets/src/prototypes.h --- stunnel-4.34/src/prototypes.h 2010-09-14 17:09:50.000000000 +0200 +++ stunnel-4.34.unixsockets/src/prototypes.h 2010-10-19 15:09:39.129283123 +0200 @@ -52,6 +52,9 @@ #if defined(USE_IPv6) struct sockaddr_in6 in6; #endif +#if defined(USE_UNIXSOCK) + struct sockaddr_un un; +#endif } SOCKADDR_UNION; typedef struct sockaddr_list { /* list of addresses */ @@ -86,6 +89,10 @@ char *win32_service; #endif +#if defined (USE_UNIXSOCK) + char *unix_sockets_dir; +#endif + /* logging-support data for log.c */ int debug_level; /* debug level for logging */ #ifndef USE_WIN32 diff -ur stunnel-4.34/src/resolver.c stunnel-4.34.unixsockets/src/resolver.c --- stunnel-4.34/src/resolver.c 2010-01-29 11:35:15.000000000 +0100 +++ stunnel-4.34.unixsockets/src/resolver.c 2010-10-19 15:09:39.129283123 +0200 @@ -96,6 +96,11 @@ /* set hostname and portname */ safecopy(tmp, name); +#if defined(USE_UNIXSOCK) + if ( *tmp == '/' ) { + return hostport2addrlist(addr_list, global_options.unix_sockets_dir, tmp); + } +#endif portname=strrchr(tmp, ':'); if(portname) { hostname=tmp; @@ -116,6 +121,17 @@ addr_list->cur=0; /* initialize round-robin counter */ +#if defined(USE_UNIXSOCK) + if ( *portname == '/' ) { + struct sockaddr_un uns; + + uns.sun_family = PF_UNIX; + snprintf(uns.sun_path, sizeof(uns.sun_path), "%s%s", hostname, portname); + memcpy(&addr_list->addr[addr_list->num], &uns, sizeof(uns)); + addr_list->num++; + return addr_list->num; /* ok - return the number of addresses */ + } +#endif memset(&hints, 0, sizeof hints); #if defined(USE_IPv6) || defined(USE_WIN32) hints.ai_family=PF_UNSPEC; @@ -156,6 +172,12 @@ char *s_ntop(char *text, SOCKADDR_UNION *addr) { char host[IPLEN-6], port[6]; +#if defined(USE_UNIXSOCK) + if ( addr->sa.sa_family == AF_UNIX ) { + snprintf(text, IPLEN, "%s", addr->un.sun_path); + return text; + } +#endif if(getnameinfo(&addr->sa, addr_len(*addr), host, IPLEN-6, port, 6, NI_NUMERICHOST|NI_NUMERICSERV)) { sockerror("getnameinfo"); diff -ur stunnel-4.34/src/stunnel.c stunnel-4.34.unixsockets/src/stunnel.c --- stunnel-4.34/src/stunnel.c 2010-08-20 11:01:35.000000000 +0200 +++ stunnel-4.34.unixsockets/src/stunnel.c 2010-10-19 15:09:39.129283123 +0200 @@ -196,12 +196,33 @@ if(set_socket_options(opt->fd, 0)<0) return 0; s_ntop(opt->local_address, &addr); +#if !defined(USE_UNIXSOCK) if(bind(opt->fd, &addr.sa, addr_len(addr))) { s_log(LOG_ERR, "Error binding %s to %s", opt->servname, opt->local_address); sockerror("bind"); return 0; } +#else + if(bind(opt->fd, &addr.sa, addr_len(addr))) { + if(addr.sa.sa_family==AF_UNIX || get_last_socket_error()==EADDRINUSE) { + /* Try to remove socket file and retry a bind */ + unlink(addr.un.sun_path); + if(bind(opt->fd, &addr.sa, addr_len(addr))) { + s_log(LOG_ERR, "Error binding %s to %s", + opt->servname, opt->local_address); + sockerror("bind"); + return 0; + } + } + else { + s_log(LOG_ERR, "Error binding %s to %s", + opt->servname, opt->local_address); + sockerror("bind"); + return 0; + } + } +#endif s_log(LOG_DEBUG, "Service %s bound to %s", opt->servname, opt->local_address); if(listen(opt->fd, 5)) {