Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e579f4601 | ||
|
|
e220357176 | ||
|
|
8bed952022 | ||
|
|
c4604a7e94 | ||
|
|
236daeae53 | ||
|
|
862c6a1baf | ||
|
|
198d86a1ee | ||
|
|
2ded9f3e09 | ||
|
|
59ed268f4d | ||
|
|
963416ad73 | ||
|
|
29c162727c | ||
|
|
1ce258bccf | ||
|
|
0de66286fa | ||
|
|
1a98bb6810 | ||
|
|
5e6879dffb | ||
|
|
1b56adb8c0 | ||
|
|
685597c795 |
23
GNUmakefile
23
GNUmakefile
@@ -3,6 +3,8 @@
|
||||
## Copyright (C) 2007-2010, Jan Vidar Krey <janvidar@extatic.org>
|
||||
#
|
||||
|
||||
-include Makefile.private
|
||||
|
||||
CC = gcc
|
||||
LD := $(CC)
|
||||
MV := mv
|
||||
@@ -116,7 +118,7 @@ CFLAGS += -DSSL_SUPPORT
|
||||
LDLIBS += -lssl
|
||||
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 "")
|
||||
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
|
||||
|
||||
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_memory.tcc \
|
||||
autotest/test_ipfilter.tcc \
|
||||
autotest/test_inf.tcc \
|
||||
autotest/test_hub.tcc \
|
||||
autotest/test_message.tcc \
|
||||
autotest/test_misc.tcc \
|
||||
autotest/test_sid.tcc \
|
||||
autotest/test_tiger.tcc \
|
||||
autotest/test_usermanager.tcc \
|
||||
autotest/test_eventqueue.tcc
|
||||
autotest/test_timer.tcc \
|
||||
autotest/test_usermanager.tcc
|
||||
|
||||
autotest_OBJECTS = autotest.o
|
||||
|
||||
@@ -222,7 +226,8 @@ revision.h.tmp:
|
||||
version.h: revision.h
|
||||
|
||||
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
|
||||
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
|
||||
@@ -251,7 +256,7 @@ dist-clean:
|
||||
@rm -rf $(all_OBJECTS) *~ core
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
|
||||
@@ -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, {
|
||||
|
||||
138
autotest/test_sid.tcc
Normal file
138
autotest/test_sid.tcc
Normal 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
119
autotest/test_timer.tcc
Normal 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;
|
||||
});
|
||||
@@ -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
|
||||
@@ -26,7 +26,9 @@
|
||||
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
|
||||
#define ADC_MSG_ASSERT(X) do { } while(0)
|
||||
#endif /* DEBUG */
|
||||
@@ -53,40 +55,18 @@ static void* msg_malloc_zero(size_t size)
|
||||
static void msg_free(void* 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
|
||||
|
||||
#define msg_malloc(X) hub_malloc(X)
|
||||
#define msg_malloc_zero(X) hub_malloc_zero(X)
|
||||
#define msg_free(X) hub_free(X)
|
||||
|
||||
#endif /* MSG_MEMORY_DEBUG */
|
||||
|
||||
|
||||
struct adc_message* adc_msg_incref(struct adc_message* msg)
|
||||
{
|
||||
if (!msg) return 0;
|
||||
#ifndef ADC_MESSAGE_INCREF
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_unprotect(msg);
|
||||
#endif
|
||||
msg->references++;
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(msg);
|
||||
@@ -204,20 +184,15 @@ void adc_msg_free(struct adc_message* msg)
|
||||
|
||||
ADC_MSG_ASSERT(msg);
|
||||
|
||||
if (msg->references > 0)
|
||||
msg->references--;
|
||||
|
||||
if (msg->references == 0)
|
||||
{
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_unprotect(msg);
|
||||
#endif
|
||||
msg->references--;
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(msg);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_unprotect(msg);
|
||||
#ifdef ADC_MSG_NULL_ON_FREE
|
||||
if (msg->cache)
|
||||
{
|
||||
*msg->cache = 0;
|
||||
}
|
||||
#endif
|
||||
msg_free(msg->cache);
|
||||
|
||||
@@ -256,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;
|
||||
|
||||
@@ -295,9 +270,6 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd)
|
||||
|
||||
ADC_MSG_ASSERT(copy);
|
||||
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(copy);
|
||||
#endif
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -360,6 +332,7 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
||||
|
||||
command->cmd = FOURCC(line[0], line[1], line[2], line[3]);
|
||||
command->priority = 0;
|
||||
command->references = 1;
|
||||
|
||||
switch (prefix)
|
||||
{
|
||||
@@ -443,7 +416,6 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
||||
|
||||
if (n == 10)
|
||||
ok = 0;
|
||||
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
@@ -510,10 +482,6 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
||||
}
|
||||
|
||||
ADC_MSG_ASSERT(command);
|
||||
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(command);
|
||||
#endif
|
||||
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* msg = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
|
||||
|
||||
if (!msg)
|
||||
return NULL; /* OOM */
|
||||
|
||||
@@ -554,11 +521,7 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
||||
|
||||
msg->cmd = fourcc;
|
||||
msg->priority = 0;
|
||||
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(msg);
|
||||
#endif
|
||||
|
||||
msg->references = 1;
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -698,10 +661,6 @@ void adc_msg_terminate(struct adc_message* cmd)
|
||||
adc_msg_cache_append(cmd, "\n", 1);
|
||||
}
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_protect(cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIXME: this looks bogus */
|
||||
@@ -709,10 +668,6 @@ void adc_msg_unterminate(struct adc_message* cmd)
|
||||
{
|
||||
ADC_MSG_ASSERT(cmd);
|
||||
|
||||
#ifdef MSG_MEMORY_DEBUG
|
||||
adc_msg_unprotect(cmd);
|
||||
#endif
|
||||
|
||||
if (cmd->length > 0 && cmd->cache[cmd->length-1] == '\n')
|
||||
{
|
||||
cmd->length--;
|
||||
@@ -884,9 +839,6 @@ 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);
|
||||
@@ -905,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++;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -119,6 +119,14 @@ void sid_pool_destroy(struct sid_pool* pool)
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
if (!sid || (sid > pool->max))
|
||||
if (!sid || (sid >= pool->max))
|
||||
return 0;
|
||||
return pool->map[sid];
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
#define DEF_SHOW_BANNER 1
|
||||
#define DEF_SHOW_BANNER_SYS_INFO 1
|
||||
#define DEF_REGISTERED_USERS_ONLY 0
|
||||
#define DEF_OBSOLETE_CLIENTS 0
|
||||
#define DEF_CHAT_ONLY 0
|
||||
#define DEF_CHAT_IS_PRIVILEGED 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_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_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)
|
||||
{
|
||||
@@ -195,6 +198,7 @@ void config_defaults(struct hub_config* config)
|
||||
DEFAULT_INTEGER(max_send_buffer_soft, DEF_MAX_SEND_BUFFER_SOFT);
|
||||
DEFAULT_BOOLEAN(show_banner, DEF_SHOW_BANNER);
|
||||
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_is_privileged, DEF_CHAT_IS_PRIVILEGED);
|
||||
DEFAULT_BOOLEAN(low_bandwidth_mode, DEF_LOW_BANDWIDTH_MODE);
|
||||
@@ -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_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_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_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_BOOL(show_banner);
|
||||
GET_BOOL(show_banner_sys_info);
|
||||
GET_BOOL(obsolete_clients);
|
||||
GET_BOOL(chat_only);
|
||||
GET_BOOL(chat_is_privileged);
|
||||
GET_BOOL(low_bandwidth_mode);
|
||||
@@ -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_hub_limit_low);
|
||||
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_require);
|
||||
GET_STR (tls_certificate);
|
||||
GET_STR (tls_private_key);
|
||||
|
||||
/* Still here -- unknown directive */
|
||||
/* Still here -- unknown directive */
|
||||
LOG_ERROR("Unknown configuration directive: '%s'", key);
|
||||
return -1;
|
||||
}
|
||||
@@ -370,6 +380,8 @@ void free_config(struct hub_config* config)
|
||||
hub_free(config->msg_user_slots_high);
|
||||
hub_free(config->msg_user_hub_limit_low);
|
||||
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_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_BOOL(show_banner, DEF_SHOW_BANNER);
|
||||
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_is_privileged, DEF_CHAT_IS_PRIVILEGED);
|
||||
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_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_proto_no_common_hash, DEF_MSG_PROTO_NO_COMMON_HASH);
|
||||
DUMP_STR (msg_proto_obsolete_adc0, DEF_MSG_PROTO_OBSOLETE_ADC0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 max_users; /**<<< "Maximum number of users allowed on the hub (default: 500)" */
|
||||
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_is_privileged; /**<<< "Allow chat for operators and above only (default: 0) */
|
||||
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_hub_limit_low; /**<<< "User is on too few 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_require; /**<<< "If SSL/TLS enabled, should it be required (default: 0) */
|
||||
|
||||
125
src/core/hub.c
125
src/core/hub.c
@@ -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 (index == 0) ok = 0; /* Need to support *SOMETHING*, at least BASE */
|
||||
|
||||
if (ok)
|
||||
{
|
||||
hub_send_handshake(hub, u);
|
||||
net_con_set_timeout(u->connection, TIMEOUT_HANDSHAKE);
|
||||
}
|
||||
else
|
||||
if (!ok)
|
||||
{
|
||||
/* disconnect user. Do not send crap during initial handshake! */
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if (config->tls_enable)
|
||||
if (!load_ssl_certificates(hub, config))
|
||||
{
|
||||
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);
|
||||
hub_free(hub);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -667,6 +714,10 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||
{
|
||||
LOG_DEBUG("hub_shutdown_service()");
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
unload_ssl_certificates(hub);
|
||||
#endif
|
||||
|
||||
event_queue_shutdown(hub->queue);
|
||||
net_con_close(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_hub_limit_low, 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
|
||||
|
||||
@@ -886,14 +939,14 @@ void hub_send_status(struct hub_info* hub, struct hub_user* user, enum status_me
|
||||
if (level >= status_level_fatal)
|
||||
{
|
||||
snprintf(buf, 230, "MS%s", escaped_text);
|
||||
adc_msg_add_argument(cmd, buf);
|
||||
adc_msg_add_argument(qui, buf);
|
||||
|
||||
if (reconnect_time != 0)
|
||||
{
|
||||
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);
|
||||
@@ -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_hub_limit_low);
|
||||
STATUS(msg_user_hub_limit_high);
|
||||
STATUS(msg_proto_no_common_hash);
|
||||
STATUS(msg_proto_obsolete_adc0);
|
||||
}
|
||||
#undef STATUS
|
||||
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_hub_limit_low);
|
||||
STATUS(msg_user_hub_limit_high);
|
||||
STATUS(msg_proto_no_common_hash);
|
||||
STATUS(msg_proto_obsolete_adc0);
|
||||
}
|
||||
#undef STATUS
|
||||
return "unknown";
|
||||
|
||||
@@ -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_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 */
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ void hub_sendq_add(struct hub_sendq* q, struct adc_message* msg_)
|
||||
#ifdef DEBUG_SENDQ
|
||||
debug_msg("hub_sendq_add", msg);
|
||||
#endif
|
||||
assert(msg->cache && *msg->cache);
|
||||
list_append(q->queue, msg);
|
||||
q->size += msg->length;
|
||||
}
|
||||
@@ -146,7 +147,7 @@ int hub_sendq_send(struct hub_sendq* q, struct hub_user* user)
|
||||
int ret;
|
||||
struct adc_message* msg = list_get_first(q->queue);
|
||||
if (!msg) return 0;
|
||||
|
||||
assert(msg->cache && *msg->cache);
|
||||
ret = net_con_send(user->connection, msg->cache + q->offset, msg->length - q->offset);
|
||||
|
||||
if (ret > 0)
|
||||
|
||||
@@ -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
|
||||
@@ -674,7 +674,6 @@ int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct ad
|
||||
/* 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. */
|
||||
@@ -798,3 +797,5 @@ int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct ad
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -24,41 +24,16 @@
|
||||
/* 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];
|
||||
struct hub_recvq* q = user->recv_queue;
|
||||
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)
|
||||
buf_size += size;
|
||||
@@ -228,7 +203,7 @@ void net_on_accept(struct net_connection* con, int event, void *arg)
|
||||
if (acl_is_ip_banned(hub->acl, addr))
|
||||
{
|
||||
LOG_INFO("Denied [%s] (IP banned)", addr);
|
||||
net_con_close(con);
|
||||
net_close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -236,7 +211,7 @@ void net_on_accept(struct net_connection* con, int event, void *arg)
|
||||
if (!probe)
|
||||
{
|
||||
LOG_ERROR("Unable to create probe after socket accepted. Out of memory?");
|
||||
net_con_close(con);
|
||||
net_close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
||||
if (memcmp(probe_recvbuf, "HSUP", 4) == 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
probe->connection = 0;
|
||||
|
||||
@@ -106,6 +106,8 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
|
||||
if (!user->connection)
|
||||
return 0;
|
||||
|
||||
assert(msg->cache && *msg->cache);
|
||||
|
||||
if (hub_sendq_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline))
|
||||
{
|
||||
/* Perform oportunistic write */
|
||||
|
||||
@@ -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)
|
||||
@@ -127,10 +134,9 @@ static int convert_support_fourcc(int fourcc)
|
||||
{
|
||||
switch (fourcc)
|
||||
{
|
||||
case FOURCC('B','A','S','0'): /* Obsolete */
|
||||
#ifndef OLD_ADC_SUPPORT
|
||||
return 0;
|
||||
#endif
|
||||
case FOURCC('B','A','S','0'):
|
||||
return feature_bas0;
|
||||
|
||||
case FOURCC('B','A','S','E'):
|
||||
return feature_base;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ enum user_flags
|
||||
feature_ping = 0x00000080, /** PING: Hub pinger information extension */
|
||||
feature_link = 0x00000100, /** LINK: Hub link (not supported) */
|
||||
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_ignore = 0x01000000, /** Ignore further reads */
|
||||
flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */
|
||||
|
||||
@@ -248,7 +248,6 @@ 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);
|
||||
@@ -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);
|
||||
|
||||
@@ -76,7 +76,7 @@ int net_backend_init()
|
||||
g_backend->common.num = 0;
|
||||
g_backend->common.max = net_get_max_sockets();
|
||||
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);
|
||||
|
||||
for (n = 0; n < sizeof(net_backend_init_funcs); n++)
|
||||
|
||||
@@ -35,7 +35,7 @@ void timeout_evt_reset(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)
|
||||
@@ -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 pos;
|
||||
size_t pos = t->last;
|
||||
size_t events = 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]))
|
||||
{
|
||||
@@ -66,7 +67,6 @@ size_t timeout_queue_process(struct timeout_queue* t, time_t now)
|
||||
events++;
|
||||
}
|
||||
}
|
||||
t->last = now;
|
||||
return events;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size
|
||||
|
||||
if (first)
|
||||
{
|
||||
uhub_assert(first->timestamp == evt->timestamp);
|
||||
first->prev->next = evt;
|
||||
evt->prev = first->prev;
|
||||
first->prev = evt;
|
||||
|
||||
Reference in New Issue
Block a user