unix_socket: add support for abstract unix domain socket #1197

Closed
wants to merge 1 commit into
from

Projects

None yet

5 participants

@frenche
Contributor
frenche commented Jan 8, 2017

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.

Reported-by: Chungtsun Li (typeless)
Signed-off-by: Isaac Boukris iboukris@gmail.com

Fixes #1061

@mention-bot

@frenche, thanks for your PR! By analyzing the history of the files in this pull request, we identified @bagder, @Lekensteyn and @yangtse to be potential reviewers.

@frenche
Contributor
frenche commented Jan 8, 2017

Note, the man pages are missing, I'll work on it asap.
Just thought maybe someone could review meanwhile, thanks.

src/tool_operate.c
- config->unix_socket_path);
+ my_setopt_str(curl, config->abstract_unix_socket ?
+ CURLOPT_ABSTRACT_UNIX_SOCKET :
+ CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path);
@jay
jay Jan 9, 2017 Member

fix for style, use column alignment. suggest parentheses and braces to make it easier to understand

if(config->unix_socket_path) {
  my_setopt_str(curl, (config->abstract_unix_socket ?
                       CURLOPT_ABSTRACT_UNIX_SOCKET :
                       CURLOPT_UNIX_SOCKET_PATH),
                config->unix_socket_path);
}
@jay
jay Jan 9, 2017 Member

Also it occurs to me that CURLoption parameter is stringized by the function-like macro so I'm pretty sure this is not going to work, run with --libcurl to confirm. Assuming that's the case do this instead

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);
  }
}
@frenche
frenche Jan 9, 2017 Contributor

Thanks, I'll fix this.

lib/curl_addrinfo.c
/* 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;
@jay
jay Jan 9, 2017 Member

I would change all the +1 to + 1 and the -1 to - 1. I don't think we have a policy on it but foo +1 looks weird and I don't recall it elsewhere in the codebase. Occasionally I've seen foo+1 but foo + 1 I believe is more common

@frenche
frenche Jan 9, 2017 Contributor

Ok.

@Lekensteyn
Member

Can you modify this to use url-escaped paths (and make this encoding requirement very clear in the docs)? That will correctly handle paths containing NUL bytes.

(As for alternatives: curl_easy_setopt only accepts one parameter, so the length cannot be given. Requiring the user to pass a fixed-length buffer is error prone as well. I also considered an option to provide the length for an abstract socket path, but this is too complicated to get right.)

@frenche
Contributor
frenche commented Jan 9, 2017

@Lekensteyn that was my initial intention (see comments in #1061), however it got complicated in matter of design, usage and implementation.
And frankly, I think using such path embedding zeros is a good recipe for troubles and should be discouraged. Also all the tools and services I've seen using abstract socket had proper normal abstract path (with only null prefix).

@frenche
Contributor
frenche commented Jan 9, 2017

I've addressed Jay's comments and added the missing doc, please review - thanks!

@bagder
bagder approved these changes Jan 10, 2017 View changes

👍

@Lekensteyn

Looks good, only some doc nitpicks below :-)

+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
@Lekensteyn
Lekensteyn Jan 12, 2017 Member

We're already in 2017 :-)

+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_ABSTRACT_UNIX_SOCKET 3 "08 Jan 2016" "libcurl 7.53.0" "curl_easy_setopt options"
src/tool_help.c
@@ -272,6 +272,7 @@ static const char *const helptext[] = {
" --tlspassword STRING TLS password",
" --tlsauthtype STRING TLS authentication type (default: SRP)",
" --unix-socket FILE Connect through this Unix domain socket",
+ " --abstract-unix-socket PATH Connect to an abstract Unix domain socket",
@Lekensteyn
Lekensteyn Jan 12, 2017 Member

For consistency with --unix-socket, maybe change FILE to PATH (or the other way round?)

@frenche
frenche Jan 12, 2017 Contributor

It isn't a file in case of abstract, but path would be fine for both, I'll fix it.

@frenche frenche 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)
57fcd60
@frenche
Contributor
frenche commented Jan 12, 2017

Thanks for the reviews, I've addressed @Lekensteyn's comments.

@jay
Member
jay commented Jan 12, 2017

It's better as FILE because that's what we use in the other options , see curl --help | grep FILE
Otherwise this looks ready to go. Before you send it upstream make sure to modify the commit message to point back to this thread with a Ref or Closes etc

@jay
Member
jay commented Jan 12, 2017

I may have spoken too soon maybe it's not better as FILE, if it's not a file.

@frenche
Contributor
frenche commented Jan 12, 2017

Yea, it is not a file, just a name (could be just 'foo', without slash).
In the unix(7) man page it is mostly referred to as path.

@jay
Member
jay commented Jan 12, 2017

Ok, nevermind then

@frenche
Contributor
frenche commented Jan 12, 2017 edited

Actually, a regular unix socket which is a file, can also be set to just 'foo' as a relative path, but abstract is really not a file on the file system.

@jay
Member
jay commented Jan 12, 2017

Ok, thanks for explaining that. I think it was fine the way you had it then, FILE for unix domain and PATH for abstract unix domain.

@frenche
Contributor
frenche commented Jan 12, 2017

The man page terminology argument was about both :)

@Lekensteyn Lekensteyn was assigned by bagder Jan 13, 2017
@Lekensteyn

LGTM. I'll try to test the new functionality after the weekend and merge then.

(Hey, if you want to get your hands wet, maybe you can create another patch that extends the test suite with support for abstract domain sockets :-))

@Lekensteyn Lekensteyn added a commit that closed this pull request Jan 13, 2017
@frenche @Lekensteyn frenche + Lekensteyn 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
1d786fa
@Lekensteyn
Member

Decided to apply it now anyway. Briefly tested with an out-of-tree autotools build. Tested things like:

socat ABSTRACT-LISTEN:meh,fork TCP-CONNECT:lekensteyn.nl:443
src/curl -vL --abstract-unix-socket meh https://lekensteyn.nl/files
@frenche
Contributor
frenche commented Jan 13, 2017

Great, thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment