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 \
--- /dev/null
+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.
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
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
--- /dev/null
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * 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), "
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 \
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 \
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 \
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
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;
/* 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 || \
# define in_addr_t unsigned long
#endif
+#include <stddef.h>
+
#include "curl_addrinfo.h"
#include "inet_pton.h"
#include "warnless.h"
* 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;
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
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) && \
#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;
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;
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 {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
+ conn->abstract_unix_socket = data->set.abstract_unix_socket;
}
#endif
#ifdef USE_UNIX_SOCKETS
char *unix_domain_socket;
+ bool abstract_unix_socket;
#endif
};
int stream_weight;
struct Curl_http2_dep *stream_dependents;
+
+ bool abstract_unix_socket;
};
struct Names {
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;
{"$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},
#endif
break;
case 'M': /* --unix-socket */
+ config->abstract_unix_socket = FALSE;
GetStr(&config->unix_socket_path, nextarg);
break;
case 'N': /* --path-as-is */
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 */
" --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",
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);