mirror of
https://github.com/openvswitch/ovs
synced 2025-10-25 15:07:05 +00:00
stream: Introduce [p]windows_[p]stream_class.
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. Now that we have a separate class
[p]stream_class for hiding kernel assigned TCP port inside a file meant for
unix domain sockets in windows, make unixctl use it.
Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
113
lib/stream-tcp.c
113
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, suffix,
|
||||
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,60 @@ 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);
|
||||
goto exit;
|
||||
}
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user