int one = 1;
tport_ws_primary_t *wspri = (tport_ws_primary_t *)self->tp_pri;
tport_ws_t *wstp = (tport_ws_t *)self;
- char *buffer, *wbuffer;
self->tp_has_connection = 1;
memset(&wstp->ws, 0, sizeof(wstp->ws));
- buffer = (char *) su_alloc((su_home_t *)self, 65536);
- wbuffer = (char *) su_alloc((su_home_t *)self, 65536);
-
- if (ws_init(&wstp->ws, socket, buffer, wbuffer, 65336, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) {
+ if (ws_init(&wstp->ws, socket, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) {
return *return_reason = "WS_INIT", -1;
}
#include "ws.h"
#include <pthread.h>
+
+#ifndef _MSC_VER
+#include <fcntl.h>
+#endif
+
#define SHA1_HASH_SIZE 20
struct globals_s globals;
do {
r = recv(wsh->sock, data, bytes, 0);
#ifndef _MSC_VER
- if (x++) usleep(10000);
+ if (x++) usleep(10000);
#else
- if (x++) Sleep(10);
+ if (x++) Sleep(10);
#endif
- } while (r == -1 && (errno == EAGAIN || errno == EINTR) && x < 100);
-
- //if (r<0) {
- // printf("READ FAIL: %s\n", strerror(errno));
- //}
-
+ } while (r == -1 && (errno == EAGAIN || errno == EINTR) && x < 100);
+
+ if (x >= 100) {
+ r = -1;
+ }
+
return r;
}
return r;
}
-int ws_init(wsh_t *wsh, ws_socket_t sock, char *buffer, char *wbuffer, size_t buflen, SSL_CTX *ssl_ctx, int close_sock)
+#ifdef _MSC_VER
+static int setup_socket(ws_socket_t sock)
+{
+ unsigned log v = 1;
+
+ if (ioctlsocket(ssock, FIONBIO, &v) == SOCKET_ERROR) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+static int restore_socket(ws_socket_t sock)
+{
+ unsigned log v = 0;
+
+ if (ioctlsocket(ssock, FIONBIO, &v) == SOCKET_ERROR) {
+ return -1;
+ }
+
+ return 0;
+
+}
+
+#else
+
+static int setup_socket(ws_socket_t sock)
+{
+ int flags = fcntl(sock, F_GETFL, 0);
+ return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+}
+
+static int restore_socket(ws_socket_t sock)
+{
+ int flags = fcntl(sock, F_GETFL, 0);
+
+ flags &= ~O_NONBLOCK;
+
+ return fcntl(sock, F_SETFL, flags);
+
+}
+
+#endif
+
+
+
+int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock)
{
memset(wsh, 0, sizeof(*wsh));
wsh->sock = sock;
wsh->close_sock = 1;
}
- if (buflen > MAXLEN) {
- buflen = MAXLEN;
- }
-
- wsh->buflen = buflen;
+ wsh->buflen = sizeof(wsh->buffer);
wsh->secure = ssl_ctx ? 1 : 0;
- if (buffer) {
- wsh->buffer = buffer;
- } else if (!wsh->buffer) {
- wsh->buffer = malloc(wsh->buflen);
- assert(wsh->buffer);
- wsh->free_buffer = 1;
- }
-
- if (wbuffer) {
- wsh->wbuffer = wbuffer;
- } else if (!wsh->wbuffer) {
- wsh->wbuffer = malloc(wsh->buflen);
- assert(wsh->wbuffer);
- wsh->free_wbuffer = 1;
- }
+ setup_socket(sock);
if (wsh->secure) {
int code;
SSL_free(wsh->ssl);
wsh->ssl = NULL;
}
-
- if (wsh->free_buffer && wsh->buffer) {
- free(wsh->buffer);
- wsh->buffer = NULL;
- }
-
- if (wsh->free_wbuffer && wsh->wbuffer) {
- free(wsh->wbuffer);
- wsh->wbuffer = NULL;
- }
}
issize_t ws_close(wsh_t *wsh, int16_t reason)
ws_raw_write(wsh, fr, 4);
}
+ restore_socket(wsh->sock);
+
if (wsh->close_sock) {
close(wsh->sock);
}
//#define WSS_STANDALONE 1
-#define MAXLEN 0x10000
#define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#define B64BUFFLEN 1024
typedef struct wsh_s {
ws_socket_t sock;
- char *buffer;
- char *wbuffer;
+ char buffer[65536];
+ char wbuffer[65536];
size_t buflen;
issize_t datalen;
issize_t wdatalen;
int handshake;
uint8_t down;
int secure;
- uint8_t free_buffer;
- uint8_t free_wbuffer;
uint8_t close_sock;
} wsh_t;
issize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes);
issize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
issize_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, char *buffer, char *wbuffer, size_t buflen, SSL_CTX *ssl_ctx, int close_sock);
+int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock);
issize_t ws_close(wsh_t *wsh, int16_t reason);
void ws_destroy(wsh_t *wsh);
void init_ssl(void);