memset(&wstp->ws, 0, sizeof(wstp->ws));
- if (ws_init(&wstp->ws, socket, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) {
+ if (ws_init(&wstp->ws, socket, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0, 0) < 0) {
ws_destroy(&wstp->ws);
wstp->ws_initialized = -1;
return *return_reason = "WS_INIT", -1;
#include <fcntl.h>
#endif
+#ifndef _MSC_VER
+#define ms_sleep(x) usleep( x * 1000);
+#else
+#define ms_sleep(x) Sleep( x );
+#endif
+
#define SHA1_HASH_SIZE 20
struct ws_globals_s ws_globals;
#endif
-
-int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock)
+static int establish_logical_layer(wsh_t *wsh)
{
- memset(wsh, 0, sizeof(*wsh));
- wsh->sock = sock;
- if (!ssl_ctx) {
- ssl_ctx = ws_globals.ssl_ctx;
+ if (!wsh->sanity) {
+ return -1;
}
- if (close_sock) {
- wsh->close_sock = 1;
+ if (wsh->logical_established) {
+ return 0;
}
- wsh->buflen = sizeof(wsh->buffer);
- wsh->secure = ssl_ctx ? 1 : 0;
-
- setup_socket(sock);
-
- if (wsh->secure) {
+ if (wsh->secure && !wsh->secure_established) {
int code;
- int sanity = 500;
-
- wsh->ssl = SSL_new(ssl_ctx);
- assert(wsh->ssl);
- SSL_set_fd(wsh->ssl, wsh->sock);
+ if (!wsh->ssl) {
+ wsh->ssl = SSL_new(wsh->ssl_ctx);
+ assert(wsh->ssl);
+
+ SSL_set_fd(wsh->ssl, wsh->sock);
+ }
do {
code = SSL_accept(wsh->ssl);
if (code == 1) {
+ wsh->secure_established = 1;
break;
}
return -1;
}
}
-#ifndef _MSC_VER
- usleep(10000);
-#else
- Sleep(10);
-#endif
-
- } while (--sanity > 0);
+
+ if (wsh->block) {
+ ms_sleep(10);
+ } else {
+ ms_sleep(1);
+ }
+
+ wsh->sanity--;
+
+ if (!wsh->block) {
+ return -2;
+ }
+
+ } while (wsh->sanity > 0);
- if (!sanity) {
+ if (!wsh->sanity) {
return -1;
}
wsh->down = 1;
return -1;
}
+
+ if (!wsh->handshake && !wsh->block) {
+ return -2;
+ }
+
+ }
+
+ wsh->logical_established = 1;
+
+ return 0;
+}
+
+
+int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int block)
+{
+ memset(wsh, 0, sizeof(*wsh));
+
+ wsh->sock = sock;
+ wsh->block = block;
+ wsh->sanity = 5000;
+ wsh->ssl_ctx = ssl_ctx;
+
+ if (!ssl_ctx) {
+ ssl_ctx = ws_globals.ssl_ctx;
+ }
+
+ if (close_sock) {
+ wsh->close_sock = 1;
+ }
+
+ wsh->buflen = sizeof(wsh->buffer);
+ wsh->secure = ssl_ctx ? 1 : 0;
+
+ setup_socket(sock);
+
+ if (establish_logical_layer(wsh) == -1) {
+ return -1;
}
if (wsh->down) {
ssize_t need = 2;
char *maskp;
+ int ll = 0;
again:
need = 2;
maskp = NULL;
*data = NULL;
+ ll = establish_logical_layer(wsh);
+
+ if (ll < 0) {
+ return ll;
+ }
+
if (wsh->down) {
return -1;
}
uint8_t down;
int secure;
uint8_t close_sock;
+ SSL_CTX *ssl_ctx;
+ int block;
+ int sanity;
+ int secure_established;
+ int logical_established;
} wsh_t;
ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc);
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes);
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes);
-int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock);
+int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int block);
ssize_t ws_close(wsh_t *wsh, int16_t reason);
void ws_destroy(wsh_t *wsh);
void init_ssl(void);