From 58e2982675c0897bcc674e1fbd29a02346aea06a Mon Sep 17 00:00:00 2001 From: Jan Vidar Krey Date: Mon, 16 Mar 2009 12:28:58 +0100 Subject: [PATCH] Fixed bug #1: Excessive send queue bug (corruption of the offset variable). Low priority messages are not relayed if soft limit send queue is reached. Signed-off-by: Jan Vidar Krey --- src/hub.c | 14 ++++++++------ src/inf.c | 4 +++- src/netevent.c | 12 +++++++----- src/route.c | 24 +++++++++++++++++++----- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/hub.c b/src/hub.c index bb0805e..18e1ce0 100644 --- a/src/hub.c +++ b/src/hub.c @@ -50,6 +50,13 @@ int hub_handle_message(struct user* u, const char* line, size_t length) so we ignore them. */ break; + case ADC_CMD_EMSG: + case ADC_CMD_DMSG: + case ADC_CMD_BMSG: + case ADC_CMD_FMSG: + ret = hub_handle_chat_message(u, cmd); + break; + case ADC_CMD_BSCH: case ADC_CMD_DSCH: case ADC_CMD_ESCH: @@ -57,18 +64,13 @@ int hub_handle_message(struct user* u, const char* line, size_t length) case ADC_CMD_DRES: case ADC_CMD_DRCM: case ADC_CMD_DCTM: + cmd->priority = -1; if (u->hub->config->chat_only && u->credentials < cred_operator) { /* These below aren't allowed in chat only hubs */ break; } - case ADC_CMD_EMSG: - case ADC_CMD_DMSG: - case ADC_CMD_BMSG: - case ADC_CMD_FMSG: - ret = hub_handle_chat_message(u, cmd); break; - default: if (user_is_logged_in(u)) { diff --git a/src/inf.c b/src/inf.c index b680678..bceda9e 100644 --- a/src/inf.c +++ b/src/inf.c @@ -768,7 +768,9 @@ int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified) { struct adc_message* cmd = adc_msg_copy(cmd_unmodified); /* FIXME: Have a small memory leak here! */ if (!cmd) return -1; /* OOM */ - + + cmd->priority = 1; + hub_handle_info_common(user, cmd); /* If user is logging in, perform more checks, diff --git a/src/netevent.c b/src/netevent.c index 704a8a6..58d4713 100644 --- a/src/netevent.c +++ b/src/netevent.c @@ -147,7 +147,6 @@ void net_on_read(int fd, short ev, void *arg) } } -#define DEBUG_SENDQ void net_on_write(int fd, short ev, void *arg) { @@ -176,15 +175,17 @@ void net_on_write(int fd, short ev, void *arg) if (ret == length) { #ifdef DEBUG_SENDQ - hub_log(log_error, "SENDQ: sent=%d bytes/%d (all), send_queue_size=%d, offset=%d\n", ret, (int) msg->length, user->send_queue_size, user->send_queue_offset); + hub_log(log_error, "SENDQ: sent=%d bytes/%d (all), send_queue_size=%d, offset=%d", ret, (int) msg->length, user->send_queue_size, user->send_queue_offset); #endif user->send_queue_size -= ret; user->send_queue_offset = 0; - + +#ifdef DEBUG_SENDQ if ((user->send_queue_size < 0) || (user->send_queue_offset < 0)) { hub_log(log_error, "INVALID: send_queue_size=%d, send_queue_offset=%d", user->send_queue_size, user->send_queue_offset); } +#endif DEBUG_SENDQ list_remove(user->send_queue, msg); @@ -202,16 +203,17 @@ void net_on_write(int fd, short ev, void *arg) else { #ifdef DEBUG_SENDQ - hub_log(log_error, "SENDQ: sent=%d bytes/%d (part), send_queue_size=%d, offset=%d\n", ret, (int) msg->length, user->send_queue_size, user->send_queue_offset); + hub_log(log_error, "SENDQ: sent=%d bytes/%d (part), send_queue_size=%d, offset=%d", ret, (int) msg->length, user->send_queue_size, user->send_queue_offset); #endif - user->send_queue_size -= ret; user->send_queue_offset += ret; +#ifdef DEBUG_SENDQ if ((user->send_queue_size < 0) || (user->send_queue_offset < 0) || (user->send_queue_offset > msg->length)) { hub_log(log_error, "INVALID: send_queue_size=%d, send_queue_offset=%d", user->send_queue_size, user->send_queue_offset); } +#endif break; } } diff --git a/src/route.c b/src/route.c index b0f34c1..c7356b4 100644 --- a/src/route.c +++ b/src/route.c @@ -63,8 +63,10 @@ static void queue_command(struct user* user, struct adc_message* msg__, int offs { struct adc_message* msg = adc_msg_incref(msg__); list_append(user->send_queue, msg); - - hub_log(log_trace, "queue_command(), user=%p, msg=%p (%zu), offset=%d", user, msg, msg->references, offset); + +#ifdef DEBUG_SENDQ + hub_log(log_trace, "SENDQ: user=%p, msg=%p (%zu), offset=%d, length=%d, total_length=%d", user, msg, msg->references, offset, msg->length, user->send_queue_size); +#endif if (offset > 0) { @@ -75,16 +77,25 @@ static void queue_command(struct user* user, struct adc_message* msg__, int offs else { user->send_queue_size += msg->length; - user->send_queue_offset = 0; } } // #define ALWAYS_QUEUE_MESSAGES static size_t get_max_send_queue(struct hub_info* hub) { - return MAX(hub->config->max_send_buffer, (hub->config->max_recv_buffer * hub_get_user_count(hub))); + /* TODO: More dynamic send queue limit, for instance: + * return MAX(hub->config->max_send_buffer, (hub->config->max_recv_buffer * hub_get_user_count(hub))); + */ + return hub->config->max_send_buffer; } +static size_t get_max_send_queue_soft(struct hub_info* hub) +{ + return hub->config->max_send_buffer_soft; +} + + + /* * @return 1 if send queue is OK. * -1 if send queue is overflowed @@ -97,7 +108,10 @@ static int check_send_queue(struct user* user, struct adc_message* msg) if ((user->send_queue_size + msg->length) > get_max_send_queue(user->hub)) return -1; - + + if (user->send_queue_size > get_max_send_queue_soft(user->hub) && msg->priority < 0) + return 0; + return 1; }