Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
7a7c4007
Commit
7a7c4007
authored
Aug 19, 2017
by
Kenton Varda
Committed by
GitHub
Aug 19, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #533 from ohwgiles/master
RPC: Support abstract unix socket addresses on Linux
parents
8fffb02d
d01db3c9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
52 additions
and
3 deletions
+52
-3
async-io-test.c++
c++/src/kj/async-io-test.c++
+25
-0
async-io-unix.c++
c++/src/kj/async-io-unix.c++
+23
-1
cxxrpc.md
doc/cxxrpc.md
+4
-2
No files found.
c++/src/kj/async-io-test.c++
View file @
7a7c4007
...
...
@@ -28,6 +28,8 @@
#include "windows-sanity.h"
#else
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#endif
namespace
kj
{
...
...
@@ -102,6 +104,7 @@ TEST(AsyncIo, AddressParsing) {
#if !_WIN32
EXPECT_EQ
(
"unix:foo/bar/baz"
,
tryParse
(
w
,
network
,
"unix:foo/bar/baz"
));
EXPECT_EQ
(
"unix-abstract:foo/bar/baz"
,
tryParse
(
w
,
network
,
"unix-abstract:foo/bar/baz"
));
#endif
// We can parse services by name...
...
...
@@ -387,5 +390,27 @@ TEST(AsyncIo, Udp) {
#endif // !_WIN32
#ifdef __linux__ // Abstract unix sockets are only supported on Linux
TEST
(
AsyncIo
,
AbstractUnixSocket
)
{
auto
ioContext
=
setupAsyncIo
();
auto
&
network
=
ioContext
.
provider
->
getNetwork
();
Own
<
NetworkAddress
>
addr
=
network
.
parseAddress
(
"unix-abstract:foo"
).
wait
(
ioContext
.
waitScope
);
Own
<
ConnectionReceiver
>
listener
=
addr
->
listen
();
// chdir proves no filesystem dependence. Test fails for regular unix socket
// but passes for abstract unix socket.
int
originalDirFd
;
KJ_SYSCALL
(
originalDirFd
=
open
(
"."
,
O_RDONLY
|
O_DIRECTORY
|
O_CLOEXEC
));
KJ_DEFER
(
close
(
originalDirFd
));
KJ_SYSCALL
(
chdir
(
"/tmp"
));
KJ_DEFER
(
KJ_SYSCALL
(
fchdir
(
originalDirFd
)));
addr
->
connect
().
attach
(
kj
::
mv
(
listener
)).
wait
(
ioContext
.
waitScope
);
}
#endif // __linux__
}
// namespace
}
// namespace kj
c++/src/kj/async-io-unix.c++
View file @
7a7c4007
...
...
@@ -449,7 +449,11 @@ public:
return
str
(
'['
,
buffer
,
"]:"
,
ntohs
(
addr
.
inet6
.
sin6_port
));
}
case
AF_UNIX
:
{
return
str
(
"unix:"
,
addr
.
unixDomain
.
sun_path
);
if
(
addr
.
unixDomain
.
sun_path
[
0
]
==
'\0'
)
{
return
str
(
"unix-abstract:"
,
addr
.
unixDomain
.
sun_path
+
1
);
}
else
{
return
str
(
"unix:"
,
addr
.
unixDomain
.
sun_path
);
}
}
default
:
return
str
(
"(unknown address family "
,
addr
.
generic
.
sa_family
,
")"
);
...
...
@@ -470,6 +474,9 @@ public:
StringPtr
path
=
str
.
slice
(
strlen
(
"unix:"
));
KJ_REQUIRE
(
path
.
size
()
<
sizeof
(
addr
.
unixDomain
.
sun_path
),
"Unix domain socket address is too long."
,
str
);
KJ_REQUIRE
(
path
.
size
()
==
strlen
(
path
.
cStr
()),
"Unix domain socket address contains NULL. Use"
" 'unix-abstract:' for the abstract namespace."
);
result
.
addr
.
unixDomain
.
sun_family
=
AF_UNIX
;
strcpy
(
result
.
addr
.
unixDomain
.
sun_path
,
path
.
cStr
());
result
.
addrlen
=
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
path
.
size
()
+
1
;
...
...
@@ -478,6 +485,21 @@ public:
return
array
.
finish
();
}
if
(
str
.
startsWith
(
"unix-abstract:"
))
{
StringPtr
path
=
str
.
slice
(
strlen
(
"unix-abstract:"
));
KJ_REQUIRE
(
path
.
size
()
+
1
<
sizeof
(
addr
.
unixDomain
.
sun_path
),
"Unix domain socket address is too long."
,
str
);
result
.
addr
.
unixDomain
.
sun_family
=
AF_UNIX
;
result
.
addr
.
unixDomain
.
sun_path
[
0
]
=
'\0'
;
// although not strictly required by Linux, also copy the trailing
// NULL terminator so that we can safely read it back in toString
memcpy
(
result
.
addr
.
unixDomain
.
sun_path
+
1
,
path
.
cStr
(),
path
.
size
()
+
1
);
result
.
addrlen
=
offsetof
(
struct
sockaddr_un
,
sun_path
)
+
path
.
size
()
+
1
;
auto
array
=
kj
::
heapArrayBuilder
<
SocketAddress
>
(
1
);
array
.
add
(
result
);
return
array
.
finish
();
}
// Try to separate the address and port.
ArrayPtr
<
const
char
>
addrPart
;
Maybe
<
StringPtr
>
portPart
;
...
...
doc/cxxrpc.md
View file @
7a7c4007
...
...
@@ -390,7 +390,8 @@ int main(int argc, const char* argv[]) {
{% endhighlight %}
Note that for the connect address, Cap'n Proto supports DNS host names as well as IPv4 and IPv6
addresses. Additionally, a Unix domain socket can be specified as
`unix:`
followed by a path name.
addresses. Additionally, a Unix domain socket can be specified as
`unix:`
followed by a path name,
and an abstract Unix domain socket can be specified as
`unix-abstract:`
followed by an identifier.
For a more complete example, see the
[
calculator client sample
](
https://github.com/sandstorm-io/capnproto/tree/master/c++/samples/calculator-client.c++
)
.
...
...
@@ -429,7 +430,8 @@ int main(int argc, const char* argv[]) {
Note that for the bind address, Cap'n Proto supports DNS host names as well as IPv4 and IPv6
addresses. The special address
`*`
can be used to bind to the same port on all local IPv4 and
IPv6 interfaces. Additionally, a Unix domain socket can be specified as
`unix:`
followed by a
path name.
path name, and an abstract Unix domain socket can be specified as
`unix-abstract:`
followed by
an identifier.
For a more complete example, see the
[
calculator server sample
](
https://github.com/sandstorm-io/capnproto/tree/master/c++/samples/calculator-server.c++
)
.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment