summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-06-08 14:02:02 -0700
committerGarrett D'Amore <garrett@damore.org>2018-06-08 14:10:01 -0700
commit0f8d5fc8bae0f20fa870dc5eda778aee12ccbda8 (patch)
tree8ec01c3d62a067bb403abcbd1466da7feaa7f94d
parenta43e6170bdc97a27602d7a75afcbb37e9d4e69e1 (diff)
downloadnng-0f8d5fc8bae0f20fa870dc5eda778aee12ccbda8.tar.gz
nng-0f8d5fc8bae0f20fa870dc5eda778aee12ccbda8.tar.bz2
nng-0f8d5fc8bae0f20fa870dc5eda778aee12ccbda8.zip
fixes #509 We need "relative" IPC URLs
This special cases the URL parser for inproc and IPC urls, changing so that they no longer parse the thing after the :// as anything special. This allows IPC URLs to be relative.
-rw-r--r--docs/man/nng_ipc.7.adoc22
-rw-r--r--src/core/url.c27
-rw-r--r--src/transport/ipc/ipc.c4
3 files changed, 34 insertions, 19 deletions
diff --git a/docs/man/nng_ipc.7.adoc b/docs/man/nng_ipc.7.adoc
index 9b49c87c..0ebf1d3d 100644
--- a/docs/man/nng_ipc.7.adoc
+++ b/docs/man/nng_ipc.7.adoc
@@ -41,14 +41,21 @@ no extra steps to use it should be necessary.
=== URI Format
(((URI, `ipc://`)))
-This transport uses URIs using the scheme `ipc://`, followed by
-an absolute path name in the file system where the socket or named pipe
-should be created.
+This transport uses URIs using the scheme `ipc://`, followed by a path
+name in the file system where the socket or named pipe should be created.
TIP: On Windows, all names are prefixed by `\\.\pipe\` and do not
-occupy the normal file system.
-On POSIX platforms, the path is taken literally,
-and is relative to the root directory.
+reside in the normal file system.
+On POSIX platforms, the path is taken literally, and is relative to
+the current directory, unless it begins with `/`, in which case it is
+relative to the root directory.
+
+NOTE: When using relative paths on POSIX systems, the address used and returned
+in properties like `NNG_OPT_LOCADDR` and `NNG_OPT_URL` will also be relative.
+Consequently, they will only be interpreted the same by processes that have
+the same working directory.
+To ensure maximum portability and safety, absolute paths are recommended
+whenever possible.
NOTE: If compatibility with legacy _nanomsg_ applications is required,
then pathnames must not be longer than 122 bytes, including the final
@@ -56,9 +63,6 @@ then pathnames must not be longer than 122 bytes, including the final
This is because legacy versions of _nanomsg_ cannot express URLs
longer than 128 bytes, including the `ipc://` prefix.
-NOTE: Legacy _nanomsg_ supported relative IPC path names; modern _nng_ does not.
-Therefore, always use an absolute path name if interoperability is required.
-
=== Socket Address
When using an `<<nng_sockaddr.5#,nng_sockaddr>>` structure,
diff --git a/src/core/url.c b/src/core/url.c
index 7d45f82d..dfbd2a88 100644
--- a/src/core/url.c
+++ b/src/core/url.c
@@ -288,11 +288,30 @@ nni_url_parse(nni_url **urlp, const char *raw)
url->u_scheme[i] = (char) tolower(s[i]);
}
url->u_scheme[len] = '\0';
+ s += len + 3; // strlen("://")
+
+ // For compatibility reasons, we treat ipc:// and inproc:// paths
+ // specially. These names URLs have a path name (ipc) or arbitrary
+ // string (inproc) and don't include anything like a host. Note that
+ // in the case of path names, it is incumbent upon the application to
+ // ensure that valid and safe path names are used. Note also that
+ // path names are not canonicalized, which means that the address and
+ // URL properties for relative paths won't be portable to other
+ // processes unless they are in the same directory. When in doubt,
+ // we recommend using absolute paths, such as ipc:///var/run/mysocket.
+
+ if ((strcmp(url->u_scheme, "ipc") == 0) ||
+ (strcmp(url->u_scheme, "inproc") == 0)) {
+ if ((url->u_path = nni_strdup(s)) == NULL) {
+ rv = NNG_ENOMEM;
+ goto error;
+ }
+ *urlp = url;
+ }
// Look for host part (including colon). Will be terminated by
// a path, or NUL. May also include an "@", separating a user
// field.
- s += len + 3; // strlen("://")
for (len = 0; (c = s[len]) != '/'; len++) {
if ((c == '\0') || (c == '#') || (c == '?')) {
break;
@@ -317,11 +336,7 @@ nni_url_parse(nni_url **urlp, const char *raw)
// If the hostname part is just '*', skip over it. (We treat it
// as an empty host for legacy nanomsg compatibility. This may be
// non-RFC compliant, but we're really only interested in parsing
- // nanomsg URLs. One weird side effect of this is that some URLS
- // which would be invalid (ipc://*/bogus for example) will now parse
- // to something that might be surprising (ipc:///bogus now), for
- // example -- although in the IPC case the URL is *always* a local
- // path without any host component.
+ // nanomsg URLs.)
if (((len == 1) && (s[0] == '*')) ||
((len > 1) && (strncmp(s, "*:", 2) == 0))) {
s++;
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index 88e11fb1..6191dea6 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.c
@@ -628,10 +628,6 @@ nni_ipc_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode)
int rv;
size_t sz;
- if (((url->u_host != NULL) && (strlen(url->u_host) > 0)) ||
- (url->u_userinfo != NULL)) {
- return (NNG_EINVAL);
- }
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}