From 94f3b90040d1f9a6e8b95a70cfdee3b0ae04e77f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 8 Jul 2013 08:25:34 -0500 Subject: [PATCH] use static buffer and nonblocking socket in websocket client --- libs/sofia-sip/.update | 2 +- .../libsofia-sip-ua/tport/tport_type_ws.c | 6 +- libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 104 +++++++++++------- libs/sofia-sip/libsofia-sip-ua/tport/ws.h | 9 +- 4 files changed, 70 insertions(+), 51 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 8024eeba38..c36486c61a 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Fri Jun 28 10:39:50 CDT 2013 +Wed Jul 3 11:09:02 CDT 2013 diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c index 8b7ecfaa7b..22c56ef07f 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c @@ -432,7 +432,6 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted, 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; @@ -458,10 +457,7 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted, 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; } diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index 6ee35e54a3..7e36b6e00d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -1,5 +1,10 @@ #include "ws.h" #include + +#ifndef _MSC_VER +#include +#endif + #define SHA1_HASH_SIZE 20 struct globals_s globals; @@ -316,16 +321,16 @@ issize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes) 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; } @@ -352,7 +357,54 @@ issize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) 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; @@ -365,28 +417,10 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, char *buffer, char *wbuffer, size_t bu 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; @@ -464,16 +498,6 @@ void ws_destroy(wsh_t *wsh) 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) @@ -494,6 +518,8 @@ 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); } diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h index 84aa46fceb..81368158b3 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h @@ -3,7 +3,6 @@ //#define WSS_STANDALONE 1 -#define MAXLEN 0x10000 #define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" #define B64BUFFLEN 1024 @@ -59,8 +58,8 @@ typedef enum { 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; @@ -71,8 +70,6 @@ typedef struct wsh_s { int handshake; uint8_t down; int secure; - uint8_t free_buffer; - uint8_t free_wbuffer; uint8_t close_sock; } wsh_t; @@ -84,7 +81,7 @@ issize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes); 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);