[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