From 4e334b95bd63e53553a53307ab5c1dc044c15008 Mon Sep 17 00:00:00 2001 From: catwood Date: Wed, 7 May 2014 16:58:04 -0400 Subject: [PATCH 1/8] Use monotonic clock to avoid issues with clock time changes --- Makefile | 2 +- src/sock.c | 28 +++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index a6384009..59418613 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ bindir = $(prefix)/bin SRC=src/entry.c src/sock.c src/hash.c src/handle_http.c src/cmd.c src/users.c src/channel.c src/config.c src/json.c src/json_parser.c src/plugins.c src/http.c src/extend.c src/utils.c src/ticks.c src/base64.c src/pipe.c src/raw.c src/events.c src/event_kqueue.c src/event_epoll.c src/event_select.c src/transports.c src/servers.c src/dns.c src/sha1.c src/log.c src/parser.c src/md5.c CFLAGS = -Wall -g -minline-all-stringops -rdynamic -I ./deps/udns-0.0.9/ -LFLAGS=-ldl -lm -lpthread +LFLAGS=-ldl -lm -lpthread -lrt CC=gcc -D_GNU_SOURCE RM=rm -f diff --git a/src/sock.c b/src/sock.c index 2693c5ac..16707399 100644 --- a/src/sock.c +++ b/src/sock.c @@ -273,7 +273,7 @@ unsigned int sockroutine(acetables *g_ape) int new_fd, nfds, sin_size = sizeof(struct sockaddr_in), i, tfd = 0; - struct timeval t_start, t_end; + struct timespec t_start, t_end; long int ticks = 0, uticks = 0, lticks = 0; struct sockaddr_in their_addr; @@ -283,7 +283,13 @@ unsigned int sockroutine(acetables *g_ape) #if 0 add_periodical(5, 0, check_idle, &sl, g_ape); #endif - gettimeofday(&t_start, NULL); + if (clock_gettime(CLOCK_MONOTONIC, &t_start) < 0) + { + ape_log(APE_ERR, __FILE__, __LINE__, g_ape, + "clock_gettime(CLOCK_MONOTONIC) : %s", strerror(errno)); + return 1; + } + while (server_is_running) { /* Linux 2.6.25 provides a fd-driven timer system. It could be usefull to implement */ int timeout_to_hang = get_first_timer_ms(g_ape); @@ -495,12 +501,24 @@ unsigned int sockroutine(acetables *g_ape) } } - gettimeofday(&t_end, NULL); + if (clock_gettime(CLOCK_MONOTONIC, &t_end) < 0) + { + ape_log(APE_ERR, __FILE__, __LINE__, g_ape, + "clock_gettime(CLOCK_MONOTONIC) : %s", strerror(errno)); + return 1; + } ticks = 0; - uticks = 1000000L * (t_end.tv_sec - t_start.tv_sec); - uticks += (t_end.tv_usec - t_start.tv_usec); + if (t_end.tv_sec >= t_start.tv_sec) + { + uticks = 1000000L * (t_end.tv_sec - t_start.tv_sec); + uticks += ((t_end.tv_nsec - t_start.tv_nsec) / 1000); + } else { + ape_log(APE_ERR, __FILE__, __LINE__, g_ape, + "end time less than start time (start:%ld, end:%ld)", t_start.tv_sec, t_end.tv_sec); + uticks = 1000; // a total hack, but probably better than 0 + } t_start = t_end; lticks += uticks; /* Tic tac, tic tac */ From 4ae96e19a51cb95c2dd884765d3d6163fa9d42a3 Mon Sep 17 00:00:00 2001 From: catwood Date: Wed, 7 May 2014 17:24:33 -0400 Subject: [PATCH 2/8] Replace some pointers with NULL after heap freed --- modules/libape-spidermonkey.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/libape-spidermonkey.c b/modules/libape-spidermonkey.c index e2510cc9..c6408007 100644 --- a/modules/libape-spidermonkey.c +++ b/modules/libape-spidermonkey.c @@ -1377,6 +1377,7 @@ static void sm_sock_ondisconnect(ape_socket *client, acetables *g_ape) free(cb->private); free(cb); + client->attach = NULL; //JS_EndRequest(cb->asc->cx); //JS_ClearContextThread(cb->asc->cx); @@ -2470,7 +2471,7 @@ APE_JS_NATIVE(ape_sm_echo) if (!g_ape->is_daemon) { fwrite(cstring, sizeof(char), JS_GetStringEncodingLength(cx, string), stdout); - //fwrite("\n", sizeof(char), 1, stdout); + fwrite("\n", sizeof(char), 1, stdout); } else { ape_log(APE_INFO, __FILE__, __LINE__, g_ape, "JavaScript : %s", cstring); @@ -2635,6 +2636,7 @@ static void mysac_setdb_success(struct _ape_mysql_data *myhandle, int code) /* TODO : Supress queue */ free(myhandle->db); + myhandle->db = NULL; } } @@ -2663,6 +2665,7 @@ static void mysac_connect_success(struct _ape_mysql_data *myhandle, int code) myhandle->on_success = NULL; free(myhandle->db); + myhandle->db = NULL; } } @@ -2723,6 +2726,7 @@ static void mysac_query_success(struct _ape_mysql_data *myhandle, int code) JS_free(myhandle->cx, queue->query); free(queue->res); free(queue); + myhandle->data = NULL; apemysql_shift_queue(myhandle); } @@ -3226,7 +3230,7 @@ static void init_module(acetables *g_ape) // Called when module is loaded rt = JS_NewRuntime(8L * 1024L * 1024L); if (rt == NULL) { - printf("[ERR] Not enougth memory\n"); + printf("[ERR] Not enough memory\n"); exit(0); } asr = xmalloc(sizeof(*asr)); From 58923d5c14a80e74ed499737b0a6033a9c972e39 Mon Sep 17 00:00:00 2001 From: catwood Date: Wed, 7 May 2014 17:28:37 -0400 Subject: [PATCH 3/8] Use safe_shutdown vs shutdown --- src/http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http.c b/src/http.c index 36f9f624..18be0c4f 100644 --- a/src/http.c +++ b/src/http.c @@ -389,7 +389,7 @@ void process_websocket(ape_socket *co, acetables *g_ape) } if (buffer->length > 502400) { - shutdown(co->fd, 2); + safe_shutdown(co->fd, g_ape); return; } From ea653eaa2e3cf0ef72863a14c20acbc2095b878e Mon Sep 17 00:00:00 2001 From: catwood Date: Wed, 7 May 2014 17:31:54 -0400 Subject: [PATCH 4/8] Add missing urldecode of JSON string values --- src/json_parser.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/json_parser.c b/src/json_parser.c index 788ad5ad..4a82b8fe 100755 --- a/src/json_parser.c +++ b/src/json_parser.c @@ -77,6 +77,7 @@ SOFTWARE. #include #include "json_parser.h" +#include "utils.h" #ifdef _MSC_VER # if _MSC_VER >= 1400 /* Visual Studio 2005 and up */ @@ -624,8 +625,9 @@ static int parse_parse_buffer(JSON_parser jc) break; case JSON_T_STRING: arg = &value; + urldecode(jc->parse_buffer); value.vu.str.value = jc->parse_buffer; - value.vu.str.length = jc->parse_buffer_count; + value.vu.str.length = strlen(jc->parse_buffer); break; } @@ -1037,8 +1039,9 @@ JSON_parser_char(JSON_parser jc, int next_char) if (jc->callback) { JSON_value value; + urldecode(jc->parse_buffer); value.vu.str.value = jc->parse_buffer; - value.vu.str.length = jc->parse_buffer_count; + value.vu.str.length = strlen(jc->parse_buffer); if (!(*jc->callback)(jc->ctx, JSON_T_KEY, &value)) { return false; } From c65f94cc5e6bf315751361bbfde15da349c4467b Mon Sep 17 00:00:00 2001 From: catwood Date: Thu, 2 Oct 2014 17:02:50 -0400 Subject: [PATCH 5/8] Prevent NULL pointer fault in ape_connect_name_cb when name cannot be resolved to an IP address. --- src/sock.c | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/sock.c b/src/sock.c index 03f27bab..69f01212 100644 --- a/src/sock.c +++ b/src/sock.c @@ -161,20 +161,21 @@ static void ape_connect_name_cb(char *ip, void *data, acetables *g_ape) struct _ape_sock_connect_async *asca = data; ape_socket *sock; - if ((sock = ape_connect(ip, asca->port, g_ape)) != NULL) { - - sock->attach = asca->sock->attach; - - sock->callbacks.on_accept = asca->sock->callbacks.on_accept; - sock->callbacks.on_connect = asca->sock->callbacks.on_connect; - sock->callbacks.on_disconnect = asca->sock->callbacks.on_disconnect; - sock->callbacks.on_read = asca->sock->callbacks.on_read; - sock->callbacks.on_read_lf = asca->sock->callbacks.on_read_lf; - sock->callbacks.on_data_completly_sent = asca->sock->callbacks.on_data_completly_sent; - sock->callbacks.on_write = asca->sock->callbacks.on_write; + if (ip != NULL) { + if ((sock = ape_connect(ip, asca->port, g_ape)) != NULL) { + + sock->attach = asca->sock->attach; + + sock->callbacks.on_accept = asca->sock->callbacks.on_accept; + sock->callbacks.on_connect = asca->sock->callbacks.on_connect; + sock->callbacks.on_disconnect = asca->sock->callbacks.on_disconnect; + sock->callbacks.on_read = asca->sock->callbacks.on_read; + sock->callbacks.on_read_lf = asca->sock->callbacks.on_read_lf; + sock->callbacks.on_data_completly_sent = asca->sock->callbacks.on_data_completly_sent; + sock->callbacks.on_write = asca->sock->callbacks.on_write; + } + free(ip); } - - free(ip); free(asca->sock); free(asca); @@ -211,6 +212,27 @@ void close_socket(int fd, acetables *g_ape) ape_socket *co = g_ape->co[fd]; if (g_ape->bufout[fd].buf != NULL) { +subuser *sub = (subuser *)(co->attach); +if (co->stream_type == STREAM_IN) { + if (sub != NULL) { + if (sub->user != NULL) { + if (sub->user->pipe != NULL) { + printf("FYI: Buffered data (%i bytes) discarded due to close of socket %i for user pubid %s\n", + g_ape->bufout[fd].buflen, fd, sub->user->pipe->pubid); + } else { + sub = NULL; + } + } else { + sub = NULL; + } + } +} else { + sub = NULL; +} +if (sub == NULL) { + printf("FYI: Buffered data (%i bytes) discarded due to close of socket %i\n", + g_ape->bufout[fd].buflen, fd); +} free(g_ape->bufout[fd].buf); g_ape->bufout[fd].buflen = 0; g_ape->bufout[fd].buf = NULL; From 108ee18ce2d719b954d80babad61dae2aa464750 Mon Sep 17 00:00:00 2001 From: catwood Date: Thu, 2 Oct 2014 17:25:49 -0400 Subject: [PATCH 6/8] Remove some accidentally-committed debug code --- src/sock.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/sock.c b/src/sock.c index 69f01212..044beaee 100644 --- a/src/sock.c +++ b/src/sock.c @@ -212,27 +212,6 @@ void close_socket(int fd, acetables *g_ape) ape_socket *co = g_ape->co[fd]; if (g_ape->bufout[fd].buf != NULL) { -subuser *sub = (subuser *)(co->attach); -if (co->stream_type == STREAM_IN) { - if (sub != NULL) { - if (sub->user != NULL) { - if (sub->user->pipe != NULL) { - printf("FYI: Buffered data (%i bytes) discarded due to close of socket %i for user pubid %s\n", - g_ape->bufout[fd].buflen, fd, sub->user->pipe->pubid); - } else { - sub = NULL; - } - } else { - sub = NULL; - } - } -} else { - sub = NULL; -} -if (sub == NULL) { - printf("FYI: Buffered data (%i bytes) discarded due to close of socket %i\n", - g_ape->bufout[fd].buflen, fd); -} free(g_ape->bufout[fd].buf); g_ape->bufout[fd].buflen = 0; g_ape->bufout[fd].buf = NULL; From aae705153b114697cfda42775b7c6b4300394d01 Mon Sep 17 00:00:00 2001 From: catwood Date: Fri, 3 Oct 2014 15:50:54 -0400 Subject: [PATCH 7/8] Back out the last two commits to do over again the right way --- src/sock.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/sock.c b/src/sock.c index 044beaee..03f27bab 100644 --- a/src/sock.c +++ b/src/sock.c @@ -161,21 +161,20 @@ static void ape_connect_name_cb(char *ip, void *data, acetables *g_ape) struct _ape_sock_connect_async *asca = data; ape_socket *sock; - if (ip != NULL) { - if ((sock = ape_connect(ip, asca->port, g_ape)) != NULL) { - - sock->attach = asca->sock->attach; - - sock->callbacks.on_accept = asca->sock->callbacks.on_accept; - sock->callbacks.on_connect = asca->sock->callbacks.on_connect; - sock->callbacks.on_disconnect = asca->sock->callbacks.on_disconnect; - sock->callbacks.on_read = asca->sock->callbacks.on_read; - sock->callbacks.on_read_lf = asca->sock->callbacks.on_read_lf; - sock->callbacks.on_data_completly_sent = asca->sock->callbacks.on_data_completly_sent; - sock->callbacks.on_write = asca->sock->callbacks.on_write; - } - free(ip); + if ((sock = ape_connect(ip, asca->port, g_ape)) != NULL) { + + sock->attach = asca->sock->attach; + + sock->callbacks.on_accept = asca->sock->callbacks.on_accept; + sock->callbacks.on_connect = asca->sock->callbacks.on_connect; + sock->callbacks.on_disconnect = asca->sock->callbacks.on_disconnect; + sock->callbacks.on_read = asca->sock->callbacks.on_read; + sock->callbacks.on_read_lf = asca->sock->callbacks.on_read_lf; + sock->callbacks.on_data_completly_sent = asca->sock->callbacks.on_data_completly_sent; + sock->callbacks.on_write = asca->sock->callbacks.on_write; } + + free(ip); free(asca->sock); free(asca); From 3a53e9d370f0c01cc6dc0f52d6d9b733a2250162 Mon Sep 17 00:00:00 2001 From: catwood Date: Fri, 3 Oct 2014 17:34:12 -0400 Subject: [PATCH 8/8] Prevent NULL pointer fault when domain name cannot be resolved into an IP address --- src/sock.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sock.c b/src/sock.c index 03f27bab..58cf7eec 100644 --- a/src/sock.c +++ b/src/sock.c @@ -161,20 +161,22 @@ static void ape_connect_name_cb(char *ip, void *data, acetables *g_ape) struct _ape_sock_connect_async *asca = data; ape_socket *sock; - if ((sock = ape_connect(ip, asca->port, g_ape)) != NULL) { - - sock->attach = asca->sock->attach; - - sock->callbacks.on_accept = asca->sock->callbacks.on_accept; - sock->callbacks.on_connect = asca->sock->callbacks.on_connect; - sock->callbacks.on_disconnect = asca->sock->callbacks.on_disconnect; - sock->callbacks.on_read = asca->sock->callbacks.on_read; - sock->callbacks.on_read_lf = asca->sock->callbacks.on_read_lf; - sock->callbacks.on_data_completly_sent = asca->sock->callbacks.on_data_completly_sent; - sock->callbacks.on_write = asca->sock->callbacks.on_write; + if (ip != NULL) { + if ((sock = ape_connect(ip, asca->port, g_ape)) != NULL) { + + sock->attach = asca->sock->attach; + + sock->callbacks.on_accept = asca->sock->callbacks.on_accept; + sock->callbacks.on_connect = asca->sock->callbacks.on_connect; + sock->callbacks.on_disconnect = asca->sock->callbacks.on_disconnect; + sock->callbacks.on_read = asca->sock->callbacks.on_read; + sock->callbacks.on_read_lf = asca->sock->callbacks.on_read_lf; + sock->callbacks.on_data_completly_sent = asca->sock->callbacks.on_data_completly_sent; + sock->callbacks.on_write = asca->sock->callbacks.on_write; + } + + free(ip); } - - free(ip); free(asca->sock); free(asca);