summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/cmdline-opts/Makefile.am3
-rw-r--r--docs/cmdline-opts/abstract-unix-socket.d9
-rw-r--r--docs/curl.14
-rw-r--r--docs/libcurl/curl_easy_setopt.32
-rw-r--r--docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.358
-rw-r--r--docs/libcurl/opts/Makefile.am3
-rw-r--r--docs/libcurl/symbols-in-versions1
-rw-r--r--include/curl/curl.h3
-rw-r--r--include/curl/typecheck-gcc.h3
-rw-r--r--lib/curl_addrinfo.c27
-rw-r--r--lib/curl_addrinfo.h2
-rw-r--r--lib/url.c14
-rw-r--r--lib/urldata.h3
-rw-r--r--src/tool_cfgable.h1
-rw-r--r--src/tool_getparam.c6
-rw-r--r--src/tool_help.c3
-rw-r--r--src/tool_operate.c16
17 files changed, 139 insertions, 19 deletions
diff --git a/docs/cmdline-opts/Makefile.am b/docs/cmdline-opts/Makefile.am
index 925f07fc1..4a10b9e5c 100644
--- a/docs/cmdline-opts/Makefile.am
+++ b/docs/cmdline-opts/Makefile.am
@@ -22,7 +22,8 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
-DPAGES = anyauth.d append.d basic.d cacert.d capath.d cert.d \
+DPAGES = abstract-unix-socket.d anyauth.d \
+ append.d basic.d cacert.d capath.d cert.d \
cert-status.d cert-type.d ciphers.d compressed.d config.d \
connect-timeout.d connect-to.d continue-at.d cookie.d cookie-jar.d \
create-dirs.d crlf.d crlfile.d data-ascii.d data-binary.d data.d \
diff --git a/docs/cmdline-opts/abstract-unix-socket.d b/docs/cmdline-opts/abstract-unix-socket.d
new file mode 100644
index 000000000..bb4467b67
--- /dev/null
+++ b/docs/cmdline-opts/abstract-unix-socket.d
@@ -0,0 +1,9 @@
+Long: abstract-unix-socket
+Arg: <path>
+Help: Connect through an abstract Unix domain socket
+Added: 7.53.0
+Protocols: HTTP
+---
+Connect through an abstract Unix domain socket, instead of using the network.
+Note: netstat shows the path of an abstract socket prefixed with '@', however
+the <path> argument should not have this leading character.
diff --git a/docs/curl.1 b/docs/curl.1
index ce54fb2f1..b930b246f 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -139,6 +139,10 @@ but prefix it with "no-". However, in this list we mostly only list and show
the --option version of them. (This concept with --no options was added in
7.19.0. Previously most options were toggled on/off on repeated use of the
same command line option.)
+.IP "--abstract-unix-socket <path>"
+(HTTP) Connect through an abstract Unix domain socket, instead of using the network.
+
+Added in 7.53.0.
.IP "--anyauth"
(HTTP) Tells curl to figure out authentication method by itself, and use the most
secure one the remote site claims to support. This is done by first doing a
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index a130a8a08..66f573464 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -207,6 +207,8 @@ Idle time before sending keep-alive. See \fICURLOPT_TCP_KEEPIDLE(3)\fP
Interval between keep-alive probes. See \fICURLOPT_TCP_KEEPINTVL(3)\fP
.IP CURLOPT_UNIX_SOCKET_PATH
Path to a Unix domain socket. See \fICURLOPT_UNIX_SOCKET_PATH(3)\fP
+.IP CURLOPT_ABSTRACT_UNIX_SOCKET
+Path to an abstract Unix domain socket. See \fICURLOPT_ABSTRACT_UNIX_SOCKET(3)\fP
.SH NAMES and PASSWORDS OPTIONS (Authentication)
.IP CURLOPT_NETRC
Enable .netrc parsing. See \fICURLOPT_NETRC(3)\fP
diff --git a/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3 b/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3
new file mode 100644
index 000000000..8b61854c0
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_ABSTRACT_UNIX_SOCKET.3
@@ -0,0 +1,58 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_ABSTRACT_UNIX_SOCKET 3 "08 Jan 2017" "libcurl 7.53.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_ABSTRACT_UNIX_SOCKET \- set an abstract Unix domain socket
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ABSTRACT_UNIX_SOCKET, char *path);
+.SH DESCRIPTION
+Enables the use of an abstract Unix domain socket instead of establishing a TCP
+connection to a host. The parameter should be a char * to a zero terminated string
+holding the path of the socket. The path will be set to \fIpath\fP prefixed by a
+NULL byte (this is the convention for abstract sockets, however it should be stressed
+that the path passed to this function should not contain a leading NULL).
+
+On non-supporting platforms, the abstract address will be interpreted as an empty
+string and fail gracefully, generating a run-time error.
+
+This option shares the same semantics as
+.BR CURLOPT_UNIX_SOCKET_PATH "(3)
+in which documentation more details can be found. Internally, these two options share
+the same storage and therefore only one of them can be set per handle.
+
+.SH DEFAULT
+Default is NULL.
+.SH EXAMPLE
+.nf
+ curl_easy_setopt(curl_handle, CURLOPT_ABSTRACT_UNIX_SOCKET, "/tmp/foo.sock");
+ curl_easy_setopt(curl_handle, CURLOPT_URL, "http://localhost/");
+.fi
+
+.SH AVAILABILITY
+Since 7.53.0.
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_UNIX_SOCKET_PATH "(3), " unix "(7), "
diff --git a/docs/libcurl/opts/Makefile.am b/docs/libcurl/opts/Makefile.am
index eb7ca1bb5..80f28ca9b 100644
--- a/docs/libcurl/opts/Makefile.am
+++ b/docs/libcurl/opts/Makefile.am
@@ -87,6 +87,7 @@ man_MANS = \
CURLMOPT_SOCKETFUNCTION.3 \
CURLMOPT_TIMERDATA.3 \
CURLMOPT_TIMERFUNCTION.3 \
+ CURLOPT_ABSTRACT_UNIX_SOCKET.3 \
CURLOPT_ACCEPTTIMEOUT_MS.3 \
CURLOPT_ACCEPT_ENCODING.3 \
CURLOPT_ADDRESS_SCOPE.3 \
@@ -397,6 +398,7 @@ HTMLPAGES = \
CURLMOPT_SOCKETFUNCTION.html \
CURLMOPT_TIMERDATA.html \
CURLMOPT_TIMERFUNCTION.html \
+ CURLOPT_ABSTRACT_UNIX_SOCKET.html \
CURLOPT_ACCEPTTIMEOUT_MS.html \
CURLOPT_ACCEPT_ENCODING.html \
CURLOPT_ADDRESS_SCOPE.html \
@@ -707,6 +709,7 @@ PDFPAGES = \
CURLMOPT_SOCKETFUNCTION.pdf \
CURLMOPT_TIMERDATA.pdf \
CURLMOPT_TIMERFUNCTION.pdf \
+ CURLOPT_ABSTRACT_UNIX_SOCKET.pdf \
CURLOPT_ACCEPTTIMEOUT_MS.pdf \
CURLOPT_ACCEPT_ENCODING.pdf \
CURLOPT_ADDRESS_SCOPE.pdf \
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index bd5960c2f..89672c5e9 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -317,6 +317,7 @@ CURLOPTTYPE_LONG 7.1
CURLOPTTYPE_OBJECTPOINT 7.1
CURLOPTTYPE_OFF_T 7.11.0
CURLOPTTYPE_STRINGPOINT 7.46.0
+CURLOPT_ABSTRACT_UNIX_SOCKET 7.53.0
CURLOPT_ACCEPTTIMEOUT_MS 7.24.0
CURLOPT_ACCEPT_ENCODING 7.21.6
CURLOPT_ADDRESS_SCOPE 7.19.0
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 9481aca8c..a626caf38 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1770,6 +1770,9 @@ typedef enum {
this option is used only if PROXY_SSL_VERIFYPEER is true */
CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
+ /* Path to an abstract Unix domain socket */
+ CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index 4eb896eaa..3d683152b 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -219,7 +219,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
/* evaluates to true if option takes a char* argument */
#define _curl_is_string_option(option) \
- ((option) == CURLOPT_ACCEPT_ENCODING || \
+ ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
+ (option) == CURLOPT_ACCEPT_ENCODING || \
(option) == CURLOPT_CAINFO || \
(option) == CURLOPT_CAPATH || \
(option) == CURLOPT_COOKIE || \
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 61cdaddc1..7182a0066 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -47,6 +47,8 @@
# define in_addr_t unsigned long
#endif
+#include <stddef.h>
+
#include "curl_addrinfo.h"
#include "inet_pton.h"
#include "warnless.h"
@@ -483,24 +485,29 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
* struct initialized with this path.
* Set '*longpath' to TRUE if the error is a too long path.
*/
-Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath)
+Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
{
Curl_addrinfo *ai;
struct sockaddr_un *sa_un;
size_t path_len;
+ *longpath = FALSE;
+
ai = calloc(1, sizeof(Curl_addrinfo));
if(!ai)
return NULL;
ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
if(!ai->ai_addr) {
free(ai);
- *longpath = FALSE;
return NULL;
}
+
+ sa_un = (void *) ai->ai_addr;
+ sa_un->sun_family = AF_UNIX;
+
/* sun_path must be able to store the NUL-terminated path */
- path_len = strlen(path);
- if(path_len >= sizeof(sa_un->sun_path)) {
+ path_len = strlen(path) + 1;
+ if(path_len > sizeof(sa_un->sun_path)) {
free(ai->ai_addr);
free(ai);
*longpath = TRUE;
@@ -509,10 +516,14 @@ Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath)
ai->ai_family = AF_UNIX;
ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
- ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
- sa_un = (void *) ai->ai_addr;
- sa_un->sun_family = AF_UNIX;
- memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
+ ai->ai_addrlen = offsetof(struct sockaddr_un, sun_path) + path_len;
+
+ /* Abstract Unix domain socket have NULL prefix instead of suffix */
+ if(abstract)
+ memcpy(sa_un->sun_path + 1, path, path_len - 1);
+ else
+ memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */
+
return ai;
}
#endif
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
index 4f24730af..8f6f3d106 100644
--- a/lib/curl_addrinfo.h
+++ b/lib/curl_addrinfo.h
@@ -80,7 +80,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
#ifdef USE_UNIX_SOCKETS
-Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath);
+Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
#endif
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
diff --git a/lib/url.c b/lib/url.c
index 074289ed4..edae1e3f3 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2814,6 +2814,12 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
#ifdef USE_UNIX_SOCKETS
case CURLOPT_UNIX_SOCKET_PATH:
+ data->set.abstract_unix_socket = FALSE;
+ result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+ va_arg(param, char *));
+ break;
+ case CURLOPT_ABSTRACT_UNIX_SOCKET:
+ data->set.abstract_unix_socket = TRUE;
result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
va_arg(param, char *));
break;
@@ -3523,6 +3529,8 @@ ConnectionExists(struct Curl_easy *data,
continue;
if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
continue;
+ if(needle->abstract_unix_socket != check->abstract_unix_socket)
+ continue;
}
else if(check->unix_domain_socket)
continue;
@@ -5863,8 +5871,9 @@ static CURLcode resolve_server(struct Curl_easy *data,
if(!hostaddr)
result = CURLE_OUT_OF_MEMORY;
else {
- int longpath=0;
- hostaddr->addr = Curl_unix2addr(path, &longpath);
+ bool longpath = FALSE;
+ hostaddr->addr = Curl_unix2addr(path, &longpath,
+ conn->abstract_unix_socket);
if(hostaddr->addr)
hostaddr->inuse++;
else {
@@ -6273,6 +6282,7 @@ static CURLcode create_conn(struct Curl_easy *data,
result = CURLE_OUT_OF_MEMORY;
goto out;
}
+ conn->abstract_unix_socket = data->set.abstract_unix_socket;
}
#endif
diff --git a/lib/urldata.h b/lib/urldata.h
index 0271d266b..96c0aca19 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1133,6 +1133,7 @@ struct connectdata {
#ifdef USE_UNIX_SOCKETS
char *unix_domain_socket;
+ bool abstract_unix_socket;
#endif
};
@@ -1754,6 +1755,8 @@ struct UserDefined {
int stream_weight;
struct Curl_http2_dep *stream_dependents;
+
+ bool abstract_unix_socket;
};
struct Names {
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 5db86f4e3..0d2f765d2 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -230,6 +230,7 @@ struct OperationConfig {
bool nonpn; /* enable/disable TLS NPN extension */
bool noalpn; /* enable/disable TLS ALPN extension */
char *unix_socket_path; /* path to Unix domain socket */
+ bool abstract_unix_socket; /* path to an abstract Unix domain socket */
bool falsestart;
bool path_as_is;
double expect100timeout;
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index d8a3c07bc..2777a0a2e 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -183,6 +183,7 @@ static const struct LongShort aliases[]= {
{"$R", "expect100-timeout", TRUE},
{"$S", "tftp-no-options", FALSE},
{"$U", "connect-to", TRUE},
+ {"$W", "abstract-unix-socket", TRUE},
{"0", "http1.0", FALSE},
{"01", "http1.1", FALSE},
{"02", "http2", FALSE},
@@ -1024,6 +1025,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
#endif
break;
case 'M': /* --unix-socket */
+ config->abstract_unix_socket = FALSE;
GetStr(&config->unix_socket_path, nextarg);
break;
case 'N': /* --path-as-is */
@@ -1054,6 +1056,10 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
if(err)
return err;
break;
+ case 'W': /* --abstract-unix-socket */
+ config->abstract_unix_socket = TRUE;
+ GetStr(&config->unix_socket_path, nextarg);
+ break;
}
break;
case '#': /* --progress-bar */
diff --git a/src/tool_help.c b/src/tool_help.c
index a21a336d9..5085e542e 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -271,7 +271,8 @@ static const char *const helptext[] = {
" --tlsuser USER TLS username",
" --tlspassword STRING TLS password",
" --tlsauthtype STRING TLS authentication type (default: SRP)",
- " --unix-socket FILE Connect through this Unix domain socket",
+ " --unix-socket PATH Connect through this Unix domain socket",
+ " --abstract-unix-socket PATH Connect to an abstract Unix domain socket",
" -A, --user-agent STRING Send User-Agent STRING to server (H)",
" -v, --verbose Make the operation more talkative",
" -V, --version Show version number and quit",
diff --git a/src/tool_operate.c b/src/tool_operate.c
index eff939f8c..db53d0d5a 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1393,11 +1393,17 @@ static CURLcode operate_do(struct GlobalConfig *global,
my_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L);
}
- /* new in 7.40.0 */
- if(config->unix_socket_path)
- my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH,
- config->unix_socket_path);
-
+ /* new in 7.40.0, abstract support added in 7.53.0 */
+ if(config->unix_socket_path) {
+ if(config->abstract_unix_socket) {
+ my_setopt_str(curl, CURLOPT_ABSTRACT_UNIX_SOCKET,
+ config->unix_socket_path);
+ }
+ else {
+ my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH,
+ config->unix_socket_path);
+ }
+ }
/* new in 7.45.0 */
if(config->proto_default)
my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default);