diff --git a/autotest/test_hub.tcc b/autotest/test_hub.tcc index 46271e5..138b903 100644 --- a/autotest/test_hub.tcc +++ b/autotest/test_hub.tcc @@ -23,7 +23,7 @@ EXO_TEST(hub_net_startup, { EXO_TEST(hub_config_initialize, { config_defaults(&g_config); - g_config.server_port = 15111; + g_config.server_port = 65111; return 1; }); diff --git a/autotest/test_memory.tcc b/autotest/test_memory.tcc index c2fa3e9..c35936b 100644 --- a/autotest/test_memory.tcc +++ b/autotest/test_memory.tcc @@ -8,27 +8,27 @@ EXO_TEST(test_message_refc_1, { }); EXO_TEST(test_message_refc_2, { - return g_msg->references == 0; // 0 + return g_msg->references == 1; }); EXO_TEST(test_message_refc_3, { adc_msg_incref(g_msg); - return g_msg->references == 1; // 1 + return g_msg->references == 2; }); EXO_TEST(test_message_refc_4, { adc_msg_incref(g_msg); - return g_msg->references == 2; // 2 + return g_msg->references == 3; }); EXO_TEST(test_message_refc_5, { adc_msg_free(g_msg); - return g_msg->references == 1; // 1 + return g_msg->references == 2; }); EXO_TEST(test_message_refc_6, { adc_msg_free(g_msg); - return g_msg->references == 0; // 0 + return g_msg->references == 1; }); EXO_TEST(test_message_refc_7, { diff --git a/src/adc/message.c b/src/adc/message.c index aeb5f8b..7ea5134 100644 --- a/src/adc/message.c +++ b/src/adc/message.c @@ -26,6 +26,7 @@ uhub_assert(X->capacity); \ uhub_assert(X->length); \ uhub_assert(X->length <= X->capacity); \ + uhub_assert(X->references > 0); \ uhub_assert(X->length == strlen(X->cache)); #define ADC_MSG_NULL_ON_FREE #else @@ -65,7 +66,6 @@ static void msg_free(void* ptr) struct adc_message* adc_msg_incref(struct adc_message* msg) { - if (!msg) return 0; #ifndef ADC_MESSAGE_INCREF msg->references++; #ifdef MSG_MEMORY_DEBUG @@ -184,11 +184,9 @@ void adc_msg_free(struct adc_message* msg) ADC_MSG_ASSERT(msg); - if (msg->references > 0) - { - msg->references--; - } - else + msg->references--; + + if (msg->references == 0) { #ifdef ADC_MSG_NULL_ON_FREE if (msg->cache) @@ -233,7 +231,7 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd) copy->length = cmd->length; copy->capacity = 0; copy->priority = cmd->priority; - copy->references = 0; + copy->references = 1; copy->feature_cast_include = 0; copy->feature_cast_exclude = 0; @@ -306,7 +304,7 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) if (command == NULL) return NULL; /* OOM */ - + if (!is_printable_utf8(line, length)) { LOG_DEBUG("Dropped message with non-printable UTF-8 characters."); @@ -324,17 +322,18 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) msg_free(command); return NULL; /* OOM */ } - + adc_msg_set_length(command, length + need_terminate); memcpy(command->cache, line, length); - + /* Ensure we are zero terminated */ command->cache[length] = 0; command->cache[length+need_terminate] = 0; - + command->cmd = FOURCC(line[0], line[1], line[2], line[3]); command->priority = 0; - + command->references = 1; + switch (prefix) { case 'U': @@ -342,12 +341,12 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) /* these should never be seen on a hub */ ok = 0; break; - + case 'I': case 'H': ok = (length > 3); break; - + case 'B': ok = (length > 8 && is_space(line[4]) && @@ -355,18 +354,18 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) is_valid_base32_char(line[6]) && is_valid_base32_char(line[7]) && is_valid_base32_char(line[8])); - + if (!ok) break; - + temp_sid[0] = line[5]; temp_sid[1] = line[6]; temp_sid[2] = line[7]; temp_sid[3] = line[8]; temp_sid[4] = '\0'; - + command->source = string_to_sid(temp_sid); break; - + case 'F': ok = (length > 8 && is_space(line[4]) && @@ -374,21 +373,21 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) is_valid_base32_char(line[6]) && is_valid_base32_char(line[7]) && is_valid_base32_char(line[8])); - + if (!ok) break; - + temp_sid[0] = line[5]; temp_sid[1] = line[6]; temp_sid[2] = line[7]; temp_sid[3] = line[8]; temp_sid[4] = '\0'; - + command->source = string_to_sid(temp_sid); - + /* Create feature cast lists */ command->feature_cast_include = list_create(); command->feature_cast_exclude = list_create(); - + if (!command->feature_cast_include || !command->feature_cast_exclude) { list_destroy(command->feature_cast_include); @@ -397,7 +396,7 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) msg_free(command); return NULL; /* OOM */ } - + n = 10; while (line[n] == '+' || line[n] == '-') { @@ -405,21 +404,20 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) feature_cast_list = command->feature_cast_include; else feature_cast_list = command->feature_cast_exclude; - + temp_sid[0] = line[n++]; temp_sid[1] = line[n++]; temp_sid[2] = line[n++]; temp_sid[3] = line[n++]; temp_sid[4] = '\0'; - + list_append(feature_cast_list, hub_strdup(temp_sid)); } - + if (n == 10) ok = 0; - break; - + case 'D': case 'E': ok = (length > 13 && @@ -433,41 +431,41 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) is_valid_base32_char(line[11]) && is_valid_base32_char(line[12]) && is_valid_base32_char(line[13])); - + if (!ok) break; - + temp_sid[0] = line[5]; temp_sid[1] = line[6]; temp_sid[2] = line[7]; temp_sid[3] = line[8]; temp_sid[4] = '\0'; - + command->source = string_to_sid(temp_sid); - + temp_sid[0] = line[10]; temp_sid[1] = line[11]; temp_sid[2] = line[12]; temp_sid[3] = line[13]; temp_sid[4] = '\0'; - + command->target = string_to_sid(temp_sid); break; - + default: ok = 0; } - + if (need_terminate) { command->cache[length] = '\n'; } - + if (!ok) { adc_msg_free(command); return NULL; } - + /* At this point the arg_offset should point to a space, or the end of message */ n = adc_msg_get_arg_offset(command); if (command->cache[n] == ' ') @@ -476,13 +474,13 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) } else if (command->cache[n] == '\n') ok = 1; else ok = 0; - + if (!ok) { adc_msg_free(command); return NULL; } - + ADC_MSG_ASSERT(command); return command; } @@ -497,7 +495,6 @@ struct adc_message* adc_msg_create(const char* line) struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size) { struct adc_message* msg = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message)); - if (!msg) return NULL; /* OOM */ @@ -508,7 +505,7 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size) msg_free(msg); return NULL; /* OOM */ } - + if (fourcc) { msg->cache[0] = (char) ((fourcc >> 24) & 0xff); @@ -516,15 +513,15 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size) msg->cache[2] = (char) ((fourcc >> 8) & 0xff); msg->cache[3] = (char) ((fourcc ) & 0xff); msg->cache[4] = '\n'; - + /* Ensure we are zero terminated */ adc_msg_set_length(msg, 5); msg->cache[msg->length] = 0; } - + msg->cmd = fourcc; msg->priority = 0; - + msg->references = 1; return msg; } @@ -591,7 +588,7 @@ int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix_[2]) int arg_offset = adc_msg_get_arg_offset(cmd); ADC_MSG_ASSERT(cmd); - + start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3); while (start) { @@ -601,7 +598,7 @@ int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix_[2]) else start = NULL; } - + return count; } @@ -614,25 +611,25 @@ char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix_[2]) size_t length; char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' }; int arg_offset = adc_msg_get_arg_offset(cmd); - + ADC_MSG_ASSERT(cmd); - + start = memmem(&cmd->cache[arg_offset], cmd->length - arg_offset, prefix, 3); if (!start) return NULL; - + start = &start[3]; end = strchr(start, ' '); if (!end) end = &cmd->cache[cmd->length]; length = &end[0] - &start[0]; - + argument = hub_strndup(start, length); if (length > 0 && argument[length-1] == '\n') { argument[length-1] = 0; } - + return argument; } @@ -650,9 +647,9 @@ int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2] { return -1; } - + ADC_MSG_ASSERT(cmd); - + return 0; } @@ -683,9 +680,9 @@ int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], co int ret = 0; if (!string) return -1; - + ADC_MSG_ASSERT(cmd); - + adc_msg_unterminate(cmd); adc_msg_cache_append(cmd, " ", 1); adc_msg_cache_append(cmd, prefix, 2); @@ -719,7 +716,7 @@ int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char prefix int adc_msg_add_argument(struct adc_message* cmd, const char* string) { ADC_MSG_ASSERT(cmd); - + adc_msg_unterminate(cmd); adc_msg_cache_append(cmd, " ", 1); adc_msg_cache_append(cmd, string, strlen(string)); @@ -785,11 +782,11 @@ int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2]) char* start; char* end; int count = 0; - + ADC_MSG_ASSERT(cmd); - + adc_msg_unterminate(cmd); - + start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' '); while (start) { @@ -842,16 +839,13 @@ int adc_msg_unescape_length(const char* str) } - - - char* adc_msg_unescape(const char* string) { char* new_string = msg_malloc(adc_msg_unescape_length(string)+1); char* ptr = (char*) new_string; char* str = (char*) string; int escaped = 0; - + while (*str) { if (escaped) { @@ -863,14 +857,12 @@ char* adc_msg_unescape(const char* string) *ptr++ = '\n'; else *ptr++ = *str; - escaped = 0; } else { if (*str == '\\') escaped = 1; else *ptr++ = *str; - } str++; } diff --git a/src/core/inf.c b/src/core/inf.c index f2229a2..003b4cc 100644 --- a/src/core/inf.c +++ b/src/core/inf.c @@ -1,6 +1,6 @@ /* * uhub - A tiny ADC p2p connection hub - * Copyright (C) 2007-2009, Jan Vidar Krey + * Copyright (C) 2007-2010, Jan Vidar Krey * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +42,7 @@ static void remove_server_restricted_flags(struct adc_message* cmd) static int set_feature_cast_supports(struct hub_user* u, struct adc_message* cmd) { char *it, *tmp; - + if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_SUPPORT)) { tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SUPPORT); @@ -58,7 +58,7 @@ static int set_feature_cast_supports(struct hub_user* u, struct adc_message* cmd user_set_feature_cast_support(u, it); it = &it[5]; } - + if (*it) { user_set_feature_cast_support(u, it); @@ -74,9 +74,9 @@ static int check_hash_tiger(const char* cid, const char* pid) char x_pid[64]; char raw_pid[64]; uint64_t tiger_res[3]; - + memset(x_pid, 0, MAX_CID_LEN+1); - + base32_decode(pid, (unsigned char*) raw_pid, MAX_CID_LEN); tiger((uint64_t*) raw_pid, TIGERSIZE, (uint64_t*) tiger_res); base32_encode((unsigned char*) tiger_res, TIGERSIZE, x_pid); @@ -102,7 +102,7 @@ static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_mes hub_free(pid); return status_msg_error_no_memory; } - + if (strlen(cid) != MAX_CID_LEN) { hub_free(cid); @@ -125,7 +125,7 @@ static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_mes hub_free(pid); return status_msg_inf_error_cid_invalid; } - + if (!is_valid_base32_char(pid[pos])) { hub_free(cid); @@ -415,7 +415,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_ int64_t shared_size = atoll(arg); if (shared_size < 0) shared_size = 0; - + if (user_is_logged_in(user)) { hub->users->shared_size -= user->limits.shared_size; @@ -425,14 +425,14 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_ hub_free(arg); arg = 0; } - + arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES); if (arg) { ssize_t shared_files = atoll(arg); if (shared_files < 0) shared_files = 0; - + if (user_is_logged_in(user)) { hub->users->shared_files -= user->limits.shared_files; @@ -442,7 +442,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_ hub_free(arg); arg = 0; } - + arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL); if (arg) { @@ -497,7 +497,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_ { return status_msg_user_share_size_high; } - + if ((user->limits.hub_count_user > hub_get_max_hubs_user(hub) && hub_get_max_hubs_user(hub)) || (user->limits.hub_count_registered > hub_get_max_hubs_reg(hub) && hub_get_max_hubs_reg(hub)) || (user->limits.hub_count_operator > hub_get_max_hubs_op(hub) && hub_get_max_hubs_op(hub)) || @@ -505,14 +505,14 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_ { return status_msg_user_hub_limit_high; } - + if ((user->limits.hub_count_user < hub_get_min_hubs_user(hub) && hub_get_min_hubs_user(hub)) || (user->limits.hub_count_registered < hub_get_min_hubs_reg(hub) && hub_get_min_hubs_reg(hub)) || (user->limits.hub_count_operator < hub_get_min_hubs_op(hub) && hub_get_min_hubs_op(hub))) { return status_msg_user_hub_limit_low; } - + if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub)) { return status_msg_user_slots_low; @@ -559,11 +559,11 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a case cred_guest: /* Nothing to be added to the info message */ break; - + case cred_user: adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER); break; - + case cred_operator: adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR); break; @@ -571,11 +571,11 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a case cred_super: adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER); break; - + case cred_admin: adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN); break; - + case cred_link: break; } @@ -670,13 +670,12 @@ int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct ad int code = 0; INF_CHECK(hub_perform_login_checks, hub, user, cmd); - + /* Private ID must never be broadcasted - drop it! */ adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID); - - + code = set_credentials(hub, user, cmd); - + /* Note: this must be done *after* set_credentials. */ if (check_is_hub_full(hub, user)) { @@ -785,16 +784,18 @@ int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct ad strip_network(user, cmd); hub_handle_info_low_bandwidth(hub, user, cmd); - + user_update_info(user, cmd); - + if (!adc_msg_is_empty(cmd)) { route_message(hub, user, cmd); } - + adc_msg_free(cmd); } - + return 0; } + + diff --git a/src/core/inf.h b/src/core/inf.h index ed855d8..0ce8ba5 100644 --- a/src/core/inf.h +++ b/src/core/inf.h @@ -1,6 +1,6 @@ /* * uhub - A tiny ADC p2p connection hub - * Copyright (C) 2007-2009, Jan Vidar Krey + * Copyright (C) 2007-2010, Jan Vidar Krey * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/core/netevent.c b/src/core/netevent.c index f903edb..c973bfc 100644 --- a/src/core/netevent.c +++ b/src/core/netevent.c @@ -24,35 +24,6 @@ /* FIXME: This should not be needed! */ extern struct hub_info* g_hub; -#ifdef DEBUG_SENDQ -void debug_sendq_send(struct hub_user* user, int sent, int total) -{ - LOG_DUMP("SEND: sd=%d, %d/%d bytes\n", user->connection->sd, sent, total); - if (sent == -1) - { - int err = net_error(); - LOG_DUMP(" errno: %d - %s\n", err, net_error_string(err)); - } -} - -void debug_sendq_recv(struct hub_user* user, int received, int max, const char* buffer) -{ - LOG_DUMP("RECV: %d/%d bytes\n", received, (int) max); - if (received == -1) - { - int err = net_error(); - LOG_DUMP(" errno: %d - %s\n", err, net_error_string(err)); - } - else if (received > 0) - { - char* data = hub_malloc_zero(received + 1); - memcpy(data, buffer, received); - LOG_DUMP("RECV: \"%s\"\n", data); - hub_free(data); - } -} -#endif - int handle_net_read(struct hub_user* user) { static char buf[MAX_RECV_BUF]; @@ -223,7 +194,7 @@ void net_on_accept(struct net_connection* con, int event, void *arg) } } - addr = ip_convert_to_string(&ipaddr); + addr = ip_convert_to_string(&ipaddr); /* FIXME: Should have a plugin log this */ LOG_TRACE("Got connection from %s", addr); diff --git a/src/core/user.c b/src/core/user.c index a251a50..3b44d19 100644 --- a/src/core/user.c +++ b/src/core/user.c @@ -83,7 +83,14 @@ void user_set_state(struct hub_user* user, enum user_state state) void user_set_info(struct hub_user* user, struct adc_message* cmd) { adc_msg_free(user->info); - user->info = adc_msg_incref(cmd); + if (cmd) + { + user->info = adc_msg_incref(cmd); + } + else + { + user->info = 0; + } } void user_update_info(struct hub_user* u, struct adc_message* cmd) @@ -97,7 +104,7 @@ void user_update_info(struct hub_user* u, struct adc_message* cmd) /* FIXME: OOM! */ return; } - + /* * FIXME: Optimization potential: * diff --git a/src/core/usermanager.c b/src/core/usermanager.c index c391f96..6f7d8ce 100644 --- a/src/core/usermanager.c +++ b/src/core/usermanager.c @@ -155,7 +155,7 @@ int uman_remove(struct hub_info* hub, struct hub_user* user) return -1; list_remove(hub->users->list, user); - + if (hub->users->count > 0) { hub->users->count--; @@ -164,12 +164,12 @@ int uman_remove(struct hub_info* hub, struct hub_user* user) { assert(!"negative count!"); } - + hub->users->shared_size -= user->limits.shared_size; hub->users->shared_files -= user->limits.shared_files; user->hub = 0; - + return 0; } @@ -237,7 +237,7 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user* target) } user = (struct hub_user*) list_get_next(hub->users->list); } - + #if 0 FIXME: FIXME FIXME handle send queue excess if (!target->send_queue_size) @@ -248,12 +248,11 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user* target) return ret; } - void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving) { struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6); adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid)); - + if (leaving->quit_reason == quit_banned || leaving->quit_reason == quit_kicked) { adc_msg_add_argument(command, ADC_QUI_FLAG_DISCONNECT); @@ -262,7 +261,6 @@ void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving) adc_msg_free(command); } - sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user) { sid_t sid = sid_alloc(hub->users->sids, user);