c260e0
From 3fef242a1e1a74140a1678d84164086d0f47d83a Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 27 Nov 2014 23:59:19 +0100
c260e0
Subject: [PATCH 01/11] sws: move away from IPv4/IPv4-only assumption
c260e0
c260e0
Instead of depending the socket domain type on use_ipv6, specify the
c260e0
domain type (AF_INET / AF_INET6) as variable. An enum is used here with
c260e0
switch to avoid compiler warnings in connect_to, complaining that rc
c260e0
is possibly undefined (which is not possible as socket_domain is
c260e0
always set).
c260e0
c260e0
Besides abstracting the socket type, make the debugging messages be
c260e0
independent on IP (introduce location_str which points to "port XXXXX").
c260e0
Rename "ipv_inuse" to "socket_type" and tighten the scope (main).
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: cf6c5c222d86088cbfc9dee4c23f8ada96ee91e7
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 tests/server/sws.c | 88 ++++++++++++++++++++++++------------------------------
c260e0
 1 file changed, 39 insertions(+), 49 deletions(-)
c260e0
c260e0
diff --git a/tests/server/sws.c b/tests/server/sws.c
c260e0
index aef55ea..fa10d54 100644
c260e0
--- a/tests/server/sws.c
c260e0
+++ b/tests/server/sws.c
c260e0
@@ -65,11 +65,13 @@
c260e0
 #define ERANGE  34 /* errno.h value */
c260e0
 #endif
c260e0
 
c260e0
+static enum {
c260e0
+  socket_domain_inet = AF_INET,
c260e0
 #ifdef ENABLE_IPV6
c260e0
-static bool use_ipv6 = FALSE;
c260e0
+  socket_domain_inet6 = AF_INET6
c260e0
 #endif
c260e0
+} socket_domain = AF_INET;
c260e0
 static bool use_gopher = FALSE;
c260e0
-static const char *ipv_inuse = "IPv4";
c260e0
 static int serverlogslocked = 0;
c260e0
 static bool is_proxy = FALSE;
c260e0
 
c260e0
@@ -1285,7 +1287,7 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
 #endif
c260e0
 
c260e0
 #ifdef ENABLE_IPV6
c260e0
-  if(use_ipv6) {
c260e0
+  if(socket_domain == AF_INET6) {
c260e0
     op_br = "[";
c260e0
     cl_br = "]";
c260e0
   }
c260e0
@@ -1297,14 +1299,8 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
   logmsg("about to connect to %s%s%s:%hu",
c260e0
          op_br, ipaddr, cl_br, port);
c260e0
 
c260e0
-#ifdef ENABLE_IPV6
c260e0
-  if(!use_ipv6)
c260e0
-#endif
c260e0
-    serverfd = socket(AF_INET, SOCK_STREAM, 0);
c260e0
-#ifdef ENABLE_IPV6
c260e0
-  else
c260e0
-    serverfd = socket(AF_INET6, SOCK_STREAM, 0);
c260e0
-#endif
c260e0
+
c260e0
+  serverfd = socket(socket_domain, SOCK_STREAM, 0);
c260e0
   if(CURL_SOCKET_BAD == serverfd) {
c260e0
     error = SOCKERRNO;
c260e0
     logmsg("Error creating socket for server conection: (%d) %s",
c260e0
@@ -1322,9 +1318,8 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
     logmsg("TCP_NODELAY set for server conection");
c260e0
 #endif
c260e0
 
c260e0
-#ifdef ENABLE_IPV6
c260e0
-  if(!use_ipv6) {
c260e0
-#endif
c260e0
+  switch(socket_domain) {
c260e0
+  case AF_INET:
c260e0
     memset(&serveraddr.sa4, 0, sizeof(serveraddr.sa4));
c260e0
     serveraddr.sa4.sin_family = AF_INET;
c260e0
     serveraddr.sa4.sin_port = htons(port);
c260e0
@@ -1335,9 +1330,9 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
     }
c260e0
 
c260e0
     rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa4));
c260e0
+    break;
c260e0
 #ifdef ENABLE_IPV6
c260e0
-  }
c260e0
-  else {
c260e0
+  case AF_INET6:
c260e0
     memset(&serveraddr.sa6, 0, sizeof(serveraddr.sa6));
c260e0
     serveraddr.sa6.sin6_family = AF_INET6;
c260e0
     serveraddr.sa6.sin6_port = htons(port);
c260e0
@@ -1348,8 +1343,9 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
     }
c260e0
 
c260e0
     rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa6));
c260e0
-  }
c260e0
+    break;
c260e0
 #endif /* ENABLE_IPV6 */
c260e0
+  }
c260e0
 
c260e0
   if(got_exit_signal) {
c260e0
     sclose(serverfd);
c260e0
@@ -1924,21 +1920,20 @@ int main(int argc, char *argv[])
c260e0
   int arg=1;
c260e0
   long pid;
c260e0
   const char *hostport = "127.0.0.1";
c260e0
+  const char *socket_type = "IPv4";
c260e0
+  char port_str[11];
c260e0
+  const char *location_str = port_str;
c260e0
   size_t socket_idx;
c260e0
 
c260e0
   memset(&req, 0, sizeof(req));
c260e0
 
c260e0
   while(argc>arg) {
c260e0
     if(!strcmp("--version", argv[arg])) {
c260e0
-      printf("sws IPv4%s"
c260e0
-             "\n"
c260e0
-             ,
c260e0
+      puts("sws IPv4"
c260e0
 #ifdef ENABLE_IPV6
c260e0
              "/IPv6"
c260e0
-#else
c260e0
-             ""
c260e0
 #endif
c260e0
-             );
c260e0
+          );
c260e0
       return 0;
c260e0
     }
c260e0
     else if(!strcmp("--pidfile", argv[arg])) {
c260e0
@@ -1957,16 +1952,16 @@ int main(int argc, char *argv[])
c260e0
       end_of_headers = "\r\n"; /* gopher style is much simpler */
c260e0
     }
c260e0
     else if(!strcmp("--ipv4", argv[arg])) {
c260e0
-#ifdef ENABLE_IPV6
c260e0
-      ipv_inuse = "IPv4";
c260e0
-      use_ipv6 = FALSE;
c260e0
-#endif
c260e0
+      socket_type = "IPv4";
c260e0
+      socket_domain = AF_INET;
c260e0
+      location_str = port_str;
c260e0
       arg++;
c260e0
     }
c260e0
     else if(!strcmp("--ipv6", argv[arg])) {
c260e0
 #ifdef ENABLE_IPV6
c260e0
-      ipv_inuse = "IPv6";
c260e0
-      use_ipv6 = TRUE;
c260e0
+      socket_type = "IPv6";
c260e0
+      socket_domain = AF_INET6;
c260e0
+      location_str = port_str;
c260e0
 #endif
c260e0
       arg++;
c260e0
     }
c260e0
@@ -2018,6 +2013,8 @@ int main(int argc, char *argv[])
c260e0
     }
c260e0
   }
c260e0
 
c260e0
+  snprintf(port_str, sizeof(port_str), "port %hu", port);
c260e0
+
c260e0
 #ifdef WIN32
c260e0
   win32_init();
c260e0
   atexit(win32_cleanup);
c260e0
@@ -2027,14 +2024,7 @@ int main(int argc, char *argv[])
c260e0
 
c260e0
   pid = (long)getpid();
c260e0
 
c260e0
-#ifdef ENABLE_IPV6
c260e0
-  if(!use_ipv6)
c260e0
-#endif
c260e0
-    sock = socket(AF_INET, SOCK_STREAM, 0);
c260e0
-#ifdef ENABLE_IPV6
c260e0
-  else
c260e0
-    sock = socket(AF_INET6, SOCK_STREAM, 0);
c260e0
-#endif
c260e0
+  sock = socket(socket_domain, SOCK_STREAM, 0);
c260e0
 
c260e0
   all_sockets[0] = sock;
c260e0
   num_sockets = 1;
c260e0
@@ -2061,33 +2051,33 @@ int main(int argc, char *argv[])
c260e0
     goto sws_cleanup;
c260e0
   }
c260e0
 
c260e0
-#ifdef ENABLE_IPV6
c260e0
-  if(!use_ipv6) {
c260e0
-#endif
c260e0
+  switch(socket_domain) {
c260e0
+  case AF_INET:
c260e0
     memset(&me.sa4, 0, sizeof(me.sa4));
c260e0
     me.sa4.sin_family = AF_INET;
c260e0
     me.sa4.sin_addr.s_addr = INADDR_ANY;
c260e0
     me.sa4.sin_port = htons(port);
c260e0
     rc = bind(sock, &me.sa, sizeof(me.sa4));
c260e0
+    break;
c260e0
 #ifdef ENABLE_IPV6
c260e0
-  }
c260e0
-  else {
c260e0
+  case AF_INET6:
c260e0
     memset(&me.sa6, 0, sizeof(me.sa6));
c260e0
     me.sa6.sin6_family = AF_INET6;
c260e0
     me.sa6.sin6_addr = in6addr_any;
c260e0
     me.sa6.sin6_port = htons(port);
c260e0
     rc = bind(sock, &me.sa, sizeof(me.sa6));
c260e0
-  }
c260e0
+    break;
c260e0
 #endif /* ENABLE_IPV6 */
c260e0
+  }
c260e0
   if(0 != rc) {
c260e0
     error = SOCKERRNO;
c260e0
-    logmsg("Error binding socket on port %hu: (%d) %s",
c260e0
-           port, error, strerror(error));
c260e0
+    logmsg("Error binding socket on %s: (%d) %s",
c260e0
+           location_str, error, strerror(error));
c260e0
     goto sws_cleanup;
c260e0
   }
c260e0
 
c260e0
-  logmsg("Running %s %s version on port %d",
c260e0
-         use_gopher?"GOPHER":"HTTP", ipv_inuse, (int)port);
c260e0
+  logmsg("Running %s %s version on %s",
c260e0
+         use_gopher?"GOPHER":"HTTP", socket_type, location_str);
c260e0
 
c260e0
   /* start accepting connections */
c260e0
   rc = listen(sock, 5);
c260e0
@@ -2251,8 +2241,8 @@ sws_cleanup:
c260e0
   restore_signal_handlers();
c260e0
 
c260e0
   if(got_exit_signal) {
c260e0
-    logmsg("========> %s sws (port: %d pid: %ld) exits with signal (%d)",
c260e0
-           ipv_inuse, (int)port, pid, exit_signal);
c260e0
+    logmsg("========> %s sws (%s pid: %ld) exits with signal (%d)",
c260e0
+           socket_type, location_str, pid, exit_signal);
c260e0
     /*
c260e0
      * To properly set the return status of the process we
c260e0
      * must raise the same signal SIGINT or SIGTERM that we
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From d8d875f7c528157feec0795c03bd065420903f5d Mon Sep 17 00:00:00 2001
c260e0
From: Steve Holme <steve_holme@hotmail.com>
c260e0
Date: Wed, 3 Dec 2014 00:00:40 +0000
c260e0
Subject: [PATCH 02/11] sws.c: Fixed compilation warning when IPv6 is disabled
c260e0
c260e0
sws.c:69: warning: comma at end of enumerator list
c260e0
c260e0
Upstream-commit: d784000a1468efc986c7d156d2e7c84d1920af87
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 tests/server/sws.c | 4 ++--
c260e0
 1 file changed, 2 insertions(+), 2 deletions(-)
c260e0
c260e0
diff --git a/tests/server/sws.c b/tests/server/sws.c
c260e0
index fa10d54..2b7e628 100644
c260e0
--- a/tests/server/sws.c
c260e0
+++ b/tests/server/sws.c
c260e0
@@ -66,9 +66,9 @@
c260e0
 #endif
c260e0
 
c260e0
 static enum {
c260e0
-  socket_domain_inet = AF_INET,
c260e0
+  socket_domain_inet = AF_INET
c260e0
 #ifdef ENABLE_IPV6
c260e0
-  socket_domain_inet6 = AF_INET6
c260e0
+  , socket_domain_inet6 = AF_INET6
c260e0
 #endif
c260e0
 } socket_domain = AF_INET;
c260e0
 static bool use_gopher = FALSE;
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From db2095dec37630309bacca6795cd4cfcf6557c9b Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 27 Nov 2014 23:59:20 +0100
c260e0
Subject: [PATCH 03/11] sws: restrict TCP_NODELAY to IP sockets
c260e0
c260e0
TCP_NODELAY does not make sense for Unix sockets, so enable it only if
c260e0
the socket is using IP.
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: fb7d7e0022f22035449bbc506068004f0568f8ae
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 tests/server/sws.c | 73 ++++++++++++++++++++++++++++++++----------------------
c260e0
 1 file changed, 44 insertions(+), 29 deletions(-)
c260e0
c260e0
diff --git a/tests/server/sws.c b/tests/server/sws.c
c260e0
index 2b7e628..0739a70 100644
c260e0
--- a/tests/server/sws.c
c260e0
+++ b/tests/server/sws.c
c260e0
@@ -331,6 +331,21 @@ static void restore_signal_handlers(void)
c260e0
 #endif
c260e0
 }
c260e0
 
c260e0
+/* returns true if the current socket is an IP one */
c260e0
+static bool socket_domain_is_ip(void)
c260e0
+{
c260e0
+  switch(socket_domain) {
c260e0
+  case AF_INET:
c260e0
+#ifdef ENABLE_IPV6
c260e0
+  case AF_INET6:
c260e0
+#endif
c260e0
+    return true;
c260e0
+  default:
c260e0
+  /* case AF_UNIX: */
c260e0
+    return false;
c260e0
+  }
c260e0
+}
c260e0
+
c260e0
 /* based on the testno, parse the correct server commands */
c260e0
 static int parse_servercmd(struct httprequest *req)
c260e0
 {
c260e0
@@ -1282,9 +1297,6 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
   int rc;
c260e0
   const char *op_br = "";
c260e0
   const char *cl_br = "";
c260e0
-#ifdef TCP_NODELAY
c260e0
-  curl_socklen_t flag;
c260e0
-#endif
c260e0
 
c260e0
 #ifdef ENABLE_IPV6
c260e0
   if(socket_domain == AF_INET6) {
c260e0
@@ -1309,13 +1321,15 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
   }
c260e0
 
c260e0
 #ifdef TCP_NODELAY
c260e0
-  /* Disable the Nagle algorithm */
c260e0
-  flag = 1;
c260e0
-  if(0 != setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY,
c260e0
-                     (void *)&flag, sizeof(flag)))
c260e0
-    logmsg("====> TCP_NODELAY for server conection failed");
c260e0
-  else
c260e0
-    logmsg("TCP_NODELAY set for server conection");
c260e0
+  if(socket_domain_is_ip()) {
c260e0
+    /* Disable the Nagle algorithm */
c260e0
+    curl_socklen_t flag = 1;
c260e0
+    if(0 != setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY,
c260e0
+                       (void *)&flag, sizeof(flag)))
c260e0
+      logmsg("====> TCP_NODELAY for server conection failed");
c260e0
+    else
c260e0
+      logmsg("TCP_NODELAY set for server conection");
c260e0
+  }
c260e0
 #endif
c260e0
 
c260e0
   switch(socket_domain) {
c260e0
@@ -1398,9 +1412,6 @@ static void http_connect(curl_socket_t *infdp,
c260e0
   bool poll_server_rd[2] = { TRUE, TRUE };
c260e0
   bool poll_client_wr[2] = { TRUE, TRUE };
c260e0
   bool poll_server_wr[2] = { TRUE, TRUE };
c260e0
-#ifdef TCP_NODELAY
c260e0
-  curl_socklen_t flag;
c260e0
-#endif
c260e0
   bool primary = FALSE;
c260e0
   bool secondary = FALSE;
c260e0
   int max_tunnel_idx; /* CTRL or DATA */
c260e0
@@ -1514,13 +1525,15 @@ static void http_connect(curl_socket_t *infdp,
c260e0
           memset(&req2, 0, sizeof(req2));
c260e0
           logmsg("====> Client connect DATA");
c260e0
 #ifdef TCP_NODELAY
c260e0
-          /* Disable the Nagle algorithm */
c260e0
-          flag = 1;
c260e0
-          if(0 != setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY,
c260e0
-                             (void *)&flag, sizeof(flag)))
c260e0
-            logmsg("====> TCP_NODELAY for client DATA conection failed");
c260e0
-          else
c260e0
-            logmsg("TCP_NODELAY set for client DATA conection");
c260e0
+          if(socket_domain_is_ip()) {
c260e0
+            /* Disable the Nagle algorithm */
c260e0
+            curl_socklen_t flag = 1;
c260e0
+            if(0 != setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY,
c260e0
+                               (void *)&flag, sizeof(flag)))
c260e0
+              logmsg("====> TCP_NODELAY for client DATA conection failed");
c260e0
+            else
c260e0
+              logmsg("TCP_NODELAY set for client DATA conection");
c260e0
+          }
c260e0
 #endif
c260e0
           req2.pipelining = FALSE;
c260e0
           init_httprequest(&req2);
c260e0
@@ -1826,15 +1839,17 @@ static curl_socket_t accept_connection(curl_socket_t sock)
c260e0
   num_sockets += 1;
c260e0
 
c260e0
 #ifdef TCP_NODELAY
c260e0
-  /*
c260e0
-   * Disable the Nagle algorithm to make it easier to send out a large
c260e0
-   * response in many small segments to torture the clients more.
c260e0
-   */
c260e0
-  if(0 != setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY,
c260e0
-                     (void *)&flag, sizeof(flag)))
c260e0
-    logmsg("====> TCP_NODELAY failed");
c260e0
-  else
c260e0
-    logmsg("TCP_NODELAY set");
c260e0
+  if(socket_domain_is_ip()) {
c260e0
+    /*
c260e0
+     * Disable the Nagle algorithm to make it easier to send out a large
c260e0
+     * response in many small segments to torture the clients more.
c260e0
+     */
c260e0
+    if(0 != setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY,
c260e0
+                       (void *)&flag, sizeof(flag)))
c260e0
+      logmsg("====> TCP_NODELAY failed");
c260e0
+    else
c260e0
+      logmsg("TCP_NODELAY set");
c260e0
+  }
c260e0
 #endif
c260e0
 
c260e0
   return msgsock;
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From 7ab987459a931e593dc9f533d6e6cb6e9a26d424 Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Wed, 3 Dec 2014 02:20:00 +0100
c260e0
Subject: [PATCH 04/11] sws: add UNIX domain socket support
c260e0
c260e0
This extends sws with a --unix-socket option which causes the port to
c260e0
be ignored (as the server now listens on the path specified by
c260e0
--unix-socket). This feature will be available in the following patch
c260e0
that enables checking for UNIX domain socket support.
c260e0
c260e0
Proxy support (CONNECT) is not considered nor tested. It does not make
c260e0
sense anyway, first connecting through a TCP proxy, then let that TCP
c260e0
proxy connect to a UNIX socket.
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: e9c7a86220ddf4e67b8bff56cddfc7388afcc9ef
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 tests/server/server_sockaddr.h |  9 ++++++-
c260e0
 tests/server/sws.c             | 53 ++++++++++++++++++++++++++++++++++++++++++
c260e0
 2 files changed, 61 insertions(+), 1 deletion(-)
c260e0
c260e0
diff --git a/tests/server/server_sockaddr.h b/tests/server/server_sockaddr.h
c260e0
index 6a17fe0..3f4cd67 100644
c260e0
--- a/tests/server/server_sockaddr.h
c260e0
+++ b/tests/server/server_sockaddr.h
c260e0
@@ -7,7 +7,7 @@
c260e0
  *                            | (__| |_| |  _ <| |___
c260e0
  *                             \___|\___/|_| \_\_____|
c260e0
  *
c260e0
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
c260e0
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
c260e0
  *
c260e0
  * This software is licensed as described in the file COPYING, which
c260e0
  * you should have received as part of this distribution. The terms
c260e0
@@ -23,12 +23,19 @@
c260e0
  ***************************************************************************/
c260e0
 #include "server_setup.h"
c260e0
 
c260e0
+#ifdef HAVE_SYS_UN_H
c260e0
+#include <sys/un.h> /* for sockaddr_un */
c260e0
+#endif
c260e0
+
c260e0
 typedef union {
c260e0
   struct sockaddr      sa;
c260e0
   struct sockaddr_in   sa4;
c260e0
 #ifdef ENABLE_IPV6
c260e0
   struct sockaddr_in6  sa6;
c260e0
 #endif
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  struct sockaddr_un   sau;
c260e0
+#endif
c260e0
 } srvr_sockaddr_union_t;
c260e0
 
c260e0
 #endif /* HEADER_CURL_SERVER_SOCKADDR_H */
c260e0
diff --git a/tests/server/sws.c b/tests/server/sws.c
c260e0
index 0739a70..24ecb8f 100644
c260e0
--- a/tests/server/sws.c
c260e0
+++ b/tests/server/sws.c
c260e0
@@ -70,6 +70,9 @@ static enum {
c260e0
 #ifdef ENABLE_IPV6
c260e0
   , socket_domain_inet6 = AF_INET6
c260e0
 #endif
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  , socket_domain_unix = AF_UNIX
c260e0
+#endif
c260e0
 } socket_domain = AF_INET;
c260e0
 static bool use_gopher = FALSE;
c260e0
 static int serverlogslocked = 0;
c260e0
@@ -1359,6 +1362,11 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
c260e0
     rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa6));
c260e0
     break;
c260e0
 #endif /* ENABLE_IPV6 */
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  case AF_UNIX:
c260e0
+    logmsg("Proxying through UNIX socket is not (yet?) supported.");
c260e0
+    return CURL_SOCKET_BAD;
c260e0
+#endif /* USE_UNIX_SOCKETS */
c260e0
   }
c260e0
 
c260e0
   if(got_exit_signal) {
c260e0
@@ -1928,6 +1936,10 @@ int main(int argc, char *argv[])
c260e0
   int wrotepidfile = 0;
c260e0
   int flag;
c260e0
   unsigned short port = DEFAULT_PORT;
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  const char *unix_socket = NULL;
c260e0
+  bool unlink_socket = false;
c260e0
+#endif
c260e0
   char *pidname= (char *)".http.pid";
c260e0
   struct httprequest req;
c260e0
   int rc;
c260e0
@@ -1948,6 +1960,9 @@ int main(int argc, char *argv[])
c260e0
 #ifdef ENABLE_IPV6
c260e0
              "/IPv6"
c260e0
 #endif
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+             "/unix"
c260e0
+#endif
c260e0
           );
c260e0
       return 0;
c260e0
     }
c260e0
@@ -1980,6 +1995,23 @@ int main(int argc, char *argv[])
c260e0
 #endif
c260e0
       arg++;
c260e0
     }
c260e0
+    else if(!strcmp("--unix-socket", argv[arg])) {
c260e0
+      arg++;
c260e0
+      if(argc>arg) {
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+        unix_socket = argv[arg];
c260e0
+        if(strlen(unix_socket) >= sizeof(me.sau.sun_path)) {
c260e0
+          fprintf(stderr, "sws: socket path must be shorter than %zu chars\n",
c260e0
+                  sizeof(me.sau.sun_path));
c260e0
+          return 0;
c260e0
+        }
c260e0
+        socket_type = "unix";
c260e0
+        socket_domain = AF_UNIX;
c260e0
+        location_str = unix_socket;
c260e0
+#endif
c260e0
+        arg++;
c260e0
+      }
c260e0
+    }
c260e0
     else if(!strcmp("--port", argv[arg])) {
c260e0
       arg++;
c260e0
       if(argc>arg) {
c260e0
@@ -2020,6 +2052,7 @@ int main(int argc, char *argv[])
c260e0
            " --pidfile [file]\n"
c260e0
            " --ipv4\n"
c260e0
            " --ipv6\n"
c260e0
+           " --unix-socket [file]\n"
c260e0
            " --port [port]\n"
c260e0
            " --srcdir [path]\n"
c260e0
            " --connect [ip4-addr]\n"
c260e0
@@ -2083,6 +2116,14 @@ int main(int argc, char *argv[])
c260e0
     rc = bind(sock, &me.sa, sizeof(me.sa6));
c260e0
     break;
c260e0
 #endif /* ENABLE_IPV6 */
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  case AF_UNIX:
c260e0
+    memset(&me.sau, 0, sizeof(me.sau));
c260e0
+    me.sau.sun_family = AF_UNIX;
c260e0
+    strncpy(me.sau.sun_path, unix_socket, sizeof(me.sau.sun_path));
c260e0
+    rc = bind(sock, &me.sa, sizeof(me.sau));
c260e0
+    break;
c260e0
+#endif /* USE_UNIX_SOCKETS */
c260e0
   }
c260e0
   if(0 != rc) {
c260e0
     error = SOCKERRNO;
c260e0
@@ -2103,6 +2144,11 @@ int main(int argc, char *argv[])
c260e0
     goto sws_cleanup;
c260e0
   }
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  /* listen succeeds, so let's assume a valid listening UNIX socket */
c260e0
+  unlink_socket = true;
c260e0
+#endif
c260e0
+
c260e0
   /*
c260e0
   ** As soon as this server writes its pid file the test harness will
c260e0
   ** attempt to connect to this server and initiate its verification.
c260e0
@@ -2242,6 +2288,13 @@ sws_cleanup:
c260e0
   if(sock != CURL_SOCKET_BAD)
c260e0
     sclose(sock);
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  if(unlink_socket && socket_domain == AF_UNIX) {
c260e0
+    rc = unlink(unix_socket);
c260e0
+    logmsg("unlink(%s) = %d (%s)", unix_socket, rc, strerror(rc));
c260e0
+  }
c260e0
+#endif
c260e0
+
c260e0
   if(got_exit_signal)
c260e0
     logmsg("signalled to die");
c260e0
 
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From d04ea6f7f09e1556f80c4bbf4fc9497f83bc37a6 Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 27 Nov 2014 23:59:23 +0100
c260e0
Subject: [PATCH 05/11] tests: add HTTP UNIX socket server testing support
c260e0
c260e0
The variable `$ipvnum` can now contain "unix" besides the integers 4
c260e0
and 6 since the variable. Functions which receive this parameter
c260e0
have their `$port` parameter renamed to `$port_or_path` to support a
c260e0
path to the UNIX domain socket (as a "port" is only meaningful for TCP).
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: f1cc2a2c0cf8e191e606c6093c679fbee95e8809
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 tests/FILEFORMAT    |  2 ++
c260e0
 tests/README        |  3 ++
c260e0
 tests/httpserver.pl | 15 ++++++++-
c260e0
 tests/runtests.pl   | 96 +++++++++++++++++++++++++++++++++++++++++++++--------
c260e0
 tests/serverhelp.pm |  4 +--
c260e0
 5 files changed, 104 insertions(+), 16 deletions(-)
c260e0
c260e0
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
c260e0
index 96cd5c8..702368f 100644
c260e0
--- a/tests/FILEFORMAT
c260e0
+++ b/tests/FILEFORMAT
c260e0
@@ -165,6 +165,7 @@ smtp
c260e0
 httptls+srp
c260e0
 httptls+srp-ipv6
c260e0
 http-proxy
c260e0
+http-unix
c260e0
 
c260e0
 Give only one per line.  This subsection is mandatory.
c260e0
 </server>
c260e0
@@ -284,6 +285,7 @@ Available substitute variables include:
c260e0
 %HTTPPORT  - Port number of the HTTP server
c260e0
 %HOST6IP   - IPv6 address of the host running this test
c260e0
 %HTTP6PORT - IPv6 port number of the HTTP server
c260e0
+%HTTPUNIXPATH - Path to the UNIX socket of the HTTP server
c260e0
 %HTTPSPORT - Port number of the HTTPS server
c260e0
 %PROXYPORT - Port number of the HTTP proxy
c260e0
 %FTPPORT   - Port number of the FTP server
c260e0
diff --git a/tests/README b/tests/README
c260e0
index fff618e..b442693 100644
c260e0
--- a/tests/README
c260e0
+++ b/tests/README
c260e0
@@ -80,6 +80,9 @@ The cURL Test Suite
c260e0
   machine, or just move the servers in case you have local services on any of
c260e0
   those ports.
c260e0
 
c260e0
+  The HTTP server supports listening on a UNIX domain socket, the default
c260e0
+  location is 'http.sock'.
c260e0
+
c260e0
  1.4 Run
c260e0
 
c260e0
   'make test'. This builds the test suite support code and invokes the
c260e0
diff --git a/tests/httpserver.pl b/tests/httpserver.pl
c260e0
index a38c3ce..1b8c3d2 100755
c260e0
--- a/tests/httpserver.pl
c260e0
+++ b/tests/httpserver.pl
c260e0
@@ -36,6 +36,7 @@ use serverhelp qw(
c260e0
 
c260e0
 my $verbose = 0;     # set to 1 for debugging
c260e0
 my $port = 8990;     # just a default
c260e0
+my $unix_socket;     # location to place a listening UNIX socket
c260e0
 my $ipvnum = 4;      # default IP version of http server
c260e0
 my $idnum = 1;       # dafault http server instance number
c260e0
 my $proto = 'http';  # protocol the http server speaks
c260e0
@@ -74,6 +75,13 @@ while(@ARGV) {
c260e0
     elsif($ARGV[0] eq '--ipv6') {
c260e0
         $ipvnum = 6;
c260e0
     }
c260e0
+    elsif($ARGV[0] eq '--unix-socket') {
c260e0
+        $ipvnum = 'unix';
c260e0
+        if($ARGV[1]) {
c260e0
+            $unix_socket = $ARGV[1];
c260e0
+            shift @ARGV;
c260e0
+        }
c260e0
+    }
c260e0
     elsif($ARGV[0] eq '--gopher') {
c260e0
         $gopher = 1;
c260e0
     }
c260e0
@@ -117,7 +125,12 @@ if(!$logfile) {
c260e0
 $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
c260e0
 $flags .= "--gopher " if($gopher);
c260e0
 $flags .= "--connect $connect " if($connect);
c260e0
-$flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
c260e0
+if($ipvnum eq 'unix') {
c260e0
+    $flags .= "--unix-socket '$unix_socket' ";
c260e0
+} else {
c260e0
+    $flags .= "--ipv$ipvnum --port $port ";
c260e0
+}
c260e0
+$flags .= "--srcdir \"$srcdir\"";
c260e0
 
c260e0
 if($verbose) {
c260e0
     print STDERR "RUN: server/sws $flags\n";
c260e0
diff --git a/tests/runtests.pl b/tests/runtests.pl
c260e0
index b39da66..fa96345 100755
c260e0
--- a/tests/runtests.pl
c260e0
+++ b/tests/runtests.pl
c260e0
@@ -140,6 +140,7 @@ my $GOPHER6PORT;         # Gopher IPv6 server port
c260e0
 my $HTTPTLSPORT;         # HTTP TLS (non-stunnel) server port
c260e0
 my $HTTPTLS6PORT;        # HTTP TLS (non-stunnel) IPv6 server port
c260e0
 my $HTTPPROXYPORT;       # HTTP proxy port, when using CONNECT
c260e0
+my $HTTPUNIXPATH;        # HTTP server UNIX domain socket path
c260e0
 
c260e0
 my $srcdir = $ENV{'srcdir'} || '.';
c260e0
 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
c260e0
@@ -201,10 +202,12 @@ my $ssl_version; # set if libcurl is built with SSL support
c260e0
 my $large_file;  # set if libcurl is built with large file support
c260e0
 my $has_idn;     # set if libcurl is built with IDN support
c260e0
 my $http_ipv6;   # set if HTTP server has IPv6 support
c260e0
+my $http_unix;   # set if HTTP server has UNIX sockets support
c260e0
 my $ftp_ipv6;    # set if FTP server has IPv6 support
c260e0
 my $tftp_ipv6;   # set if TFTP server has IPv6 support
c260e0
 my $gopher_ipv6; # set if Gopher server has IPv6 support
c260e0
 my $has_ipv6;    # set if libcurl is built with IPv6 support
c260e0
+my $has_unix;    # set if libcurl is built with UNIX sockets support
c260e0
 my $has_libz;    # set if libcurl is built with libz support
c260e0
 my $has_getrlimit;  # set if system has getrlimit()
c260e0
 my $has_ntlm;    # set if libcurl is built with NTLM support
c260e0
@@ -358,6 +361,13 @@ sub init_serverpidfile_hash {
c260e0
       }
c260e0
     }
c260e0
   }
c260e0
+  for my $proto (('http', 'imap', 'pop3', 'smtp')) {
c260e0
+    for my $ssl (('', 's')) {
c260e0
+      my $serv = servername_id("$proto$ssl", "unix", 1);
c260e0
+      my $pidf = server_pidfilename("$proto$ssl", "unix", 1);
c260e0
+      $serverpidfile{$serv} = $pidf;
c260e0
+    }
c260e0
+  }
c260e0
 }
c260e0
 
c260e0
 #######################################################################
c260e0
@@ -641,11 +651,11 @@ sub stopserver {
c260e0
     # All servers relative to the given one must be stopped also
c260e0
     #
c260e0
     my @killservers;
c260e0
-    if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
c260e0
+    if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
c260e0
         # given a stunnel based ssl server, also kill non-ssl underlying one
c260e0
         push @killservers, "${1}${2}";
c260e0
     }
c260e0
-    elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
c260e0
+    elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
c260e0
         # given a non-ssl server, also kill stunnel based ssl piggybacking one
c260e0
         push @killservers, "${1}s${2}";
c260e0
     }
c260e0
@@ -691,10 +701,12 @@ sub stopserver {
c260e0
 # assign requested address")
c260e0
 #
c260e0
 sub verifyhttp {
c260e0
-    my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
c260e0
+    my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_;
c260e0
     my $server = servername_id($proto, $ipvnum, $idnum);
c260e0
     my $pid = 0;
c260e0
     my $bonus="";
c260e0
+    # $port_or_path contains a path for UNIX sockets, sws ignores the port
c260e0
+    my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
c260e0
 
c260e0
     my $verifyout = "$LOGDIR/".
c260e0
         servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
c260e0
@@ -714,6 +726,7 @@ sub verifyhttp {
c260e0
     $flags .= "--silent ";
c260e0
     $flags .= "--verbose ";
c260e0
     $flags .= "--globoff ";
c260e0
+    $flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
c260e0
     $flags .= "-1 "         if($has_axtls);
c260e0
     $flags .= "--insecure " if($proto eq 'https');
c260e0
     $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
c260e0
@@ -1160,7 +1173,7 @@ sub responsiveserver {
c260e0
 # start the http server
c260e0
 #
c260e0
 sub runhttpserver {
c260e0
-    my ($proto, $verbose, $alt, $port) = @_;
c260e0
+    my ($proto, $verbose, $alt, $port_or_path) = @_;
c260e0
     my $ip = $HOSTIP;
c260e0
     my $ipvnum = 4;
c260e0
     my $idnum = 1;
c260e0
@@ -1188,6 +1201,10 @@ sub runhttpserver {
c260e0
     if ($doesntrun{$pidfile}) {
c260e0
         return (0,0);
c260e0
     }
c260e0
+    elsif($alt eq "unix") {
c260e0
+        # IP (protocol) is mutually exclusive with UNIX sockets
c260e0
+        $ipvnum = "unix";
c260e0
+    }
c260e0
 
c260e0
     my $pid = processexists($pidfile);
c260e0
     if($pid > 0) {
c260e0
@@ -1204,7 +1221,12 @@ sub runhttpserver {
c260e0
     $flags .= "--verbose " if($debugprotocol);
c260e0
     $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
c260e0
     $flags .= "--id $idnum " if($idnum > 1);
c260e0
-    $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
c260e0
+    if($ipvnum eq "unix") {
c260e0
+        $flags .= "--unix-socket '$port_or_path' ";
c260e0
+    } else {
c260e0
+        $flags .= "--ipv$ipvnum --port $port_or_path ";
c260e0
+    }
c260e0
+    $flags .= "--srcdir \"$srcdir\"";
c260e0
 
c260e0
     my $cmd = "$perl $srcdir/httpserver.pl $flags";
c260e0
     my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
c260e0
@@ -1219,7 +1241,7 @@ sub runhttpserver {
c260e0
     }
c260e0
 
c260e0
     # Server is up. Verify that we can speak to it.
c260e0
-    my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
c260e0
+    my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
c260e0
     if(!$pid3) {
c260e0
         logmsg "RUN: $srvrname server failed verification\n";
c260e0
         # failed to talk to it properly. Kill the server and return failure
c260e0
@@ -1984,7 +2006,7 @@ sub runsocksserver {
c260e0
 # be used to verify that a server present in %run hash is still functional
c260e0
 #
c260e0
 sub responsive_http_server {
c260e0
-    my ($proto, $verbose, $alt, $port) = @_;
c260e0
+    my ($proto, $verbose, $alt, $port_or_path) = @_;
c260e0
     my $ip = $HOSTIP;
c260e0
     my $ipvnum = 4;
c260e0
     my $idnum = 1;
c260e0
@@ -1997,8 +2019,12 @@ sub responsive_http_server {
c260e0
     elsif($alt eq "proxy") {
c260e0
         $idnum = 2;
c260e0
     }
c260e0
+    elsif($alt eq "unix") {
c260e0
+        # IP (protocol) is mutually exclusive with UNIX sockets
c260e0
+        $ipvnum = "unix";
c260e0
+    }
c260e0
 
c260e0
-    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
c260e0
+    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
c260e0
 }
c260e0
 
c260e0
 #######################################################################
c260e0
@@ -2264,9 +2290,10 @@ sub checksystem {
c260e0
             @protocols = split(' ', lc($1));
c260e0
 
c260e0
             # Generate a "proto-ipv6" version of each protocol to match the
c260e0
-            # IPv6 <server> name. This works even if IPv6 support isn't
c260e0
+            # IPv6 <server> name and a "proto-unix" to match the variant which
c260e0
+            # uses UNIX domain sockets. This works even if support isn't
c260e0
             # compiled in because the <features> test will fail.
c260e0
-            push @protocols, map($_ . '-ipv6', @protocols);
c260e0
+            push @protocols, map(("$_-ipv6", "$_-unix"), @protocols);
c260e0
 
c260e0
             # 'http-proxy' is used in test cases to do CONNECT through
c260e0
             push @protocols, 'http-proxy';
c260e0
@@ -2299,6 +2326,9 @@ sub checksystem {
c260e0
             if($feat =~ /IPv6/i) {
c260e0
                 $has_ipv6 = 1;
c260e0
             }
c260e0
+            if($feat =~ /unix-sockets/i) {
c260e0
+                $has_unix = 1;
c260e0
+            }
c260e0
             if($feat =~ /libz/i) {
c260e0
                 $has_libz = 1;
c260e0
             }
c260e0
@@ -2396,6 +2426,12 @@ sub checksystem {
c260e0
         }
c260e0
     }
c260e0
 
c260e0
+    if($has_unix) {
c260e0
+        # client has UNIX sockets support, check whether the HTTP server has it
c260e0
+        my @sws = `server/sws --version`;
c260e0
+        $http_unix = 1 if($sws[0] =~ /unix/);
c260e0
+    }
c260e0
+
c260e0
     if(!$curl_debug && $torture) {
c260e0
         die "can't run torture tests since curl was not built with curldebug";
c260e0
     }
c260e0
@@ -2423,6 +2459,7 @@ sub checksystem {
c260e0
     logmsg sprintf("  track memory: %s\n", $curl_debug?"ON ":"OFF");
c260e0
     logmsg sprintf("* valgrind:     %8s", $valgrind?"ON ":"OFF");
c260e0
     logmsg sprintf("  HTTP IPv6     %s\n", $http_ipv6?"ON ":"OFF");
c260e0
+    logmsg sprintf("* HTTP UNIX     %s\n", $http_unix?"ON ":"OFF");
c260e0
     logmsg sprintf("* FTP IPv6      %8s", $ftp_ipv6?"ON ":"OFF");
c260e0
     logmsg sprintf("  Libtool lib:  %s\n", $libtool?"ON ":"OFF");
c260e0
     logmsg sprintf("* Shared build:      %s\n", $has_shared);
c260e0
@@ -2473,6 +2510,13 @@ sub checksystem {
c260e0
         logmsg "\n";
c260e0
     }
c260e0
 
c260e0
+    if($has_unix) {
c260e0
+        logmsg "* UNIX socket paths:\n";
c260e0
+        if($http_unix) {
c260e0
+            logmsg sprintf("*   HTTP-UNIX:%s\n", $HTTPUNIXPATH);
c260e0
+        }
c260e0
+    }
c260e0
+
c260e0
     $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
c260e0
 
c260e0
     logmsg "***************************************** \n";
c260e0
@@ -2520,6 +2564,10 @@ sub subVariables {
c260e0
   $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
c260e0
   $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
c260e0
 
c260e0
+  # server UNIX domain socket paths
c260e0
+
c260e0
+  $$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g;
c260e0
+
c260e0
   # client IP addresses
c260e0
 
c260e0
   $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
c260e0
@@ -2707,6 +2755,11 @@ sub singletest {
c260e0
                 next;
c260e0
             }
c260e0
         }
c260e0
+        elsif($f eq "unix-sockets") {
c260e0
+            if($has_unix) {
c260e0
+                next;
c260e0
+            }
c260e0
+        }
c260e0
         elsif($f eq "libz") {
c260e0
             if($has_libz) {
c260e0
                 next;
c260e0
@@ -3219,11 +3272,11 @@ sub singletest {
c260e0
         my @killservers;
c260e0
         foreach my $server (@killtestservers) {
c260e0
             chomp $server;
c260e0
-            if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
c260e0
+            if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
c260e0
                 # given a stunnel ssl server, also kill non-ssl underlying one
c260e0
                 push @killservers, "${1}${2}";
c260e0
             }
c260e0
-            elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
c260e0
+            elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
c260e0
                 # given a non-ssl server, also kill stunnel piggybacking one
c260e0
                 push @killservers, "${1}s${2}";
c260e0
             }
c260e0
@@ -3728,7 +3781,7 @@ sub startservers {
c260e0
         $what =~ s/[^a-z0-9-]//g;
c260e0
 
c260e0
         my $certfile;
c260e0
-        if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
c260e0
+        if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
c260e0
             $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
c260e0
         }
c260e0
 
c260e0
@@ -4066,6 +4119,22 @@ sub startservers {
c260e0
                 }
c260e0
             }
c260e0
         }
c260e0
+        elsif($what eq "http-unix") {
c260e0
+            if($torture && $run{'http-unix'} &&
c260e0
+               !responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
c260e0
+                stopserver('http-unix');
c260e0
+            }
c260e0
+            if(!$run{'http-unix'}) {
c260e0
+                ($pid, $pid2) = runhttpserver("http", $verbose, "unix",
c260e0
+                                              $HTTPUNIXPATH);
c260e0
+                if($pid <= 0) {
c260e0
+                    return "failed starting HTTP-unix server";
c260e0
+                }
c260e0
+                logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
c260e0
+                    if($verbose);
c260e0
+                $run{'http-unix'}="$pid $pid2";
c260e0
+            }
c260e0
+        }
c260e0
         elsif($what eq "none") {
c260e0
             logmsg "* starts no server\n" if ($verbose);
c260e0
         }
c260e0
@@ -4502,6 +4571,7 @@ $GOPHER6PORT     = $base++; # Gopher IPv6 server port
c260e0
 $HTTPTLSPORT     = $base++; # HTTP TLS (non-stunnel) server port
c260e0
 $HTTPTLS6PORT    = $base++; # HTTP TLS (non-stunnel) IPv6 server port
c260e0
 $HTTPPROXYPORT   = $base++; # HTTP proxy port, when using CONNECT
c260e0
+$HTTPUNIXPATH    = 'http.sock'; # HTTP server UNIX domain socket path
c260e0
 
c260e0
 #######################################################################
c260e0
 # clear and create logging directory:
c260e0
diff --git a/tests/serverhelp.pm b/tests/serverhelp.pm
c260e0
index a1d1dc3..1fc621b 100644
c260e0
--- a/tests/serverhelp.pm
c260e0
+++ b/tests/serverhelp.pm
c260e0
@@ -109,8 +109,8 @@ sub servername_str {
c260e0
 
c260e0
     $ipver = (not $ipver) ? 'ipv4' : lc($ipver);
c260e0
     die "unsupported IP version: '$ipver'" unless($ipver &&
c260e0
-        ($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6)$/));
c260e0
-    $ipver = ($ipver =~ /6$/) ? '-IPv6' : '';
c260e0
+        ($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6|unix)$/));
c260e0
+    $ipver = ($ipver =~ /6$/) ? '-IPv6' : (($ipver =~ /unix$/) ? '-unix' : '');
c260e0
 
c260e0
     $idnum = 1 if(not $idnum);
c260e0
     die "unsupported ID number: '$idnum'" unless($idnum &&
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From d2f7b1d51e356586356da87d1ae32c0c44274887 Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 27 Nov 2014 23:59:24 +0100
c260e0
Subject: [PATCH 06/11] tests: add two HTTP over UNIX socket tests
c260e0
c260e0
test1435: a simple test that checks whether a HTTP request can be
c260e0
performed over the UNIX socket. The hostname/port are interpreted
c260e0
by sws and should be ignored by cURL.
c260e0
c260e0
test1436: test for the ability to do two requests to the same host,
c260e0
interleaved with one to a different hostname.
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: 479abdd32eee15dab78d0cd6b1786d569680f0ac
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 tests/data/Makefile.am |  1 +
c260e0
 tests/data/Makefile.in |  1 +
c260e0
 tests/data/test1435    | 46 +++++++++++++++++++++++++++
c260e0
 tests/data/test1436    | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
c260e0
 4 files changed, 133 insertions(+)
c260e0
 create mode 100644 tests/data/test1435
c260e0
 create mode 100644 tests/data/test1436
c260e0
c260e0
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
c260e0
index c4f76df..35bc6eb 100644
c260e0
--- a/tests/data/Makefile.am
c260e0
+++ b/tests/data/Makefile.am
c260e0
@@ -93,6 +93,7 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
c260e0
 test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
c260e0
 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
c260e0
 test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
c260e0
+test1435 test1436 \
c260e0
 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
c260e0
 test1508 test1529 \
c260e0
 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
c260e0
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
c260e0
index e73ca96..d5e5f01 100644
c260e0
--- a/tests/data/Makefile.in
c260e0
+++ b/tests/data/Makefile.in
c260e0
@@ -357,6 +357,7 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
c260e0
 test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
c260e0
 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
c260e0
 test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
c260e0
+test1435 test1436 \
c260e0
 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
c260e0
 test1508 test1529 \
c260e0
 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
c260e0
diff --git a/tests/data/test1435 b/tests/data/test1435
c260e0
new file mode 100644
c260e0
index 0000000..56ff9d1
c260e0
--- /dev/null
c260e0
+++ b/tests/data/test1435
c260e0
@@ -0,0 +1,46 @@
c260e0
+<testcase>
c260e0
+<info>
c260e0
+<keywords>
c260e0
+HTTP
c260e0
+HTTP GET
c260e0
+unix sockets
c260e0
+</keywords>
c260e0
+</info>
c260e0
+
c260e0
+<reply>
c260e0
+<data>
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Sun, 16 Nov 2014 23:47:38 GMT
c260e0
+Content-Length: 17
c260e0
+
c260e0
+Based on test300
c260e0
+</data>
c260e0
+</reply>
c260e0
+
c260e0
+<client>
c260e0
+<features>
c260e0
+unix-sockets
c260e0
+</features>
c260e0
+<server>
c260e0
+http-unix
c260e0
+</server>
c260e0
+ <name>
c260e0
+simple HTTP GET over UNIX socket
c260e0
+ </name>
c260e0
+ <command>
c260e0
+--unix-socket %HTTPUNIXPATH http://server-interpreted.example.com/1435
c260e0
+</command>
c260e0
+</client>
c260e0
+
c260e0
+<verify>
c260e0
+<strip>
c260e0
+^User-Agent:.*
c260e0
+</strip>
c260e0
+<protocol>
c260e0
+GET /1435 HTTP/1.1
c260e0
+Host: server-interpreted.example.com
c260e0
+Accept: */*
c260e0
+
c260e0
+</protocol>
c260e0
+</verify>
c260e0
+</testcase>
c260e0
diff --git a/tests/data/test1436 b/tests/data/test1436
c260e0
new file mode 100644
c260e0
index 0000000..b16eadd
c260e0
--- /dev/null
c260e0
+++ b/tests/data/test1436
c260e0
@@ -0,0 +1,85 @@
c260e0
+<testcase>
c260e0
+<info>
c260e0
+<keywords>
c260e0
+HTTP
c260e0
+HTTP GET
c260e0
+unix sockets
c260e0
+</keywords>
c260e0
+</info>
c260e0
+
c260e0
+<reply>
c260e0
+<data1>
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Mon, 17 Nov 2014 13:42:47 GMT
c260e0
+Content-Length: 6
c260e0
+
c260e0
+First
c260e0
+</data1>
c260e0
+<data2>
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Mon, 17 Nov 2014 13:42:48 GMT
c260e0
+Content-Length: 7
c260e0
+
c260e0
+Second
c260e0
+</data2>
c260e0
+<data3>
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Mon, 17 Nov 2014 13:42:49 GMT
c260e0
+Content-Length: 6
c260e0
+
c260e0
+Third
c260e0
+</data3>
c260e0
+</reply>
c260e0
+
c260e0
+<client>
c260e0
+<features>
c260e0
+unix-sockets
c260e0
+</features>
c260e0
+<server>
c260e0
+http-unix
c260e0
+</server>
c260e0
+ <name>
c260e0
+HTTP requests with multiple connections over UNIX socket
c260e0
+ </name>
c260e0
+ <command>
c260e0
+--unix-socket %HTTPUNIXPATH http://one.example.com/14360001 http://two.example.com/14360002 http://one.example.com/14360003
c260e0
+</command>
c260e0
+</client>
c260e0
+
c260e0
+<verify>
c260e0
+<strip>
c260e0
+^User-Agent:.*
c260e0
+</strip>
c260e0
+<protocol>
c260e0
+GET /14360001 HTTP/1.1
c260e0
+Host: one.example.com
c260e0
+Accept: */*
c260e0
+
c260e0
+GET /14360002 HTTP/1.1
c260e0
+Host: two.example.com
c260e0
+Accept: */*
c260e0
+
c260e0
+GET /14360003 HTTP/1.1
c260e0
+Host: one.example.com
c260e0
+Accept: */*
c260e0
+
c260e0
+</protocol>
c260e0
+<stdout>
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Mon, 17 Nov 2014 13:42:47 GMT
c260e0
+Content-Length: 6
c260e0
+
c260e0
+First
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Mon, 17 Nov 2014 13:42:48 GMT
c260e0
+Content-Length: 7
c260e0
+
c260e0
+Second
c260e0
+HTTP/1.1 200 OK
c260e0
+Date: Mon, 17 Nov 2014 13:42:49 GMT
c260e0
+Content-Length: 6
c260e0
+
c260e0
+Third
c260e0
+</stdout>
c260e0
+</verify>
c260e0
+</testcase>
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From f784b2d3d6cf08193662a23aae9305f11c4a4559 Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 27 Nov 2014 23:59:25 +0100
c260e0
Subject: [PATCH 07/11] libcurl: add UNIX domain sockets support
c260e0
c260e0
The ability to do HTTP requests over a UNIX domain socket has been
c260e0
requested before, in Apr 2008 [0][1] and Sep 2010 [2]. While a
c260e0
discussion happened, no patch seems to get through. I decided to give it
c260e0
a go since I need to test a nginx HTTP server which listens on a UNIX
c260e0
domain socket.
c260e0
c260e0
One patch [3] seems to make it possible to use the
c260e0
CURLOPT_OPENSOCKETFUNCTION function to gain a UNIX domain socket.
c260e0
Another person wrote a Go program which can do HTTP over a UNIX socket
c260e0
for Docker[4] which uses a special URL scheme (though the name contains
c260e0
cURL, it has no relation to the cURL library).
c260e0
c260e0
This patch considers support for UNIX domain sockets at the same level
c260e0
as HTTP proxies / IPv6, it acts as an intermediate socket provider and
c260e0
not as a separate protocol. Since this feature affects network
c260e0
operations, a new feature flag was added ("unix-sockets") with a
c260e0
corresponding CURL_VERSION_UNIX_SOCKETS macro.
c260e0
c260e0
A new CURLOPT_UNIX_SOCKET_PATH option is added and documented. This
c260e0
option enables UNIX domain sockets support for all requests on the
c260e0
handle (replacing IP sockets and skipping proxies).
c260e0
c260e0
A new configure option (--enable-unix-sockets) and CMake option
c260e0
(ENABLE_UNIX_SOCKETS) can disable this optional feature. Note that I
c260e0
deliberately did not mark this feature as advanced, this is a
c260e0
feature/component that should easily be available.
c260e0
c260e0
 [0]: http://curl.haxx.se/mail/lib-2008-04/0279.html
c260e0
 [1]: http://daniel.haxx.se/blog/2008/04/14/http-over-unix-domain-sockets/
c260e0
 [2]: http://sourceforge.net/p/curl/feature-requests/53/
c260e0
 [3]: http://curl.haxx.se/mail/lib-2008-04/0361.html
c260e0
 [4]: https://github.com/Soulou/curl-unix-socket
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: 970c22f970f0172e6a4c98ccc3176c740ddaa1c6
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 configure                        | 112 +++++++++++++++++++++++++++++++++++++++
c260e0
 configure.ac                     |  38 +++++++++++++
c260e0
 docs/libcurl/curl_easy_setopt.3  |  12 +++++
c260e0
 docs/libcurl/curl_version_info.3 |   2 +
c260e0
 docs/libcurl/symbols-in-versions |   2 +
c260e0
 include/curl/curl.h              |   4 ++
c260e0
 lib/Makefile.in                  |   1 +
c260e0
 lib/curl_addrinfo.c              |  39 ++++++++++++++
c260e0
 lib/curl_addrinfo.h              |   4 ++
c260e0
 lib/curl_config.h.in             |   3 ++
c260e0
 lib/url.c                        |  44 +++++++++++++++
c260e0
 lib/urldata.h                    |   4 ++
c260e0
 lib/version.c                    |   3 ++
c260e0
 src/Makefile.in                  |   1 +
c260e0
 src/tool_getparam.c              |   3 +-
c260e0
 tests/server/Makefile.in         |   1 +
c260e0
 16 files changed, 272 insertions(+), 1 deletion(-)
c260e0
c260e0
diff --git a/configure b/configure
c260e0
index c5d1817..3e1f5d3 100755
c260e0
--- a/configure
c260e0
+++ b/configure
c260e0
@@ -889,6 +889,7 @@ SONAME_BUMP_TRUE
c260e0
 CFLAG_CURL_SYMBOL_HIDING
c260e0
 DOING_CURL_SYMBOL_HIDING_FALSE
c260e0
 DOING_CURL_SYMBOL_HIDING_TRUE
c260e0
+USE_UNIX_SOCKETS
c260e0
 BUILD_LIBHOSTNAME_FALSE
c260e0
 BUILD_LIBHOSTNAME_TRUE
c260e0
 USE_EMBEDDED_ARES_FALSE
c260e0
@@ -1159,6 +1160,7 @@ enable_sspi
c260e0
 enable_crypto_auth
c260e0
 enable_ntlm_wb
c260e0
 enable_tls_srp
c260e0
+enable_unix_sockets
c260e0
 enable_cookies
c260e0
 enable_soname_bump
c260e0
 '
c260e0
@@ -1873,6 +1875,8 @@ Optional Features:
c260e0
                           helper
c260e0
   --enable-tls-srp        Enable TLS-SRP authentication
c260e0
   --disable-tls-srp       Disable TLS-SRP authentication
c260e0
+  --enable-unix-sockets   Enable UNIX domain sockets
c260e0
+  --disable-unix-sockets  Disable UNIX domain sockets
c260e0
   --enable-cookies        Enable cookies support
c260e0
   --disable-cookies       Disable cookies support
c260e0
   --enable-soname-bump    Enable enforced SONAME bump
c260e0
@@ -2607,6 +2611,61 @@ $as_echo "$ac_res" >&6; }
c260e0
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
c260e0
 
c260e0
 } # ac_fn_c_check_type
c260e0
+
c260e0
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
c260e0
+# ----------------------------------------------------
c260e0
+# Tries to find if the field MEMBER exists in type AGGR, after including
c260e0
+# INCLUDES, setting cache variable VAR accordingly.
c260e0
+ac_fn_c_check_member ()
c260e0
+{
c260e0
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
c260e0
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
c260e0
+$as_echo_n "checking for $2.$3... " >&6; }
c260e0
+if eval \${$4+:} false; then :
c260e0
+  $as_echo_n "(cached) " >&6
c260e0
+else
c260e0
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
c260e0
+/* end confdefs.h.  */
c260e0
+$5
c260e0
+int main (void)
c260e0
+{
c260e0
+static $2 ac_aggr;
c260e0
+if (ac_aggr.$3)
c260e0
+return 0;
c260e0
+ ;
c260e0
+ return 0;
c260e0
+}
c260e0
+_ACEOF
c260e0
+if ac_fn_c_try_compile "$LINENO"; then :
c260e0
+  eval "$4=yes"
c260e0
+else
c260e0
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
c260e0
+/* end confdefs.h.  */
c260e0
+$5
c260e0
+int main (void)
c260e0
+{
c260e0
+static $2 ac_aggr;
c260e0
+if (sizeof ac_aggr.$3)
c260e0
+return 0;
c260e0
+ ;
c260e0
+ return 0;
c260e0
+}
c260e0
+_ACEOF
c260e0
+if ac_fn_c_try_compile "$LINENO"; then :
c260e0
+  eval "$4=yes"
c260e0
+else
c260e0
+  eval "$4=no"
c260e0
+fi
c260e0
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
c260e0
+fi
c260e0
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
c260e0
+fi
c260e0
+eval ac_res=\$$4
c260e0
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
c260e0
+$as_echo "$ac_res" >&6; }
c260e0
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
c260e0
+
c260e0
+} # ac_fn_c_check_member
c260e0
 cat >config.log <<_ACEOF
c260e0
 This file contains any messages produced by compilers while
c260e0
 running configure, to aid debugging if configure makes a mistake.
c260e0
@@ -5447,6 +5506,7 @@ PKGADD_VENDOR="curl.haxx.se"
c260e0
 curl_tls_srp_msg="no      (--enable-tls-srp)"
c260e0
     curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
c260e0
    curl_ipv6_msg="no      (--enable-ipv6)"
c260e0
+curl_unix_sockets_msg="no      (--enable-unix-sockets)"
c260e0
     curl_idn_msg="no      (--with-{libidn,winidn})"
c260e0
  curl_manual_msg="no      (--enable-manual)"
c260e0
 curl_libcurl_msg="enabled (--disable-libcurl-option)"
c260e0
@@ -39239,6 +39299,53 @@ $as_echo "#define USE_TLS_SRP 1" >>confdefs.h
c260e0
    curl_tls_srp_msg="enabled"
c260e0
 fi
c260e0
 
c260e0
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable UNIX domain sockets" >&5
c260e0
+$as_echo_n "checking whether to enable UNIX domain sockets... " >&6; }
c260e0
+# Check whether --enable-unix-sockets was given.
c260e0
+if test "${enable_unix_sockets+set}" = set; then :
c260e0
+  enableval=$enable_unix_sockets;  case "$enableval" in
c260e0
+  no)  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
c260e0
+$as_echo "no" >&6; }
c260e0
+       want_unix_sockets=no
c260e0
+       ;;
c260e0
+  *)   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
c260e0
+$as_echo "yes" >&6; }
c260e0
+       want_unix_sockets=yes
c260e0
+       ;;
c260e0
+  esac
c260e0
+else
c260e0
+
c260e0
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: auto" >&5
c260e0
+$as_echo "auto" >&6; }
c260e0
+       want_unix_sockets=auto
c260e0
+
c260e0
+
c260e0
+fi
c260e0
+
c260e0
+if test "x$want_unix_sockets" != "xno"; then
c260e0
+  ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_path" "ac_cv_member_struct_sockaddr_un_sun_path" "
c260e0
+    #include <sys/un.h>
c260e0
+
c260e0
+"
c260e0
+if test "x$ac_cv_member_struct_sockaddr_un_sun_path" = xyes; then :
c260e0
+
c260e0
+
c260e0
+$as_echo "#define USE_UNIX_SOCKETS 1" >>confdefs.h
c260e0
+
c260e0
+    USE_UNIX_SOCKETS=1
c260e0
+
c260e0
+    curl_unix_sockets_msg="enabled"
c260e0
+
c260e0
+else
c260e0
+
c260e0
+    if test "x$want_unix_sockets" = "xyes"; then
c260e0
+      as_fn_error $? "--enable-unix-sockets is not available on this platform!" "$LINENO" 5
c260e0
+    fi
c260e0
+
c260e0
+fi
c260e0
+
c260e0
+fi
c260e0
+
c260e0
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable support for cookies" >&5
c260e0
 $as_echo_n "checking whether to enable support for cookies... " >&6; }
c260e0
 # Check whether --enable-cookies was given.
c260e0
@@ -39357,6 +39464,9 @@ fi
c260e0
 if test "x$IPV6_ENABLED" = "x1"; then
c260e0
   SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6"
c260e0
 fi
c260e0
+if test "x$USE_UNIX_SOCKETS" = "x1"; then
c260e0
+  SUPPORT_FEATURES="$SUPPORT_FEATURES unix-sockets"
c260e0
+fi
c260e0
 if test "x$HAVE_LIBZ" = "x1"; then
c260e0
   SUPPORT_FEATURES="$SUPPORT_FEATURES libz"
c260e0
 fi
c260e0
@@ -42289,6 +42399,7 @@ _EOF
c260e0
   TLS-SRP support:  ${curl_tls_srp_msg}
c260e0
   resolver:         ${curl_res_msg}
c260e0
   ipv6 support:     ${curl_ipv6_msg}
c260e0
+  UNIX sockets support: ${curl_unix_sockets_msg}
c260e0
   IDN support:      ${curl_idn_msg}
c260e0
   Build libcurl:    Shared=${enable_shared}, Static=${enable_static}
c260e0
   Built-in manual:  ${curl_manual_msg}
c260e0
@@ -42319,6 +42430,7 @@ $as_echo "$as_me: Configured to build curl/libcurl:
c260e0
   TLS-SRP support:  ${curl_tls_srp_msg}
c260e0
   resolver:         ${curl_res_msg}
c260e0
   ipv6 support:     ${curl_ipv6_msg}
c260e0
+  UNIX sockets support: ${curl_unix_sockets_msg}
c260e0
   IDN support:      ${curl_idn_msg}
c260e0
   Build libcurl:    Shared=${enable_shared}, Static=${enable_static}
c260e0
   Built-in manual:  ${curl_manual_msg}
c260e0
diff --git a/configure.ac b/configure.ac
c260e0
index 60a6b58..9612c2f 100644
c260e0
--- a/configure.ac
c260e0
+++ b/configure.ac
c260e0
@@ -156,6 +156,7 @@ dnl initialize all the info variables
c260e0
 curl_tls_srp_msg="no      (--enable-tls-srp)"
c260e0
     curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
c260e0
    curl_ipv6_msg="no      (--enable-ipv6)"
c260e0
+curl_unix_sockets_msg="no      (--enable-unix-sockets)"
c260e0
     curl_idn_msg="no      (--with-{libidn,winidn})"
c260e0
  curl_manual_msg="no      (--enable-manual)"
c260e0
 curl_libcurl_msg="enabled (--disable-libcurl-option)"
c260e0
@@ -3302,6 +3303,39 @@ if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$
c260e0
 fi
c260e0
 
c260e0
 dnl ************************************************************
c260e0
+dnl disable UNIX domain sockets support
c260e0
+dnl
c260e0
+AC_MSG_CHECKING([whether to enable UNIX domain sockets])
c260e0
+AC_ARG_ENABLE(unix-sockets,
c260e0
+AC_HELP_STRING([--enable-unix-sockets],[Enable UNIX domain sockets])
c260e0
+AC_HELP_STRING([--disable-unix-sockets],[Disable UNIX domain sockets]),
c260e0
+[ case "$enableval" in
c260e0
+  no)  AC_MSG_RESULT(no)
c260e0
+       want_unix_sockets=no
c260e0
+       ;;
c260e0
+  *)   AC_MSG_RESULT(yes)
c260e0
+       want_unix_sockets=yes
c260e0
+       ;;
c260e0
+  esac ], [
c260e0
+       AC_MSG_RESULT(auto)
c260e0
+       want_unix_sockets=auto
c260e0
+       ]
c260e0
+)
c260e0
+if test "x$want_unix_sockets" != "xno"; then
c260e0
+  AC_CHECK_MEMBER([struct sockaddr_un.sun_path], [
c260e0
+    AC_DEFINE(USE_UNIX_SOCKETS, 1, [Use UNIX domain sockets])
c260e0
+    AC_SUBST(USE_UNIX_SOCKETS, [1])
c260e0
+    curl_unix_sockets_msg="enabled"
c260e0
+  ], [
c260e0
+    if test "x$want_unix_sockets" = "xyes"; then
c260e0
+      AC_MSG_ERROR([--enable-unix-sockets is not available on this platform!])
c260e0
+    fi
c260e0
+  ], [
c260e0
+    #include <sys/un.h>
c260e0
+  ])
c260e0
+fi
c260e0
+
c260e0
+dnl ************************************************************
c260e0
 dnl disable cookies support
c260e0
 dnl
c260e0
 AC_MSG_CHECKING([whether to enable support for cookies])
c260e0
@@ -3382,6 +3416,9 @@ fi
c260e0
 if test "x$IPV6_ENABLED" = "x1"; then
c260e0
   SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6"
c260e0
 fi
c260e0
+if test "x$USE_UNIX_SOCKETS" = "x1"; then
c260e0
+  SUPPORT_FEATURES="$SUPPORT_FEATURES unix-sockets"
c260e0
+fi
c260e0
 if test "x$HAVE_LIBZ" = "x1"; then
c260e0
   SUPPORT_FEATURES="$SUPPORT_FEATURES libz"
c260e0
 fi
c260e0
@@ -3557,6 +3594,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
c260e0
   TLS-SRP support:  ${curl_tls_srp_msg}
c260e0
   resolver:         ${curl_res_msg}
c260e0
   ipv6 support:     ${curl_ipv6_msg}
c260e0
+  UNIX sockets support: ${curl_unix_sockets_msg}
c260e0
   IDN support:      ${curl_idn_msg}
c260e0
   Build libcurl:    Shared=${enable_shared}, Static=${enable_static}
c260e0
   Built-in manual:  ${curl_manual_msg}
c260e0
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
c260e0
index d73b664..ad739e1 100644
c260e0
--- a/docs/libcurl/curl_easy_setopt.3
c260e0
+++ b/docs/libcurl/curl_easy_setopt.3
c260e0
@@ -961,6 +961,18 @@ systems support this option. (Added in 7.25.0)
c260e0
 Pass a long. Sets the interval, in seconds, that the operating system will wait
c260e0
 between sending keepalive probes. Not all operating systems support this
c260e0
 option. (Added in 7.25.0)
c260e0
+.IP CURLOPT_UNIX_SOCKET_PATH
c260e0
+Pass a \fIpath\fP to a UNIX domain socket. This enables the use of UNIX domain
c260e0
+sockets as connection end point and sets the path to \fIpath\fP. If \fIpath\fP
c260e0
+is NULL, then UNIX domain sockets are disabled. An empty string will result in
c260e0
+an error at some point.
c260e0
+
c260e0
+When enabled, cURL will connect to the UNIX domain socket instead of
c260e0
+establishing a TCP connection to a host. Since no TCP connection is
c260e0
+established, cURL does not need to resolve the DNS hostname in the URL.
c260e0
+
c260e0
+The maximum path length on Cygwin, Linux and Solaris is 107. On other platforms
c260e0
+might be even less.
c260e0
 .SH NAMES and PASSWORDS OPTIONS (Authentication)
c260e0
 .IP CURLOPT_NETRC
c260e0
 This parameter controls the preference of libcurl between using user names and
c260e0
diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3
c260e0
index ccb2028..c148cbc 100644
c260e0
--- a/docs/libcurl/curl_version_info.3
c260e0
+++ b/docs/libcurl/curl_version_info.3
c260e0
@@ -133,6 +133,8 @@ libcurl was built with support for TLS-SRP. (Added in 7.21.4)
c260e0
 .IP CURL_VERSION_NTLM_WB
c260e0
 libcurl was built with support for NTLM delegation to a winbind helper.
c260e0
 (Added in 7.22.0)
c260e0
+.IP CURL_VERSION_UNIX_SOCKETS
c260e0
+libcurl was built with support for UNIX domain sockets.
c260e0
 .RE
c260e0
 \fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl
c260e0
 has no SSL support, this is NULL.
c260e0
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
c260e0
index b275900..0f7469d 100644
c260e0
--- a/docs/libcurl/symbols-in-versions
c260e0
+++ b/docs/libcurl/symbols-in-versions
c260e0
@@ -503,6 +503,7 @@ CURLOPT_TLSAUTH_TYPE            7.21.4
c260e0
 CURLOPT_TLSAUTH_USERNAME        7.21.4
c260e0
 CURLOPT_TRANSFERTEXT            7.1.1
c260e0
 CURLOPT_TRANSFER_ENCODING       7.21.6
c260e0
+CURLOPT_UNIX_SOCKET_PATH        7.40.0
c260e0
 CURLOPT_UNRESTRICTED_AUTH       7.10.4
c260e0
 CURLOPT_UPLOAD                  7.1
c260e0
 CURLOPT_URL                     7.1
c260e0
@@ -703,6 +704,7 @@ CURL_VERSION_SPNEGO             7.10.8
c260e0
 CURL_VERSION_SSL                7.10
c260e0
 CURL_VERSION_SSPI               7.13.2
c260e0
 CURL_VERSION_TLSAUTH_SRP        7.21.4
c260e0
+CURL_VERSION_UNIX_SOCKETS       7.40.0
c260e0
 CURL_WAIT_POLLIN                7.28.0
c260e0
 CURL_WAIT_POLLOUT               7.28.0
c260e0
 CURL_WAIT_POLLPRI               7.28.0
c260e0
diff --git a/include/curl/curl.h b/include/curl/curl.h
c260e0
index 8e548e3..14f6fd7 100644
c260e0
--- a/include/curl/curl.h
c260e0
+++ b/include/curl/curl.h
c260e0
@@ -1536,6 +1536,9 @@ typedef enum {
c260e0
   /* set the SMTP auth originator */
c260e0
   CINIT(MAIL_AUTH, OBJECTPOINT, 217),
c260e0
 
c260e0
+  /* Path to UNIX domain socket */
c260e0
+  CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
c260e0
+
c260e0
   CURLOPT_LASTENTRY /* the last unused */
c260e0
 } CURLoption;
c260e0
 
c260e0
@@ -2154,6 +2157,7 @@ typedef struct {
c260e0
 #define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
c260e0
 #define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
c260e0
 #define CURL_VERSION_NTLM_WB   (1<<15) /* NTLM delegating to winbind helper */
c260e0
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* UNIX domain sockets support */
c260e0
 
c260e0
  /*
c260e0
  * NAME curl_version_info()
c260e0
diff --git a/lib/Makefile.in b/lib/Makefile.in
c260e0
index ca02e27..5ad2600 100644
c260e0
--- a/lib/Makefile.in
c260e0
+++ b/lib/Makefile.in
c260e0
@@ -386,6 +386,7 @@ USE_OPENLDAP = @USE_OPENLDAP@
c260e0
 USE_POLARSSL = @USE_POLARSSL@
c260e0
 USE_SCHANNEL = @USE_SCHANNEL@
c260e0
 USE_SSLEAY = @USE_SSLEAY@
c260e0
+USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
c260e0
 USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
c260e0
 VERSION = @VERSION@
c260e0
 VERSIONED_FLAVOUR = @VERSIONED_FLAVOUR@
c260e0
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
c260e0
index 10652c6..52e45ce 100644
c260e0
--- a/lib/curl_addrinfo.c
c260e0
+++ b/lib/curl_addrinfo.c
c260e0
@@ -33,6 +33,9 @@
c260e0
 #ifdef HAVE_ARPA_INET_H
c260e0
 #  include <arpa/inet.h>
c260e0
 #endif
c260e0
+#ifdef HAVE_SYS_UN_H
c260e0
+#  include <sys/un.h>
c260e0
+#endif
c260e0
 
c260e0
 #ifdef __VMS
c260e0
 #  include <in.h>
c260e0
@@ -477,6 +480,42 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
c260e0
   return NULL; /* bad input format */
c260e0
 }
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+/**
c260e0
+ * Given a path to a UNIX domain socket, return a newly allocated Curl_addrinfo
c260e0
+ * struct initialized with this path.
c260e0
+ */
c260e0
+Curl_addrinfo *Curl_unix2addr(const char *path)
c260e0
+{
c260e0
+  Curl_addrinfo *ai;
c260e0
+  struct sockaddr_un *sun;
c260e0
+  size_t path_len;
c260e0
+
c260e0
+  ai = calloc(1, sizeof(Curl_addrinfo));
c260e0
+  if(!ai)
c260e0
+    return NULL;
c260e0
+  if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
c260e0
+    free(ai);
c260e0
+    return NULL;
c260e0
+  }
c260e0
+  /* sun_path must be able to store the NUL-terminated path */
c260e0
+  path_len = strlen(path);
c260e0
+  if(path_len >= sizeof(sun->sun_path)) {
c260e0
+    free(ai->ai_addr);
c260e0
+    free(ai);
c260e0
+    return NULL;
c260e0
+  }
c260e0
+
c260e0
+  ai->ai_family = AF_UNIX;
c260e0
+  ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
c260e0
+  ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
c260e0
+  sun = (void *) ai->ai_addr;
c260e0
+  sun->sun_family = AF_UNIX;
c260e0
+  memcpy(sun->sun_path, path, path_len + 1); /* copy NUL byte */
c260e0
+  return ai;
c260e0
+}
c260e0
+#endif
c260e0
+
c260e0
 #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
c260e0
 /*
c260e0
  * curl_dofreeaddrinfo()
c260e0
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
c260e0
index 6d2b753..4ef8827 100644
c260e0
--- a/lib/curl_addrinfo.h
c260e0
+++ b/lib/curl_addrinfo.h
c260e0
@@ -79,6 +79,10 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
c260e0
 
c260e0
 Curl_addrinfo *Curl_str2addr(char *dotted, int port);
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+Curl_addrinfo *Curl_unix2addr(const char *path);
c260e0
+#endif
c260e0
+
c260e0
 #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
c260e0
 void
c260e0
 curl_dofreeaddrinfo(struct addrinfo *freethis,
c260e0
diff --git a/lib/curl_config.h.in b/lib/curl_config.h.in
c260e0
index 1716c96..19b66fa 100644
c260e0
--- a/lib/curl_config.h.in
c260e0
+++ b/lib/curl_config.h.in
c260e0
@@ -1017,6 +1017,9 @@
c260e0
 /* Use TLS-SRP authentication */
c260e0
 #undef USE_TLS_SRP
c260e0
 
c260e0
+/* Use UNIX domain sockets */
c260e0
+#undef USE_UNIX_SOCKETS
c260e0
+
c260e0
 /* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */
c260e0
 #undef USE_WIN32_IDN
c260e0
 
c260e0
diff --git a/lib/url.c b/lib/url.c
c260e0
index 57944e4..7257b5e 100644
c260e0
--- a/lib/url.c
c260e0
+++ b/lib/url.c
c260e0
@@ -47,6 +47,10 @@
c260e0
 #include <inet.h>
c260e0
 #endif
c260e0
 
c260e0
+#ifdef HAVE_SYS_UN_H
c260e0
+#include <sys/un.h>
c260e0
+#endif
c260e0
+
c260e0
 #ifndef HAVE_SOCKET
c260e0
 #error "We can't compile without socket() support!"
c260e0
 #endif
c260e0
@@ -2429,6 +2433,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
c260e0
     data->set.tcp_keepintvl = va_arg(param, long);
c260e0
     break;
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  case CURLOPT_UNIX_SOCKET_PATH:
c260e0
+    result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
c260e0
+                       va_arg(param, char *));
c260e0
+    break;
c260e0
+#endif
c260e0
+
c260e0
   default:
c260e0
     /* unknown tag and its companion, just ignore: */
c260e0
     result = CURLE_UNKNOWN_OPTION;
c260e0
@@ -4764,6 +4775,32 @@ static CURLcode resolve_server(struct SessionHandle *data,
c260e0
     /* set a pointer to the hostname we display */
c260e0
     fix_hostname(data, conn, &conn->host);
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+    if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
c260e0
+      /* UNIX domain sockets are local. The host gets ignored, just use the
c260e0
+       * specified domain socket address. Do not cache "DNS entries". There is
c260e0
+       * no DNS involved and we already have the filesystem path available */
c260e0
+      const char *path = data->set.str[STRING_UNIX_SOCKET_PATH];
c260e0
+
c260e0
+      hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
c260e0
+      if(!hostaddr)
c260e0
+        result = CURLE_OUT_OF_MEMORY;
c260e0
+      else if((hostaddr->addr = Curl_unix2addr(path)) != NULL)
c260e0
+        hostaddr->inuse++;
c260e0
+      else {
c260e0
+        /* Long paths are not supported for now */
c260e0
+        if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
c260e0
+          failf(data, "UNIX socket path too long: '%s'", path);
c260e0
+          result = CURLE_COULDNT_RESOLVE_HOST;
c260e0
+        }
c260e0
+        else
c260e0
+          result = CURLE_OUT_OF_MEMORY;
c260e0
+        free(hostaddr);
c260e0
+        hostaddr = NULL;
c260e0
+      }
c260e0
+    }
c260e0
+    else
c260e0
+#endif
c260e0
     if(!conn->proxy.name || !*conn->proxy.name) {
c260e0
       /* If not connecting via a proxy, extract the port from the URL, if it is
c260e0
        * there, thus overriding any defaults that might have been set above. */
c260e0
@@ -5071,6 +5108,13 @@ static CURLcode create_conn(struct SessionHandle *data,
c260e0
   else if(!proxy)
c260e0
     proxy = detect_proxy(conn);
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) {
c260e0
+    free(proxy);  /* UNIX domain sockets cannot be proxied, so disable it */
c260e0
+    proxy = NULL;
c260e0
+  }
c260e0
+#endif
c260e0
+
c260e0
   if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
c260e0
     free(proxy);  /* Don't bother with an empty proxy string or if the
c260e0
                      protocol doesn't work with network */
c260e0
diff --git a/lib/urldata.h b/lib/urldata.h
c260e0
index b3ee7e3..723e40d 100644
c260e0
--- a/lib/urldata.h
c260e0
+++ b/lib/urldata.h
c260e0
@@ -1375,6 +1375,10 @@ enum dupstring {
c260e0
   STRING_TLSAUTH_PASSWORD,     /* TLS auth <password> */
c260e0
 #endif
c260e0
 
c260e0
+#ifdef USE_UNIX_SOCKETS
c260e0
+  STRING_UNIX_SOCKET_PATH,  /* path to UNIX socket, if used */
c260e0
+#endif
c260e0
+
c260e0
   /* -- end of zero-terminated strings -- */
c260e0
 
c260e0
   STRING_LASTZEROTERMINATED,
c260e0
diff --git a/lib/version.c b/lib/version.c
c260e0
index d39fe0c..e798738 100644
c260e0
--- a/lib/version.c
c260e0
+++ b/lib/version.c
c260e0
@@ -278,6 +278,9 @@ static curl_version_info_data version_info = {
c260e0
 #if defined(USE_TLS_SRP)
c260e0
   | CURL_VERSION_TLSAUTH_SRP
c260e0
 #endif
c260e0
+#if defined(USE_UNIX_SOCKETS)
c260e0
+  | CURL_VERSION_UNIX_SOCKETS
c260e0
+#endif
c260e0
   ,
c260e0
   NULL, /* ssl_version */
c260e0
   0,    /* ssl_version_num, this is kept at zero */
c260e0
diff --git a/src/Makefile.in b/src/Makefile.in
c260e0
index 5f739a9..948092f 100644
c260e0
--- a/src/Makefile.in
c260e0
+++ b/src/Makefile.in
c260e0
@@ -272,6 +272,7 @@ USE_OPENLDAP = @USE_OPENLDAP@
c260e0
 USE_POLARSSL = @USE_POLARSSL@
c260e0
 USE_SCHANNEL = @USE_SCHANNEL@
c260e0
 USE_SSLEAY = @USE_SSLEAY@
c260e0
+USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
c260e0
 USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
c260e0
 VERSION = @VERSION@
c260e0
 VERSIONED_FLAVOUR = @VERSIONED_FLAVOUR@
c260e0
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
c260e0
index 98d53a7..0cd84d5 100644
c260e0
--- a/src/tool_getparam.c
c260e0
+++ b/src/tool_getparam.c
c260e0
@@ -285,7 +285,8 @@ static const struct feat feats[] = {
c260e0
   {"krb4",           CURL_VERSION_KERBEROS4},
c260e0
   {"libz",           CURL_VERSION_LIBZ},
c260e0
   {"CharConv",       CURL_VERSION_CONV},
c260e0
-  {"TLS-SRP",        CURL_VERSION_TLSAUTH_SRP}
c260e0
+  {"TLS-SRP",        CURL_VERSION_TLSAUTH_SRP},
c260e0
+  {"unix-sockets",   CURL_VERSION_UNIX_SOCKETS}
c260e0
 };
c260e0
 
c260e0
 ParameterError getparameter(char *flag,    /* f or -long-flag */
c260e0
diff --git a/tests/server/Makefile.in b/tests/server/Makefile.in
c260e0
index 0ca4380..055fe9b 100644
c260e0
--- a/tests/server/Makefile.in
c260e0
+++ b/tests/server/Makefile.in
c260e0
@@ -329,6 +329,7 @@ USE_OPENLDAP = @USE_OPENLDAP@
c260e0
 USE_POLARSSL = @USE_POLARSSL@
c260e0
 USE_SCHANNEL = @USE_SCHANNEL@
c260e0
 USE_SSLEAY = @USE_SSLEAY@
c260e0
+USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
c260e0
 USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
c260e0
 VERSION = @VERSION@
c260e0
 VERSIONED_FLAVOUR = @VERSIONED_FLAVOUR@
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From 877e40cd741b5b65f503236a6947e38c28a2d6ce Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 27 Nov 2014 23:59:26 +0100
c260e0
Subject: [PATCH 08/11] tool: add --unix-socket option
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: c8644d1f638fdd8f4bf34fe64e910ba704fb26c0
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 src/tool_cfgable.c  | 1 +
c260e0
 src/tool_cfgable.h  | 2 ++
c260e0
 src/tool_getparam.c | 6 +++++-
c260e0
 src/tool_help.c     | 1 +
c260e0
 src/tool_operate.c  | 4 ++++
c260e0
 5 files changed, 13 insertions(+), 1 deletion(-)
c260e0
c260e0
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
c260e0
index da11f4a..2479b73 100644
c260e0
--- a/src/tool_cfgable.c
c260e0
+++ b/src/tool_cfgable.c
c260e0
@@ -98,6 +98,7 @@ void free_config_fields(struct Configurable *config)
c260e0
 
c260e0
   config->trace_stream = NULL; /* closed elsewhere when appropriate */
c260e0
 
c260e0
+  Curl_safefree(config->unix_socket_path);
c260e0
   Curl_safefree(config->writeout);
c260e0
 
c260e0
   config->errors = NULL; /* closed elsewhere when appropriate */
c260e0
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
c260e0
index 1f6f948..a9b033b 100644
c260e0
--- a/src/tool_cfgable.h
c260e0
+++ b/src/tool_cfgable.h
c260e0
@@ -204,6 +204,8 @@ struct Configurable {
c260e0
   bool use_metalink;        /* process given URLs as metalink XML file */
c260e0
   metalinkfile *metalinkfile_list; /* point to the first node */
c260e0
   metalinkfile *metalinkfile_last; /* point to the last/current node */
c260e0
+
c260e0
+  char *unix_socket_path;   /* path to UNIX domain socket */
c260e0
 }; /* struct Configurable */
c260e0
 
c260e0
 void free_config_fields(struct Configurable *config);
c260e0
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
c260e0
index 0cd84d5..57cf97d 100644
c260e0
--- a/src/tool_getparam.c
c260e0
+++ b/src/tool_getparam.c
c260e0
@@ -144,7 +144,7 @@ static const struct LongShort aliases[]= {
c260e0
   {"$v", "ssl-reqd",                 FALSE},
c260e0
          /* 'ssl-reqd' new in 7.20.0, previously this was ftp-ssl-reqd */
c260e0
   {"$w", "sessionid",                FALSE},
c260e0
-         /* ¡sessionid' listed as --no-sessionid in the help */
c260e0
+         /* ?sessionid' listed as --no-sessionid in the help */
c260e0
   {"$x", "ftp-ssl-control",          FALSE},
c260e0
   {"$y", "ftp-ssl-ccc",              FALSE},
c260e0
   {"$j", "ftp-ssl-ccc-mode",         TRUE},
c260e0
@@ -173,6 +173,7 @@ static const struct LongShort aliases[]= {
c260e0
   {"$H", "mail-auth",                TRUE},
c260e0
   {"$I", "post303",                  FALSE},
c260e0
   {"$J", "metalink",                 FALSE},
c260e0
+  {"$M", "unix-socket",              TRUE},
c260e0
   {"0",  "http1.0",                  FALSE},
c260e0
   {"1",  "tlsv1",                    FALSE},
c260e0
   {"10",  "tlsv1.0",                 FALSE},
c260e0
@@ -862,6 +863,9 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
c260e0
 #endif
c260e0
           break;
c260e0
         }
c260e0
+      case 'M': /* --unix-socket */
c260e0
+        GetStr(&config->unix_socket_path, nextarg);
c260e0
+        break;
c260e0
       }
c260e0
       break;
c260e0
     case '#': /* --progress-bar */
c260e0
diff --git a/src/tool_help.c b/src/tool_help.c
c260e0
index f7cd618..3a64e35 100644
c260e0
--- a/src/tool_help.c
c260e0
+++ b/src/tool_help.c
c260e0
@@ -214,6 +214,7 @@ static const char *const helptext[] = {
c260e0
   "     --tlsuser USER  TLS username",
c260e0
   "     --tlspassword STRING TLS password",
c260e0
   "     --tlsauthtype STRING  TLS authentication type (default SRP)",
c260e0
+  "     --unix-socket FILE    Connect through this UNIX domain socket",
c260e0
   " -A, --user-agent STRING  User-Agent to send to server (H)",
c260e0
   " -v, --verbose       Make the operation more talkative",
c260e0
   " -V, --version       Show version number and quit",
c260e0
diff --git a/src/tool_operate.c b/src/tool_operate.c
c260e0
index 4166fc2..7a13fcf 100644
c260e0
--- a/src/tool_operate.c
c260e0
+++ b/src/tool_operate.c
c260e0
@@ -1320,6 +1320,10 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
c260e0
         if(config->mail_auth)
c260e0
           my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth);
c260e0
 
c260e0
+        /* new in 7.40.0 */
c260e0
+        if(config->unix_socket_path)
c260e0
+          my_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path);
c260e0
+
c260e0
         /* initialize retry vars for loop below */
c260e0
         retry_sleep_default = (config->retry_delay) ?
c260e0
           config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From 60bdcf03a1696b3d09ad1c04824816766c513dcd Mon Sep 17 00:00:00 2001
c260e0
From: Daniel Stenberg <daniel@haxx.se>
c260e0
Date: Wed, 3 Dec 2014 02:35:12 +0100
c260e0
Subject: [PATCH 09/11] curl.1: added --unix-socket
c260e0
c260e0
Upstream-commit: 7853c1cfe6fc7828afbb812791a383781aca3be3
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 docs/curl.1 | 3 +++
c260e0
 1 file changed, 3 insertions(+)
c260e0
c260e0
diff --git a/docs/curl.1 b/docs/curl.1
c260e0
index 7f3571b..38fa084 100644
c260e0
--- a/docs/curl.1
c260e0
+++ b/docs/curl.1
c260e0
@@ -1471,6 +1471,9 @@ If this option is used several times, the last one will be used.
c260e0
 .IP "--trace-time"
c260e0
 Prepends a time stamp to each trace or verbose line that curl displays.
c260e0
 (Added in 7.14.0)
c260e0
+.IP "--unix-socket <path>"
c260e0
+(HTTP) Connect through this UNIX domain socket, instead of using the
c260e0
+network. (Added in 7.40.0)
c260e0
 .IP "-u, --user <user:password>"
c260e0
 Specify the user name and password to use for server authentication. Overrides
c260e0
 \fI-n, --netrc\fP and \fI--netrc-optional\fP.
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From af6fa1e00657c637d52cc24eab6d769b8eb793a9 Mon Sep 17 00:00:00 2001
c260e0
From: Daniel Stenberg <daniel@haxx.se>
c260e0
Date: Thu, 4 Dec 2014 02:46:15 +0100
c260e0
Subject: [PATCH 10/11] updateconninfo: clear destination struct before
c260e0
 getsockname()
c260e0
c260e0
Otherwise we may read uninitialized bytes later in the unix-domain
c260e0
sockets case.
c260e0
c260e0
Upstream-commit: 9730c9fb7075792a112b65a023379fad3ec8dda4
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 lib/connect.c | 1 +
c260e0
 1 file changed, 1 insertion(+)
c260e0
c260e0
diff --git a/lib/connect.c b/lib/connect.c
c260e0
index ba9ab92..5aa53fe 100644
c260e0
--- a/lib/connect.c
c260e0
+++ b/lib/connect.c
c260e0
@@ -630,6 +630,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
c260e0
     }
c260e0
 
c260e0
     len = sizeof(struct Curl_sockaddr_storage);
c260e0
+    memset(&ssloc, 0, sizeof(ssloc));
c260e0
     if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
c260e0
       error = SOCKERRNO;
c260e0
       failf(data, "getsockname() failed with errno %d: %s",
c260e0
-- 
c260e0
2.5.2
c260e0
c260e0
c260e0
From 8d951bb327fb6a1e107e044dbc179096883c4489 Mon Sep 17 00:00:00 2001
c260e0
From: Peter Wu <peter@lekensteyn.nl>
c260e0
Date: Thu, 4 Dec 2014 11:01:41 -0800
c260e0
Subject: [PATCH 11/11] tool: fix CURLOPT_UNIX_SOCKET_PATH in --libcurl output
c260e0
c260e0
Mark CURLOPT_UNIX_SOCKET_PATH as string to ensure that it ends up as
c260e0
option in the file generated by --libcurl.
c260e0
c260e0
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
c260e0
c260e0
Upstream-commit: 2e557de09431854e4ad137cd741a582caa917517
c260e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
c260e0
---
c260e0
 src/tool_operate.c | 3 ++-
c260e0
 1 file changed, 2 insertions(+), 1 deletion(-)
c260e0
c260e0
diff --git a/src/tool_operate.c b/src/tool_operate.c
c260e0
index 7a13fcf..41b0e6b 100644
c260e0
--- a/src/tool_operate.c
c260e0
+++ b/src/tool_operate.c
c260e0
@@ -1322,7 +1322,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
c260e0
 
c260e0
         /* new in 7.40.0 */
c260e0
         if(config->unix_socket_path)
c260e0
-          my_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path);
c260e0
+          my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH,
c260e0
+                        config->unix_socket_path);
c260e0
 
c260e0
         /* initialize retry vars for loop below */
c260e0
         retry_sleep_default = (config->retry_delay) ?
c260e0
-- 
c260e0
2.5.2
c260e0