refactor add ssl read write single implementation
authorAndy Green <andy.green@linaro.org>
Sun, 6 Apr 2014 05:26:35 +0000 (06:26 +0100)
committerAndy Green <andy.green@linaro.org>
Sun, 6 Apr 2014 05:26:35 +0000 (06:26 +0100)
Signed-off-by: Andy Green <andy.green@linaro.org>
CMakeLists.txt
README.build
lib/libwebsockets.h
lib/output.c
lib/private-libwebsockets.h
lib/ssl.c

index fcd678d..4d511e2 100644 (file)
@@ -486,7 +486,7 @@ if (LWS_WITH_SSL)
                message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
 
                include_directories("${OPENSSL_INCLUDE_DIR}")
-               list(APPEND LIB_LIST ${OPENSSL_LIBRARIES})
+               list(APPEND LIB_LIST ${OPENSSL_LIBRARIES} dl)
        endif()
 endif(LWS_WITH_SSL)
 
index 9c33e17..4620661 100644 (file)
@@ -60,6 +60,13 @@ Building on Unix:
        following to the cmake line
 
                -DLIB_SUFFIX=64
+               
+       NOTE4
+       If you are building against a non-distro OpenSSL (eg, in order to get
+       access to ALPN support only in newer OpenSSL versions) the nice way to
+       express that in one cmake command is eg,
+       
+               -DOPENSSL_ROOT_DIR=/usr/local/ssl
 
 4. Finally you can build using the generated Makefile:
 
index 8d56458..c5b1701 100644 (file)
@@ -1010,6 +1010,7 @@ enum pending_timeout {
        PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE,
        PENDING_TIMEOUT_SSL_ACCEPT,
        PENDING_TIMEOUT_HTTP_CONTENT,
+       PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
 };
 
 LWS_VISIBLE LWS_EXTERN void
index a7e2087..5502ae9 100644 (file)
@@ -123,42 +123,16 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
         * nope, send it on the socket directly
         */
        lws_latency_pre(context, wsi);
-#ifdef LWS_OPENSSL_SUPPORT
-       if (wsi->ssl) {
-               n = SSL_write(wsi->ssl, buf, len);
-               lws_latency(context, wsi, "SSL_write lws_issue_raw", n, n >= 0);
-               if (n < 0) {
-                       n = SSL_get_error(wsi->ssl, n);
-                       if (n == SSL_ERROR_WANT_READ ||
-                                               n == SSL_ERROR_WANT_WRITE) {
-                               if (n == SSL_ERROR_WANT_WRITE)
-                                       lws_set_blocking_send(wsi);
-                               n = 0;
-                               goto handle_truncated_send;
 
-                       }
-                       lwsl_debug("ERROR writing to socket\n");
-                       return -1;
-               }
-       } else {
-#endif
-               n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
-               lws_latency(context, wsi, "send lws_issue_raw", n, n == len);
-               if (n < 0) {
-                       if (LWS_ERRNO == LWS_EAGAIN ||
-                           LWS_ERRNO == LWS_EWOULDBLOCK ||
-                           LWS_ERRNO == LWS_EINTR) {
-                               if (LWS_ERRNO == LWS_EWOULDBLOCK)
-                                       lws_set_blocking_send(wsi);
-                               n = 0;
-                               goto handle_truncated_send;
-                       }
-                       lwsl_debug("ERROR writing len %d to skt %d\n", len, n);
-                       return -1;
-               }
-#ifdef LWS_OPENSSL_SUPPORT
+       n = lws_ssl_capable_write(wsi, buf, len);
+       lws_latency(context, wsi, "send lws_issue_raw", n, n == len);
+       switch (n) {
+       case LWS_SSL_CAPABLE_ERROR:
+               return -1;
+       case LWS_SSL_CAPABLE_MORE_SERVICE:
+               n = 0;
+               goto handle_truncated_send;
        }
-#endif
 
 handle_truncated_send:
        /*
@@ -549,3 +523,38 @@ all_sent:
 
        return 0; /* indicates further processing must be done */
 }
+
+LWS_VISIBLE int
+lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
+{
+       int n;
+
+       n = recv(wsi->sock, buf, len, 0);
+       if (n < 0) {
+               lwsl_warn("error on reading from skt\n");
+               return LWS_SSL_CAPABLE_ERROR;
+       }
+       
+       return n;
+}
+
+LWS_VISIBLE int
+lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
+{
+       int n;
+       
+       n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
+       if (n < 0) {
+               if (LWS_ERRNO == LWS_EAGAIN ||
+                   LWS_ERRNO == LWS_EWOULDBLOCK ||
+                   LWS_ERRNO == LWS_EINTR) {
+                       if (LWS_ERRNO == LWS_EWOULDBLOCK)
+                               lws_set_blocking_send(wsi);
+                       return LWS_SSL_CAPABLE_MORE_SERVICE;
+               }
+               lwsl_debug("ERROR writing len %d to skt %d\n", len, n);
+               return LWS_SSL_CAPABLE_ERROR;
+       }
+
+       return n;
+}
index c365a80..9df6651 100644 (file)
@@ -327,6 +327,7 @@ enum connection_mode {
        LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT,
        LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY,
        LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE,
+       LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2,
        LWS_CONNMODE_WS_CLIENT_WAITING_SSL,
        LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY,
        LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT,
@@ -742,9 +743,18 @@ SHA1(const unsigned char *d, size_t n, unsigned char *md);
 #define lws_context_init_server_ssl(_a, _b) (0)
 #define lws_ssl_destroy(_a)
 #define lws_context_init_http2_ssl(_a)
+#define lws_ssl_pending(_a) (0)
+#define lws_ssl_capable_read lws_ssl_capable_read_no_ssl
+#define lws_ssl_capable_write lws_ssl_capable_write_no_ssl
 #else
-
+LWS_EXTERN int lws_ssl_pending(struct libwebsocket *wsi);
 LWS_EXTERN int openssl_websocket_private_data_index;
+LWS_EXTERN int
+lws_ssl_capable_read(struct libwebsocket *wsi, unsigned char *buf, int len);
+
+LWS_EXTERN int
+lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len);
+
 #ifndef LWS_NO_SERVER
 LWS_EXTERN int
 lws_context_init_server_ssl(struct lws_context_creation_info *info,
@@ -755,6 +765,17 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
 LWS_EXTERN void
 lws_ssl_destroy(struct libwebsocket_context *context);
 
+enum lws_ssl_capable_status {
+       LWS_SSL_CAPABLE_ERROR = -1,
+       LWS_SSL_CAPABLE_MORE_SERVICE = -2,
+};
+
+LWS_EXTERN int
+lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len);
+
+LWS_EXTERN int
+lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len);
+
 /* HTTP2-related */
 
 #ifdef LWS_USE_HTTP2
@@ -763,7 +784,6 @@ lws_context_init_http2_ssl(struct libwebsocket_context *context);
 #else
 #define lws_context_init_http2_ssl(_a)
 #endif
-
 #endif
 
 #ifndef LWS_NO_CLIENT
index 480256f..c653454 100644 (file)
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -331,4 +331,53 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
        
        return 0;
 }
-#endif
\ No newline at end of file
+#endif
+
+LWS_VISIBLE int
+lws_ssl_capable_read(struct libwebsocket *wsi, unsigned char *buf, int len)
+{
+       int n;
+
+       if (!wsi->ssl)
+               return lws_ssl_capable_read_no_ssl(wsi, buf, len);
+
+       n = SSL_read(wsi->ssl, buf, len);
+       if (n >= 0)
+               return n;
+
+       n = SSL_get_error(wsi->ssl, len);
+       if (n ==  SSL_ERROR_WANT_READ || n ==  SSL_ERROR_WANT_WRITE)
+               return LWS_SSL_CAPABLE_MORE_SERVICE;
+
+       return LWS_SSL_CAPABLE_ERROR; 
+}
+
+LWS_VISIBLE int
+lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len)
+{
+       int n;
+
+       if (!wsi->ssl)
+               return lws_ssl_capable_write_no_ssl(wsi, buf, len);
+       
+       n = SSL_write(wsi->ssl, buf, len);
+       if (n >= 0)
+               return n;
+
+       n = SSL_get_error(wsi->ssl, len);
+       if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE) {
+               if (n == SSL_ERROR_WANT_WRITE)
+                       lws_set_blocking_send(wsi);
+               return LWS_SSL_CAPABLE_MORE_SERVICE;
+       }
+
+       return LWS_SSL_CAPABLE_ERROR;
+}
+
+LWS_VISIBLE int
+lws_ssl_pending(struct libwebsocket *wsi)
+{
+       if (wsi->ssl)
+               return SSL_pending(wsi->ssl);
+       return 0;
+}
\ No newline at end of file