[ovs-dev] [PATCH 02/11] stream: Introduce [p]windows_[p]stream_class.

Gurucharan Shetty shettyg at nicira.com
Fri Apr 18 18:04:09 UTC 2014


On Linux, we heavily use --remote=punix:* to listen for
connections through unix domain sockets. We also use, unix:*
to connect to a daemon that is listening on unix domain sockets.
Many times, we create default unix domain sockets for listening
and many utilities connect to these sockets by default.

Windows does not have unix domain sockets. So far, we could just use
ptcp:* and tcp:* for listening and initiating connections respectively.
The drawback here is that one has to provide a specific TCP port.

For unit tests, it looks useful to let kernel choose that port.
As such, we can let that chosen kernel port be stored in the
file specified with punix:* and unix:*. For this purpose, introduce
a new [p]windows_[p]stream_class. Since it is just a wrapper around
[p]tcp_[p]stream_class, add it to stream-tcp.c.

commit cb54a8c (unixctl: Add support for Windows.) used the above concept
for only control channel connections (i.e., --unixctl for daemons and its
interaction with ovs-appctl). This commit adds the same support for
all unix domain sockets.

Signed-off-by: Gurucharan Shetty <gshetty at nicira.com>
---
 lib/stream-provider.h    |    5 +++
 lib/stream-tcp.c         |  111 ++++++++++++++++++++++++++++++++++++++++++++++
 lib/stream.c             |    4 ++
 lib/vconn-active.man     |    4 +-
 lib/vconn-passive.man    |    5 ++-
 ovsdb/remote-active.man  |    5 ++-
 ovsdb/remote-passive.man |    5 ++-
 7 files changed, 135 insertions(+), 4 deletions(-)

diff --git a/lib/stream-provider.h b/lib/stream-provider.h
index 44d75d3..8347ac6 100644
--- a/lib/stream-provider.h
+++ b/lib/stream-provider.h
@@ -191,8 +191,13 @@ struct pstream_class {
 /* Active and passive stream classes. */
 extern const struct stream_class tcp_stream_class;
 extern const struct pstream_class ptcp_pstream_class;
+#ifndef _WIN32
 extern const struct stream_class unix_stream_class;
 extern const struct pstream_class punix_pstream_class;
+#else
+extern const struct stream_class windows_stream_class;
+extern const struct pstream_class pwindows_pstream_class;
+#endif
 #ifdef HAVE_OPENSSL
 extern const struct stream_class ssl_stream_class;
 extern const struct pstream_class pssl_pstream_class;
diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c
index d62e9c3..19d7314 100644
--- a/lib/stream-tcp.c
+++ b/lib/stream-tcp.c
@@ -91,6 +91,62 @@ const struct stream_class tcp_stream_class = {
     NULL,                       /* run_wait */
     NULL,                       /* wait */
 };
+
+#ifdef _WIN32
+static int
+windows_open(const char *name, char *suffix, struct stream **streamp,
+             uint8_t dscp)
+{
+    int error, port;
+    FILE *file;
+    char *suffix_new, *path;
+
+    /* If the path does not contain a ':', assume it is relative to
+     * OVS_RUNDIR. */
+    if (!strchr(suffix, ':')) {
+        path = xasprintf("%s/%s", ovs_rundir(), suffix);
+    } else {
+        path = strdup(suffix);
+    }
+
+    file = fopen(path, "r");
+    if (!file) {
+        error = errno;
+        VLOG_DBG("%s: could not open %s (%s)", name, path,
+                 ovs_strerror(error));
+        return error;
+    }
+
+    error = fscanf(file, "%d", &port);
+    if (error != 1) {
+        VLOG_ERR("failed to read port from %s", suffix);
+        fclose(file);
+        return EINVAL;
+    }
+    fclose(file);
+
+    suffix_new = xasprintf("127.0.0.1:%d", port);
+
+    error = tcp_open(name, suffix_new, streamp, dscp);
+
+    free(suffix_new);
+    free(path);
+    return error;
+}
+
+const struct stream_class windows_stream_class = {
+    "unix",                     /* name */
+    false,                      /* needs_probes */
+    windows_open,                  /* open */
+    NULL,                       /* close */
+    NULL,                       /* connect */
+    NULL,                       /* recv */
+    NULL,                       /* send */
+    NULL,                       /* run */
+    NULL,                       /* run_wait */
+    NULL,                       /* wait */
+};
+#endif
 
 /* Passive TCP. */
 
@@ -148,3 +204,58 @@ const struct pstream_class ptcp_pstream_class = {
     NULL,
 };
 
+#ifdef _WIN32
+static int
+pwindows_open(const char *name OVS_UNUSED, char *suffix,
+              struct pstream **pstreamp, uint8_t dscp)
+{
+    int error;
+    char *suffix_new, *path;
+    FILE *file;
+    struct pstream *listener;
+
+    suffix_new = xstrdup("0:127.0.0.1");
+    error = ptcp_open(name, suffix_new, pstreamp, dscp);
+    if (error) {
+        goto exit;
+    }
+    listener = *pstreamp;
+
+    /* If the path does not contain a ':', assume it is relative to
+     * OVS_RUNDIR. */
+    if (!strchr(suffix, ':')) {
+        path = xasprintf("%s/%s", ovs_rundir(), suffix);
+    } else {
+        path = strdup(suffix);
+    }
+
+    file = fopen(path, "w");
+    if (!file) {
+        error = errno;
+        VLOG_DBG("could not open %s (%s)", path, ovs_strerror(error));
+        goto exit;
+    }
+
+    fprintf(file, "%d\n", ntohs(listener->bound_port));
+    if (fflush(file) == EOF) {
+        error = EIO;
+        VLOG_ERR("write failed for %s", path);
+    }
+    fclose(file);
+    free(path);
+
+exit:
+    free(suffix_new);
+    return error;
+}
+
+const struct pstream_class pwindows_pstream_class = {
+    "punix",
+    false,
+    pwindows_open,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+};
+#endif
diff --git a/lib/stream.c b/lib/stream.c
index fa5b6d6..55632fe 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -55,6 +55,8 @@ static const struct stream_class *stream_classes[] = {
     &tcp_stream_class,
 #ifndef _WIN32
     &unix_stream_class,
+#else
+    &windows_stream_class,
 #endif
 #ifdef HAVE_OPENSSL
     &ssl_stream_class,
@@ -65,6 +67,8 @@ static const struct pstream_class *pstream_classes[] = {
     &ptcp_pstream_class,
 #ifndef _WIN32
     &punix_pstream_class,
+#else
+    &pwindows_pstream_class,
 #endif
 #ifdef HAVE_OPENSSL
     &pssl_pstream_class,
diff --git a/lib/vconn-active.man b/lib/vconn-active.man
index c1e9281..b0c4ace 100644
--- a/lib/vconn-active.man
+++ b/lib/vconn-active.man
@@ -11,4 +11,6 @@ future, the default will change to 6653, which is the IANA-defined
 value.
 .TP
 \fBunix:\fIfile\fR
-The Unix domain server socket named \fIfile\fR.
+On POSIX, a Unix domain server socket named \fIfile\fR.
+.IP
+On Windows, a localhost TCP port written in \fIfile\fR.
diff --git a/lib/vconn-passive.man b/lib/vconn-passive.man
index 0cf8fc1..a9e01ea 100644
--- a/lib/vconn-passive.man
+++ b/lib/vconn-passive.man
@@ -11,5 +11,8 @@ options are mandatory.
 .IP
 .
 .IP "\fBpunix:\fIfile\fR"
-Listens for OpenFlow connections on the Unix domain server socket
+On POSIX, listens for OpenFlow connections on the Unix domain server socket
 named \fIfile\fR.
+.IP
+On Windows, listen on a kernel chosen TCP port on the localhost. The kernel
+chosen TCP port value is written in \fIfile\fR
diff --git a/ovsdb/remote-active.man b/ovsdb/remote-active.man
index 419b1c8..5facf0a 100644
--- a/ovsdb/remote-active.man
+++ b/ovsdb/remote-active.man
@@ -12,4 +12,7 @@ or IPv6 address. If \fIip\fR is an IPv6 address, then wrap \fIip\fR with
 square brackets, e.g.: \fBtcp:[::1]:6632\fR.
 .
 .IP "\fBunix:\fIfile\fR"
-Connect to the Unix domain server socket named \fIfile\fR.
+On POSIX, connect to the Unix domain server socket named \fIfile\fR.
+.IP
+On Windows, connect to a localhost TCP port whose value is written in
+\fIfile\fR.
diff --git a/ovsdb/remote-passive.man b/ovsdb/remote-passive.man
index 200651b..e5e5c98 100644
--- a/ovsdb/remote-passive.man
+++ b/ovsdb/remote-passive.man
@@ -19,5 +19,8 @@ an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
 \fBptcp:6632:[::1]\fR.
 .
 .IP "\fBpunix:\fIfile\fR"
-Listen on the Unix domain server socket named \fIfile\fR for a
+On POSIX, listen on the Unix domain server socket named \fIfile\fR for a
 connection.
+.IP
+On Windows, listen on a kernel chosen TCP port on the localhost. The kernel
+chosen TCP port value is written in \fIfile\fR.
-- 
1.7.9.5




More information about the dev mailing list