diff --git a/src/common.h b/src/common.h
index a92427c..6818c2b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -229,6 +229,10 @@ typedef unsigned long u32;
 #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__"
@@ -286,6 +290,9 @@ typedef unsigned long u32;
 
 #include <netinet/in.h>  /* struct sockaddr_in */
 #include <sys/socket.h>  /* getpeername */
+#if defined(USE_UNIXSOCK)
+#include <sys/un.h>    /* unix socket */
+#endif
 #include <arpa/inet.h>   /* inet_ntoa */
 #include <sys/time.h>    /* select */
 #include <sys/ioctl.h>   /* ioctl */
@@ -399,12 +406,23 @@ extern char *sys_errlist[];
         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 --git a/src/network.c b/src/network.c
index ebf116a..f5b6ad7 100644
--- a/src/network.c
+++ b/src/network.c
@@ -524,7 +524,12 @@ int set_socket_options(int s, int type) {
     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 */
@@ -541,6 +546,10 @@ int set_socket_options(int s, int type) {
         default:
             opt_size=sizeof(int);
         }
+#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)) {
             if(get_last_socket_error()==EOPNOTSUPP) {
diff --git a/src/options.c b/src/options.c
index 27aab5c..357d174 100644
--- a/src/options.c
+++ b/src/options.c
@@ -314,6 +314,26 @@ static char *parse_global_option(CMD cmd, char *opt, char *arg) {
     }
 #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=str_dup_err(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 --git a/src/prototypes.h b/src/prototypes.h
index f42407b..9faeb1b 100644
--- a/src/prototypes.h
+++ b/src/prototypes.h
@@ -57,6 +57,9 @@ typedef union sockaddr_union {
 #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 @@ typedef struct {
     int uid, gid;
 #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 --git a/src/resolver.c b/src/resolver.c
index 7740cb2..74d3bbc 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -97,6 +97,12 @@ int name2addrlist(SOCKADDR_LIST *addr_list, char *name, char *default_host) {
 
     /* set hostname and portname */
     tmp=str_dup(name);
+#if defined(USE_UNIXSOCK)
+    if ( *tmp == '/' ) {
+        str_free(tmp);
+	return hostport2addrlist(addr_list, global_options.unix_sockets_dir, name);
+    }
+#endif  
     portname=strrchr(tmp, ':');
     if(portname) {
         hostname=tmp;
@@ -119,6 +125,17 @@ int hostport2addrlist(SOCKADDR_LIST *addr_list,
 
     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;
@@ -166,6 +183,12 @@ int hostport2addrlist(SOCKADDR_LIST *addr_list,
 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 --git a/src/stunnel.c b/src/stunnel.c
index 034b1c5..10fa1da 100644
--- a/src/stunnel.c
+++ b/src/stunnel.c
@@ -240,6 +240,7 @@ int bind_ports(void) {
                 return 1;
             }
             s_ntop(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, local_address);
@@ -247,6 +248,30 @@ int bind_ports(void) {
                 closesocket(opt->fd);
                 return 1;
             }
+#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, local_address);
+                       sockerror("bind");
+                       closesocket(opt->fd);
+               	       return 1;
+                   }
+                }
+                else {
+                    s_log(LOG_ERR, "Error binding %s to %s",
+                       opt->servname, local_address);
+                    sockerror("bind");
+                    closesocket(opt->fd);
+               	    return 1;
+                }
+            }
+#endif
+
+
             s_log(LOG_DEBUG, "Service %s bound to %s",
                 opt->servname, local_address);
             if(listen(opt->fd, SOMAXCONN)) {
