Compare commits

...

26 Commits

Author SHA1 Message Date
Jan Vidar Krey
e9915df87c remove timezone from logs, as it screws up on windows.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-21 04:11:14 +01:00
Jan Vidar Krey
408829e330 Another 0.2.7 candidate.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-21 03:59:12 +01:00
Jan Vidar Krey
1a1b5bdb38 Fixed nasty crash if a user sends a very large command to the hub.
Will overwrite heap memory.
Thanks to Toast who found this bug.

Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-21 02:58:53 +01:00
Jan Vidar Krey
abedec692a 0.2.7 release candidate
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:12:18 +01:00
Jan Vidar Krey
7738baf38e Log configuration reloads.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:09:55 +01:00
Jan Vidar Krey
3c4c52d0f9 Log configuration reloads.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:08:24 +01:00
Jan Vidar Krey
76588fb1bd Don't print OK or ERROR when dumping config.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:05:25 +01:00
Jan Vidar Krey
f9e95ec582 Minor cleanups
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:02:32 +01:00
Jan Vidar Krey
7985d4fed0 Cleanup credentials to string handling
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 18:54:05 +01:00
Jan Vidar Krey
77343d3c21 Remove duplicate access_denied checks.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 18:38:42 +01:00
Jan Vidar Krey
f8d5b72a89 Cleanup command list, automatically generate help list depending on user credentials. 2009-03-20 18:37:38 +01:00
Jan Vidar Krey
cf2994b570 Fix whitespace 2009-03-20 18:37:05 +01:00
Jan Vidar Krey
7a9d40d8dd Fix autotests for event queue.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 17:42:29 +01:00
Jan Vidar Krey
b1f84b5b4a Cleanup logging.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 17:40:50 +01:00
Jan Vidar Krey
998c6c36ce Fix indentation 2009-03-20 16:40:59 +01:00
Jan Vidar Krey
4112b8111a Fix problems with clients sending multiple INF messages during the login stage. Only the first one will be checked. 2009-03-20 16:40:34 +01:00
Jan Vidar Krey
1929f2fae7 Fix bug #9 - net_get_peer_address() failure on CentOS/Xen configurations.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 15:07:52 +01:00
Jan Vidar Krey
77e41371b5 Ensure we install to /usr/local by default.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 20:02:03 +01:00
Jan Vidar Krey
0266c8bb9c Libevent fixes, and memory leak fix.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 17:57:04 +01:00
Jan Vidar Krey
5e3eabb677 Fix help message typo
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 01:30:46 +01:00
Jan Vidar Krey
669ab14022 Minor cleanups and stack reduction.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 01:27:34 +01:00
Jan Vidar Krey
1d491055c5 Do not use event_loopexit with new event loop.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 01:13:02 +01:00
Jan Vidar Krey
08351ea8e7 Merge branch 'event_queue_work' 2009-03-19 01:08:57 +01:00
Jan Vidar Krey
e2ac690164 Reindented code. 2009-03-19 01:01:36 +01:00
Jan Vidar Krey
3bb563b432 Cleaned up command system somewhat. Added admin commands for reload and shutdown. 2009-03-19 00:55:11 +01:00
Jan Vidar Krey
e10582fec2 Cleaned up command system slightly.
Added admin commands for reload and shutdown.
2009-03-19 00:53:44 +01:00
15 changed files with 263 additions and 212 deletions

View File

@@ -1,4 +1,13 @@
0.2.7:
- Fixed a nasty crash (bug #11), Thanks Toast for finding it.
- Fix bug #9 - net_get_peer_address() failure on CentOS/Xen configurations.
- Write a log message if an operator reloads the config file.
- Don't print OK or ERROR when using '-s' or '-S' show the configuration.
- Cleanup credential string handling
- Made sure "!help" only display accessible commands.
- Cleanup in-hub command parsing
- Fix a possible crash if multiple INF messages are sent during login.
- Rewrote the mainloop to not use a timer.
0.2.6:

View File

@@ -32,7 +32,7 @@ BIN_EXT ?= .exe
else
DESTDIR ?= /
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
UHUB_PREFIX ?= $(DESTDIR)/usr/
UHUB_PREFIX ?= $(DESTDIR)/usr/local
CFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib
BIN_EXT ?=

View File

@@ -2,7 +2,6 @@
static struct event_queue* eq;
static int eq_val;
struct event* libevent_handle;
static void eq_callback(void* callback_data, struct event_data* event_data)
{
@@ -17,8 +16,6 @@ EXO_TEST(eventqueue_init_1, {
EXO_TEST(eventqueue_init_2, {
/* hack */
libevent_handle = eq->event;
eq->event = 0;
return eq->callback_data == &eq_val && eq->callback == eq_callback && eq->q1 && eq->q2 && !eq->locked;
});
@@ -81,7 +78,6 @@ EXO_TEST(eventqueue_size_4, {
});
EXO_TEST(eventqueue_shutdown_1, {
eq->event = libevent_handle;
event_queue_shutdown(eq);
return 1;
});

View File

@@ -23,7 +23,7 @@
#define ACL_ADD_BOOL(S, L) do { ret = check_cmd_bool(S, L, line, line_count); if (ret != 0) return ret; } while(0)
#define ACL_ADD_ADDR(S, L) do { ret = check_cmd_addr(S, L, line, line_count); if (ret != 0) return ret; } while(0)
static const char* get_user_credential_string(enum user_credentials cred)
const char* get_user_credential_string(enum user_credentials cred)
{
switch (cred)
{

View File

@@ -48,6 +48,8 @@ enum user_credentials
cred_link, /**<<< "User is a link (not used currently)" */
};
const char* get_user_credential_string(enum user_credentials cred);
struct user_access_info
{
char* username; /* name of user, cid or IP range */

View File

@@ -19,165 +19,175 @@
#include "uhub.h"
static int command_access_denied(struct user* user)
typedef int (*command_handler)(struct user* user, const char* message);
struct commands_handler
{
struct adc_message* command;
char* buffer = adc_msg_escape("Access denied.");
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
return 0;
const char* prefix;
size_t length;
enum user_credentials cred;
command_handler handler;
const char* description;
};
static struct commands_handler command_handlers[];
static void send_message(struct user* user, const char* message)
{
char* buffer = adc_msg_escape(message);
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
}
static int command_access_denied(struct user* user, const char* command)
{
char temp[64];
snprintf(temp, 64, "*** Access denied: \"%s\"", command);
send_message(user, temp);
return 0;
}
static int command_stats(struct user* user, const char* message)
{
struct adc_message* command;
if (user->credentials < cred_super)
return command_access_denied(user);
char temp[128];
snprintf(temp, 128, "*** Stats: %zu users, peak: %zu. Network (up/down): %d/%d KB/s, peak: %d/%d KB/s",
char temp[128];
snprintf(temp, 128, "*** Stats: %zu users, peak: %zu. Network (up/down): %d/%d KB/s, peak: %d/%d KB/s",
user->hub->users->count,
user->hub->users->count_peak,
(int) user->hub->stats.net_tx / 1024,
(int) user->hub->stats.net_rx / 1024,
(int) user->hub->stats.net_tx_peak / 1024,
(int) user->hub->stats.net_rx_peak / 1024);
char* buffer = adc_msg_escape(temp);
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
return 0;
send_message(user, temp);
return 0;
}
static int command_help(struct user* user, const char* message)
{
struct adc_message* command;
char* buffer = adc_msg_escape("\n"
"*** Available commands:\n"
"!help - Show this help message\n"
"!stats - Show hub stats (super)\n"
"!version - Show this help message\n"
"!uptime - Display hub uptime\n"
"!kick <user> - Kick user (operator)\n"
);
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
#define MAX_HELP_MSG 1024
size_t n;
char msg[MAX_HELP_MSG];
msg[0] = 0;
strcat(msg, "\n*** Available commands:\n");
for (n = 0; command_handlers[n].prefix; n++)
{
if (command_handlers[n].cred <= user->credentials)
{
strcat(msg, command_handlers[n].prefix);
strcat(msg, " - ");
strcat(msg, command_handlers[n].description);
strcat(msg, "\n");
}
}
send_message(user, msg);
return 0;
}
static int command_uptime(struct user* user, const char* message)
{
struct adc_message* command;
char tmp[128];
size_t d;
size_t h;
size_t m;
size_t D = (size_t) difftime(time(0), user->hub->tm_started);
char tmp[128];
size_t d;
size_t h;
size_t m;
size_t D = (size_t) difftime(time(0), user->hub->tm_started);
d = D / (24 * 3600);
D = D % (24 * 3600);
h = D / 3600;
D = D % 3600;
m = D / 60;
d = D / (24 * 3600);
D = D % (24 * 3600);
h = D / 3600;
D = D % 3600;
m = D / 60;
tmp[0] = 0;
strcat(tmp, "*** Uptime: ");
if (d)
{
strcat(tmp, uhub_itoa((int) d));
strcat(tmp, " day");
if (d != 1) strcat(tmp, "s");
strcat(tmp, ", ");
}
tmp[0] = 0;
strcat(tmp, "*** Uptime: ");
if (h < 10) strcat(tmp, "0");
strcat(tmp, uhub_itoa((int) h));
strcat(tmp, ":");
if (m < 10) strcat(tmp, "0");
strcat(tmp, uhub_itoa((int) m));
if (d)
{
strcat(tmp, uhub_itoa((int) d));
strcat(tmp, " day");
if (d != 1) strcat(tmp, "s");
strcat(tmp, ", ");
}
char* buffer = adc_msg_escape(tmp);
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
return 0;
if (h < 10) strcat(tmp, "0");
strcat(tmp, uhub_itoa((int) h));
strcat(tmp, ":");
if (m < 10) strcat(tmp, "0");
strcat(tmp, uhub_itoa((int) m));
send_message(user, tmp);
return 0;
}
static int command_kick(struct user* user, const char* message)
{
struct adc_message* command;
if (user->credentials < cred_operator)
return command_access_denied(user);
char* buffer = adc_msg_escape("*** Kick not implemented!");
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
return 0;
send_message(user, "*** Kick not implemented!");
return 0;
}
static int command_reload(struct user* user, const char* message)
{
send_message(user, "*** Reloading configuration");
user->hub->status = hub_status_restart;
return 0;
}
static int command_shutdown(struct user* user, const char* message)
{
send_message(user, "*** Hub shuting down...");
user->hub->status = hub_status_shutdown;
return 0;
}
static int command_version(struct user* user, const char* message)
{
struct adc_message* command;
char* buffer = adc_msg_escape("*** Powered by " PRODUCT "/" VERSION);
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
send_message(user, "*** Powered by " PRODUCT "/" VERSION);
return 0;
}
static int command_myip(struct user* user, const char* message)
{
struct adc_message* command;
char tmp[128];
char* buffer;
tmp[0] = 0;
strcat(tmp, "*** Your IP: ");
strcat(tmp, ip_convert_to_string(&user->ipaddr));
buffer = adc_msg_escape(tmp);
command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(user, command);
adc_msg_free(command);
hub_free(buffer);
snprintf(tmp, 128, "*** Your IP: %s", ip_convert_to_string(&user->ipaddr));
send_message(user, tmp);
return 0;
}
int command_dipatcher(struct user* user, const char* message)
{
if (!strncmp(message, "!stats", 6)) command_stats(user, message);
else if (!strncmp(message, "!help", 5)) command_help(user, message);
else if (!strncmp(message, "!kick", 5)) command_kick(user, message);
else if (!strncmp(message, "!version", 8)) command_version(user, message);
else if (!strncmp(message, "!uptime", 7)) command_uptime(user, message);
else if (!strncmp(message, "+myip", 5)) command_myip(user, message);
else
size_t n = 0;
for (n = 0; command_handlers[n].prefix; n++)
{
if (!strncmp(message, command_handlers[n].prefix, command_handlers[n].length))
{
if (command_handlers[n].cred <= user->credentials)
{
return command_handlers[n].handler(user, message);
}
else
{
return command_access_denied(user, &command_handlers[n].prefix[1]);
}
}
}
return 1;
return 0;
}
static struct commands_handler command_handlers[] = {
{ "!help", 5, cred_guest, command_help, "Show this help message." },
{ "!stats", 6, cred_super, command_stats, "Show hub statistics." },
{ "!version", 8, cred_guest, command_version, "Show hub version info." },
{ "!uptime", 7, cred_guest, command_uptime, "Display hub uptime info." },
{ "!kick", 5, cred_operator, command_kick, "Kick a user" },
{ "!reload", 7, cred_admin, command_reload, "Reload configuration files." },
{ "!shutdown", 9, cred_admin, command_shutdown, "Shutdown hub." },
{ "+myip", 5, cred_guest, command_myip, "Show your own IP." },
{ 0, 0, cred_none, command_help, "{ Last dummy option }" }
};

View File

@@ -479,7 +479,11 @@ struct hub_info* hub_start_service(struct hub_config* config)
net_address_to_string(AF_INET6, &((struct sockaddr_in6*) &addr)->sin6_addr, address_buf, INET6_ADDRSTRLEN);
}
#ifdef LIBEVENT_1_4
hub->evbase = event_base_new();
#else
hub->evbase = event_init();
#endif
if (!hub->evbase)
{
hub_log(log_error, "Unable to initialize libevent.");
@@ -487,7 +491,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
return 0;
}
hub_log(log_info, "Starting server, listening on %s:%d...", address_buf, config->server_port);
hub_log(log_info, "Starting " PRODUCT "/" VERSION ", listening on %s:%d...", address_buf, config->server_port);
server_tcp = net_socket_create(af, SOCK_STREAM, IPPROTO_TCP);
if (server_tcp == -1)

View File

@@ -19,12 +19,36 @@
#include "uhub.h"
static void log_user_login(struct user* u)
{
const char* cred = get_user_credential_string(u->credentials);
const char* addr = ip_convert_to_string(&u->ipaddr);
hub_log(log_user, "LoginOK %s/%s %s \"%s\" (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, cred, u->user_agent);
}
static void log_user_login_error(struct user* u, enum status_message msg)
{
const char* addr = ip_convert_to_string(&u->ipaddr);
const char* message = hub_get_status_message(u->hub, msg);
hub_log(log_user, "LoginError %s/%s %s \"%s\" (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, message, u->user_agent);
}
static void log_user_logout(struct user* u, const char* message)
{
const char* addr = ip_convert_to_string(&u->ipaddr);
hub_log(log_user, "Logout %s/%s %s \"%s\" (%s)", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, message);
}
static void log_user_nick_change(struct user* u, const char* nick)
{
const char* addr = ip_convert_to_string(&u->ipaddr);
hub_log(log_user, "NickChange %s/%s %s \"%s\" -> \"%s\"", sid_to_string(u->id.sid), u->id.cid, addr, u->id.nick, nick);
}
/* Send MOTD, do logging etc */
void on_login_success(struct user* u)
{
/* Logging - FIXME: Move this to a plugin */
const char* addr = ip_convert_to_string(&u->ipaddr);
const char* credentials_string[] = { "!none!", "link", "guest", "user", "operator", "super", "admin" };
struct timeval timeout = { TIMEOUT_IDLE, 0 };
/* Send user list of all existing users */
@@ -36,7 +60,7 @@ void on_login_success(struct user* u)
user_manager_add(u);
/* Print log message */
hub_log(log_user, "Login OK %s/%s \"%s\" [%s] (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, u->id.nick, addr, credentials_string[u->credentials], u->user_agent);
log_user_login(u);
/* Announce new user to all connected users */
if (user_is_logged_in(u))
@@ -51,36 +75,29 @@ void on_login_success(struct user* u)
event_add(u->ev_read, &timeout);
}
void on_login_failure(struct user* u, enum status_message msg)
{
const char* addr = ip_convert_to_string(&u->ipaddr);
const char* message = hub_get_status_message(u->hub, msg);
hub_log(log_user, "Login FAIL %s/%s \"%s\" [%s] (%s) \"%s\"", sid_to_string(u->id.sid), u->id.cid, u->id.nick, addr, message, u->user_agent);
log_user_login_error(u, msg);
hub_send_status(u, msg, status_level_fatal);
user_disconnect(u, quit_logon_error);
}
void on_nick_change(struct user* u, const char* nick)
{
if (user_is_logged_in(u))
{
hub_log(log_user, "Nick change %s/%s \"%s\" -> \"%s\"", sid_to_string(u->id.sid), u->id.cid, u->id.nick, nick);
log_user_nick_change(u, nick);
}
}
void on_logout_user(struct user* user)
{
const char* reason = "";
const char* addr;
/* These are used for logging purposes */
switch (user->quit_reason)
{
case quit_disconnected: reason = "disconnected"; break;
case quit_disconnected: reason = "disconnected"; break;
case quit_kicked: reason = "kicked"; break;
case quit_banned: reason = "banned"; break;
case quit_timeout: reason = "timeout"; break;
@@ -90,6 +107,7 @@ void on_logout_user(struct user* user)
case quit_protocol_error: reason = "protocol error"; break;
case quit_logon_error: reason = "login error"; break;
case quit_hub_disabled: reason = "hub disabled"; break;
case quit_ghost_timeout: reason = "ghost"; break;
default:
if (user->hub->status == hub_status_shutdown)
reason = "hub shutdown";
@@ -98,10 +116,7 @@ void on_logout_user(struct user* user)
break;
}
addr = ip_convert_to_string(&user->ipaddr);
hub_log(log_user, "Logout %s/%s \"%s\" [%s] (%s)", sid_to_string(user->id.sid), user->id.cid, user->id.nick, addr, reason);
log_user_logout(user, reason);
user->quit_reason = 0;
}

View File

@@ -332,7 +332,7 @@ static int check_logged_in(struct user* user, struct adc_message* cmd)
if (lookup1 == lookup2)
{
hub_log(log_debug, "check_logged_in: exact same user is logged in: %s", user->id.nick);
user_disconnect(lookup1, quit_timeout);
user_disconnect(lookup1, quit_ghost_timeout);
return 0;
}
else
@@ -645,6 +645,7 @@ void update_user_info(struct user* u, struct adc_message* cmd)
argument = adc_msg_get_argument(cmd, n++);
}
user_set_info(u, cmd_new);
adc_msg_free(cmd_new);
}
@@ -766,7 +767,7 @@ int hub_handle_info_login(struct user* user, struct adc_message* cmd)
*/
int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified)
{
struct adc_message* cmd = adc_msg_copy(cmd_unmodified); /* FIXME: Have a small memory leak here! */
struct adc_message* cmd = adc_msg_copy(cmd_unmodified);
if (!cmd) return -1; /* OOM */
cmd->priority = 1;
@@ -778,6 +779,16 @@ int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified)
*/
if (user_is_connecting(user))
{
/*
* Don't allow the user to send multiple INF messages in this stage!
* Since that can have serious side-effects.
*/
if (user->info)
{
adc_msg_free(cmd);
return 0;
}
int ret = hub_handle_info_login(user, cmd);
if (ret < 0)
{

View File

@@ -177,8 +177,8 @@ void hub_log(int log_verbosity, const char *format, ...)
if (log_verbosity < verbosity)
{
t = time(NULL);
tmp = gmtime(&t);
strftime(timestamp, 32, "%a, %d %b %Y %H:%M:%S +0000", tmp);
tmp = localtime(&t);
strftime(timestamp, 32, "%Y-%m-%d %H:%M:%S", tmp);
va_start(args, format);
vsnprintf(logmsg, 1024, format, args);
va_end(args);

View File

@@ -37,47 +37,29 @@ void hub_handle_signal(int fd, short events, void* arg)
{
struct hub_info* hub = (struct hub_info*) arg;
int signal = fd;
struct timeval now = {0, 0};
switch (signal)
{
case SIGINT:
hub_log(log_info, "Interrupted. Shutting down...");
hub->status = hub_status_shutdown;
event_loopexit(&now);
break;
case SIGTERM:
hub_log(log_info, "Terminated. Shutting down...");
hub->status = hub_status_shutdown;
event_loopexit(&now);
break;
case SIGPIPE:
hub_log(log_trace, "hub_handle_signal(): caught SIGPIPE (ignoring)");
break;
case SIGHUP:
hub_log(log_info, "Caught hangup signal. Reloading configuration files...");
hub->status = hub_status_restart;
event_loopexit(&now);
break;
case SIGUSR1:
hub_log(log_trace, "hub_handle_signal(): caught SIGUSR1 -- FIXME");
break;
case SIGUSR2:
hub_log(log_trace, "hub_handle_signal(): caught SIGUSR2");
{
user_manager_print_stats(hub);
}
break;
default:
hub_log(log_trace, "hub_handle_signal(): caught unknown signal: %d", signal);
hub->status = hub_status_shutdown;
event_loopexit(&now);
break;
}
}
@@ -89,8 +71,6 @@ static int signals[] =
SIGTERM, /* Terminate the application */
SIGPIPE, /* prevent sigpipe from kills the application */
SIGHUP, /* reload configuration */
SIGUSR1, /* dump statistics */
SIGUSR2, /* (unused) */
0
};
@@ -131,6 +111,11 @@ int main_loop()
do
{
if (hub)
{
hub_log(log_info, "Reloading configuration files...");
}
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
return -1;
@@ -188,6 +173,9 @@ int check_configuration(int dump)
puts("");
}
if (dump)
return 0;
if (ret == -1)
{
fprintf(stderr, "ERROR\n");

View File

@@ -25,10 +25,9 @@ void net_on_read(int fd, short ev, void *arg)
static char buf[MAX_RECV_BUF];
struct user* user = (struct user*) arg;
char* pos;
char* start;
ssize_t offset;
size_t offset;
size_t buflen;
ssize_t size;
ssize_t buflen;
int more = 1;
int flag_close = 0;
@@ -55,11 +54,7 @@ void net_on_read(int fd, short ev, void *arg)
memcpy(buf, user->recv_buf, user->recv_buf_offset);
offset = user->recv_buf_offset;
}
else
{
offset = 0;
}
size = net_recv(fd, &buf[offset], MAX_RECV_BUF - offset, 0);
if (size == -1)
{
@@ -75,40 +70,63 @@ void net_on_read(int fd, short ev, void *arg)
else
{
buflen = offset + size;
start = buf;
while ((pos = strchr(start, '\n')))
ssize_t handled = 0;
while ((pos = memchr(&buf[handled], '\n', (buflen - handled))))
{
pos[0] = '\0';
if (*start && strlen(start) < user->hub->config->max_recv_buffer)
{
if (hub_handle_message(user, start, &pos[0]-&start[0]) == -1)
{
flag_close = quit_protocol_error;
more = 0;
break;
}
}
start = &pos[1];
}
if (!more) break;
if (&buf[offset + size] > &start[0])
{
if (!user->recv_buf)
{
user->recv_buf = hub_malloc(user->hub->config->max_recv_buffer);
}
size_t msglen = &pos[0] - &buf[handled];
if (!user->recv_buf)
if (user_flag_get(user, flag_maxbuf))
{
flag_close = quit_memory_error;
break;
user_flag_unset(user, flag_maxbuf);
}
else
{
memcpy(user->recv_buf, start, &buf[offset + size] - &start[0]);
user->recv_buf_offset = &buf[offset + size] - &start[0];
if (msglen < user->hub->config->max_recv_buffer)
{
if (hub_handle_message(user, &buf[handled], msglen) == -1)
{
flag_close = quit_protocol_error;
more = 0;
break;
}
}
}
handled += msglen;
handled++;
}
if (handled == 0 && user_flag_get(user, flag_maxbuf))
handled = buflen;
if (!more)
break;
if (handled < buflen)
{
if ((buflen - handled) > user->hub->config->max_recv_buffer)
{
user_flag_set(user, flag_maxbuf);
hub_free(user->recv_buf);
user->recv_buf = 0;
user->recv_buf_offset = 0;
}
else
{
if (!user->recv_buf)
user->recv_buf = hub_malloc(user->hub->config->max_recv_buffer);
if (user->recv_buf)
{
memcpy(user->recv_buf, &buf[handled], buflen - handled);
user->recv_buf_offset = buflen - handled;
}
else
{
flag_close = quit_memory_error;
break;
}
}
}
else
@@ -242,11 +260,10 @@ void net_on_accept(int server_fd, short ev, void *arg)
{
struct hub_info* hub = (struct hub_info*) arg;
struct user* user = 0;
int accept_more = 1;
const char* addr;
struct timeval timeout = { TIMEOUT_CONNECTED, 0 };
while (accept_more)
for (;;)
{
int fd = net_accept(server_fd);
if (fd == -1)
@@ -294,7 +311,6 @@ void net_on_accept(int server_fd, short ev, void *arg)
event_base_set(hub->evbase, user->ev_read);
event_base_set(hub->evbase, user->ev_write);
event_add(user->ev_read, &timeout);
}
}

View File

@@ -465,11 +465,9 @@ const char* net_get_peer_address(int fd)
name4 = (struct sockaddr_in*) &storage;
name = (struct sockaddr*) &storage;
int af = net_is_ipv6_supported() ? AF_INET6 : AF_INET;
if (getpeername(fd, (struct sockaddr*) name, &namelen) != -1)
{
int af = name4->sin_family;
if (af == AF_INET6)
{
net_address_to_string(af, (void*) &name6->sin6_addr, address, INET6_ADDRSTRLEN);

View File

@@ -35,7 +35,7 @@ enum user_state
};
enum user_flags
enum user_flags
{
feature_base = 0x00000001, /** BASE: Basic configuration (required by all clients) */
feature_auto = 0x00000002, /** AUT0: Automatic nat detection traversal */
@@ -47,11 +47,12 @@ enum user_flags
feature_ping = 0x00000080, /** PING: Hub pinger information extension */
feature_link = 0x00000100, /** LINK: Hub link (not supported) */
flag_ignore = 0x01000000, /** Ignore further reads */
flag_choke = 0x02000000, /** Choked: Cannot send, waiting for write event */
flag_want_read = 0x04000000, /** Need to read (SSL) */
flag_want_write = 0x08000000, /** Need to write (SSL) */
flag_user_list = 0x10000000, /** Send queue bypass (when receiving the send queue) */
flag_nat = 0x20000000, /** nat override enabled */
flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */
flag_choke = 0x04000000, /** Choked: Cannot send, waiting for write event */
flag_want_read = 0x08000000, /** Need to read (SSL) */
flag_want_write = 0x10000000, /** Need to write (SSL) */
flag_user_list = 0x20000000, /** Send queue bypass (when receiving the send queue) */
flag_nat = 0x40000000, /** nat override enabled */
};
@@ -68,12 +69,13 @@ enum user_quit_reason
quit_protocol_error = 8, /** Fatal protocol error */
quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */
quit_hub_disabled = 10, /** Hub is disabled. No new connections allowed */
quit_ghost_timeout = 11, /** The user is a ghost, and trying to login from another connection */
};
struct user_info
{
sid_t sid; /** session ID */
sid_t sid; /** session ID */
char cid[MAX_CID_LEN+1]; /** global client ID */
char nick[MAX_NICK_LEN+1]; /** User's nick name */
};

View File

@@ -7,7 +7,7 @@
#endif
#ifndef VERSION
#define VERSION "0.2.7-alpha"
#define VERSION "0.2.7"
#endif
#ifndef COPYRIGHT