Compare commits

...

17 Commits

Author SHA1 Message Date
Jan Vidar Krey
8e579f4601 Fix #123: accept() fails if IP is banned. 2010-04-05 13:44:17 +02:00
Jan Vidar Krey
e220357176 Added configuration option to enable support for obsolete pre-ADC/1.0 clients. 2010-04-05 13:43:28 +02:00
Jan Vidar Krey
8bed952022 Fixed nasty hub freeze caused by timers being injected for the same timestamp as it is being removed from. 2010-03-23 01:06:04 +01:00
Jan Vidar Krey
c4604a7e94 Make code clearer. 2010-03-23 00:46:25 +01:00
Jan Vidar Krey
236daeae53 Assert if inserting an invalid timer. 2010-03-15 22:59:16 +01:00
Jan Vidar Krey
862c6a1baf Reduce timeout queue window size. 2010-03-13 00:16:15 +01:00
Jan Vidar Krey
198d86a1ee Added some automatic tests for the timeout handling. 2010-02-25 17:57:50 +01:00
Jan Vidar Krey
2ded9f3e09 Make the revision file if it does not exist. 2010-02-25 16:38:05 +01:00
Jan Vidar Krey
59ed268f4d Added test cases for sid allocation.
This revealed a few bugs:
* when sid allocator is full, then uhub will loop indefinitely when allocating one more (unlikely to occur).
* looking up a user object based on a sid that is out of range (off by one) returns invalid memory.
2010-02-18 16:02:13 +01:00
Jan Vidar Krey
963416ad73 Cleanup reference adc message reference counting somewhat. 2010-02-16 20:51:10 +01:00
Jan Vidar Krey
29c162727c Added lots of new asserts which should trigger in case we double delete a ADC message. 2010-02-15 19:03:19 +01:00
Jan Vidar Krey
1ce258bccf Tidy up the certificate loading code somewhat. 2010-02-15 19:02:31 +01:00
Jan Vidar Krey
0de66286fa Partially fix bug #117 - tls_require ignored entirely in 0.3.0 released
If tls_require is enabled then the hub will simply close the connection if a
user connects without TLS.
In the future we should redirect the user either to another server or to the adcs server.
2010-02-15 19:00:48 +01:00
Jan Vidar Krey
1a98bb6810 Added optional include of local makefile. 2010-02-15 18:56:23 +01:00
Jan Vidar Krey
5e6879dffb Fix for partial read operations. 2010-02-12 20:33:17 +01:00
Jan Vidar Krey
1b56adb8c0 Fix wrong IQUI message. Partially fixes bug #4. 2010-02-12 19:25:09 +01:00
Jan Vidar Krey
685597c795 Make sure we delete the revision.h files when updating.
Also, only use annotated tags for git revision numbers.
2010-02-11 09:16:30 +01:00
23 changed files with 546 additions and 255 deletions

View File

@@ -3,6 +3,8 @@
## Copyright (C) 2007-2010, Jan Vidar Krey <janvidar@extatic.org> ## Copyright (C) 2007-2010, Jan Vidar Krey <janvidar@extatic.org>
# #
-include Makefile.private
CC = gcc CC = gcc
LD := $(CC) LD := $(CC)
MV := mv MV := mv
@@ -116,7 +118,7 @@ CFLAGS += -DSSL_SUPPORT
LDLIBS += -lssl LDLIBS += -lssl
endif endif
GIT_VERSION=$(shell git describe 2>/dev/null || echo "") GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "") GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"") OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"")
@@ -165,16 +167,18 @@ adcrush_SOURCES := src/tools/adcrush.c
admin_SOURCES := src/tools/admin.c admin_SOURCES := src/tools/admin.c
autotest_SOURCES := \ autotest_SOURCES := \
autotest/test_message.tcc \ autotest/test_eventqueue.tcc \
autotest/test_hub.tcc \
autotest/test_inf.tcc \
autotest/test_ipfilter.tcc \
autotest/test_list.tcc \ autotest/test_list.tcc \
autotest/test_memory.tcc \ autotest/test_memory.tcc \
autotest/test_ipfilter.tcc \ autotest/test_message.tcc \
autotest/test_inf.tcc \
autotest/test_hub.tcc \
autotest/test_misc.tcc \ autotest/test_misc.tcc \
autotest/test_sid.tcc \
autotest/test_tiger.tcc \ autotest/test_tiger.tcc \
autotest/test_usermanager.tcc \ autotest/test_timer.tcc \
autotest/test_eventqueue.tcc autotest/test_usermanager.tcc
autotest_OBJECTS = autotest.o autotest_OBJECTS = autotest.o
@@ -222,7 +226,8 @@ revision.h.tmp:
version.h: revision.h version.h: revision.h
revision.h: revision.h.tmp revision.h: revision.h.tmp
@if [ '$(GIT_REVISION)' != '$(OLD_REVISION)' ]; then cat $@.tmp > $@; fi @if [ '$(GIT_REVISION)' != '$(OLD_REVISION)' ]; then cp $@.tmp $@; fi
@if [ ! -f $@ ]; then cp $@.tmp $@; fi
$(autotest_OBJECTS): autotest.c $(autotest_OBJECTS): autotest.c
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $< $(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
@@ -251,7 +256,7 @@ dist-clean:
@rm -rf $(all_OBJECTS) *~ core @rm -rf $(all_OBJECTS) *~ core
clean: clean:
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) autotest.c && \ @rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) autotest.c revision.h revision.h.tmp && \
echo $(MSG_CLEAN) echo $(MSG_CLEAN)

View File

@@ -23,7 +23,7 @@ EXO_TEST(hub_net_startup, {
EXO_TEST(hub_config_initialize, { EXO_TEST(hub_config_initialize, {
config_defaults(&g_config); config_defaults(&g_config);
g_config.server_port = 15111; g_config.server_port = 65111;
return 1; return 1;
}); });

View File

@@ -8,27 +8,27 @@ EXO_TEST(test_message_refc_1, {
}); });
EXO_TEST(test_message_refc_2, { EXO_TEST(test_message_refc_2, {
return g_msg->references == 0; // 0 return g_msg->references == 1;
}); });
EXO_TEST(test_message_refc_3, { EXO_TEST(test_message_refc_3, {
adc_msg_incref(g_msg); adc_msg_incref(g_msg);
return g_msg->references == 1; // 1 return g_msg->references == 2;
}); });
EXO_TEST(test_message_refc_4, { EXO_TEST(test_message_refc_4, {
adc_msg_incref(g_msg); adc_msg_incref(g_msg);
return g_msg->references == 2; // 2 return g_msg->references == 3;
}); });
EXO_TEST(test_message_refc_5, { EXO_TEST(test_message_refc_5, {
adc_msg_free(g_msg); adc_msg_free(g_msg);
return g_msg->references == 1; // 1 return g_msg->references == 2;
}); });
EXO_TEST(test_message_refc_6, { EXO_TEST(test_message_refc_6, {
adc_msg_free(g_msg); adc_msg_free(g_msg);
return g_msg->references == 0; // 0 return g_msg->references == 1;
}); });
EXO_TEST(test_message_refc_7, { EXO_TEST(test_message_refc_7, {

138
autotest/test_sid.tcc Normal file
View File

@@ -0,0 +1,138 @@
#include <uhub.h>
static struct sid_pool* sid_pool = 0;
struct dummy_user
{
sid_t sid;
};
static struct dummy_user* last = 0;
sid_t last_sid = 0;
EXO_TEST(sid_create_pool, {
sid_pool = sid_pool_create(4);
return sid_pool != 0;
});
EXO_TEST(sid_check_0a, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 0);
return user == 0;
});
EXO_TEST(sid_check_0b, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 5);
return user == 0;
});
EXO_TEST(sid_alloc_1, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last = user;
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_1a, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last == user;
});
EXO_TEST(sid_check_1b, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid+1);
return user == 0;
});
EXO_TEST(sid_alloc_2, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_2, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last != user;
});
EXO_TEST(sid_alloc_3, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_3, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last != user;
});
EXO_TEST(sid_alloc_4, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_4, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last != user;
});
EXO_TEST(sid_alloc_5, {
struct dummy_user user;
sid_t sid;
sid = sid_alloc(sid_pool, (struct hub_user*) &user);
return sid == 0;
});
EXO_TEST(sid_check_6, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 0);
return user == 0;
});
EXO_TEST(sid_list_all_1, {
sid_t s;
size_t n = 0;
int ok = 1;
for (s = last->sid; s <= last_sid; s++)
{
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, s);
if (s != (user ? user->sid : -1))
{
ok = 0;
break;
}
n++;
}
return ok && n == 4;
});
#define FREE_SID(N) \
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, N); \
sid_free(sid_pool, N); \
hub_free(user); \
return sid_lookup(sid_pool, N) == NULL;
EXO_TEST(sid_remove_1, {
FREE_SID(2);
});
EXO_TEST(sid_remove_2, {
FREE_SID(1);
});
EXO_TEST(sid_remove_3, {
FREE_SID(4);
});
EXO_TEST(sid_remove_4, {
FREE_SID(3);
});
EXO_TEST(sid_destroy_pool, {
sid_pool_destroy(sid_pool);
sid_pool = 0;
return sid_pool == 0;
});

119
autotest/test_timer.tcc Normal file
View File

@@ -0,0 +1,119 @@
#include <uhub.h>
#define MAX_EVENTS 15
static struct timeout_queue* g_queue;
static time_t g_now;
static size_t g_max;
static struct timeout_evt g_events[MAX_EVENTS];
static size_t g_triggered;
static void timeout_cb(struct timeout_evt* t)
{
g_triggered++;
}
/*
typedef void (*timeout_evt_cb)(struct timeout_evt*);
struct timeout_evt
{
time_t timestamp;
timeout_evt_cb callback;
void* ptr;
struct timeout_evt* prev;
struct timeout_evt* next;
};
void timeout_evt_initialize(struct timeout_evt*, timeout_evt_cb, void* ptr);
void timeout_evt_reset(struct timeout_evt*);
int timeout_evt_is_scheduled(struct timeout_evt*);
struct timeout_queue
{
time_t last;
size_t max;
struct timeout_evt** events;
};
void timeout_queue_initialize(struct timeout_queue*, time_t now, size_t max);
void timeout_queue_shutdown(struct timeout_queue*);
size_t timeout_queue_process(struct timeout_queue*, time_t now);
void timeout_queue_insert(struct timeout_queue*, struct timeout_evt*, size_t seconds);
void timeout_queue_remove(struct timeout_queue*, struct timeout_evt*);
void timeout_queue_reschedule(struct timeout_queue*, struct timeout_evt*, size_t seconds);
size_t timeout_queue_get_next_timeout(struct timeout_queue*, time_t now);
*/
EXO_TEST(timer_setup,{
size_t n;
g_queue = hub_malloc_zero(sizeof(struct timeout_queue));
g_now = 0;
g_max = 5;
g_triggered = 0;
timeout_queue_initialize(g_queue, g_now, g_max);
memset(g_events, 0, sizeof(g_events));
for (n = 0; n < MAX_EVENTS; n++)
{
timeout_evt_initialize(&g_events[n], timeout_cb, &g_events[n]);
}
return g_queue != NULL;
});
EXO_TEST(timer_check_timeout_0,{
return timeout_queue_get_next_timeout(g_queue, g_now) == g_max;
});
EXO_TEST(timer_add_event_1,{
timeout_queue_insert(g_queue, &g_events[0], 2);
return g_events[0].prev != NULL;
});
EXO_TEST(timer_check_timeout_1,{
return timeout_queue_get_next_timeout(g_queue, g_now) == 2;
});
EXO_TEST(timer_remove_event_1,{
timeout_queue_remove(g_queue, &g_events[0]);
return g_events[0].prev == NULL;
});
EXO_TEST(timer_check_timeout_2,{
return timeout_queue_get_next_timeout(g_queue, g_now) == g_max;
});
/* test re-removing an event - should not crash! */
EXO_TEST(timer_remove_event_1_no_crash,{
timeout_queue_remove(g_queue, &g_events[0]);
return g_events[0].prev == NULL;
});
EXO_TEST(timer_add_5_events_1,{
timeout_queue_insert(g_queue, &g_events[0], 0);
timeout_queue_insert(g_queue, &g_events[1], 1);
timeout_queue_insert(g_queue, &g_events[2], 2);
timeout_queue_insert(g_queue, &g_events[3], 3);
timeout_queue_insert(g_queue, &g_events[4], 4);
return (g_events[0].prev != NULL &&
g_events[1].prev != NULL &&
g_events[2].prev != NULL &&
g_events[3].prev != NULL &&
g_events[4].prev != NULL);
});
EXO_TEST(timer_check_5_events_1,{
return timeout_queue_get_next_timeout(g_queue, g_now) == 1;
});
EXO_TEST(timer_process_5_events_1,{
g_now = 4;
return timeout_queue_process(g_queue, g_now) == g_triggered;
});

View File

@@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,9 @@
uhub_assert(X->capacity); \ uhub_assert(X->capacity); \
uhub_assert(X->length); \ uhub_assert(X->length); \
uhub_assert(X->length <= X->capacity); \ uhub_assert(X->length <= X->capacity); \
uhub_assert(X->references > 0); \
uhub_assert(X->length == strlen(X->cache)); uhub_assert(X->length == strlen(X->cache));
#define ADC_MSG_NULL_ON_FREE
#else #else
#define ADC_MSG_ASSERT(X) do { } while(0) #define ADC_MSG_ASSERT(X) do { } while(0)
#endif /* DEBUG */ #endif /* DEBUG */
@@ -53,40 +55,18 @@ static void* msg_malloc_zero(size_t size)
static void msg_free(void* ptr) static void msg_free(void* ptr)
{ {
LOG_MEMORY("msg_free: %p", ptr); LOG_MEMORY("msg_free: %p", ptr);
// hub_free(ptr); hub_free(ptr);
} }
#include <sys/mman.h>
static void adc_msg_protect(struct adc_message* cmd)
{
LOG_MEMORY("msg_prot: %p %d", cmd, cmd->capacity);
mprotect(cmd, sizeof(cmd), PROT_READ);
mprotect(cmd->cache, sizeof(cmd->capacity), PROT_READ);
}
static void adc_msg_unprotect(struct adc_message* cmd)
{
LOG_MEMORY("msg_unprot: %p %d", cmd, cmd->capacity);
mprotect(cmd, sizeof(cmd), PROT_READ | PROT_WRITE);
mprotect(cmd->cache, sizeof(cmd->capacity), PROT_READ | PROT_WRITE);
}
#else #else
#define msg_malloc(X) hub_malloc(X) #define msg_malloc(X) hub_malloc(X)
#define msg_malloc_zero(X) hub_malloc_zero(X) #define msg_malloc_zero(X) hub_malloc_zero(X)
#define msg_free(X) hub_free(X) #define msg_free(X) hub_free(X)
#endif /* MSG_MEMORY_DEBUG */ #endif /* MSG_MEMORY_DEBUG */
struct adc_message* adc_msg_incref(struct adc_message* msg) struct adc_message* adc_msg_incref(struct adc_message* msg)
{ {
if (!msg) return 0;
#ifndef ADC_MESSAGE_INCREF #ifndef ADC_MESSAGE_INCREF
#ifdef MSG_MEMORY_DEBUG
adc_msg_unprotect(msg);
#endif
msg->references++; msg->references++;
#ifdef MSG_MEMORY_DEBUG #ifdef MSG_MEMORY_DEBUG
adc_msg_protect(msg); adc_msg_protect(msg);
@@ -201,40 +181,35 @@ int adc_msg_is_empty(struct adc_message* msg)
void adc_msg_free(struct adc_message* msg) void adc_msg_free(struct adc_message* msg)
{ {
if (!msg) return; if (!msg) return;
ADC_MSG_ASSERT(msg); ADC_MSG_ASSERT(msg);
if (msg->references > 0) msg->references--;
if (msg->references == 0)
{ {
#ifdef MSG_MEMORY_DEBUG #ifdef ADC_MSG_NULL_ON_FREE
adc_msg_unprotect(msg); if (msg->cache)
#endif {
msg->references--; *msg->cache = 0;
#ifdef MSG_MEMORY_DEBUG }
adc_msg_protect(msg);
#endif
}
else
{
#ifdef MSG_MEMORY_DEBUG
adc_msg_unprotect(msg);
#endif #endif
msg_free(msg->cache); msg_free(msg->cache);
if (msg->feature_cast_include) if (msg->feature_cast_include)
{ {
list_clear(msg->feature_cast_include, &hub_free); list_clear(msg->feature_cast_include, &hub_free);
list_destroy(msg->feature_cast_include); list_destroy(msg->feature_cast_include);
msg->feature_cast_include = 0; msg->feature_cast_include = 0;
} }
if (msg->feature_cast_exclude) if (msg->feature_cast_exclude)
{ {
list_clear(msg->feature_cast_exclude, &hub_free); list_clear(msg->feature_cast_exclude, &hub_free);
list_destroy(msg->feature_cast_exclude); list_destroy(msg->feature_cast_exclude);
msg->feature_cast_exclude = 0; msg->feature_cast_exclude = 0;
} }
msg_free(msg); msg_free(msg);
} }
} }
@@ -256,7 +231,7 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd)
copy->length = cmd->length; copy->length = cmd->length;
copy->capacity = 0; copy->capacity = 0;
copy->priority = cmd->priority; copy->priority = cmd->priority;
copy->references = 0; copy->references = 1;
copy->feature_cast_include = 0; copy->feature_cast_include = 0;
copy->feature_cast_exclude = 0; copy->feature_cast_exclude = 0;
@@ -295,9 +270,6 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd)
ADC_MSG_ASSERT(copy); ADC_MSG_ASSERT(copy);
#ifdef MSG_MEMORY_DEBUG
adc_msg_protect(copy);
#endif
return copy; return copy;
} }
@@ -332,7 +304,7 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
if (command == NULL) if (command == NULL)
return NULL; /* OOM */ return NULL; /* OOM */
if (!is_printable_utf8(line, length)) if (!is_printable_utf8(line, length))
{ {
LOG_DEBUG("Dropped message with non-printable UTF-8 characters."); LOG_DEBUG("Dropped message with non-printable UTF-8 characters.");
@@ -350,17 +322,18 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
msg_free(command); msg_free(command);
return NULL; /* OOM */ return NULL; /* OOM */
} }
adc_msg_set_length(command, length + need_terminate); adc_msg_set_length(command, length + need_terminate);
memcpy(command->cache, line, length); memcpy(command->cache, line, length);
/* Ensure we are zero terminated */ /* Ensure we are zero terminated */
command->cache[length] = 0; command->cache[length] = 0;
command->cache[length+need_terminate] = 0; command->cache[length+need_terminate] = 0;
command->cmd = FOURCC(line[0], line[1], line[2], line[3]); command->cmd = FOURCC(line[0], line[1], line[2], line[3]);
command->priority = 0; command->priority = 0;
command->references = 1;
switch (prefix) switch (prefix)
{ {
case 'U': case 'U':
@@ -368,12 +341,12 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
/* these should never be seen on a hub */ /* these should never be seen on a hub */
ok = 0; ok = 0;
break; break;
case 'I': case 'I':
case 'H': case 'H':
ok = (length > 3); ok = (length > 3);
break; break;
case 'B': case 'B':
ok = (length > 8 && ok = (length > 8 &&
is_space(line[4]) && is_space(line[4]) &&
@@ -381,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[6]) &&
is_valid_base32_char(line[7]) && is_valid_base32_char(line[7]) &&
is_valid_base32_char(line[8])); is_valid_base32_char(line[8]));
if (!ok) break; if (!ok) break;
temp_sid[0] = line[5]; temp_sid[0] = line[5];
temp_sid[1] = line[6]; temp_sid[1] = line[6];
temp_sid[2] = line[7]; temp_sid[2] = line[7];
temp_sid[3] = line[8]; temp_sid[3] = line[8];
temp_sid[4] = '\0'; temp_sid[4] = '\0';
command->source = string_to_sid(temp_sid); command->source = string_to_sid(temp_sid);
break; break;
case 'F': case 'F':
ok = (length > 8 && ok = (length > 8 &&
is_space(line[4]) && is_space(line[4]) &&
@@ -400,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[6]) &&
is_valid_base32_char(line[7]) && is_valid_base32_char(line[7]) &&
is_valid_base32_char(line[8])); is_valid_base32_char(line[8]));
if (!ok) break; if (!ok) break;
temp_sid[0] = line[5]; temp_sid[0] = line[5];
temp_sid[1] = line[6]; temp_sid[1] = line[6];
temp_sid[2] = line[7]; temp_sid[2] = line[7];
temp_sid[3] = line[8]; temp_sid[3] = line[8];
temp_sid[4] = '\0'; temp_sid[4] = '\0';
command->source = string_to_sid(temp_sid); command->source = string_to_sid(temp_sid);
/* Create feature cast lists */ /* Create feature cast lists */
command->feature_cast_include = list_create(); command->feature_cast_include = list_create();
command->feature_cast_exclude = list_create(); command->feature_cast_exclude = list_create();
if (!command->feature_cast_include || !command->feature_cast_exclude) if (!command->feature_cast_include || !command->feature_cast_exclude)
{ {
list_destroy(command->feature_cast_include); list_destroy(command->feature_cast_include);
@@ -423,7 +396,7 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
msg_free(command); msg_free(command);
return NULL; /* OOM */ return NULL; /* OOM */
} }
n = 10; n = 10;
while (line[n] == '+' || line[n] == '-') while (line[n] == '+' || line[n] == '-')
{ {
@@ -431,21 +404,20 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
feature_cast_list = command->feature_cast_include; feature_cast_list = command->feature_cast_include;
else else
feature_cast_list = command->feature_cast_exclude; feature_cast_list = command->feature_cast_exclude;
temp_sid[0] = line[n++]; temp_sid[0] = line[n++];
temp_sid[1] = line[n++]; temp_sid[1] = line[n++];
temp_sid[2] = line[n++]; temp_sid[2] = line[n++];
temp_sid[3] = line[n++]; temp_sid[3] = line[n++];
temp_sid[4] = '\0'; temp_sid[4] = '\0';
list_append(feature_cast_list, hub_strdup(temp_sid)); list_append(feature_cast_list, hub_strdup(temp_sid));
} }
if (n == 10) if (n == 10)
ok = 0; ok = 0;
break; break;
case 'D': case 'D':
case 'E': case 'E':
ok = (length > 13 && ok = (length > 13 &&
@@ -459,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[11]) &&
is_valid_base32_char(line[12]) && is_valid_base32_char(line[12]) &&
is_valid_base32_char(line[13])); is_valid_base32_char(line[13]));
if (!ok) break; if (!ok) break;
temp_sid[0] = line[5]; temp_sid[0] = line[5];
temp_sid[1] = line[6]; temp_sid[1] = line[6];
temp_sid[2] = line[7]; temp_sid[2] = line[7];
temp_sid[3] = line[8]; temp_sid[3] = line[8];
temp_sid[4] = '\0'; temp_sid[4] = '\0';
command->source = string_to_sid(temp_sid); command->source = string_to_sid(temp_sid);
temp_sid[0] = line[10]; temp_sid[0] = line[10];
temp_sid[1] = line[11]; temp_sid[1] = line[11];
temp_sid[2] = line[12]; temp_sid[2] = line[12];
temp_sid[3] = line[13]; temp_sid[3] = line[13];
temp_sid[4] = '\0'; temp_sid[4] = '\0';
command->target = string_to_sid(temp_sid); command->target = string_to_sid(temp_sid);
break; break;
default: default:
ok = 0; ok = 0;
} }
if (need_terminate) if (need_terminate)
{ {
command->cache[length] = '\n'; command->cache[length] = '\n';
} }
if (!ok) if (!ok)
{ {
adc_msg_free(command); adc_msg_free(command);
return NULL; return NULL;
} }
/* At this point the arg_offset should point to a space, or the end of message */ /* At this point the arg_offset should point to a space, or the end of message */
n = adc_msg_get_arg_offset(command); n = adc_msg_get_arg_offset(command);
if (command->cache[n] == ' ') if (command->cache[n] == ' ')
@@ -502,18 +474,14 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
} }
else if (command->cache[n] == '\n') ok = 1; else if (command->cache[n] == '\n') ok = 1;
else ok = 0; else ok = 0;
if (!ok) if (!ok)
{ {
adc_msg_free(command); adc_msg_free(command);
return NULL; return NULL;
} }
ADC_MSG_ASSERT(command);
#ifdef MSG_MEMORY_DEBUG ADC_MSG_ASSERT(command);
adc_msg_protect(command);
#endif
return command; return command;
} }
@@ -527,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* adc_msg_construct(fourcc_t fourcc, size_t size)
{ {
struct adc_message* msg = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message)); struct adc_message* msg = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
if (!msg) if (!msg)
return NULL; /* OOM */ return NULL; /* OOM */
@@ -538,7 +505,7 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
msg_free(msg); msg_free(msg);
return NULL; /* OOM */ return NULL; /* OOM */
} }
if (fourcc) if (fourcc)
{ {
msg->cache[0] = (char) ((fourcc >> 24) & 0xff); msg->cache[0] = (char) ((fourcc >> 24) & 0xff);
@@ -546,19 +513,15 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
msg->cache[2] = (char) ((fourcc >> 8) & 0xff); msg->cache[2] = (char) ((fourcc >> 8) & 0xff);
msg->cache[3] = (char) ((fourcc ) & 0xff); msg->cache[3] = (char) ((fourcc ) & 0xff);
msg->cache[4] = '\n'; msg->cache[4] = '\n';
/* Ensure we are zero terminated */ /* Ensure we are zero terminated */
adc_msg_set_length(msg, 5); adc_msg_set_length(msg, 5);
msg->cache[msg->length] = 0; msg->cache[msg->length] = 0;
} }
msg->cmd = fourcc; msg->cmd = fourcc;
msg->priority = 0; msg->priority = 0;
msg->references = 1;
#ifdef MSG_MEMORY_DEBUG
adc_msg_protect(msg);
#endif
return msg; return msg;
} }
@@ -625,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); int arg_offset = adc_msg_get_arg_offset(cmd);
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3); start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
while (start) while (start)
{ {
@@ -635,7 +598,7 @@ int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix_[2])
else else
start = NULL; start = NULL;
} }
return count; return count;
} }
@@ -648,25 +611,25 @@ char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix_[2])
size_t length; size_t length;
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' }; char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
int arg_offset = adc_msg_get_arg_offset(cmd); int arg_offset = adc_msg_get_arg_offset(cmd);
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
start = memmem(&cmd->cache[arg_offset], cmd->length - arg_offset, prefix, 3); start = memmem(&cmd->cache[arg_offset], cmd->length - arg_offset, prefix, 3);
if (!start) if (!start)
return NULL; return NULL;
start = &start[3]; start = &start[3];
end = strchr(start, ' '); end = strchr(start, ' ');
if (!end) end = &cmd->cache[cmd->length]; if (!end) end = &cmd->cache[cmd->length];
length = &end[0] - &start[0]; length = &end[0] - &start[0];
argument = hub_strndup(start, length); argument = hub_strndup(start, length);
if (length > 0 && argument[length-1] == '\n') if (length > 0 && argument[length-1] == '\n')
{ {
argument[length-1] = 0; argument[length-1] = 0;
} }
return argument; return argument;
} }
@@ -684,9 +647,9 @@ int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2]
{ {
return -1; return -1;
} }
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
return 0; return 0;
} }
@@ -698,10 +661,6 @@ void adc_msg_terminate(struct adc_message* cmd)
adc_msg_cache_append(cmd, "\n", 1); adc_msg_cache_append(cmd, "\n", 1);
} }
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
#ifdef MSG_MEMORY_DEBUG
adc_msg_protect(cmd);
#endif
} }
/* FIXME: this looks bogus */ /* FIXME: this looks bogus */
@@ -709,10 +668,6 @@ void adc_msg_unterminate(struct adc_message* cmd)
{ {
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
#ifdef MSG_MEMORY_DEBUG
adc_msg_unprotect(cmd);
#endif
if (cmd->length > 0 && cmd->cache[cmd->length-1] == '\n') if (cmd->length > 0 && cmd->cache[cmd->length-1] == '\n')
{ {
cmd->length--; cmd->length--;
@@ -725,9 +680,9 @@ int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], co
int ret = 0; int ret = 0;
if (!string) if (!string)
return -1; return -1;
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd); adc_msg_unterminate(cmd);
adc_msg_cache_append(cmd, " ", 1); adc_msg_cache_append(cmd, " ", 1);
adc_msg_cache_append(cmd, prefix, 2); adc_msg_cache_append(cmd, prefix, 2);
@@ -761,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) int adc_msg_add_argument(struct adc_message* cmd, const char* string)
{ {
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd); adc_msg_unterminate(cmd);
adc_msg_cache_append(cmd, " ", 1); adc_msg_cache_append(cmd, " ", 1);
adc_msg_cache_append(cmd, string, strlen(string)); adc_msg_cache_append(cmd, string, strlen(string));
@@ -827,11 +782,11 @@ int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2])
char* start; char* start;
char* end; char* end;
int count = 0; int count = 0;
ADC_MSG_ASSERT(cmd); ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd); adc_msg_unterminate(cmd);
start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' '); start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' ');
while (start) while (start)
{ {
@@ -884,16 +839,13 @@ int adc_msg_unescape_length(const char* str)
} }
char* adc_msg_unescape(const char* string) char* adc_msg_unescape(const char* string)
{ {
char* new_string = msg_malloc(adc_msg_unescape_length(string)+1); char* new_string = msg_malloc(adc_msg_unescape_length(string)+1);
char* ptr = (char*) new_string; char* ptr = (char*) new_string;
char* str = (char*) string; char* str = (char*) string;
int escaped = 0; int escaped = 0;
while (*str) while (*str)
{ {
if (escaped) { if (escaped) {
@@ -905,14 +857,12 @@ char* adc_msg_unescape(const char* string)
*ptr++ = '\n'; *ptr++ = '\n';
else else
*ptr++ = *str; *ptr++ = *str;
escaped = 0; escaped = 0;
} else { } else {
if (*str == '\\') if (*str == '\\')
escaped = 1; escaped = 1;
else else
*ptr++ = *str; *ptr++ = *str;
} }
str++; str++;
} }

View File

@@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -119,6 +119,14 @@ void sid_pool_destroy(struct sid_pool* pool)
sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user) sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
{ {
if (pool->count >= (pool->max - pool->min))
{
#ifdef DEBUG_SID
LOG_DUMP("SID_POOL: alloc, sid pool is full.");
#endif
return 0;
}
sid_t n = (++pool->count); sid_t n = (++pool->count);
for (; (pool->map[n % pool->max]); n++) ; for (; (pool->map[n % pool->max]); n++) ;
@@ -140,7 +148,7 @@ void sid_free(struct sid_pool* pool, sid_t sid)
struct hub_user* sid_lookup(struct sid_pool* pool, sid_t sid) struct hub_user* sid_lookup(struct sid_pool* pool, sid_t sid)
{ {
if (!sid || (sid > pool->max)) if (!sid || (sid >= pool->max))
return 0; return 0;
return pool->map[sid]; return pool->map[sid];
} }

View File

@@ -127,6 +127,7 @@
#define DEF_SHOW_BANNER 1 #define DEF_SHOW_BANNER 1
#define DEF_SHOW_BANNER_SYS_INFO 1 #define DEF_SHOW_BANNER_SYS_INFO 1
#define DEF_REGISTERED_USERS_ONLY 0 #define DEF_REGISTERED_USERS_ONLY 0
#define DEF_OBSOLETE_CLIENTS 0
#define DEF_CHAT_ONLY 0 #define DEF_CHAT_ONLY 0
#define DEF_CHAT_IS_PRIVILEGED 0 #define DEF_CHAT_IS_PRIVILEGED 0
#define DEF_LOW_BANDWIDTH_MODE 0 #define DEF_LOW_BANDWIDTH_MODE 0
@@ -174,6 +175,8 @@
#define DEF_MSG_USER_SLOTS_HIGH "User have too many upload slots." #define DEF_MSG_USER_SLOTS_HIGH "User have too many upload slots."
#define DEF_MSG_USER_HUB_LIMIT_LOW "User is on too few hubs." #define DEF_MSG_USER_HUB_LIMIT_LOW "User is on too few hubs."
#define DEF_MSG_USER_HUB_LIMIT_HIGH "User is on too many hubs." #define DEF_MSG_USER_HUB_LIMIT_HIGH "User is on too many hubs."
#define DEF_MSG_PROTO_NO_COMMON_HASH "No common hash algorithm."
#define DEF_MSG_PROTO_OBSOLETE_ADC0 "Your client does not support ADC/1.0."
void config_defaults(struct hub_config* config) void config_defaults(struct hub_config* config)
{ {
@@ -195,11 +198,12 @@ void config_defaults(struct hub_config* config)
DEFAULT_INTEGER(max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT); DEFAULT_INTEGER(max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT);
DEFAULT_BOOLEAN(show_banner, DEF_SHOW_BANNER); DEFAULT_BOOLEAN(show_banner, DEF_SHOW_BANNER);
DEFAULT_BOOLEAN(show_banner_sys_info, DEF_SHOW_BANNER_SYS_INFO); DEFAULT_BOOLEAN(show_banner_sys_info, DEF_SHOW_BANNER_SYS_INFO);
DEFAULT_BOOLEAN(obsolete_clients, DEF_OBSOLETE_CLIENTS);
DEFAULT_BOOLEAN(chat_only, DEF_CHAT_ONLY); DEFAULT_BOOLEAN(chat_only, DEF_CHAT_ONLY);
DEFAULT_BOOLEAN(chat_is_privileged, DEF_CHAT_IS_PRIVILEGED); DEFAULT_BOOLEAN(chat_is_privileged, DEF_CHAT_IS_PRIVILEGED);
DEFAULT_BOOLEAN(low_bandwidth_mode, DEF_LOW_BANDWIDTH_MODE); DEFAULT_BOOLEAN(low_bandwidth_mode, DEF_LOW_BANDWIDTH_MODE);
DEFAULT_BOOLEAN(registered_users_only, DEF_REGISTERED_USERS_ONLY); DEFAULT_BOOLEAN(registered_users_only, DEF_REGISTERED_USERS_ONLY);
/* Limits enforced on users */ /* Limits enforced on users */
DEFAULT_INTEGER(limit_max_hubs_user, DEF_LIMIT_MAX_HUBS_USER); DEFAULT_INTEGER(limit_max_hubs_user, DEF_LIMIT_MAX_HUBS_USER);
DEFAULT_INTEGER(limit_max_hubs_reg, DEF_LIMIT_MAX_HUBS_REG); DEFAULT_INTEGER(limit_max_hubs_reg, DEF_LIMIT_MAX_HUBS_REG);
@@ -243,6 +247,8 @@ void config_defaults(struct hub_config* config)
DEFAULT_STRING (msg_user_slots_high, DEF_MSG_USER_SLOTS_HIGH); DEFAULT_STRING (msg_user_slots_high, DEF_MSG_USER_SLOTS_HIGH);
DEFAULT_STRING (msg_user_hub_limit_low, DEF_MSG_USER_HUB_LIMIT_LOW); DEFAULT_STRING (msg_user_hub_limit_low, DEF_MSG_USER_HUB_LIMIT_LOW);
DEFAULT_STRING (msg_user_hub_limit_high, DEF_MSG_USER_HUB_LIMIT_HIGH); DEFAULT_STRING (msg_user_hub_limit_high, DEF_MSG_USER_HUB_LIMIT_HIGH);
DEFAULT_STRING (msg_proto_no_common_hash, DEF_MSG_PROTO_NO_COMMON_HASH);
DEFAULT_STRING (msg_proto_obsolete_adc0, DEF_MSG_PROTO_OBSOLETE_ADC0);
DEFAULT_INTEGER(tls_enable, DEF_TLS_ENABLE); DEFAULT_INTEGER(tls_enable, DEF_TLS_ENABLE);
DEFAULT_INTEGER(tls_require, DEF_TLS_REQUIRE); DEFAULT_INTEGER(tls_require, DEF_TLS_REQUIRE);
@@ -271,6 +277,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
GET_INT (max_send_buffer_soft); GET_INT (max_send_buffer_soft);
GET_BOOL(show_banner); GET_BOOL(show_banner);
GET_BOOL(show_banner_sys_info); GET_BOOL(show_banner_sys_info);
GET_BOOL(obsolete_clients);
GET_BOOL(chat_only); GET_BOOL(chat_only);
GET_BOOL(chat_is_privileged); GET_BOOL(chat_is_privileged);
GET_BOOL(low_bandwidth_mode); GET_BOOL(low_bandwidth_mode);
@@ -288,7 +295,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
GET_INT(limit_max_share); GET_INT(limit_max_share);
GET_INT(limit_min_slots); GET_INT(limit_min_slots);
GET_INT(limit_max_slots); GET_INT(limit_max_slots);
/* Status/error strings */ /* Status/error strings */
GET_STR (msg_hub_full); GET_STR (msg_hub_full);
GET_STR (msg_hub_disabled); GET_STR (msg_hub_disabled);
@@ -319,13 +326,16 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
GET_STR (msg_user_slots_high); GET_STR (msg_user_slots_high);
GET_STR (msg_user_hub_limit_low); GET_STR (msg_user_hub_limit_low);
GET_STR (msg_user_hub_limit_high); GET_STR (msg_user_hub_limit_high);
GET_STR (msg_proto_no_common_hash);
GET_STR (msg_proto_obsolete_adc0);
/* TLS/SSL related */
GET_BOOL(tls_enable); GET_BOOL(tls_enable);
GET_BOOL(tls_require); GET_BOOL(tls_require);
GET_STR (tls_certificate); GET_STR (tls_certificate);
GET_STR (tls_private_key); GET_STR (tls_private_key);
/* Still here -- unknown directive */ /* Still here -- unknown directive */
LOG_ERROR("Unknown configuration directive: '%s'", key); LOG_ERROR("Unknown configuration directive: '%s'", key);
return -1; return -1;
} }
@@ -340,7 +350,7 @@ void free_config(struct hub_config* config)
hub_free(config->file_rules); hub_free(config->file_rules);
hub_free(config->hub_name); hub_free(config->hub_name);
hub_free(config->hub_description); hub_free(config->hub_description);
hub_free(config->msg_hub_full); hub_free(config->msg_hub_full);
hub_free(config->msg_hub_disabled); hub_free(config->msg_hub_disabled);
hub_free(config->msg_hub_registered_users_only); hub_free(config->msg_hub_registered_users_only);
@@ -370,7 +380,9 @@ void free_config(struct hub_config* config)
hub_free(config->msg_user_slots_high); hub_free(config->msg_user_slots_high);
hub_free(config->msg_user_hub_limit_low); hub_free(config->msg_user_hub_limit_low);
hub_free(config->msg_user_hub_limit_high); hub_free(config->msg_user_hub_limit_high);
hub_free(config->msg_proto_no_common_hash);
hub_free(config->msg_proto_obsolete_adc0);
hub_free(config->tls_certificate); hub_free(config->tls_certificate);
hub_free(config->tls_private_key); hub_free(config->tls_private_key);
@@ -425,6 +437,7 @@ void dump_config(struct hub_config* config, int ignore_defaults)
DUMP_INT (max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT); DUMP_INT (max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT);
DUMP_BOOL(show_banner, DEF_SHOW_BANNER); DUMP_BOOL(show_banner, DEF_SHOW_BANNER);
DUMP_BOOL(show_banner_sys_info, DEF_SHOW_BANNER_SYS_INFO); DUMP_BOOL(show_banner_sys_info, DEF_SHOW_BANNER_SYS_INFO);
DUMP_BOOL(obsolete_clients, DEF_OBSOLETE_CLIENTS);
DUMP_BOOL(chat_only, DEF_CHAT_ONLY); DUMP_BOOL(chat_only, DEF_CHAT_ONLY);
DUMP_BOOL(chat_is_privileged, DEF_CHAT_IS_PRIVILEGED); DUMP_BOOL(chat_is_privileged, DEF_CHAT_IS_PRIVILEGED);
DUMP_BOOL(low_bandwidth_mode, DEF_LOW_BANDWIDTH_MODE); DUMP_BOOL(low_bandwidth_mode, DEF_LOW_BANDWIDTH_MODE);
@@ -480,6 +493,8 @@ void dump_config(struct hub_config* config, int ignore_defaults)
DUMP_STR (msg_user_slots_high, DEF_MSG_USER_SLOTS_HIGH); DUMP_STR (msg_user_slots_high, DEF_MSG_USER_SLOTS_HIGH);
DUMP_STR (msg_user_hub_limit_low, DEF_MSG_USER_HUB_LIMIT_LOW); DUMP_STR (msg_user_hub_limit_low, DEF_MSG_USER_HUB_LIMIT_LOW);
DUMP_STR (msg_user_hub_limit_high, DEF_MSG_USER_HUB_LIMIT_HIGH); DUMP_STR (msg_user_hub_limit_high, DEF_MSG_USER_HUB_LIMIT_HIGH);
DUMP_STR (msg_proto_no_common_hash, DEF_MSG_PROTO_NO_COMMON_HASH);
DUMP_STR (msg_proto_obsolete_adc0, DEF_MSG_PROTO_OBSOLETE_ADC0);
} }

View File

@@ -31,6 +31,7 @@ struct hub_config
int show_banner_sys_info; /**<<< "Show banner system information (default: 1). Has no effect unless show_banner is enabled." */ int show_banner_sys_info; /**<<< "Show banner system information (default: 1). Has no effect unless show_banner is enabled." */
int max_users; /**<<< "Maximum number of users allowed on the hub (default: 500)" */ int max_users; /**<<< "Maximum number of users allowed on the hub (default: 500)" */
int registered_users_only; /**<<< "Allow registered users only (default: 0)" */ int registered_users_only; /**<<< "Allow registered users only (default: 0)" */
int obsolete_clients; /**<<< "Support obsolete clients using a ADC protocol prior to 1.0 (default: off)" */
int chat_only; /**<<< "Allow chat only operation on hub (default: 0)" */ int chat_only; /**<<< "Allow chat only operation on hub (default: 0)" */
int chat_is_privileged; /**<<< "Allow chat for operators and above only (default: 0) */ int chat_is_privileged; /**<<< "Allow chat for operators and above only (default: 0) */
char* file_motd; /**<<< "File containing the 'message of the day' (default: '' - no motd)" */ char* file_motd; /**<<< "File containing the 'message of the day' (default: '' - no motd)" */
@@ -89,6 +90,8 @@ struct hub_config
char* msg_user_slots_high; /**<<< "User have too many upload slots." */ char* msg_user_slots_high; /**<<< "User have too many upload slots." */
char* msg_user_hub_limit_low; /**<<< "User is on too few hubs." */ char* msg_user_hub_limit_low; /**<<< "User is on too few hubs." */
char* msg_user_hub_limit_high; /**<<< "User is on too many hubs." */ char* msg_user_hub_limit_high; /**<<< "User is on too many hubs." */
char* msg_proto_no_common_hash; /**<<< "No common hash algorithm." */
char* msg_proto_obsolete_adc0; /**<<< "Client is using an obsolete ADC protocol version." */
int tls_enable; /**<<< "Enable SSL/TLS support (default: 0)" */ int tls_enable; /**<<< "Enable SSL/TLS support (default: 0)" */
int tls_require; /**<<< "If SSL/TLS enabled, should it be required (default: 0) */ int tls_require; /**<<< "If SSL/TLS enabled, should it be required (default: 0) */

View File

@@ -137,17 +137,46 @@ int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_mess
if (u->state == state_protocol) if (u->state == state_protocol)
{ {
if (index == 0) ok = 0; /* Need to support *SOMETHING*, at least BASE */ if (index == 0) ok = 0; /* Need to support *SOMETHING*, at least BASE */
if (!ok)
if (ok)
{
hub_send_handshake(hub, u);
net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE);
}
else
{ {
/* disconnect user. Do not send crap during initial handshake! */ /* disconnect user. Do not send crap during initial handshake! */
hub_disconnect_user(hub, u, quit_logon_error); hub_disconnect_user(hub, u, quit_logon_error);
ret = -1; return -1;
}
if (user_flag_get(u, feature_base))
{
/* User supports ADC/1.0 and a hash we know */
if (user_flag_get(u, feature_tiger))
{
hub_send_handshake(hub, u);
net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE);
}
else
{
// no common hash algorithm.
hub_send_status(hub, u, status_msg_proto_no_common_hash, status_level_fatal);
hub_disconnect_user(hub, u, quit_protocol_error);
}
}
else if (user_flag_get(u, feature_bas0))
{
if (hub->config->obsolete_clients)
{
hub_send_handshake(hub, u);
net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE);
}
else
{
/* disconnect user for using an obsolete client. */
hub_send_status(hub, u, status_msg_proto_obsolete_adc0, status_level_fatal);
hub_disconnect_user(hub, u, quit_protocol_error);
}
}
else
{
/* Not speaking a compatible protocol - just disconnect. */
hub_disconnect_user(hub, u, quit_logon_error);
} }
} }
@@ -552,7 +581,45 @@ static void server_alt_port_stop(struct hub_info* hub)
} }
} }
#ifdef SSL_SUPPORT
static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config)
{
if (config->tls_enable)
{
hub->ssl_method = SSLv23_method(); /* TLSv1_method() */
hub->ssl_ctx = SSL_CTX_new(hub->ssl_method);
/* Disable SSLv2 */
SSL_CTX_set_options(hub->ssl_ctx, SSL_OP_NO_SSLv2);
if (SSL_CTX_use_certificate_file(hub->ssl_ctx, config->tls_certificate, SSL_FILETYPE_PEM) < 0)
{
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
}
if (SSL_CTX_use_PrivateKey_file(hub->ssl_ctx, config->tls_private_key, SSL_FILETYPE_PEM) < 0)
{
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
}
if (SSL_CTX_check_private_key(hub->ssl_ctx) != 1)
{
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
return 0;
}
LOG_INFO("Enabling TLS, using certificate: %s, private key: %s", config->tls_certificate, config->tls_private_key);
}
return 1;
}
static void unload_ssl_certificates(struct hub_info* hub)
{
if (hub->ssl_ctx)
{
SSL_CTX_free(hub->ssl_ctx);
}
}
#endif
struct hub_info* hub_start_service(struct hub_config* config) struct hub_info* hub_start_service(struct hub_config* config)
{ {
@@ -583,30 +650,10 @@ struct hub_info* hub_start_service(struct hub_config* config)
LOG_INFO("Starting " PRODUCT "/" VERSION ", listening on %s:%d...", net_get_local_address(hub->server->sd), config->server_port); LOG_INFO("Starting " PRODUCT "/" VERSION ", listening on %s:%d...", net_get_local_address(hub->server->sd), config->server_port);
#ifdef SSL_SUPPORT #ifdef SSL_SUPPORT
if (config->tls_enable) if (!load_ssl_certificates(hub, config))
{ {
hub->ssl_method = SSLv23_method(); /* TLSv1_method() */ hub_free(hub);
hub->ssl_ctx = SSL_CTX_new(hub->ssl_method); return 0;
/* Disable SSLv2 */
SSL_CTX_set_options(hub->ssl_ctx, SSL_OP_NO_SSLv2);
if (SSL_CTX_use_certificate_file(hub->ssl_ctx, config->tls_certificate, SSL_FILETYPE_PEM) < 0)
{
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
}
if (SSL_CTX_use_PrivateKey_file(hub->ssl_ctx, config->tls_private_key, SSL_FILETYPE_PEM) < 0)
{
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
}
if (SSL_CTX_check_private_key(hub->ssl_ctx) != 1)
{
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
return 0;
}
LOG_INFO("Enabling TLS, using certificate: %s, private key: %s", config->tls_certificate, config->tls_private_key);
} }
#endif #endif
@@ -667,6 +714,10 @@ void hub_shutdown_service(struct hub_info* hub)
{ {
LOG_DEBUG("hub_shutdown_service()"); LOG_DEBUG("hub_shutdown_service()");
#ifdef SSL_SUPPORT
unload_ssl_certificates(hub);
#endif
event_queue_shutdown(hub->queue); event_queue_shutdown(hub->queue);
net_con_close(hub->server); net_con_close(hub->server);
hub_free(hub->server); hub_free(hub->server);
@@ -868,6 +919,8 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
STATUS(43, msg_user_slots_high, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0); STATUS(43, msg_user_slots_high, "FB" ADC_INF_FLAG_UPLOAD_SLOTS, 0);
STATUS(43, msg_user_hub_limit_low, 0, 0); STATUS(43, msg_user_hub_limit_low, 0, 0);
STATUS(43, msg_user_hub_limit_high, 0, 0); STATUS(43, msg_user_hub_limit_high, 0, 0);
STATUS(47, msg_proto_no_common_hash, 0, -1);
STATUS(40, msg_proto_obsolete_adc0, 0, -1);
} }
#undef STATUS #undef STATUS
@@ -886,14 +939,14 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
if (level >= status_level_fatal) if (level >= status_level_fatal)
{ {
snprintf(buf, 230, "MS%s", escaped_text); snprintf(buf, 230, "MS%s", escaped_text);
adc_msg_add_argument(cmd, buf); adc_msg_add_argument(qui, buf);
if (reconnect_time != 0) if (reconnect_time != 0)
{ {
snprintf(buf, 10, "TL%d", reconnect_time); snprintf(buf, 10, "TL%d", reconnect_time);
adc_msg_add_argument(cmd, buf); adc_msg_add_argument(qui, buf);
} }
route_to_user(hub, user, cmd); route_to_user(hub, user, qui);
} }
hub_free(escaped_text); hub_free(escaped_text);
@@ -936,6 +989,8 @@ const char* hub_get_status_message(struct hub_info* hub, enum status_message msg
STATUS(msg_user_slots_high); STATUS(msg_user_slots_high);
STATUS(msg_user_hub_limit_low); STATUS(msg_user_hub_limit_low);
STATUS(msg_user_hub_limit_high); STATUS(msg_user_hub_limit_high);
STATUS(msg_proto_no_common_hash);
STATUS(msg_proto_obsolete_adc0);
} }
#undef STATUS #undef STATUS
return "Unknown"; return "Unknown";
@@ -975,6 +1030,8 @@ const char* hub_get_status_message_log(struct hub_info* hub, enum status_message
STATUS(msg_user_slots_high); STATUS(msg_user_slots_high);
STATUS(msg_user_hub_limit_low); STATUS(msg_user_hub_limit_low);
STATUS(msg_user_hub_limit_high); STATUS(msg_user_hub_limit_high);
STATUS(msg_proto_no_common_hash);
STATUS(msg_proto_obsolete_adc0);
} }
#undef STATUS #undef STATUS
return "unknown"; return "unknown";

View File

@@ -53,6 +53,10 @@ enum status_message
status_msg_user_hub_limit_low = -44, /* Use is on too few hubs. */ status_msg_user_hub_limit_low = -44, /* Use is on too few hubs. */
status_msg_user_hub_limit_high = -45, /* Use is on too many hubs. */ status_msg_user_hub_limit_high = -45, /* Use is on too many hubs. */
status_msg_proto_no_common_hash = -50, /* No common hash algorithms */
status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */
}; };

View File

@@ -126,6 +126,7 @@ void hub_sendq_add(struct hub_sendq* q, struct adc_message* msg_)
#ifdef DEBUG_SENDQ #ifdef DEBUG_SENDQ
debug_msg("hub_sendq_add", msg); debug_msg("hub_sendq_add", msg);
#endif #endif
assert(msg->cache && *msg->cache);
list_append(q->queue, msg); list_append(q->queue, msg);
q->size += msg->length; q->size += msg->length;
} }
@@ -146,7 +147,7 @@ int hub_sendq_send(struct hub_sendq* q, struct hub_user* user)
int ret; int ret;
struct adc_message* msg = list_get_first(q->queue); struct adc_message* msg = list_get_first(q->queue);
if (!msg) return 0; if (!msg) return 0;
assert(msg->cache && *msg->cache);
ret = net_con_send(user->connection, msg->cache + q->offset, msg->length - q->offset); ret = net_con_send(user->connection, msg->cache + q->offset, msg->length - q->offset);
if (ret > 0) if (ret > 0)

View File

@@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * 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) static int set_feature_cast_supports(struct hub_user* u, struct adc_message* cmd)
{ {
char *it, *tmp; char *it, *tmp;
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_SUPPORT)) if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_SUPPORT))
{ {
tmp = adc_msg_get_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); user_set_feature_cast_support(u, it);
it = &it[5]; it = &it[5];
} }
if (*it) if (*it)
{ {
user_set_feature_cast_support(u, 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 x_pid[64];
char raw_pid[64]; char raw_pid[64];
uint64_t tiger_res[3]; uint64_t tiger_res[3];
memset(x_pid, 0, MAX_CID_LEN+1); memset(x_pid, 0, MAX_CID_LEN+1);
base32_decode(pid, (unsigned char*) raw_pid, MAX_CID_LEN); base32_decode(pid, (unsigned char*) raw_pid, MAX_CID_LEN);
tiger((uint64_t*) raw_pid, TIGERSIZE, (uint64_t*) tiger_res); tiger((uint64_t*) raw_pid, TIGERSIZE, (uint64_t*) tiger_res);
base32_encode((unsigned char*) tiger_res, TIGERSIZE, x_pid); 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); hub_free(pid);
return status_msg_error_no_memory; return status_msg_error_no_memory;
} }
if (strlen(cid) != MAX_CID_LEN) if (strlen(cid) != MAX_CID_LEN)
{ {
hub_free(cid); 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); hub_free(pid);
return status_msg_inf_error_cid_invalid; return status_msg_inf_error_cid_invalid;
} }
if (!is_valid_base32_char(pid[pos])) if (!is_valid_base32_char(pid[pos]))
{ {
hub_free(cid); 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); int64_t shared_size = atoll(arg);
if (shared_size < 0) if (shared_size < 0)
shared_size = 0; shared_size = 0;
if (user_is_logged_in(user)) if (user_is_logged_in(user))
{ {
hub->users->shared_size -= user->limits.shared_size; 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); hub_free(arg);
arg = 0; arg = 0;
} }
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES); arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
if (arg) if (arg)
{ {
ssize_t shared_files = atoll(arg); ssize_t shared_files = atoll(arg);
if (shared_files < 0) if (shared_files < 0)
shared_files = 0; shared_files = 0;
if (user_is_logged_in(user)) if (user_is_logged_in(user))
{ {
hub->users->shared_files -= user->limits.shared_files; 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); hub_free(arg);
arg = 0; arg = 0;
} }
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL); arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
if (arg) 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; 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)) || 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_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)) || (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; 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)) || 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_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))) (user->limits.hub_count_operator < hub_get_min_hubs_op(hub) && hub_get_min_hubs_op(hub)))
{ {
return status_msg_user_hub_limit_low; return status_msg_user_hub_limit_low;
} }
if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub)) if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub))
{ {
return status_msg_user_slots_low; 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: case cred_guest:
/* Nothing to be added to the info message */ /* Nothing to be added to the info message */
break; break;
case cred_user: case cred_user:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER);
break; break;
case cred_operator: case cred_operator:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
break; break;
@@ -571,11 +571,11 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
case cred_super: case cred_super:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
break; break;
case cred_admin: case cred_admin:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN);
break; break;
case cred_link: case cred_link:
break; break;
} }
@@ -670,13 +670,12 @@ int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct ad
int code = 0; int code = 0;
INF_CHECK(hub_perform_login_checks, hub, user, cmd); INF_CHECK(hub_perform_login_checks, hub, user, cmd);
/* Private ID must never be broadcasted - drop it! */ /* Private ID must never be broadcasted - drop it! */
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
code = set_credentials(hub, user, cmd); code = set_credentials(hub, user, cmd);
/* Note: this must be done *after* set_credentials. */ /* Note: this must be done *after* set_credentials. */
if (check_is_hub_full(hub, user)) 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); strip_network(user, cmd);
hub_handle_info_low_bandwidth(hub, user, cmd); hub_handle_info_low_bandwidth(hub, user, cmd);
user_update_info(user, cmd); user_update_info(user, cmd);
if (!adc_msg_is_empty(cmd)) if (!adc_msg_is_empty(cmd))
{ {
route_message(hub, user, cmd); route_message(hub, user, cmd);
} }
adc_msg_free(cmd); adc_msg_free(cmd);
} }
return 0; return 0;
} }

View File

@@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * 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 * 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 * it under the terms of the GNU General Public License as published by

View File

@@ -24,41 +24,16 @@
/* FIXME: This should not be needed! */ /* FIXME: This should not be needed! */
extern struct hub_info* g_hub; 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) int handle_net_read(struct hub_user* user)
{ {
static char buf[MAX_RECV_BUF]; static char buf[MAX_RECV_BUF];
struct hub_recvq* q = user->recv_queue; struct hub_recvq* q = user->recv_queue;
size_t buf_size = hub_recvq_get(q, buf, MAX_RECV_BUF); size_t buf_size = hub_recvq_get(q, buf, MAX_RECV_BUF);
ssize_t size = net_con_recv(user->connection, buf, MAX_RECV_BUF); ssize_t size;
if (user_flag_get(user, flag_maxbuf))
buf_size = 0;
size = net_con_recv(user->connection, buf + buf_size, MAX_RECV_BUF - buf_size);
if (size > 0) if (size > 0)
buf_size += size; buf_size += size;
@@ -219,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 */ /* FIXME: Should have a plugin log this */
LOG_TRACE("Got connection from %s", addr); LOG_TRACE("Got connection from %s", addr);
@@ -228,7 +203,7 @@ void net_on_accept(struct net_connection* con, int event, void *arg)
if (acl_is_ip_banned(hub->acl, addr)) if (acl_is_ip_banned(hub->acl, addr))
{ {
LOG_INFO("Denied [%s] (IP banned)", addr); LOG_INFO("Denied [%s] (IP banned)", addr);
net_con_close(con); net_close(fd);
continue; continue;
} }
@@ -236,7 +211,7 @@ void net_on_accept(struct net_connection* con, int event, void *arg)
if (!probe) if (!probe)
{ {
LOG_ERROR("Unable to create probe after socket accepted. Out of memory?"); LOG_ERROR("Unable to create probe after socket accepted. Out of memory?");
net_con_close(con); net_close(fd);
break; break;
} }
} }

View File

@@ -46,6 +46,13 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
if (memcmp(probe_recvbuf, "HSUP", 4) == 0) if (memcmp(probe_recvbuf, "HSUP", 4) == 0)
{ {
LOG_TRACE("Probed ADC"); LOG_TRACE("Probed ADC");
#ifdef SSL_SUPPORT
if (probe->hub->config->tls_enable && probe->hub->config->tls_require)
{
LOG_TRACE("Not TLS connection - closing connection.");
}
else
#endif
if (user_create(probe->hub, probe->connection, &probe->addr)) if (user_create(probe->hub, probe->connection, &probe->addr))
{ {
probe->connection = 0; probe->connection = 0;

View File

@@ -106,6 +106,8 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
if (!user->connection) if (!user->connection)
return 0; return 0;
assert(msg->cache && *msg->cache);
if (hub_sendq_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline)) if (hub_sendq_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline))
{ {
/* Perform oportunistic write */ /* Perform oportunistic write */

View File

@@ -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) void user_set_info(struct hub_user* user, struct adc_message* cmd)
{ {
adc_msg_free(user->info); 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) 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! */ /* FIXME: OOM! */
return; return;
} }
/* /*
* FIXME: Optimization potential: * FIXME: Optimization potential:
* *
@@ -127,10 +134,9 @@ static int convert_support_fourcc(int fourcc)
{ {
switch (fourcc) switch (fourcc)
{ {
case FOURCC('B','A','S','0'): /* Obsolete */ case FOURCC('B','A','S','0'):
#ifndef OLD_ADC_SUPPORT return feature_bas0;
return 0;
#endif
case FOURCC('B','A','S','E'): case FOURCC('B','A','S','E'):
return feature_base; return feature_base;

View File

@@ -45,6 +45,7 @@ enum user_flags
feature_ping = 0x00000080, /** PING: Hub pinger information extension */ feature_ping = 0x00000080, /** PING: Hub pinger information extension */
feature_link = 0x00000100, /** LINK: Hub link (not supported) */ feature_link = 0x00000100, /** LINK: Hub link (not supported) */
feature_adcs = 0x00000200, /** ADCS: ADC over TLS/SSL */ feature_adcs = 0x00000200, /** ADCS: ADC over TLS/SSL */
feature_bas0 = 0x00000400, /** BAS0: Obsolete pre-ADC/1.0 protocol version */
flag_muted = 0x00800000, /** User is muted (cannot chat) */ flag_muted = 0x00800000, /** User is muted (cannot chat) */
flag_ignore = 0x01000000, /** Ignore further reads */ flag_ignore = 0x01000000, /** Ignore further reads */
flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */ flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */

View File

@@ -155,7 +155,7 @@ int uman_remove(struct hub_info* hub, struct hub_user* user)
return -1; return -1;
list_remove(hub->users->list, user); list_remove(hub->users->list, user);
if (hub->users->count > 0) if (hub->users->count > 0)
{ {
hub->users->count--; hub->users->count--;
@@ -164,12 +164,12 @@ int uman_remove(struct hub_info* hub, struct hub_user* user)
{ {
assert(!"negative count!"); assert(!"negative count!");
} }
hub->users->shared_size -= user->limits.shared_size; hub->users->shared_size -= user->limits.shared_size;
hub->users->shared_files -= user->limits.shared_files; hub->users->shared_files -= user->limits.shared_files;
user->hub = 0; user->hub = 0;
return 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); user = (struct hub_user*) list_get_next(hub->users->list);
} }
#if 0 #if 0
FIXME: FIXME FIXME handle send queue excess FIXME: FIXME FIXME handle send queue excess
if (!target->send_queue_size) if (!target->send_queue_size)
@@ -248,12 +248,11 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user* target)
return ret; return ret;
} }
void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving) void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving)
{ {
struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6); struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6);
adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid)); adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid));
if (leaving->quit_reason == quit_banned || leaving->quit_reason == quit_kicked) if (leaving->quit_reason == quit_banned || leaving->quit_reason == quit_kicked)
{ {
adc_msg_add_argument(command, ADC_QUI_FLAG_DISCONNECT); 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); adc_msg_free(command);
} }
sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user) sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user)
{ {
sid_t sid = sid_alloc(hub->users->sids, user); sid_t sid = sid_alloc(hub->users->sids, user);

View File

@@ -76,7 +76,7 @@ int net_backend_init()
g_backend->common.num = 0; g_backend->common.num = 0;
g_backend->common.max = net_get_max_sockets(); g_backend->common.max = net_get_max_sockets();
g_backend->now = time(0); g_backend->now = time(0);
timeout_queue_initialize(&g_backend->timeout_queue, g_backend->now, 600); /* FIXME: max 600 secs! */ timeout_queue_initialize(&g_backend->timeout_queue, g_backend->now, 120); /* FIXME: max 120 secs! */
g_backend->cleaner = net_cleanup_initialize(g_backend->common.max); g_backend->cleaner = net_cleanup_initialize(g_backend->common.max);
for (n = 0; n < sizeof(net_backend_init_funcs); n++) for (n = 0; n < sizeof(net_backend_init_funcs); n++)

View File

@@ -35,7 +35,7 @@ void timeout_evt_reset(struct timeout_evt* t)
int timeout_evt_is_scheduled(struct timeout_evt* t) int timeout_evt_is_scheduled(struct timeout_evt* t)
{ {
return !!t->prev; return t->prev != NULL;
} }
void timeout_queue_initialize(struct timeout_queue* t, time_t now, size_t max) void timeout_queue_initialize(struct timeout_queue* t, time_t now, size_t max)
@@ -54,10 +54,11 @@ void timeout_queue_shutdown(struct timeout_queue* t)
size_t timeout_queue_process(struct timeout_queue* t, time_t now) size_t timeout_queue_process(struct timeout_queue* t, time_t now)
{ {
size_t pos; size_t pos = t->last;
size_t events = 0; size_t events = 0;
struct timeout_evt* evt = 0; struct timeout_evt* evt = 0;
for (pos = t->last; pos <= now; pos++) t->last = now;
for (; pos <= now; pos++)
{ {
while ((evt = t->events[pos % t->max])) while ((evt = t->events[pos % t->max]))
{ {
@@ -66,7 +67,6 @@ size_t timeout_queue_process(struct timeout_queue* t, time_t now)
events++; events++;
} }
} }
t->last = now;
return events; return events;
} }
@@ -94,6 +94,7 @@ void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size
if (first) if (first)
{ {
uhub_assert(first->timestamp == evt->timestamp);
first->prev->next = evt; first->prev->next = evt;
evt->prev = first->prev; evt->prev = first->prev;
first->prev = evt; first->prev = evt;