From 680d88916b634628981bf0deab3c1a838986cbb1 Mon Sep 17 00:00:00 2001
From: Tomas Hozza <thozza () redhat com>
Date: Wed, 19 Sep 2012 16:06:49 +0200
Subject: [PATCH 1/2] Implementation of UNIX-domain sockets for Nsock.

Implementation of UNIX-domain sockets functionality
for Nsock. Also some minor necessary changes to
existing Nsock functions, to work properly with
UNIX-domain sockets.
---
 nsock/include/nsock.h           |  28 ++++++++++
 nsock/include/nsock_config.h.in |   3 +
 nsock/src/configure.ac          |   2 +-
 nsock/src/netutils.c            |  14 +++++
 nsock/src/netutils.h            |   9 +++
 nsock/src/nsock_connect.c       | 118 +++++++++++++++++++++++++++++++++++++++-
 nsock/src/nsock_core.c          |  64 ++++++++++++++++------
 nsock/src/nsock_internal.h      |  10 +++-
 nsock/src/nsock_read.c          |  31 +++++++++--
 nsock/src/nsock_write.c         |  47 ++++++++++++----
 10 files changed, 291 insertions(+), 35 deletions(-)

diff --git a/nsock/include/nsock.h b/nsock/include/nsock.h
index d43dc24..ea1c8c2 100644
--- a/nsock/include/nsock.h
+++ b/nsock/include/nsock.h
@@ -76,6 +76,16 @@
 #include <sys/time.h>
 #endif
 
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+
+#ifndef SUN_LEN
+#include <string.h>
+# define SUN_LEN(ptr) (sizeof(*(ptr)) - sizeof((ptr)->sun_path))     \
+                      + strlen ((ptr)->sun_path))
+#endif
+#endif  /* HAVE_SYS_UN_H */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -415,6 +425,24 @@ typedef void (*nsock_ev_handler)(nsock_pool, nsock_event, void *);
 /* Initialize an unconnected UDP socket. */
 int nsock_setup_udp(nsock_pool nsp, nsock_iod ms_iod, int af);
 
+#if HAVE_SYS_UN_H
+
+/* Request a UNIX domain sockets connection to the same system (by path to socket).
+ * This function connects to the socket of type SOCK_STREAM.  ss should be a 
+ * sockaddr_storage, sockaddr_un as appropriate (just like what you would pass to 
+ * connect).  sslen should be the sizeof the structure you are passing in. */
+nsock_event_id nsock_connect_unixsock_stream(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handler handler,
+                                             int timeout_msecs, void *userdata, struct sockaddr *ss,
+                                             size_t sslen);
+
+/* Request a UNIX domain sockets connection to the same system (by path to socket).
+ * This function connects to the socket of type SOCK_DGRAM.  ss should be a 
+ * sockaddr_storage, sockaddr_un as appropriate (just like what you would pass to 
+ * connect).  sslen should be the sizeof the structure you are passing in. */
+nsock_event_id nsock_connect_unixsock_datagram(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handler handler,
+                                               void *userdata, struct sockaddr *ss, size_t sslen);
+#endif
+
 /* Request a TCP connection to another system (by IP address).  The in_addr is
  * normal network byte order, but the port number should be given in HOST BYTE
  * ORDER.  ss should be a sockaddr_storage, sockaddr_in6, or sockaddr_in as
diff --git a/nsock/include/nsock_config.h.in b/nsock/include/nsock_config.h.in
index f719906..0ed2142 100644
--- a/nsock/include/nsock_config.h.in
+++ b/nsock/include/nsock_config.h.in
@@ -75,6 +75,9 @@
 #undef HAVE_NET_BPF_H
 #undef HAVE_SYS_IOCTL_H
 
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
 #undef HAVE_SSL_SET_TLSEXT_HOST_NAME
 
 #undef HAVE_EPOLL
diff --git a/nsock/src/configure.ac b/nsock/src/configure.ac
index 4ff667f..74ed2b5 100644
--- a/nsock/src/configure.ac
+++ b/nsock/src/configure.ac
@@ -138,7 +138,7 @@ AC_CHECK_FUNC(nanosleep, , AC_CHECK_LIB(posix4, nanosleep))
 
 dnl Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS(net/bpf.h sys/ioctl.h)
+AC_CHECK_HEADERS(net/bpf.h sys/ioctl.h sys/un.h)
 
 # We test whether they specified openssl desires explicitly
 use_openssl="yes"
diff --git a/nsock/src/netutils.c b/nsock/src/netutils.c
index 3a8757f..7e790da 100644
--- a/nsock/src/netutils.c
+++ b/nsock/src/netutils.c
@@ -83,6 +83,9 @@
 #if HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
 
 static int netutils_debugging = 0;
 
@@ -134,3 +137,14 @@ int maximize_fdlimit(void) {
   return 0;
 }
 
+#ifdef HAVE_SYS_UN_H
+/* Get the UNIX domain socket path or NULL if the socket family != AF_UNIX. */
+const char *get_unixsock_path(struct sockaddr_storage *addr)
+{
+    if (!addr || addr->ss_family != AF_UNIX)
+        return NULL;
+
+    struct sockaddr_un *su = (struct sockaddr_un *)addr;
+    return (const char *)su->sun_path;
+}
+#endif
diff --git a/nsock/src/netutils.h b/nsock/src/netutils.h
index 52b8d26..9cb2cf3 100644
--- a/nsock/src/netutils.h
+++ b/nsock/src/netutils.h
@@ -63,6 +63,10 @@
 #include "nbase_config.h"
 #endif
 
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
 #ifdef WIN32
 #include "nbase_winconfig.h"
 /* nbase_winunix.h somehow reason.h to get included */
@@ -75,5 +79,10 @@
  * count toward this limit.  Leave a little slack */
 int maximize_fdlimit(void);
 
+#if HAVE_SYS_UN_H
+/* Get the UNIX domain socket path or NULL if the socket family != AF_UNIX. */
+const char *get_unixsock_path(struct sockaddr_storage *addr);
+#endif
+
 #endif /* NETUTILS_H */
 
diff --git a/nsock/src/nsock_connect.c b/nsock/src/nsock_connect.c
index 54e35f0..bf28e4d 100644
--- a/nsock/src/nsock_connect.c
+++ b/nsock/src/nsock_connect.c
@@ -165,6 +165,122 @@ void nsock_connect_internal(mspool *ms, msevent *nse, int proto, struct sockaddr
   }
 }
 
+#if HAVE_SYS_UN_H
+
+/* Create the actual socket (nse->iod->sd) underlying the iod. This unblocks the
+ * socket, binds to the localaddr address. Trying to change these functions after
+ * making this call will not have an effect. This function needs to be called before
+ * you try to read or write on the iod. */
+static int nsock_make_unixsocket(mspool *ms, msiod *iod, int type) {
+  /* inheritable_socket is from nbase */
+  iod->sd = (int)inheritable_socket(AF_UNIX, type, 0);
+  if (iod->sd == -1) {
+    perror("Socket troubles");
+    return -1;
+  }
+
+  unblock_socket(iod->sd);
+
+  iod->lastproto = 0;
+
+  if (iod->locallen) {
+    int one = 1;
+    
+    setsockopt(iod->sd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one));
+    
+    if (bind(iod->sd, (struct sockaddr *)&iod->local, (int) iod->locallen) == -1) {
+      if (ms->tracelevel > 0)
+        nsock_trace(ms, "Bind to %s failed (IOD #%li)", get_unixsock_path(&iod->local), iod->id);
+    }
+  }
+  return iod->sd;
+}
+
+/* This does the actual logistics of requesting a UNIX domain socket connection.
+ * It is shared by nsock_connect_unixsock_stream and nsock_connect_unixsock_datagram. */
+void nsock_connect_unixsock_internal(mspool *ms, msevent *nse, int type, struct sockaddr_storage *ss, size_t sslen) {
+
+  msiod *iod = nse->iod;
+
+  /* Now it is time to actually attempt the connection */
+  if (nsock_make_unixsocket(ms, iod, type) == -1) {
+    nse->event_done = 1;
+    nse->status = NSE_STATUS_ERROR;
+    nse->errnum = socket_errno();
+
+  } else {
+    assert(sslen <= sizeof(iod->peer));
+    if (&iod->peer != ss)
+      memcpy(&iod->peer, ss, sslen);
+    iod->peerlen = sslen;
+
+    if (connect(iod->sd, (struct sockaddr *)ss, sslen) == -1) {
+      int err = socket_errno();
+
+      if (err != EINPROGRESS && err != EAGAIN) {
+        nse->event_done = 1;
+        nse->status = NSE_STATUS_ERROR;
+        nse->errnum = err;
+      }
+    }
+    /* The callback handle_connect_result handles the connection once it completes. */
+  }
+}
+
+/* Request a UNIX domain sockets connection to the same system (by path to socket).
+ * This function connects to the socket of type SOCK_STREAM.  ss should be a 
+ * sockaddr_storage, sockaddr_un as appropriate (just like what you would pass to 
+ * connect).  sslen should be the sizeof the structure you are passing in. */
+nsock_event_id nsock_connect_unixsock_stream(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handler handler, int timeout_msecs,
+                                             void *userdata, struct sockaddr *saddr, size_t sslen) {
+  msiod *nsi = (msiod *)nsiod;
+  mspool *ms = (mspool *)nsp;
+  msevent *nse;
+  struct sockaddr_storage *ss = (struct sockaddr_storage *)saddr;
+
+  assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN);
+
+  nse = msevent_new(ms, NSE_TYPE_CONNECT, nsi, timeout_msecs, handler, userdata);
+  assert(nse);
+
+  if (ms->tracelevel > 0)
+    nsock_trace(ms, "UNIX domain socket (STREAM) connection requested to %s (IOD #%li) EID %li",
+                get_unixsock_path(ss), nsi->id, nse->id);
+
+  nsock_connect_unixsock_internal(ms, nse, SOCK_STREAM, ss, sslen);
+  nsp_add_event(ms, nse);
+
+  return nse->id;
+
+}
+
+/* Request a UNIX domain sockets connection to the same system (by path to socket).
+ * This function connects to the socket of type SOCK_DGRAM.  ss should be a 
+ * sockaddr_storage, sockaddr_un as appropriate (just like what you would pass to 
+ * connect).  sslen should be the sizeof the structure you are passing in. */
+nsock_event_id nsock_connect_unixsock_datagram(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handler handler,
+                                               void *userdata, struct sockaddr *saddr, size_t sslen) {
+  msiod *nsi = (msiod *)nsiod;
+  mspool *ms = (mspool *)nsp;
+  msevent *nse;
+  struct sockaddr_storage *ss = (struct sockaddr_storage *)saddr;
+
+  assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN);
+
+  nse = msevent_new(ms, NSE_TYPE_CONNECT, nsi, -1, handler, userdata);
+  assert(nse);
+
+  if (ms->tracelevel > 0)
+    nsock_trace(ms, "UNIX domain socket (DGRAM) connection requested to %s (IOD #%li) EID %li", 
+                get_unixsock_path(ss), nsi->id, nse->id);
+
+  nsock_connect_unixsock_internal(ms, nse, SOCK_DGRAM, ss, sslen);
+  nsp_add_event(ms, nse);
+
+  return nse->id;
+}
+
+#endif  /* HAVE_SYS_UN_H */
 
 /* Request a TCP connection to another system (by IP address).  The in_addr is
  * normal network byte order, but the port number should be given in HOST BYTE
@@ -369,7 +485,7 @@ int nsi_getlastcommunicationinfo(nsock_iod ms_iod, int *protocol, int *af, struc
       if (*protocol == -1) res = 0;
     }
     if (af) {
-      *af = ((struct sockaddr_in *)&nsi->peer)->sin_family;
+      *af = nsi->peer.ss_family;
     }
     if (local) {
       if (nsi->sd >= 0) {
diff --git a/nsock/src/nsock_core.c b/nsock/src/nsock_core.c
index 39e8422..bd9973b 100644
--- a/nsock/src/nsock_core.c
+++ b/nsock/src/nsock_core.c
@@ -78,6 +78,9 @@
 #if HAVE_STRING_H
 #include <string.h>
 #endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
 
 #include "netutils.h"
 
@@ -1264,18 +1267,32 @@ void nsock_trace_handler_callback(mspool *ms, msevent *nse) {
   switch(nse->type) {
     case NSE_TYPE_CONNECT:
     case NSE_TYPE_CONNECT_SSL:
-      nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s:%d]",
-                  nse_type2str(nse->type), nse_status2str(nse->status), errstr,
-                  nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi));
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+        nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s]",
+                    nse_type2str(nse->type), nse_status2str(nse->status), errstr,
+                    nse->id, get_unixsock_path(&nsi->peer));
+      else
+#endif
+        nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s:%d]",
+                    nse_type2str(nse->type), nse_status2str(nse->status), errstr,
+                    nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi));
       break;
 
     case NSE_TYPE_READ:
       if (nse->status != NSE_STATUS_SUCCESS) {
         if (nsi->peerlen > 0) {
-           nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s:%d]",
-                       nse_type2str(nse->type), nse_status2str(nse->status),
-                       errstr, nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen),
-                       nsi_peerport(nsi));
+#if HAVE_SYS_UN_H
+          if (nsi->peer.ss_family == AF_UNIX)
+            nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s]",
+                        nse_type2str(nse->type), nse_status2str(nse->status), errstr,
+                        nse->id, get_unixsock_path(&nsi->peer));
+          else
+#endif
+            nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s:%d]",
+                        nse_type2str(nse->type), nse_status2str(nse->status),
+                        errstr, nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen),
+                        nsi_peerport(nsi));
         } else {
           nsock_trace(ms, "Callback: %s %s %sfor EID %li (peer unspecified)",
                       nse_type2str(nse->type), nse_status2str(nse->status),
@@ -1293,11 +1310,19 @@ void nsock_trace_handler_callback(mspool *ms, msevent *nse) {
         }
 
         if (nsi->peerlen > 0) {
-          nsock_trace(ms, "Callback: %s %s for EID %li [%s:%d] %s(%d bytes)%s",
-                      nse_type2str(nse->type), nse_status2str(nse->status),
-                      nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen),
-                      nsi_peerport(nsi), nse_eof(nse)? "[EOF]" : "", strlength,
-                      displaystr);
+#if HAVE_SYS_UN_H
+          if (nsi->peer.ss_family == AF_UNIX)
+            nsock_trace(ms, "Callback: %s %s for EID %li [%s] %s(%d bytes)%s",
+                        nse_type2str(nse->type), nse_status2str(nse->status),
+                        nse->id, get_unixsock_path(&nsi->peer), nse_eof(nse)? "[EOF]" : "",
+                        strlength, displaystr);
+          else
+#endif
+            nsock_trace(ms, "Callback: %s %s for EID %li [%s:%d] %s(%d bytes)%s",
+                        nse_type2str(nse->type), nse_status2str(nse->status),
+                        nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen),
+                        nsi_peerport(nsi), nse_eof(nse)? "[EOF]" : "", strlength,
+                        displaystr);
         } else {
           nsock_trace(ms, "Callback %s %s for EID %li (peer unspecified) %s(%d bytes)%s",
                       nse_type2str(nse->type), nse_status2str(nse->status),
@@ -1307,10 +1332,17 @@ void nsock_trace_handler_callback(mspool *ms, msevent *nse) {
       break;
 
     case NSE_TYPE_WRITE:
-      nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s:%d]",
-                  nse_type2str(nse->type), nse_status2str(nse->status), errstr,
-                  nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen),
-                  nsi_peerport(nsi));
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+         nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s]",
+                    nse_type2str(nse->type), nse_status2str(nse->status), errstr,
+                    nse->id, get_unixsock_path(&nsi->peer));
+      else
+#endif
+        nsock_trace(ms, "Callback: %s %s %sfor EID %li [%s:%d]",
+                    nse_type2str(nse->type), nse_status2str(nse->status), errstr,
+                    nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen),
+                    nsi_peerport(nsi));
       break;
 
     case NSE_TYPE_TIMER:
diff --git a/nsock/src/nsock_internal.h b/nsock/src/nsock_internal.h
index 49d7671..018c67e 100644
--- a/nsock/src/nsock_internal.h
+++ b/nsock/src/nsock_internal.h
@@ -97,6 +97,9 @@
 #if HAVE_STRINGS_H
 #include <strings.h>
 #endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
 
 #ifndef IPPROTO_SCTP
 #define IPPROTO_SCTP 132
@@ -252,7 +255,8 @@ typedef struct {
   struct sockaddr_storage local;
 
   /* The length of peer/local actually used (sizeof(sockaddr_in) or
-   * sizeof(sockaddr_in6), or 0 if peer/local has not been filled in */
+   * sizeof(sockaddr_in6), SUN_LEN(sockaddr_un), or 0 if peer/local 
+   * has not been filled in */
   size_t locallen;
   size_t peerlen;
 
@@ -422,6 +426,10 @@ void nsp_add_event(mspool *nsp, msevent *nse);
 
 void nsock_connect_internal(mspool *ms, msevent *nse, int proto, struct sockaddr_storage *ss, size_t sslen, unsigned short port);
 
+#if HAVE_SYS_UN_H
+void nsock_connect_unixsock_internal(mspool *ms, msevent *nse, int type, struct sockaddr_storage *ss, size_t sslen);
+#endif
+
 /* Comments on using the following handle_*_result functions are available in nsock_core.c */
 
 /* handle_connect_results assumes that select or poll have already shown the
diff --git a/nsock/src/nsock_read.c b/nsock/src/nsock_read.c
index 766489b..497cf96 100644
--- a/nsock/src/nsock_read.c
+++ b/nsock/src/nsock_read.c
@@ -55,6 +55,7 @@
 
 /* $Id: nsock_read.c 28190 2012-03-01 06:32:23Z fyodor $ */
 
+#include "netutils.h"
 #include "nsock_internal.h"
 
 
@@ -74,8 +75,14 @@ nsock_event_id nsock_readlines(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handle
 
   if (ms->tracelevel > 0) {
     if (nsi->peerlen > 0)
-      nsock_trace(ms, "Read request for %d lines from IOD #%li [%s:%d] EID %li",
-                  nlines, nsi->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), nse->id);
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+        nsock_trace(ms, "Read request for %d lines from IOD #%li [%s] EID %li",
+                    nlines, nsi->id, get_unixsock_path(&nsi->peer), nse->id);
+      else
+#endif
+        nsock_trace(ms, "Read request for %d lines from IOD #%li [%s:%d] EID %li",
+                    nlines, nsi->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), nse->id);
     else
       nsock_trace(ms, "Read request for %d lines from IOD #%li (peer unspecified) EID %li",
                   nlines, nsi->id, nse->id);
@@ -102,8 +109,14 @@ nsock_event_id nsock_readbytes(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handle
 
   if (ms->tracelevel > 0) {
     if (nsi->peerlen > 0)
-      nsock_trace(ms, "Read request for %d bytes from IOD #%li [%s:%d] EID %li",
-                  nbytes, nsi->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), nse->id);
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+        nsock_trace(ms, "Read request for %d bytes from IOD #%li [%s] EID %li",
+                    nbytes, nsi->id, get_unixsock_path(&nsi->peer), nse->id);
+      else
+#endif
+        nsock_trace(ms, "Read request for %d bytes from IOD #%li [%s:%d] EID %li",
+                    nbytes, nsi->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), nse->id);
     else
       nsock_trace(ms, "Read request for %d bytes from IOD #%li (peer unspecified) EID %li",
                   nbytes, nsi->id, nse->id);
@@ -130,8 +143,14 @@ nsock_event_id nsock_read(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handler han
 
   if (ms->tracelevel > 0) {
     if (nsi->peerlen > 0)
-      nsock_trace(ms, "Read request from IOD #%li [%s:%d] (timeout: %dms) EID %li",
-                  nsi->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), timeout_msecs, nse->id);
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+        nsock_trace(ms, "Read request from IOD #%li [%s] (timeout: %dms) EID %li",
+                    nsi->id, get_unixsock_path(&nsi->peer), timeout_msecs, nse->id);
+      else
+#endif
+        nsock_trace(ms, "Read request from IOD #%li [%s:%d] (timeout: %dms) EID %li",
+                    nsi->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), timeout_msecs, nse->id);
     else
       nsock_trace(ms, "Read request from IOD #%li (peer unspecified) (timeout: %dms) EID %li",
                   nsi->id, timeout_msecs, nse->id);
diff --git a/nsock/src/nsock_write.c b/nsock/src/nsock_write.c
index 854a5ed..7d7fae0 100644
--- a/nsock/src/nsock_write.c
+++ b/nsock/src/nsock_write.c
@@ -55,6 +55,7 @@
 
 /* $Id: nsock_write.c 28190 2012-03-01 06:32:23Z fyodor $ */
 
+#include "netutils.h"
 #include "nsock.h"
 #include "nsock_internal.h"
 
@@ -72,14 +73,21 @@ nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod, nsock_ev_handl
 #if HAVE_IPV6
   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;
 #endif
+#if HAVE_SYS_UN_H
+  struct sockaddr_un *sun = (struct sockaddr_un *)saddr;
+#endif
 
   nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
   assert(nse);
 
-  if (sin->sin_family == AF_INET) {
+  if (saddr->sa_family == AF_INET) {
     sin->sin_port = htons(port);
+#if HAVE_SYS_UN_H
+  } else if (saddr->sa_family == AF_INET6) {
+#else
   } else {
-      assert(sin->sin_family == AF_INET6);
+#endif
+      assert(saddr->sa_family == AF_INET6);
 #if HAVE_IPV6
     sin6->sin6_port = htons(port);
 #else
@@ -107,10 +115,17 @@ nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod, nsock_ev_handl
     } else {
       displaystr[0] = '\0';
     }
-    nsock_trace(nsp, "Sendto request for %d bytes to IOD #%li EID %li [%s:%hu]%s",
-                datalen, nsi->id, nse->id,
-                inet_ntop_ez(&nse->writeinfo.dest, nse->writeinfo.destlen), port,
-                displaystr);
+#if HAVE_SYS_UN_H
+    if (saddr->sa_family == AF_UNIX)
+      nsock_trace(nsp, "Sendto request for %d bytes to IOD #%li EID %li [%s]%s",
+                  datalen, nsi->id, nse->id, get_unixsock_path(&nse->writeinfo.dest),
+                  displaystr);
+    else
+#endif
+      nsock_trace(nsp, "Sendto request for %d bytes to IOD #%li EID %li [%s:%hu]%s",
+                  datalen, nsi->id, nse->id,
+                  inet_ntop_ez(&nse->writeinfo.dest, nse->writeinfo.destlen), port,
+                  displaystr);
   }
 
   fscat(&nse->iobuf, data, datalen);
@@ -147,8 +162,14 @@ nsock_event_id nsock_write(nsock_pool ms_pool, nsock_iod ms_iod,
       replacenonprintable(displaystr + 2, datalen, '.');
     } else displaystr[0] = '\0';
     if (nsi->peerlen > 0)
-      nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%d]%s", datalen, nsi->id,
-                  nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+        nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s]%s", datalen, nsi->id,
+                    nse->id, get_unixsock_path(&nsi->peer), displaystr);
+      else
+#endif
+        nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%d]%s", datalen, nsi->id,
+                    nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
     else
       nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li (peer unspecified)%s", datalen,
                   nsi->id, nse->id, displaystr);
@@ -220,8 +241,14 @@ nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
       displaystr[0] = '\0';
     }
     if (nsi->peerlen > 0)
-      nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%d]%s", strlength, nsi->id,
-                  nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
+#if HAVE_SYS_UN_H
+      if (nsi->peer.ss_family == AF_UNIX)
+        nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s]%s", strlength, nsi->id,
+                    nse->id, get_unixsock_path(&nsi->peer), displaystr);
+      else
+#endif
+        nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%d]%s", strlength, nsi->id,
+                    nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
     else
       nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li (peer unspecified)%s", strlength,
                   nsi->id, nse->id, displaystr);
-- 
1.7.11.4

