diff options
author | Isaac Boukris <iboukris@gmail.com> | 2017-01-09 00:51:08 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2017-01-13 16:25:20 +0100 |
commit | 1d786faee1046ff90e71252aeef4a997c3bf0d8d (patch) | |
tree | 325ebddb13f12be61a28062c2f06980e2a34754a /lib/curl_addrinfo.c | |
parent | a7c73ae309c03bd84b28659421ac613e503565ce (diff) | |
download | curl-1d786faee1046ff90e71252aeef4a997c3bf0d8d.tar.gz |
unix_socket: add support for abstract unix domain socket
In addition to unix domain sockets, Linux also supports an
abstract namespace which is independent of the filesystem.
In order to support it, add new CURLOPT_ABSTRACT_UNIX_SOCKET
option which uses the same storage as CURLOPT_UNIX_SOCKET_PATH
internally, along with a flag to specify abstract socket.
On non-supporting platforms, the abstract address will be
interpreted as an empty string and fail gracefully.
Also add new --abstract-unix-socket tool parameter.
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
Reported-by: Chungtsun Li (typeless)
Reviewed-by: Daniel Stenberg
Reviewed-by: Peter Wu
Closes #1197
Fixes #1061
Diffstat (limited to 'lib/curl_addrinfo.c')
-rw-r--r-- | lib/curl_addrinfo.c | 27 |
1 files changed, 19 insertions, 8 deletions
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 |