Unix domain socket support
diff --git a/src/core/iomgr/resolve_address.c b/src/core/iomgr/resolve_address.c
index 575f884..58daade 100644
--- a/src/core/iomgr/resolve_address.c
+++ b/src/core/iomgr/resolve_address.c
@@ -39,6 +39,7 @@
 #include "src/core/iomgr/resolve_address.h"
 
 #include <sys/types.h>
+#include <sys/un.h>
 #include <string.h>
 
 #include "src/core/iomgr/iomgr_internal.h"
@@ -123,6 +124,18 @@
   size_t i;
   grpc_resolved_addresses *addrs = NULL;
   const gpr_timespec start_time = gpr_now();
+  struct sockaddr_un *un;
+
+  if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && name[4] == ':' && name[5] != 0) {
+    addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
+    addrs->naddrs = 1;
+    addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address));
+    un = (struct sockaddr_un *)addrs->addrs->addr;
+    un->sun_family = AF_UNIX;
+    strcpy(un->sun_path, name + 5);
+    addrs->addrs->len = strlen(un->sun_path) + sizeof(un->sun_family);
+    return addrs;
+  }
 
   /* parse name, splitting it into host and port parts */
   split_host_port(name, &host, &port);
diff --git a/src/core/iomgr/sockaddr_utils.c b/src/core/iomgr/sockaddr_utils.c
index 8dcfca7..f794241 100644
--- a/src/core/iomgr/sockaddr_utils.c
+++ b/src/core/iomgr/sockaddr_utils.c
@@ -166,6 +166,8 @@
       return ntohs(((struct sockaddr_in *)addr)->sin_port);
     case AF_INET6:
       return ntohs(((struct sockaddr_in6 *)addr)->sin6_port);
+    case AF_UNIX:
+      return 1;
     default:
       gpr_log(GPR_ERROR, "Unknown socket family %d in %s", addr->sa_family,
               __FUNCTION__);
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index 851530c..397dff5 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -62,13 +62,13 @@
   int refs;
 } async_connect;
 
-static int prepare_socket(int fd) {
+static int prepare_socket(const struct sockaddr* addr, int fd) {
   if (fd < 0) {
     goto error;
   }
 
   if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
-      !grpc_set_socket_low_latency(fd, 1)) {
+      (addr->sa_family != AF_UNIX && !grpc_set_socket_low_latency(fd, 1))) {
     gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
             strerror(errno));
     goto error;
@@ -200,7 +200,7 @@
     addr = (struct sockaddr *)&addr4_copy;
     addr_len = sizeof(addr4_copy);
   }
-  if (!prepare_socket(fd)) {
+  if (!prepare_socket(addr, fd)) {
     cb(arg, NULL);
     return;
   }
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 091f0aa..b69dbd9 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -48,12 +48,14 @@
 #include <netinet/tcp.h>
 #include <stdio.h>
 #include <sys/types.h>
+#include <sys/un.h>
 #include <sys/socket.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
 
 #include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/resolve_address.h"
 #include "src/core/iomgr/sockaddr_utils.h"
 #include "src/core/iomgr/socket_utils_posix.h"
 #include "src/core/iomgr/tcp_posix.h"
@@ -73,6 +75,8 @@
   int fd;
   grpc_fd *emfd;
   grpc_tcp_server *server;
+  gpr_uint8 addr[GRPC_MAX_SOCKADDR_SIZE];
+  int addr_len;
 } server_port;
 
 /* the overall server */
@@ -121,6 +125,10 @@
   /* delete ALL the things */
   for (i = 0; i < s->nports; i++) {
     server_port *sp = &s->ports[i];
+    if (((struct sockaddr *)sp->addr)->sa_family == AF_UNIX) {
+      struct sockaddr_un *un = (struct sockaddr_un *)sp->addr;
+      unlink(un->sun_path);
+    }
     grpc_fd_orphan(sp->emfd, NULL, NULL);
   }
   gpr_free(s->ports);
@@ -170,8 +178,7 @@
   }
 
   if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
-      !grpc_set_socket_low_latency(fd, 1) ||
-      !grpc_set_socket_reuse_addr(fd, 1)) {
+      (addr->sa_family != AF_UNIX && (!grpc_set_socket_low_latency(fd, 1) || !grpc_set_socket_reuse_addr(fd, 1)))) {
     gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
             strerror(errno));
     goto error;
@@ -265,6 +272,8 @@
     sp->server = s;
     sp->fd = fd;
     sp->emfd = grpc_fd_create(fd);
+    memcpy(sp->addr, addr, addr_len);
+    sp->addr_len = addr_len;
     GPR_ASSERT(sp->emfd);
     gpr_mu_unlock(&s->mu);
   }