diff --git a/GNUmakefile b/GNUmakefile index 55ac718..c4bfe41 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -189,6 +189,7 @@ autotest_SOURCES := \ autotest/test_hub.tcc \ autotest/test_misc.tcc \ autotest/test_tiger.tcc \ + autotest/test_usermanager.tcc \ autotest/test_eventqueue.tcc autotest_OBJECTS = autotest.o diff --git a/src/commands.c b/src/commands.c index 736457e..bd6b13e 100644 --- a/src/commands.c +++ b/src/commands.c @@ -19,7 +19,7 @@ #include "uhub.h" -typedef int (*command_handler)(struct user* user, const char* message); +typedef int (*command_handler)(struct hub_info* hub, struct user* user, const char* message); struct commands_handler { @@ -32,7 +32,7 @@ struct commands_handler static struct commands_handler command_handlers[]; -static void send_message(struct user* user, const char* message) +static void send_message(struct hub_info* hub, 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); @@ -42,45 +42,45 @@ static void send_message(struct user* user, const char* message) hub_free(buffer); } -static int command_access_denied(struct user* user, const char* command) +static int command_access_denied(struct hub_info* hub, struct user* user, const char* command) { char temp[128]; snprintf(temp, 128, "*** Access denied: \"%s\"", command); - send_message(user, temp); + send_message(hub, user, temp); return 0; } -static int command_not_found(struct user* user, const char* command) +static int command_not_found(struct hub_info* hub, struct user* user, const char* command) { char temp[128]; snprintf(temp, 128, "*** Command not found: \"%s\"", command); - send_message(user, temp); + send_message(hub, user, temp); return 0; } -static int command_status(struct user* user, const char* command, const char* message) +static int command_status(struct hub_info* hub, struct user* user, const char* command, const char* message) { char temp[1024]; snprintf(temp, 1024, "*** %s: %s", command, message); - send_message(user, temp); + send_message(hub, user, temp); return 0; } -static int command_stats(struct user* user, const char* message) +static int command_stats(struct hub_info* hub, struct user* user, const char* message) { char temp[128]; snprintf(temp, 128, "%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); + hub->users->count, + hub->users->count_peak, + (int) hub->stats.net_tx / 1024, + (int) hub->stats.net_rx / 1024, + (int) hub->stats.net_tx_peak / 1024, + (int) hub->stats.net_rx_peak / 1024); - return command_status(user, "stats", message); + return command_status(hub, user, "stats", message); } -static int command_help(struct user* user, const char* message) +static int command_help(struct hub_info* hub, struct user* user, const char* message) { #define MAX_HELP_MSG 1024 size_t n; @@ -99,16 +99,16 @@ static int command_help(struct user* user, const char* message) strcat(msg, "\n"); } } - return command_status(user, "help", msg); + return command_status(hub, user, "help", msg); } -static int command_uptime(struct user* user, const char* message) +static int command_uptime(struct hub_info* hub, struct user* user, const char* message) { char tmp[128]; size_t d; size_t h; size_t m; - size_t D = (size_t) difftime(time(0), user->hub->tm_started); + size_t D = (size_t) difftime(time(0), hub->tm_started); d = D / (24 * 3600); D = D % (24 * 3600); @@ -131,59 +131,58 @@ static int command_uptime(struct user* user, const char* message) if (m < 10) strcat(tmp, "0"); strcat(tmp, uhub_itoa((int) m)); - return command_status(user, "uptime", tmp); + return command_status(hub, user, "uptime", tmp); } -static int command_kick(struct user* user, const char* message) +static int command_kick(struct hub_info* hub, struct user* user, const char* message) { if (strlen(message) < 7) { - return command_status(user, "kick", "No nickname given"); + return command_status(hub, user, "kick", "No nickname given"); } const char* nick = &message[7]; - struct user* target = get_user_by_nick(user->hub, nick); + struct user* target = get_user_by_nick(hub, nick); if (!target) { - return command_status(user, "kick", "No such user"); + return command_status(hub, user, "kick", "No such user"); } if (target == user) { - return command_status(user, "kick", "Cannot kick yourself"); + return command_status(hub, user, "kick", "Cannot kick yourself"); } user_disconnect(target, quit_kicked); - return command_status(user, "kick", nick); + return command_status(hub, user, "kick", nick); } -static int command_reload(struct user* user, const char* message) +static int command_reload(struct hub_info* hub, struct user* user, const char* message) { - user->hub->status = hub_status_restart; - return command_status(user, "reload", "Reloading configuration..."); + hub->status = hub_status_restart; + return command_status(hub, user, "reload", "Reloading configuration..."); } -static int command_shutdown(struct user* user, const char* message) +static int command_shutdown(struct hub_info* hub, struct user* user, const char* message) { - user->hub->status = hub_status_shutdown; - return command_status(user, "shutdown", "Hub shutting down..."); + hub->status = hub_status_shutdown; + return command_status(hub, user, "shutdown", "Hub shutting down..."); } - -static int command_version(struct user* user, const char* message) +static int command_version(struct hub_info* hub, struct user* user, const char* message) { - return command_status(user, "version", "Powered by " PRODUCT "/" VERSION); + return command_status(hub, user, "version", "Powered by " PRODUCT "/" VERSION); } -static int command_myip(struct user* user, const char* message) +static int command_myip(struct hub_info* hub, struct user* user, const char* message) { char tmp[128]; snprintf(tmp, 128, "Your IP is \"%s\"", ip_convert_to_string(&user->ipaddr)); - return command_status(user, "myip", tmp); + return command_status(hub, user, "myip", tmp); } -int command_dipatcher(struct user* user, const char* message) +int command_dipatcher(struct hub_info* hub, struct user* user, const char* message) { size_t n = 0; for (n = 0; command_handlers[n].prefix; n++) @@ -192,16 +191,16 @@ int command_dipatcher(struct user* user, const char* message) { if (command_handlers[n].cred <= user->credentials) { - return command_handlers[n].handler(user, message); + return command_handlers[n].handler(hub, user, message); } else { - return command_access_denied(user, command_handlers[n].prefix); + return command_access_denied(hub, user, command_handlers[n].prefix); } } } - command_not_found(user, message); + command_not_found(hub, user, message); return 1; } diff --git a/src/commands.h b/src/commands.h index 4c26c83..82eb2b4 100644 --- a/src/commands.h +++ b/src/commands.h @@ -32,4 +32,4 @@ struct command_info plugin_event_chat_message function; }; -int command_dipatcher(struct user* user, const char* message); +int command_dipatcher(struct hub_info* hub, struct user* user, const char* message); diff --git a/src/hub.c b/src/hub.c index 96b0f89..4e80005 100644 --- a/src/hub.c +++ b/src/hub.c @@ -19,7 +19,7 @@ #include "uhub.h" -int hub_handle_message(struct user* u, const char* line, size_t length) +int hub_handle_message(struct hub_info* hub, struct user* u, const char* line, size_t length) { int ret = 0; struct adc_message* cmd = 0; @@ -36,12 +36,12 @@ int hub_handle_message(struct user* u, const char* line, size_t length) { switch (cmd->cmd) { - case ADC_CMD_HSUP: ret = hub_handle_support(u, cmd); break; - case ADC_CMD_HPAS: ret = hub_handle_password(u, cmd); break; - case ADC_CMD_BINF: ret = hub_handle_info(u, cmd); break; + case ADC_CMD_HSUP: ret = hub_handle_support(hub, u, cmd); break; + case ADC_CMD_HPAS: ret = hub_handle_password(hub, u, cmd); break; + case ADC_CMD_BINF: ret = hub_handle_info(hub, u, cmd); break; #ifdef ADC_UDP_OPERATION - case ADC_CMD_HCHK: ret = hub_handle_autocheck(u, cmd); break; + case ADC_CMD_HCHK: ret = hub_handle_autocheck(hub, u, cmd); break; #endif case ADC_CMD_DINF: case ADC_CMD_EINF: @@ -54,7 +54,7 @@ int hub_handle_message(struct user* u, const char* line, size_t length) case ADC_CMD_DMSG: case ADC_CMD_BMSG: case ADC_CMD_FMSG: - ret = hub_handle_chat_message(u, cmd); + ret = hub_handle_chat_message(hub, u, cmd); break; case ADC_CMD_BSCH: @@ -65,7 +65,7 @@ int hub_handle_message(struct user* u, const char* line, size_t length) case ADC_CMD_DRCM: case ADC_CMD_DCTM: cmd->priority = -1; - if (u->hub->config->chat_only && u->credentials < cred_operator) + if (hub->config->chat_only && u->credentials < cred_operator) { /* These below aren't allowed in chat only hubs */ break; @@ -96,7 +96,7 @@ int hub_handle_message(struct user* u, const char* line, size_t length) } -int hub_handle_support(struct user* u, struct adc_message* cmd) +int hub_handle_support(struct hub_info* hub, struct user* u, struct adc_message* cmd) { int ret = 0; int index = 0; @@ -104,9 +104,9 @@ int hub_handle_support(struct user* u, struct adc_message* cmd) char* arg = adc_msg_get_argument(cmd, index); struct timeval timeout = { TIMEOUT_HANDSHAKE, 0 }; - if (u->hub->status == hub_status_disabled && u->state == state_protocol) + if (hub->status == hub_status_disabled && u->state == state_protocol) { - on_login_failure(u, status_msg_hub_disabled); + on_login_failure(hub, u, status_msg_hub_disabled); return -1; } @@ -145,7 +145,7 @@ int hub_handle_support(struct user* u, struct adc_message* cmd) if (ok) { - hub_send_handshake(u); + hub_send_handshake(hub, u); if (u->ev_read) event_add(u->ev_read, &timeout); } @@ -161,7 +161,7 @@ int hub_handle_support(struct user* u, struct adc_message* cmd) } -int hub_handle_password(struct user* u, struct adc_message* cmd) +int hub_handle_password(struct hub_info* hub, struct user* u, struct adc_message* cmd) { char* password = adc_msg_get_argument(cmd, 0); int ret = 0; @@ -170,11 +170,11 @@ int hub_handle_password(struct user* u, struct adc_message* cmd) { if (password_verify(u, password)) { - on_login_success(u); + on_login_success(hub, u); } else { - on_login_failure(u, status_msg_auth_invalid_password); + on_login_failure(hub, u, status_msg_auth_invalid_password); ret = -1; } } @@ -184,7 +184,7 @@ int hub_handle_password(struct user* u, struct adc_message* cmd) } -int hub_handle_chat_message(struct user* u, struct adc_message* cmd) +int hub_handle_chat_message(struct hub_info* hub, struct user* u, struct adc_message* cmd) { char* message = adc_msg_get_argument(cmd, 0); int ret = 0; @@ -193,7 +193,7 @@ int hub_handle_chat_message(struct user* u, struct adc_message* cmd) /* TODO: Check for hub-commands here. Set relay to 0 and the message will not be sent to other users. */ if (message[0] == '!' || message[0] == '+') { - relay = command_dipatcher(u, message); + relay = command_dipatcher(hub, u, message); } if (relay && user_is_logged_in(u)) @@ -244,29 +244,29 @@ int hub_handle_autocheck(struct user* u, struct adc_message* cmd) } #endif - +#ifdef ADC_UDP_OPERATION void hub_send_autocheck(struct user* u, uint16_t port, const char* token) { } +#endif - -void hub_send_support(struct user* u) +void hub_send_support(struct hub_info* hub, struct user* u) { if (user_is_connecting(u) || user_is_logged_in(u)) { - route_to_user(u, u->hub->command_support); + route_to_user(u, hub->command_support); } } -void hub_send_sid(struct user* u) +void hub_send_sid(struct hub_info* hub, struct user* u) { struct adc_message* command; if (user_is_connecting(u)) { command = adc_msg_construct(ADC_CMD_ISID, 10); - u->id.sid = user_manager_get_free_sid(u->hub); + u->id.sid = user_manager_get_free_sid(hub); adc_msg_add_argument(command, (const char*) sid_to_string(u->id.sid)); route_to_user(u, command); adc_msg_free(command); @@ -274,7 +274,7 @@ void hub_send_sid(struct user* u) } -void hub_send_ping(struct user* user) +void hub_send_ping(struct hub_info* hub, struct user* user) { /* This will just send a newline, despite appearing to do more below. */ struct adc_message* ping = adc_msg_construct(0, 0); @@ -287,9 +287,9 @@ void hub_send_ping(struct user* user) } -void hub_send_hubinfo(struct user* u) +void hub_send_hubinfo(struct hub_info* hub, struct user* u) { - struct adc_message* info = adc_msg_copy(u->hub->command_info); + struct adc_message* info = adc_msg_copy(hub->command_info); int value = 0; if (user_flag_get(u, feature_ping)) @@ -301,43 +301,43 @@ void hub_send_hubinfo(struct user* u) NE - Hub Network OW - Hub Owner name */ - adc_msg_add_named_argument(info, "UC", uhub_itoa(hub_get_user_count(u->hub))); - adc_msg_add_named_argument(info, "MC", uhub_itoa(hub_get_max_user_count(u->hub))); - adc_msg_add_named_argument(info, "SS", uhub_ulltoa(hub_get_shared_size(u->hub))); - adc_msg_add_named_argument(info, "SF", uhub_itoa(hub_get_shared_files(u->hub))); + adc_msg_add_named_argument(info, "UC", uhub_itoa(hub_get_user_count(hub))); + adc_msg_add_named_argument(info, "MC", uhub_itoa(hub_get_max_user_count(hub))); + adc_msg_add_named_argument(info, "SS", uhub_ulltoa(hub_get_shared_size(hub))); + adc_msg_add_named_argument(info, "SF", uhub_itoa(hub_get_shared_files(hub))); /* Maximum/minimum share size */ - value = hub_get_max_share(u->hub); + value = hub_get_max_share(hub); if (value) adc_msg_add_named_argument(info, "XS", uhub_itoa(value)); - value = hub_get_min_share(u->hub); + value = hub_get_min_share(hub); if (value) adc_msg_add_named_argument(info, "MS", uhub_itoa(value)); /* Maximum/minimum upload slots allowed per user */ - value = hub_get_max_slots(u->hub); + value = hub_get_max_slots(hub); if (value) adc_msg_add_named_argument(info, "XL", uhub_itoa(value)); - value = hub_get_min_slots(u->hub); + value = hub_get_min_slots(hub); if (value) adc_msg_add_named_argument(info, "ML", uhub_itoa(value)); /* guest users must be on min/max hubs */ - value = hub_get_max_hubs_user(u->hub); + value = hub_get_max_hubs_user(hub); if (value) adc_msg_add_named_argument(info, "XU", uhub_itoa(value)); - value = hub_get_min_hubs_user(u->hub); + value = hub_get_min_hubs_user(hub); if (value) adc_msg_add_named_argument(info, "MU", uhub_itoa(value)); /* registered users must be on min/max hubs */ - value = hub_get_max_hubs_reg(u->hub); + value = hub_get_max_hubs_reg(hub); if (value) adc_msg_add_named_argument(info, "XR", uhub_itoa(value)); - value = hub_get_min_hubs_reg(u->hub); + value = hub_get_min_hubs_reg(hub); if (value) adc_msg_add_named_argument(info, "MR", uhub_itoa(value)); /* operators must be on min/max hubs */ - value = hub_get_max_hubs_op(u->hub); + value = hub_get_max_hubs_op(hub); if (value) adc_msg_add_named_argument(info, "XO", uhub_itoa(value)); - value = hub_get_min_hubs_op(u->hub); + value = hub_get_min_hubs_op(hub); if (value) adc_msg_add_named_argument(info, "MO", uhub_itoa(value)); /* uptime in seconds */ - adc_msg_add_named_argument(info, "UP", uhub_itoa((int) difftime(time(0), u->hub->tm_started))); + adc_msg_add_named_argument(info, "UP", uhub_itoa((int) difftime(time(0), hub->tm_started))); } if (user_is_connecting(u) || user_is_logged_in(u)) @@ -347,20 +347,17 @@ void hub_send_hubinfo(struct user* u) adc_msg_free(info); /* Only send banner when connecting */ - if (u->hub->config->show_banner && user_is_connecting(u)) + if (hub->config->show_banner && user_is_connecting(u)) { - route_to_user(u, u->hub->command_banner); + route_to_user(u, hub->command_banner); } - - } - -void hub_send_handshake(struct user* u) +void hub_send_handshake(struct hub_info* hub, struct user* u) { - hub_send_support(u); - hub_send_sid(u); - hub_send_hubinfo(u); + hub_send_support(hub, u); + hub_send_sid(hub, u); + hub_send_hubinfo(hub, u); if (!user_is_disconnecting(u)) { @@ -368,17 +365,15 @@ void hub_send_handshake(struct user* u) } } - -void hub_send_motd(struct user* u) +void hub_send_motd(struct hub_info* hub, struct user* u) { - if (u->hub->command_motd) + if (hub->command_motd) { - route_to_user(u, u->hub->command_motd); + route_to_user(u, hub->command_motd); } } - -void hub_send_password_challenge(struct user* u) +void hub_send_password_challenge(struct hub_info* hub, struct user* u) { struct adc_message* igpa; igpa = adc_msg_construct(ADC_CMD_IGPA, 38); @@ -390,8 +385,8 @@ void hub_send_password_challenge(struct user* u) static void hub_event_dispatcher(void* callback_data, struct event_data* message) { -/* struct hub_info* hub = (struct hub_info*) callback_data; +/* hub_log(log_trace, "hub_event_dispatcher: %x (ptr=%p)", message->id, message->ptr); */ @@ -404,20 +399,20 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message if (message->flags) { - hub_send_password_challenge((struct user*) message->ptr); + hub_send_password_challenge(hub, (struct user*) message->ptr); } else { - on_login_success((struct user*) message->ptr); + on_login_success(hub, (struct user*) message->ptr); } break; } case UHUB_EVENT_USER_QUIT: { - user_manager_remove((struct user*) message->ptr); + user_manager_remove(hub, (struct user*) message->ptr); send_quit_message((struct user*) message->ptr); - on_logout_user((struct user*) message->ptr); + on_logout_user(hub, (struct user*) message->ptr); user_schedule_destroy((struct user*) message->ptr); break; } @@ -797,9 +792,9 @@ static void set_status_code(enum msg_status_level level, int code, char buffer[4 * @param msg See enum status_message * @param level See enum status_level */ -void hub_send_status(struct user* user, enum status_message msg, enum msg_status_level level) +void hub_send_status(struct hub_info* hub, struct user* user, enum status_message msg, enum msg_status_level level) { - struct hub_config* cfg = user->hub->config; + struct hub_config* cfg = hub->config; struct adc_message* cmd = adc_msg_construct(ADC_CMD_ISTA, 6); if (!cmd) return; char code[4]; diff --git a/src/hub.h b/src/hub.h index 4a5149c..2e27afe 100644 --- a/src/hub.h +++ b/src/hub.h @@ -116,106 +116,117 @@ struct hub_info * * @return 0 on success, -1 on error */ -extern int hub_handle_message(struct user* u, const char* message, size_t length); +extern int hub_handle_message(struct hub_info* hub, struct user* u, const char* message, size_t length); /** * Handle protocol support/subscription messages received clients. * * @return 0 on success, -1 on error */ -extern int hub_handle_support(struct user* u, struct adc_message* cmd); +extern int hub_handle_support(struct hub_info* hub, struct user* u, struct adc_message* cmd); /** * Handle password messages received from clients. * * @return 0 on success, -1 on error */ -extern int hub_handle_password(struct user* u, struct adc_message* cmd); +extern int hub_handle_password(struct hub_info* hub, struct user* u, struct adc_message* cmd); /** * Handle chat messages received from clients. * @return 0 on success, -1 on error. */ -extern int hub_handle_chat_message(struct user* u, struct adc_message* cmd); +extern int hub_handle_chat_message(struct hub_info* hub, struct user* u, struct adc_message* cmd); /** * Used internally by hub_handle_info * @return 1 if nickname is OK, or 0 if nickname is not accepted. */ -extern int hub_handle_info_check_nick(struct user* u, struct adc_message* cmd); +extern int hub_handle_info_check_nick(struct hub_info* hub, struct user* u, struct adc_message* cmd); /** * Used internally by hub_handle_info * @return 1 if CID/PID is OK, or 0 if not valid. */ -extern int hub_handle_info_check_cid(struct user* u, struct adc_message* cmd); +extern int hub_handle_info_check_cid(struct hub_info* hub, struct user* u, struct adc_message* cmd); /** * Can only be used by administrators or operators. * * @return 0 on success, -1 on error */ -extern int hub_handle_kick(struct user* u, struct adc_message* cmd); +extern int hub_handle_kick(struct hub_info* hub, struct user* u, struct adc_message* cmd); #ifdef ADC_UDP_OPERATION /** * Handle incoming autocheck message. */ -extern int hub_handle_autocheck(struct user* u, struct adc_message* cmd); +extern int hub_handle_autocheck(struct hub_info* hub, struct user* u, struct adc_message* cmd); #endif /** * Send the support line for the hub to a particular user. * Only used during the initial handshake. */ -extern void hub_send_support(struct user* u); +extern void hub_send_support(struct hub_info* hub, struct user* u); /** * Send a message assigning a SID for a user. * This is only sent after hub_send_support() during initial handshake. */ -extern void hub_send_sid(struct user* u); +extern void hub_send_sid(struct hub_info* hub, struct user* u); /** * Send a 'ping' message to user. */ -extern void hub_send_ping(struct user* user); +extern void hub_send_ping(struct hub_info* hub, struct user* user); /** * Send a message containing hub information to a particular user. * This is sent during user connection, but can safely be sent at any * point later. */ -extern void hub_send_hubinfo(struct user* u); +extern void hub_send_hubinfo(struct hub_info* hub, struct user* u); /** * Send handshake. This basically calls * hub_send_support() and hub_send_sid() */ -extern void hub_send_handshake(struct user* u); +extern void hub_send_handshake(struct hub_info* hub, struct user* u); /** * Send a welcome message containing the message of the day to * one particular user. This can be sent in any point in time. */ -extern void hub_send_motd(struct user* u); +extern void hub_send_motd(struct hub_info* hub, struct user* u); /** * Send a password challenge to a user. * This is only used if the user tries to access the hub using a * password protected nick name. */ -extern void hub_send_password_challenge(struct user* u); +extern void hub_send_password_challenge(struct hub_info* hub, struct user* u); +/** + * Sends a status_message to a user. + */ +extern void hub_send_status(struct hub_info*, struct user* user, enum status_message msg, enum msg_status_level level); + +#ifdef ADC_UDP_OPERATION /** * Send an autocheck message to a user. * This is basically a UDP message. The user's client can then determine * if UDP communication works by either hole punching or configuring UPnP. */ -extern void hub_send_autocheck(struct user* u, uint16_t port, const char* token); +extern void hub_send_autocheck(struct hub_info* hub, struct user* u, uint16_t port, const char* token); +#endif /** - * This starts the hub. + * Allocates memory, initializes the hub based on the configuration, + * and returns a hub handle. + * This hub handle must be passed to hub_shutdown_service() in order to cleanup before exiting. + * + * @return a pointer to the hub info. */ extern struct hub_info* hub_start_service(struct hub_config* config); @@ -240,12 +251,6 @@ extern void hub_free_variables(struct hub_info* hub); extern const char* hub_get_status_message(struct hub_info* hub, enum status_message msg); extern const char* hub_get_status_message_log(struct hub_info* hub, enum status_message msg); - -/** - * Sends a status_message to a user. - */ -extern void hub_send_status(struct user* user, enum status_message msg, enum msg_status_level level); - /** * Returns the number of logged in users on the hub. */ diff --git a/src/hubevent.c b/src/hubevent.c index 0ccb273..aab1f28 100644 --- a/src/hubevent.c +++ b/src/hubevent.c @@ -47,7 +47,7 @@ static void log_user_nick_change(struct user* u, const char* nick) /* Send MOTD, do logging etc */ -void on_login_success(struct user* u) +void on_login_success(struct hub_info* hub, struct user* u) { struct timeval timeout = { TIMEOUT_IDLE, 0 }; @@ -57,7 +57,7 @@ void on_login_success(struct user* u) /* Mark as being in the normal state, and add user to the user list */ user_set_state(u, state_normal); - user_manager_add(u); + user_manager_add(hub, u); /* Print log message */ log_user_login(u); @@ -68,21 +68,21 @@ void on_login_success(struct user* u) /* Send message of the day (if any) */ if (user_is_logged_in(u)) /* Previous send() can fail! */ - hub_send_motd(u); + hub_send_motd(hub, u); /* reset to idle timeout */ if (u->ev_read) event_add(u->ev_read, &timeout); } -void on_login_failure(struct user* u, enum status_message msg) +void on_login_failure(struct hub_info* hub, struct user* u, enum status_message msg) { log_user_login_error(u, msg); - hub_send_status(u, msg, status_level_fatal); + hub_send_status(hub, u, msg, status_level_fatal); user_disconnect(u, quit_logon_error); } -void on_nick_change(struct user* u, const char* nick) +void on_nick_change(struct hub_info* hub, struct user* u, const char* nick) { if (user_is_logged_in(u)) { @@ -90,7 +90,7 @@ void on_nick_change(struct user* u, const char* nick) } } -void on_logout_user(struct user* user) +void on_logout_user(struct hub_info* hub, struct user* user) { const char* reason = ""; @@ -109,7 +109,7 @@ void on_logout_user(struct user* user) case quit_hub_disabled: reason = "hub disabled"; break; case quit_ghost_timeout: reason = "ghost"; break; default: - if (user->hub->status == hub_status_shutdown) + if (hub->status == hub_status_shutdown) reason = "hub shutdown"; else reason = "unknown error"; diff --git a/src/hubevent.h b/src/hubevent.h index 746c935..744d68f 100644 --- a/src/hubevent.h +++ b/src/hubevent.h @@ -23,22 +23,22 @@ /** * This event is triggered whenever a user successfully logs in to the hub. */ -extern void on_login_success(struct user* u); +extern void on_login_success(struct hub_info* hub, struct user* u); /** * This event is triggered whenever a user failed to log in to the hub. */ -extern void on_login_failure(struct user* u, enum status_message msg); +extern void on_login_failure(struct hub_info* hub, struct user* u, enum status_message msg); /** * This event is triggered whenever a previously logged in user leaves the hub. */ -extern void on_logout_user(struct user* u); +extern void on_logout_user(struct hub_info* hub, struct user* u); /** * This event is triggered whenever a user changes his/her nickname. */ -extern void on_nick_change(struct user* u, const char* nick); +extern void on_nick_change(struct hub_info* hub, struct user* u, const char* nick); #endif /* HAVE_UHUB_HUB_EVENT_H */ diff --git a/src/inf.c b/src/inf.c index f606209..b1a4c3b 100644 --- a/src/inf.c +++ b/src/inf.c @@ -89,7 +89,7 @@ static int check_hash_tiger(const char* cid, const char* pid) /* * FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in! */ -static int check_cid(struct user* user, struct adc_message* cmd) +static int check_cid(struct hub_info* hub, struct user* user, struct adc_message* cmd) { size_t pos; char* cid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID); @@ -150,7 +150,7 @@ static int check_cid(struct user* user, struct adc_message* cmd) } -static int check_required_login_flags(struct user* user, struct adc_message* cmd) +static int check_required_login_flags(struct hub_info* hub, struct user* user, struct adc_message* cmd) { int num = 0; @@ -186,12 +186,12 @@ static int check_required_login_flags(struct user* user, struct adc_message* cmd * remove any wrong address, and replace it with the correct one * as seen by the hub. */ -int check_network(struct user* user, struct adc_message* cmd) +int check_network(struct hub_info* hub, struct user* user, struct adc_message* cmd) { const char* address = ip_convert_to_string(&user->ipaddr); /* Check for NAT override address */ - if (acl_is_ip_nat_override(user->hub->acl, address)) + if (acl_is_ip_nat_override(hub->acl, address)) { char* client_given_ip = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR); if (strcmp(client_given_ip, "0.0.0.0") != 0) @@ -276,7 +276,7 @@ static int nick_is_utf8(const char* nick) } -static int check_nick(struct user* user, struct adc_message* cmd) +static int check_nick(struct hub_info* hub, struct user* user, struct adc_message* cmd) { char* nick; char* tmp; @@ -324,10 +324,10 @@ static int check_nick(struct user* user, struct adc_message* cmd) } -static int check_logged_in(struct user* user, struct adc_message* cmd) +static int check_logged_in(struct hub_info* hub, struct user* user, struct adc_message* cmd) { - struct user* lookup1 = get_user_by_nick(user->hub, user->id.nick); - struct user* lookup2 = get_user_by_cid(user->hub, user->id.cid); + struct user* lookup1 = get_user_by_nick(hub, user->id.nick); + struct user* lookup2 = get_user_by_cid(hub, user->id.cid); if (lookup1 == user) { @@ -365,7 +365,7 @@ static int check_logged_in(struct user* user, struct adc_message* cmd) * But this is not something we want to do, and is deprecated in the ADC specification. * One should rather look at capabilities/features. */ -static int check_user_agent(struct user* user, struct adc_message* cmd) +static int check_user_agent(struct hub_info* hub, struct user* user, struct adc_message* cmd) { char* ua_encoded = 0; char* ua = 0; @@ -386,19 +386,19 @@ static int check_user_agent(struct user* user, struct adc_message* cmd) } -static int check_acl(struct user* user, struct adc_message* cmd) +static int check_acl(struct hub_info* hub, struct user* user, struct adc_message* cmd) { - if (acl_is_cid_banned(user->hub->acl, user->id.cid)) + if (acl_is_cid_banned(hub->acl, user->id.cid)) { return status_msg_ban_permanently; } - if (acl_is_user_banned(user->hub->acl, user->id.nick)) + if (acl_is_user_banned(hub->acl, user->id.nick)) { return status_msg_ban_permanently; } - if (acl_is_user_denied(user->hub->acl, user->id.nick)) + if (acl_is_user_denied(hub->acl, user->id.nick)) { return status_msg_inf_error_nick_restricted; } @@ -406,7 +406,7 @@ static int check_acl(struct user* user, struct adc_message* cmd) return 0; } -static int check_limits(struct user* user, struct adc_message* cmd) +static int check_limits(struct hub_info* hub, struct user* user, struct adc_message* cmd) { char* arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_SIZE); if (arg) @@ -417,8 +417,8 @@ static int check_limits(struct user* user, struct adc_message* cmd) if (user_is_logged_in(user)) { - user->hub->users->shared_size -= user->limits.shared_size; - user->hub->users->shared_size += shared_size; + hub->users->shared_size -= user->limits.shared_size; + hub->users->shared_size += shared_size; } user->limits.shared_size = shared_size; hub_free(arg); @@ -434,8 +434,8 @@ static int check_limits(struct user* user, struct adc_message* cmd) if (user_is_logged_in(user)) { - user->hub->users->shared_files -= user->limits.shared_files; - user->hub->users->shared_files += shared_files; + hub->users->shared_files -= user->limits.shared_files; + hub->users->shared_files += shared_files; } user->limits.shared_files = shared_files; hub_free(arg); @@ -487,37 +487,37 @@ static int check_limits(struct user* user, struct adc_message* cmd) if (!user_is_protected(user)) { - if (user->limits.shared_size < hub_get_min_share(user->hub) && hub_get_min_share(user->hub)) + if (user->limits.shared_size < hub_get_min_share(hub) && hub_get_min_share(hub)) { return status_msg_user_share_size_low; } - if (user->limits.shared_size > hub_get_max_share(user->hub) && hub_get_max_share(user->hub)) + if (user->limits.shared_size > hub_get_max_share(hub) && hub_get_max_share(hub)) { return status_msg_user_share_size_high; } - if ((user->limits.hub_count_user > hub_get_max_hubs_user(user->hub) && hub_get_max_hubs_user(user->hub)) || - (user->limits.hub_count_registered > hub_get_max_hubs_reg(user->hub) && hub_get_max_hubs_reg(user->hub)) || - (user->limits.hub_count_operator > hub_get_max_hubs_op(user->hub) && hub_get_max_hubs_op(user->hub)) || - (user->limits.hub_count_total > hub_get_max_hubs_total(user->hub) && hub_get_max_hubs_total(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_operator > hub_get_max_hubs_op(hub) && hub_get_max_hubs_op(hub)) || + (user->limits.hub_count_total > hub_get_max_hubs_total(hub) && hub_get_max_hubs_total(hub))) { return status_msg_user_hub_limit_high; } - if ((user->limits.hub_count_user < hub_get_min_hubs_user(user->hub) && hub_get_min_hubs_user(user->hub)) || - (user->limits.hub_count_registered < hub_get_min_hubs_reg(user->hub) && hub_get_min_hubs_reg(user->hub)) || - (user->limits.hub_count_operator < hub_get_min_hubs_op(user->hub) && hub_get_min_hubs_op(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_operator < hub_get_min_hubs_op(hub) && hub_get_min_hubs_op(hub))) { return status_msg_user_hub_limit_low; } - if (user->limits.upload_slots < hub_get_min_slots(user->hub) && hub_get_min_slots(user->hub)) + if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub)) { return status_msg_user_slots_low; } - if (user->limits.upload_slots > hub_get_max_slots(user->hub) && hub_get_max_slots(user->hub)) + if (user->limits.upload_slots > hub_get_max_slots(hub) && hub_get_max_slots(hub)) { return status_msg_user_slots_high; } @@ -532,10 +532,10 @@ static int check_limits(struct user* user, struct adc_message* cmd) * If the hub is configured to allow only registered users and the user * is not recognized this will return 1. */ -static int set_credentials(struct user* user, struct adc_message* cmd) +static int set_credentials(struct hub_info* hub, struct user* user, struct adc_message* cmd) { int ret = 0; - struct user_access_info* info = acl_get_access_info(user->hub->acl, user->id.nick); + struct user_access_info* info = acl_get_access_info(hub->acl, user->id.nick); if (info) { @@ -626,7 +626,7 @@ static int user_is_registered(struct user* user) } -void update_user_info(struct user* u, struct adc_message* cmd) +void update_user_info(struct hub_info* hub, struct user* u, struct adc_message* cmd) { char prefix[2]; char* argument; @@ -656,13 +656,13 @@ void update_user_info(struct user* u, struct adc_message* cmd) } -static int check_is_hub_full(struct user* user) +static int check_is_hub_full(struct hub_info* hub, struct user* user) { /* * If hub is full, don't let users in, but we still want to allow * operators and admins to enter the hub. */ - if (user->hub->config->max_users && user->hub->users->count >= user->hub->config->max_users && !user_is_protected(user)) + if (hub->config->max_users && hub->users->count >= hub->config->max_users && !user_is_protected(user)) { return 1; } @@ -670,18 +670,18 @@ static int check_is_hub_full(struct user* user) } -static int check_registered_users_only(struct user* user) +static int check_registered_users_only(struct hub_info* hub, struct user* user) { - if (user->hub->config->registered_users_only && !user_is_registered(user)) + if (hub->config->registered_users_only && !user_is_registered(user)) { return 1; } return 0; } -#define INF_CHECK(FUNC, USER, CMD) \ +#define INF_CHECK(FUNC, HUB, USER, CMD) \ do { \ - int ret = FUNC(USER, CMD); \ + int ret = FUNC(HUB, USER, CMD); \ if (ret < 0) \ return ret; \ } while(0) @@ -697,9 +697,9 @@ static int hub_handle_info_common(struct user* user, struct adc_message* cmd) return 0; } -static int hub_handle_info_low_bandwidth(struct user* user, struct adc_message* cmd) +static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct user* user, struct adc_message* cmd) { - if (user->hub->config->low_bandwidth_mode) + if (hub->config->low_bandwidth_mode) { adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES); @@ -718,40 +718,40 @@ static int hub_handle_info_low_bandwidth(struct user* user, struct adc_message* return 0; } -int hub_handle_info_login(struct user* user, struct adc_message* cmd) +int hub_handle_info_login(struct hub_info* hub, struct user* user, struct adc_message* cmd) { int need_auth = 0; /* Make syntax checks. */ - INF_CHECK(check_required_login_flags, user, cmd); - INF_CHECK(check_cid, user, cmd); - INF_CHECK(check_nick, user, cmd); - INF_CHECK(check_network, user, cmd); - INF_CHECK(check_user_agent, user, cmd); - INF_CHECK(check_acl, user, cmd); - INF_CHECK(check_logged_in, user, cmd); + INF_CHECK(check_required_login_flags, hub, user, cmd); + INF_CHECK(check_cid, hub, user, cmd); + INF_CHECK(check_nick, hub, user, cmd); + INF_CHECK(check_network, hub, user, cmd); + INF_CHECK(check_user_agent, hub, user, cmd); + INF_CHECK(check_acl, hub, user, cmd); + INF_CHECK(check_logged_in, hub, user, cmd); /* Private ID must never be broadcasted - drop it! */ adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID); /* FIXME: This needs some cleaning up */ - need_auth = set_credentials(user, cmd); + need_auth = set_credentials(hub, user, cmd); /* Note: this must be done *after* set_credentials. */ - if (check_is_hub_full(user)) + if (check_is_hub_full(hub, user)) { return status_msg_hub_full; } - if (check_registered_users_only(user)) + if (check_registered_users_only(hub, user)) { return status_msg_hub_registered_users_only; } - INF_CHECK(check_limits, user, cmd); + INF_CHECK(check_limits, hub, user, cmd); /* strip off stuff if low_bandwidth_mode is enabled */ - hub_handle_info_low_bandwidth(user, cmd); + hub_handle_info_low_bandwidth(hub, user, cmd); /* Set initial user info */ user_set_info(user, cmd); @@ -772,7 +772,7 @@ int hub_handle_info_login(struct user* user, struct adc_message* cmd) * - CID/PID (valid, not taken, etc). * - IP addresses (IPv4 and IPv6) */ -int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified) +int hub_handle_info(struct hub_info* hub, struct user* user, const struct adc_message* cmd_unmodified) { struct adc_message* cmd = adc_msg_copy(cmd_unmodified); if (!cmd) return -1; /* OOM */ @@ -796,10 +796,10 @@ int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified) return 0; } - int ret = hub_handle_info_login(user, cmd); + int ret = hub_handle_info_login(hub, user, cmd); if (ret < 0) { - on_login_failure(user, ret); + on_login_failure(hub, user, ret); adc_msg_free(cmd); return -1; } @@ -811,7 +811,7 @@ int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified) post.id = UHUB_EVENT_USER_JOIN; post.ptr = user; post.flags = ret; /* 0 - all OK, 1 - need authentication */ - event_queue_post(user->hub->queue, &post); + event_queue_post(hub->queue, &post); adc_msg_free(cmd); return 0; } @@ -829,18 +829,18 @@ int hub_handle_info(struct user* user, const struct adc_message* cmd_unmodified) if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK)) { #if ALLOW_CHANGE_NICK - if (!check_nick(user, cmd)) + if (!check_nick(hub, user, cmd)) #endif adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK); } /* FIXME - What if limits are not met ? */ - check_limits(user, cmd); + check_limits(hub, user, cmd); strip_network(user, cmd); - hub_handle_info_low_bandwidth(user, cmd); + hub_handle_info_low_bandwidth(hub, user, cmd); - update_user_info(user, cmd); + update_user_info(hub, user, cmd); if (!adc_msg_is_empty(cmd)) { diff --git a/src/inf.h b/src/inf.h index e0b611d..95a8c88 100644 --- a/src/inf.h +++ b/src/inf.h @@ -47,7 +47,7 @@ enum nick_status * * @return 0 on success, -1 on error */ -extern int hub_handle_info(struct user* u, const struct adc_message* cmd); +extern int hub_handle_info(struct hub_info* hub, struct user* u, const struct adc_message* cmd); #endif /* HAVE_UHUB_INF_PARSER_H */ diff --git a/src/netevent.c b/src/netevent.c index ef42051..13cc7b6 100644 --- a/src/netevent.c +++ b/src/netevent.c @@ -42,7 +42,8 @@ void net_on_read(int fd, short ev, void *arg) } else { - hub_send_ping(user); + // FIXME: hub is not neccesarily set! + // hub_send_ping(hub, user); } } @@ -85,7 +86,8 @@ void net_on_read(int fd, short ev, void *arg) { if (msglen < user->hub->config->max_recv_buffer) { - if (hub_handle_message(user, &buf[handled], msglen) == -1) + // FIXME: hub is not set???? + if (hub_handle_message(user->hub, user, &buf[handled], msglen) == -1) { flag_close = quit_protocol_error; more = 0; diff --git a/src/usermanager.c b/src/usermanager.c index 5a2f42f..740005c 100644 --- a/src/usermanager.c +++ b/src/usermanager.c @@ -68,6 +68,7 @@ void user_manager_print_stats(struct hub_info* hub) (int) hub->stats.net_rx_peak / 1024); } +#ifdef USERMANAGER_TIMER static void timer_statistics(int fd, short ev, void *arg) { struct hub_info* hub = (struct hub_info*) arg; @@ -77,14 +78,21 @@ static void timer_statistics(int fd, short ev, void *arg) event_base_set(hub->evbase, &hub->ev_timer); evtimer_add(&hub->ev_timer, &timeout); } +#endif int user_manager_init(struct hub_info* hub) { struct user_manager* users = NULL; +#ifdef USERMANAGER_TIMER struct timeval timeout = { TIMEOUT_STATS, 0 }; +#endif + if (!hub) + return -1; users = (struct user_manager*) hub_malloc_zero(sizeof(struct user_manager)); + if (!users) + return -1; users->list = list_create(); users->free_sid = 1; @@ -96,42 +104,68 @@ int user_manager_init(struct hub_info* hub) } hub->users = users; - + +#ifdef USERMANAGER_TIMER evtimer_set(&hub->ev_timer, timer_statistics, hub); event_base_set(hub->evbase, &hub->ev_timer); evtimer_add(&hub->ev_timer, &timeout); +#endif // 0 return 0; } -void user_manager_shutdown(struct hub_info* hub) +int user_manager_shutdown(struct hub_info* hub) { - struct user_manager* users = hub->users; + if (!hub || !hub->users) + return -1; + +#ifdef USERMANAGER_TIMER event_del(&hub->ev_timer); +#endif - list_clear(users->list, &clear_user_list_callback); - list_destroy(users->list); + if (hub->users->list) + { + list_clear(hub->users->list, &clear_user_list_callback); + list_destroy(hub->users->list); + } hub_free(hub->users); + hub->users = 0; + + return 0; } -void user_manager_add(struct user* user) +int user_manager_add(struct hub_info* hub, struct user* user) { - list_append(user->hub->users->list, user); - user->hub->users->count++; - user->hub->users->count_peak = MAX(user->hub->users->count, user->hub->users->count_peak); + if (!hub || !user) + return -1; - user->hub->users->shared_size += user->limits.shared_size; - user->hub->users->shared_files += user->limits.shared_files; + if (user->hub) + return -1; + + list_append(hub->users->list, user); + hub->users->count++; + hub->users->count_peak = MAX(hub->users->count, hub->users->count_peak); + + hub->users->shared_size += user->limits.shared_size; + hub->users->shared_files += user->limits.shared_files; + + user->hub = hub; + return 0; } -void user_manager_remove(struct user* user) +int user_manager_remove(struct hub_info* hub, struct user* user) { - list_remove(user->hub->users->list, user); - user->hub->users->count--; + if (!hub || !user) + return -1; + + list_remove(hub->users->list, user); + hub->users->count--; - user->hub->users->shared_size -= user->limits.shared_size; - user->hub->users->shared_files -= user->limits.shared_files; + hub->users->shared_size -= user->limits.shared_size; + hub->users->shared_files -= user->limits.shared_files; + + return 0; } diff --git a/src/usermanager.h b/src/usermanager.h index 348fc5e..622781f 100644 --- a/src/usermanager.h +++ b/src/usermanager.h @@ -39,8 +39,10 @@ extern int user_manager_init(struct hub_info* hub); /** * Shuts down the user manager. * All users will be disconnected and deleted as part of this. + * + * @return 0 on success, or -1 in an error occured (hub is invalid). */ -extern void user_manager_shutdown(struct hub_info* hub); +extern int user_manager_shutdown(struct hub_info* hub); /** * Generate statistics for logfiles. @@ -49,31 +51,44 @@ extern void user_manager_update_stats(struct hub_info* hub); extern void user_manager_print_stats(struct hub_info* hub); /** - * Add a new user to the user manager. + * Add a user to the user manager. + * + * @param hub The hub to add the user to + * @param user The user to be added to the hub. */ -extern void user_manager_add(struct user* user); +extern int user_manager_add(struct hub_info* hub, struct user* user); /** * Remove a user from the user manager. * This user is connected, and will be moved to the leaving queue, pending * all messages in the message queue, and resource cleanup. + * + * @return 0 if successfully removed, -1 if error. */ -extern void user_manager_remove(struct user* user); +extern int user_manager_remove(struct hub_info* hub, struct user* user); /** - * Returns a free sid for a new user. + * Returns and allocates an unused session ID (SID). */ extern sid_t user_manager_get_free_sid(struct hub_info* hub); /** - * Lookup a user based on the session ID (sid). - * NOTE: This will only search connected users. + * Lookup a user based on the session ID (SID). + * + * NOTE: This function will only search connected users, which means + * that SIDs assigned to users who are not yet completely logged in, + * or are in the process of being disconnected will result in this + * function returning NULL even though the sid is not freely available. + * + * FIXME: Is that really safe / sensible ? + * - Makes sense from a message routing point of view. + * * @return a user if found, or NULL if not found */ extern struct user* get_user_by_sid(struct hub_info* hub, sid_t sid); /** - * Lookup a user based on the client ID (cid). + * Lookup a user based on the client ID (CID). * @return a user if found, or NULL if not found */ extern struct user* get_user_by_cid(struct hub_info* hub, const char* cid); diff --git a/version.h b/version.h index 7f6b644..62bff96 100644 --- a/version.h +++ b/version.h @@ -7,7 +7,7 @@ #endif #ifndef VERSION -#define VERSION "0.2.9-alpha" +#define VERSION "0.3.0-alpha" #endif #ifndef COPYRIGHT