ssl optimize poll when buffered ssl read data
[platform/upstream/libwebsockets.git] / lib / private-libwebsockets.h
old mode 100644 (file)
new mode 100755 (executable)
index 76fc2cc..9c19f22
 #else
  #include <ifaddrs.h>
 #endif
+#if defined (__ANDROID__)
+#include <syslog.h>
+#else
 #include <sys/syslog.h>
+#endif
 #include <sys/un.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #ifdef LWS_OPENSSL_SUPPORT
 #ifdef USE_CYASSL
 #include <cyassl/openssl/ssl.h>
-#include <cyassl/error.h>
-unsigned char *
-SHA1(const unsigned char *d, size_t n, unsigned char *md);
+#include <cyassl/error-ssl.h>
 #else
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
@@ -205,6 +207,20 @@ typedef unsigned __int64 u_int64_t;
 #include <endian.h>
 #endif
 
+#if defined(__QNX__)
+       #include <gulliver.h>
+       #if defined(__LITTLEENDIAN__)
+               #define BYTE_ORDER __LITTLEENDIAN__
+               #define LITTLE_ENDIAN __LITTLEENDIAN__
+               #define BIG_ENDIAN 4321  /* to show byte order (taken from gcc); for suppres warning that BIG_ENDIAN is not defined. */
+       #endif
+       #if defined(__BIGENDIAN__)
+               #define BYTE_ORDER __BIGENDIAN__
+               #define LITTLE_ENDIAN 1234  /* to show byte order (taken from gcc); for suppres warning that LITTLE_ENDIAN is not defined. */
+               #define BIG_ENDIAN __BIGENDIAN__
+       #endif
+#endif
+
 #if !defined(BYTE_ORDER)
 # define BYTE_ORDER __BYTE_ORDER
 #endif
@@ -289,6 +305,26 @@ enum lws_connection_states {
        WSI_STATE_RETURNED_CLOSE_ALREADY,
        WSI_STATE_AWAITING_CLOSE_ACK,
        WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE,
+       
+       WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE,
+       WSI_STATE_HTTP2_ESTABLISHED_PRE_SETTINGS,
+       WSI_STATE_HTTP2_ESTABLISHED,
+};
+
+enum http_version {
+       HTTP_VERSION_1_0,
+       HTTP_VERSION_1_1,
+};
+
+enum http_connection_type {
+       HTTP_CONNECTION_CLOSE,
+       HTTP_CONNECTION_KEEP_ALIVE
+};
+
+enum lws_pending_protocol_send {
+       LWS_PPS_NONE,
+       LWS_PPS_HTTP2_MY_SETTINGS,
+       LWS_PPS_HTTP2_ACK_SETTINGS,
 };
 
 enum lws_rx_parse_state {
@@ -327,6 +363,8 @@ enum connection_mode {
 
        LWS_CONNMODE_WS_SERVING,
        LWS_CONNMODE_WS_CLIENT,
+       
+       LWS_CONNMODE_HTTP2_SERVING,
 
        /* transient, ssl delay hiding */
        LWS_CONNMODE_SSL_ACK_PENDING,
@@ -426,12 +464,14 @@ struct libwebsocket_context {
        int allow_non_ssl_on_ssl_port;
        SSL_CTX *ssl_ctx;
        SSL_CTX *ssl_client_ctx;
+       unsigned int ssl_flag_buffered_reads:1;
 #endif
        struct libwebsocket_protocols *protocols;
        int count_protocols;
 #ifndef LWS_NO_EXTENSIONS
        struct libwebsocket_extension *extensions;
 #endif
+    struct lws_token_limits *token_limits;
        void *user_space;
 };
 
@@ -459,10 +499,10 @@ lws_libev_run(struct libwebsocket_context *context);
 #define LWS_LIBEV_ENABLED(context) (0)
 #define lws_feature_status_libev(_a) \
                        lwsl_notice("libev support not compiled in\n")
-#define lws_libev_accept(_a, _b, _c)
-#define lws_libev_io(_a, _b, _c)
+#define lws_libev_accept(_a, _b, _c) ((void) 0)
+#define lws_libev_io(_a, _b, _c) ((void) 0)
 #define lws_libev_init_fd_table(_a) (0)
-#define lws_libev_run(_a)
+#define lws_libev_run(_a) ((void) 0)
 #endif
 
 #ifdef LWS_USE_IPV6
@@ -497,6 +537,18 @@ struct lws_fragments {
        unsigned char next_frag_index;
 };
 
+/* notice that these union members:
+ * 
+ *  hdr
+ *  http
+ *  http2
+ * 
+ * all have a pointer to allocated_headers struct as their first member.
+ * 
+ * It means for allocated_headers access, the three union paths can all be
+ * used interchangably to access the same data
+ */
+
 struct allocated_headers {
        unsigned short next_frag_index;
        unsigned short pos;
@@ -510,6 +562,7 @@ struct allocated_headers {
 };
 
 struct _lws_http_mode_related {
+       /* MUST be first in struct */
        struct allocated_headers *ah; /* mirroring  _lws_header_related */
 #if defined(WIN32) || defined(_WIN32)
        HANDLE fd;
@@ -519,15 +572,89 @@ struct _lws_http_mode_related {
        unsigned long filepos;
        unsigned long filelen;
 
+       enum http_version request_version;
+       enum http_connection_type connection_type;
        int content_length;
-       int content_length_seen;
-       int body_index;
-       unsigned char *post_buffer;
+       int content_remain;
+};
+
+#ifdef LWS_USE_HTTP2
+
+enum lws_http2_settings {
+       LWS_HTTP2_SETTINGS__HEADER_TABLE_SIZE = 1,
+       LWS_HTTP2_SETTINGS__ENABLE_PUSH,
+       LWS_HTTP2_SETTINGS__MAX_CONCURRENT_STREAMS,
+       LWS_HTTP2_SETTINGS__INITIAL_WINDOW_SIZE,
+       LWS_HTTP2_SETTINGS__MAX_FRAME_SIZE,
+       LWS_HTTP2_SETTINGS__MAX_HEADER_LIST_SIZE,
+       
+       LWS_HTTP2_SETTINGS__COUNT /* always last */
+};
+
+enum lws_http2_wellknown_frame_types {
+       LWS_HTTP2_FRAME_TYPE_DATA,
+       LWS_HTTP2_FRAME_TYPE_HEADERS,
+       LWS_HTTP2_FRAME_TYPE_PRIORITY,
+       LWS_HTTP2_FRAME_TYPE_RST_STREAM,
+       LWS_HTTP2_FRAME_TYPE_SETTINGS,
+       LWS_HTTP2_FRAME_TYPE_PUSH_PROMISE,
+       LWS_HTTP2_FRAME_TYPE_PING,
+       LWS_HTTP2_FRAME_TYPE_GOAWAY,
+       LWS_HTTP2_FRAME_TYPE_WINDOW_UPDATE,
+       LWS_HTTP2_FRAME_TYPE_CONTINUATION,
+       
+       LWS_HTTP2_FRAME_TYPE_COUNT /* always last */
+};
+
+#define LWS_HTTP2_STREAM_ID_MASTER 0
+#define LWS_HTTP2_FRAME_HEADER_LENGTH 9
+#define LWS_HTTP2_SETTINGS_LENGTH 6
+
+struct http2_settings {
+       unsigned int setting[LWS_HTTP2_SETTINGS__COUNT];
+};
+
+struct _lws_http2_related {
+       /* 
+        * having this first lets us also re-use all HTTP union code
+        * and in turn, http_mode_related has allocated headers in right
+        * place so we can use the header apis on the wsi directly still
+        */
+       struct _lws_http_mode_related http; /* MUST BE FIRST IN STRUCT */
+
+       struct http2_settings my_settings;
+       struct http2_settings peer_settings;
+       
+       struct libwebsocket *parent_wsi;
+       struct libwebsocket *next_child_wsi;
+
+       unsigned int count;
+       
+       /* frame */
+       unsigned int length;
+       unsigned int stream_id;
+       struct libwebsocket *stream_wsi;
+       unsigned char type;
+       unsigned char flags;
+       unsigned char frame_state;
+
+       unsigned int tx_credit;
+       unsigned int my_stream_id;
+       unsigned int child_count;
+       int my_priority;
+       unsigned char initialized;
+       unsigned char one_setting[LWS_HTTP2_SETTINGS_LENGTH];
 };
 
+#define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->parent_wsi)
+
+#endif
+
 struct _lws_header_related {
+       /* MUST be first in struct */
        struct allocated_headers *ah;
        short lextable_pos;
+       unsigned short current_token_limit;
        unsigned char parser_state; /* enum lws_token_indexes */
        enum uri_path_states ups;
        enum uri_esc_states ues;
@@ -546,13 +673,14 @@ struct _lws_websocket_related {
        unsigned int frame_is_binary:1;
        unsigned int all_zero_nonce:1;
        short close_reason; /* enum lws_close_status */
-       unsigned char *rxflow_buffer;
-       int rxflow_len;
-       int rxflow_pos;
-       unsigned int rxflow_change_to:2;
+
        unsigned int this_frame_masked:1;
        unsigned int inside_frame:1; /* next write will be more of frame */
        unsigned int clean_buffer:1; /* buffer not rewritten by extension */
+
+       unsigned char *ping_payload_buf; /* non-NULL if malloc'd */
+       unsigned int ping_payload_alloc; /* length malloc'd */
+       unsigned int ping_payload_len; /* nonzero if PONG pending */
 };
 
 struct libwebsocket {
@@ -572,6 +700,7 @@ struct libwebsocket {
        unsigned int extension_data_pending:1;
 #endif
        unsigned char ietf_spec_revision;
+       enum lws_pending_protocol_send pps;
 
        char mode; /* enum connection_mode */
        char state; /* enum lws_connection_states */
@@ -579,6 +708,7 @@ struct libwebsocket {
        char rx_frame_type; /* enum libwebsocket_write_protocol */
 
        unsigned int hdr_parsing_completed:1;
+       unsigned int user_space_externally_allocated:1;
 
        char pending_timeout; /* enum pending_timeout */
        time_t pending_timeout_limit;
@@ -589,6 +719,11 @@ struct libwebsocket {
        unsigned long action_start;
        unsigned long latency_start;
 #endif
+       /* rxflow handling */
+       unsigned char *rxflow_buffer;
+       int rxflow_len;
+       int rxflow_pos;
+       unsigned int rxflow_change_to:2;
 
        /* truncated send handling */
        unsigned char *truncated_send_malloc; /* non-NULL means buffering in progress */
@@ -602,6 +737,9 @@ struct libwebsocket {
 
        union u {
                struct _lws_http_mode_related http;
+#ifdef LWS_USE_HTTP2
+               struct _lws_http2_related http2;
+#endif
                struct _lws_header_related hdr;
                struct _lws_websocket_related ws;
        } u;
@@ -610,6 +748,7 @@ struct libwebsocket {
        SSL *ssl;
        BIO *client_bio;
        unsigned int use_ssl:2;
+       unsigned int buffered_reads_pending:1;
 #endif
 
 #ifdef _WIN32
@@ -626,6 +765,8 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
 LWS_EXTERN int
 remove_wsi_socket_from_fds(struct libwebsocket_context *context,
                                                      struct libwebsocket *wsi);
+LWS_EXTERN int
+lws_rxflow_cache(struct libwebsocket *wsi, unsigned char *buf, int n, int len);
 
 #ifndef LWS_LATENCY
 static inline void lws_latency(struct libwebsocket_context *context,
@@ -641,11 +782,18 @@ lws_latency(struct libwebsocket_context *context,
                                                       int ret, int completion);
 #endif
 
+LWS_EXTERN void lws_set_protocol_write_pending(struct libwebsocket_context *context,
+                                   struct libwebsocket *wsi,
+                                   enum lws_pending_protocol_send pend);
 LWS_EXTERN int
 libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
 
 LWS_EXTERN int
-libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
+libwebsocket_parse(struct libwebsocket_context *context,
+               struct libwebsocket *wsi, unsigned char c);
+
+LWS_EXTERN int
+lws_http_action(struct libwebsocket_context *context, struct libwebsocket *wsi);
 
 LWS_EXTERN int
 lws_b64_selftest(void);
@@ -728,6 +876,18 @@ user_callback_handle_rxflow(callback_function,
                        struct libwebsocket *wsi,
                         enum libwebsocket_callback_reasons reason, void *user,
                                                          void *in, size_t len);
+#ifdef LWS_USE_HTTP2
+LWS_EXTERN int
+lws_http2_interpret_settings_payload(struct http2_settings *settings, unsigned char *buf, int len);
+LWS_EXTERN void lws_http2_init(struct http2_settings *settings);
+LWS_EXTERN int
+lws_http2_parser(struct libwebsocket_context *context,
+                    struct libwebsocket *wsi, unsigned char c);
+LWS_EXTERN int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsocket *wsi);
+LWS_EXTERN int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigned int sid, unsigned int len, unsigned char *buf);
+LWS_EXTERN struct libwebsocket *
+lws_http2_wsi_from_id(struct libwebsocket *wsi, unsigned int sid);
+#endif
 
 LWS_EXTERN int
 lws_plat_set_socket_options(struct libwebsocket_context *context, int fd);
@@ -789,12 +949,9 @@ enum lws_ssl_capable_status {
 
 #ifndef LWS_OPENSSL_SUPPORT
 #define LWS_SSL_ENABLED(context) (0)
-unsigned char *
-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
 #define lws_server_socket_service_ssl(_a, _b, _c, _d, _e) (0)
@@ -802,10 +959,10 @@ SHA1(const unsigned char *d, size_t n, unsigned char *md);
 #define lws_ssl_context_destroy(_a)
 #else
 #define LWS_SSL_ENABLED(context) (context->use_ssl)
-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_ssl_capable_read(struct libwebsocket_context *context,
+                    struct libwebsocket *wsi, unsigned char *buf, int len);
 
 LWS_EXTERN int
 lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len);
@@ -838,7 +995,8 @@ lws_context_init_http2_ssl(struct libwebsocket_context *context);
 #endif
 
 LWS_EXTERN int
-lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len);
+lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
+                           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);