[ovs-dev] [PATCH 4/4] stream-ssl: Add support for windows platform.
Gurucharan Shetty
shettyg at nicira.com
Thu Feb 6 16:12:33 UTC 2014
This commit creates events and associates them with
socket file descriptors to get woken up from poll_block().
One difference with the Linux implementation is that
we cannot register for separate network events with poll_block().
i.e., we cannot say, we only should be woken up for POLLIN or POLLOUT.
So this would mean that we will be woken up from poll_block() more
often.
Some other changes:
* Windows does not have sys/fcntl.h but has a fcntl.h
On Linux, there is fctnl.h too.
* SHUT_RDWR is equivalent to SD_BOTH on Windows.
Signed-off-by: Gurucharan Shetty <gshetty at nicira.com>
---
lib/stream-ssl.c | 85 ++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 69 insertions(+), 16 deletions(-)
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index 2ed5282..a483c5c 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -29,7 +29,7 @@
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <poll.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "coverage.h"
@@ -47,6 +47,10 @@
#include "timeval.h"
#include "vlog.h"
+#ifdef _WIN32
+#define SHUT_RDWR SD_BOTH
+#endif
+
VLOG_DEFINE_THIS_MODULE(stream_ssl);
/* Active SSL. */
@@ -67,6 +71,7 @@ struct ssl_stream
enum ssl_state state;
enum session_type type;
int fd;
+ HANDLE wevent;
SSL *ssl;
struct ofpbuf *txbuf;
unsigned int session_nr;
@@ -183,6 +188,9 @@ static void stream_ssl_set_ca_cert_file__(const char *file_name,
static void ssl_protocol_cb(int write_p, int version, int content_type,
const void *, size_t, SSL *, void *sslv_);
static bool update_ssl_config(struct ssl_config_file *, const char *file_name);
+static void close_socket(int fd);
+static HANDLE create_handle(int fd);
+static void clear_handle(int fd, HANDLE wevent);
static short int
want_to_poll_events(int want)
@@ -243,10 +251,12 @@ new_ssl_stream(const char *name, int fd, enum session_type type,
}
/* Disable Nagle. */
- retval = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
+ retval = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&on,
+ sizeof on);
if (retval) {
- VLOG_ERR("%s: setsockopt(TCP_NODELAY): %s", name, ovs_strerror(errno));
- retval = errno;
+ char *msg_buf = sock_strerror(sock_errno());
+ VLOG_ERR("%s: setsockopt(TCP_NODELAY): %s", name, msg_buf);
+ LocalFree(msg_buf);
goto error;
}
@@ -272,6 +282,7 @@ new_ssl_stream(const char *name, int fd, enum session_type type,
sslv->state = state;
sslv->type = type;
sslv->fd = fd;
+ sslv->wevent = create_handle(fd);
sslv->ssl = ssl;
sslv->txbuf = NULL;
sslv->rx_want = sslv->tx_want = SSL_NOTHING;
@@ -290,7 +301,7 @@ error:
if (ssl) {
SSL_free(ssl);
}
- close(fd);
+ close_socket(fd);
return retval;
}
@@ -500,7 +511,8 @@ ssl_close(struct stream *stream)
ERR_clear_error();
SSL_free(sslv->ssl);
- close(sslv->fd);
+ clear_handle(sslv->fd, sslv->wevent);
+ close_socket(sslv->fd);
free(sslv);
}
@@ -691,7 +703,8 @@ ssl_run_wait(struct stream *stream)
struct ssl_stream *sslv = ssl_stream_cast(stream);
if (sslv->tx_want != SSL_NOTHING) {
- poll_fd_wait(sslv->fd, want_to_poll_events(sslv->tx_want));
+ poll_fd_wait_event(sslv->fd, sslv->wevent,
+ want_to_poll_events(sslv->tx_want));
}
}
@@ -707,14 +720,14 @@ ssl_wait(struct stream *stream, enum stream_wait_type wait)
} else {
switch (sslv->state) {
case STATE_TCP_CONNECTING:
- poll_fd_wait(sslv->fd, POLLOUT);
+ poll_fd_wait_event(sslv->fd, sslv->wevent, POLLOUT);
break;
case STATE_SSL_CONNECTING:
/* ssl_connect() called SSL_accept() or SSL_connect(), which
* set up the status that we test here. */
- poll_fd_wait(sslv->fd,
- want_to_poll_events(SSL_want(sslv->ssl)));
+ poll_fd_wait_event(sslv->fd, sslv->wevent,
+ want_to_poll_events(SSL_want(sslv->ssl)));
break;
default:
@@ -725,7 +738,8 @@ ssl_wait(struct stream *stream, enum stream_wait_type wait)
case STREAM_RECV:
if (sslv->rx_want != SSL_NOTHING) {
- poll_fd_wait(sslv->fd, want_to_poll_events(sslv->rx_want));
+ poll_fd_wait_event(sslv->fd, sslv->wevent,
+ want_to_poll_events(sslv->rx_want));
} else {
poll_immediate_wake();
}
@@ -765,6 +779,7 @@ struct pssl_pstream
{
struct pstream pstream;
int fd;
+ HANDLE wevent;
};
const struct pstream_class pssl_pstream_class;
@@ -802,6 +817,7 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
pstream_set_bound_port(&pssl->pstream, sin.sin_port);
pssl->fd = fd;
+ pssl->wevent = create_handle(fd);
*pstreamp = &pssl->pstream;
return 0;
}
@@ -810,7 +826,8 @@ static void
pssl_close(struct pstream *pstream)
{
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
- close(pssl->fd);
+ clear_handle(pssl->fd, pssl->wevent);
+ close_socket(pssl->fd);
free(pssl);
}
@@ -826,16 +843,18 @@ pssl_accept(struct pstream *pstream, struct stream **new_streamp)
new_fd = accept(pssl->fd, (struct sockaddr *) &sin, &sin_len);
if (new_fd < 0) {
- error = errno;
+ error = sock_errno();
if (error != EAGAIN) {
- VLOG_DBG_RL(&rl, "accept: %s", ovs_strerror(error));
+ char *msg_buf = sock_strerror(error);
+ VLOG_DBG_RL(&rl, "accept: %s", msg_buf);
+ LocalFree(msg_buf);
}
return error;
}
error = set_nonblocking(new_fd);
if (error) {
- close(new_fd);
+ close_socket(new_fd);
return error;
}
@@ -851,7 +870,7 @@ static void
pssl_wait(struct pstream *pstream)
{
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
- poll_fd_wait(pssl->fd, POLLIN);
+ poll_fd_wait_event(pssl->fd, pssl->wevent, POLLIN);
}
static int
@@ -1370,3 +1389,37 @@ ssl_protocol_cb(int write_p, int version OVS_UNUSED, int content_type,
ds_destroy(&details);
}
+
+static void
+close_socket(int fd)
+{
+#ifdef _WIN32
+ closesocket(fd);
+#else
+ close(fd);
+#endif
+}
+
+static HANDLE
+create_handle(int fd OVS_UNUSED)
+{
+#ifdef _WIN32
+ HANDLE wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ WSAEventSelect(fd, wevent, FD_ALL_EVENTS);
+ return wevent;
+#endif
+ return 0;
+}
+
+static void
+clear_handle(int fd OVS_UNUSED, HANDLE wevent OVS_UNUSED)
+{
+#ifdef _WIN32
+ if (fd) {
+ WSAEventSelect(fd, NULL, 0);
+ }
+ if (wevent) {
+ CloseHandle(wevent);
+ }
+#endif
+}
--
1.7.9.5
More information about the dev
mailing list