More API fixes; remove implicit relationship between hub and user

in APIs.
This commit is contained in:
Jan Vidar Krey 2009-05-18 16:30:17 +02:00
parent caec28f63f
commit 1dbf2640d2
18 changed files with 258 additions and 109 deletions

View File

@ -67,5 +67,5 @@ EXO_TEST(hub_service_shutdown, {
});
EXO_TEST(hub_net_shutdown, {
return (net_shutdown() != -1);
return (net_destroy() != -1);
});

View File

@ -595,5 +595,5 @@ EXO_TEST(ip6_bitwise_OR_3, {
});
EXO_TEST(shutdown_network, {
return net_shutdown() == 0;
return net_destroy() == 0;
});

View File

@ -0,0 +1,105 @@
#include <uhub.h>
#define MAX_USERS 64
static struct hub_info um_hub;
static struct user um_user[MAX_USERS];
EXO_TEST(um_test_setup, {
int i = 0;
memset(&um_hub, 0, sizeof(um_hub));
for (i = 0; i < MAX_USERS; i++)
{
memset(&um_user[i], 0, sizeof(struct user));
um_user[i].id.sid = i+1;
um_user[i].sd = -1;
}
return 1;
});
EXO_TEST(um_init_1, {
return uman_init(0) != 0;
});
EXO_TEST(um_init_2, {
return uman_init(&um_hub) == 0;
});
EXO_TEST(um_shutdown_1, {
return uman_shutdown(0) == -1;
});
EXO_TEST(um_shutdown_2, {
return uman_shutdown(&um_hub) == 0;
});
EXO_TEST(um_shutdown_3, {
return uman_shutdown(&um_hub) == -1;
});
EXO_TEST(um_init_3, {
return uman_init(&um_hub) == 0;
});
EXO_TEST(um_add_1, {
return uman_add(&um_hub, &um_user[0]) == 0;
});
EXO_TEST(um_size_1, {
return hub_get_user_count(&um_hub) == 1;
});
EXO_TEST(um_remove_1, {
return uman_remove(&um_hub, &um_user[0]) == 0;
});
EXO_TEST(um_size_2, {
return hub_get_user_count(&um_hub) == 0;
});
EXO_TEST(um_add_2, {
int i;
for (i = 0; i < MAX_USERS; i++)
{
if (uman_add(&um_hub, &um_user[i]) != 0)
return 0;
}
return 1;
});
EXO_TEST(um_size_3, {
return hub_get_user_count(&um_hub) == MAX_USERS;
});
EXO_TEST(um_add_3, {
return uman_add(&um_hub, &um_user[5]) != 0;
});
EXO_TEST(um_remove_2, {
int i;
for (i = 0; i < MAX_USERS; i++)
{
if (uman_remove(&um_hub, &um_user[i]) != 0)
return 0;
}
return 1;
});
/* Last test */
EXO_TEST(um_shutdown_4, {
return uman_shutdown(&um_hub) == 0;
});

View File

@ -37,7 +37,7 @@ static void send_message(struct hub_info* hub, struct user* user, const char* me
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);
route_to_user(hub, user, command);
adc_msg_free(command);
hub_free(buffer);
}
@ -154,7 +154,7 @@ static int command_kick(struct hub_info* hub, struct user* user, const char* mes
return command_status(hub, user, "kick", "Cannot kick yourself");
}
user_disconnect(target, quit_kicked);
hub_disconnect_user(hub, target, quit_kicked);
return command_status(hub, user, "kick", nick);
}

View File

@ -19,6 +19,8 @@
#include "uhub.h"
struct hub_info* g_hub = 0;
int hub_handle_message(struct hub_info* hub, struct user* u, const char* line, size_t length)
{
int ret = 0;
@ -70,7 +72,7 @@ int hub_handle_message(struct hub_info* hub, struct user* u, const char* line, s
default:
if (user_is_logged_in(u))
{
ret = route_message(u, cmd);
ret = route_message(hub, u, cmd);
}
else
{
@ -148,7 +150,7 @@ int hub_handle_support(struct hub_info* hub, struct user* u, struct adc_message*
else
{
/* disconnect user. Do not send crap during initial handshake! */
user_disconnect(u, quit_logon_error);
hub_disconnect_user(hub, u, quit_logon_error);
ret = -1;
}
}
@ -195,7 +197,7 @@ int hub_handle_chat_message(struct hub_info* hub, struct user* u, struct adc_mes
if (relay && user_is_logged_in(u))
{
/* adc_msg_remove_named_argument(cmd, "PM"); */
ret = route_message(u, cmd);
ret = route_message(hub, u, cmd);
}
free(message);
@ -206,7 +208,7 @@ 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, hub->command_support);
route_to_user(hub, u, hub->command_support);
}
}
@ -219,7 +221,7 @@ void hub_send_sid(struct hub_info* hub, struct user* u)
command = adc_msg_construct(ADC_CMD_ISID, 10);
u->id.sid = uman_get_free_sid(hub);
adc_msg_add_argument(command, (const char*) sid_to_string(u->id.sid));
route_to_user(u, command);
route_to_user(hub, u, command);
adc_msg_free(command);
}
}
@ -233,7 +235,7 @@ void hub_send_ping(struct hub_info* hub, struct user* user)
ping->cache[1] = 0;
ping->length = 1;
ping->priority = 1;
route_to_user(user, ping);
route_to_user(hub, user, ping);
adc_msg_free(ping);
}
@ -293,14 +295,14 @@ void hub_send_hubinfo(struct hub_info* hub, struct user* u)
if (user_is_connecting(u) || user_is_logged_in(u))
{
route_to_user(u, info);
route_to_user(hub, u, info);
}
adc_msg_free(info);
/* Only send banner when connecting */
if (hub->config->show_banner && user_is_connecting(u))
{
route_to_user(u, hub->command_banner);
route_to_user(hub, u, hub->command_banner);
}
}
@ -320,7 +322,7 @@ void hub_send_motd(struct hub_info* hub, struct user* u)
{
if (hub->command_motd)
{
route_to_user(u, hub->command_motd);
route_to_user(hub, u, hub->command_motd);
}
}
@ -330,7 +332,7 @@ void hub_send_password_challenge(struct hub_info* hub, struct user* u)
igpa = adc_msg_construct(ADC_CMD_IGPA, 38);
adc_msg_add_argument(igpa, password_generate_challenge(u));
user_set_state(u, state_verify);
route_to_user(u, igpa);
route_to_user(hub, u, igpa);
adc_msg_free(igpa);
}
@ -362,9 +364,9 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
case UHUB_EVENT_USER_QUIT:
{
uman_remove(hub, (struct user*) message->ptr);
uman_send_quit_message((struct user*) message->ptr);
uman_send_quit_message(hub, (struct user*) message->ptr);
on_logout_user(hub, (struct user*) message->ptr);
user_schedule_destroy((struct user*) message->ptr);
hub_schedule_destroy_user(hub, (struct user*) message->ptr);
break;
}
@ -514,6 +516,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
hub->status = hub_status_running;
g_hub = hub;
return hub;
}
@ -530,6 +533,7 @@ void hub_shutdown_service(struct hub_info* hub)
event_base_free(hub->evbase);
hub_free(hub);
hub = 0;
g_hub = 0;
}
#define SERVER "" PRODUCT "/" VERSION ""
@ -707,7 +711,7 @@ void hub_send_status(struct hub_info* hub, struct user* user, enum status_messag
adc_msg_add_argument(cmd, flag);
}
route_to_user(user, cmd);
route_to_user(hub, user, cmd);
adc_msg_free(cmd);
}
@ -887,3 +891,56 @@ void hub_event_loop(struct hub_info* hub)
}
while (hub->status == hub_status_running || hub->status == hub_status_disabled);
}
void hub_schedule_destroy_user(struct hub_info* hub, struct user* user)
{
struct event_data post;
memset(&post, 0, sizeof(post));
post.id = UHUB_EVENT_USER_DESTROY;
post.ptr = user;
event_queue_post(hub->queue, &post);
}
void hub_disconnect_user(struct hub_info* hub, struct user* user, int reason)
{
struct event_data post;
int need_notify = 0;
/* is user already being disconnected ? */
if (user_is_disconnecting(user))
{
return;
}
/* dont read more data from this user */
/* FIXME: Remove this from here! */
if (user->ev_read)
{
event_del(user->ev_read);
hub_free(user->ev_read);
user->ev_read = 0;
}
/* this should be enough? */
net_shutdown_r(user->sd);
hub_log(log_trace, "hub_disconnect_user(), user=%p, reason=%d, state=%d", user, reason, user->state);
need_notify = user_is_logged_in(user);
user->quit_reason = reason;
user_set_state(user, state_cleanup);
if (need_notify)
{
memset(&post, 0, sizeof(post));
post.id = UHUB_EVENT_USER_QUIT;
post.ptr = user;
event_queue_post(hub->queue, &post);
}
else
{
user->quit_reason = quit_unknown;
hub_schedule_destroy_user(hub, user);
}
}

View File

@ -318,6 +318,16 @@ extern void hub_schedule_runslice(struct hub_info* hub);
*/
extern void hub_event_loop(struct hub_info* hub);
/**
* Schedule destroying a user.
*/
extern void hub_schedule_destroy_user(struct hub_info* hub, struct user* user);
/**
* Disconnect a user from the hub.
*/
extern void hub_disconnect_user(struct hub_info* hub, struct user* user, int reason);
#endif /* HAVE_UHUB_HUB_H */

View File

@ -52,7 +52,7 @@ void on_login_success(struct hub_info* hub, struct user* u)
struct timeval timeout = { TIMEOUT_IDLE, 0 };
/* Send user list of all existing users */
if (!uman_send_user_list(u))
if (!uman_send_user_list(hub, u))
return;
/* Mark as being in the normal state, and add user to the user list */
@ -64,7 +64,7 @@ void on_login_success(struct hub_info* hub, struct user* u)
/* Announce new user to all connected users */
if (user_is_logged_in(u))
route_info_message(u);
route_info_message(hub, u);
/* Send message of the day (if any) */
if (user_is_logged_in(u)) /* Previous send() can fail! */
@ -79,7 +79,7 @@ void on_login_failure(struct hub_info* hub, struct user* u, enum status_message
{
log_user_login_error(u, msg);
hub_send_status(hub, u, msg, status_level_fatal);
user_disconnect(u, quit_logon_error);
hub_disconnect_user(hub, u, quit_logon_error);
}
void on_nick_change(struct hub_info* hub, struct user* u, const char* nick)

View File

@ -339,7 +339,7 @@ static int check_logged_in(struct hub_info* hub, struct user* user, struct adc_m
if (lookup1 == lookup2)
{
hub_log(log_debug, "check_logged_in: exact same user is logged in: %s", user->id.nick);
user_disconnect(lookup1, quit_ghost_timeout);
hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
return 0;
}
else
@ -702,17 +702,22 @@ int hub_perform_login_checks(struct hub_info* hub, struct user* user, struct adc
return 0;
}
/**
* Perform additional INF checks used at time of login.
*
* @return 0 if success, <0 if error, >0 if authentication needed.
*/
int hub_handle_info_login(struct hub_info* hub, struct user* user, struct adc_message* cmd)
{
int need_auth = 0;
int code = 0;
INF_CHECK(hub_perform_login_checks, hub, user, cmd);
/* Private ID must never be broadcasted - drop it! */
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
/* FIXME: This needs some cleaning up */
need_auth = set_credentials(hub, user, cmd);
code = set_credentials(hub, user, cmd);
/* Note: this must be done *after* set_credentials. */
if (check_is_hub_full(hub, user))
@ -733,7 +738,7 @@ int hub_handle_info_login(struct hub_info* hub, struct user* user, struct adc_me
/* Set initial user info */
user_set_info(user, cmd);
return need_auth;
return code;
}
/*
@ -820,7 +825,7 @@ int hub_handle_info(struct hub_info* hub, struct user* user, const struct adc_me
if (!adc_msg_is_empty(cmd))
{
route_message(user, cmd);
route_message(hub, user, cmd);
}
adc_msg_free(cmd);

View File

@ -157,7 +157,7 @@ int main_loop()
hub_shutdown_service(hub);
}
net_shutdown();
net_destroy();
hub_log_shutdown();
return 0;
}

View File

@ -19,6 +19,8 @@
#include "uhub.h"
/* FIXME: This should not be needed! */
extern struct hub_info* g_hub;
void net_on_read(int fd, short ev, void *arg)
{
@ -145,7 +147,7 @@ void net_on_read(int fd, short ev, void *arg)
if (flag_close)
{
user_disconnect(user, flag_close);
hub_disconnect_user(g_hub, user, flag_close);
return;
}
@ -248,7 +250,7 @@ void net_on_write(int fd, short ev, void *arg)
if (close_flag)
{
user_disconnect(user, close_flag);
hub_disconnect_user(g_hub, user, close_flag);
}
else
{

View File

@ -59,7 +59,7 @@ int net_initialize()
}
int net_shutdown()
int net_destroy()
{
if (net_initialized)
{
@ -235,6 +235,20 @@ int net_close(int fd)
return ret;
}
int net_shutdown_r(int fd)
{
return shutdown(fd, SHUT_RD);
}
int net_shutdown_w(int fd)
{
return shutdown(fd, SHUT_WR);
}
int net_shutdown_rw(int fd)
{
return shutdown(fd, SHUT_RDWR);
}
int net_accept(int fd, struct ip_addr_encap* ipaddr)
{

View File

@ -47,7 +47,7 @@ extern int net_initialize();
*
* @return -1 on error, 0 on success
*/
extern int net_shutdown();
extern int net_destroy();
/**
* @return the number of sockets currrently being monitored.
@ -81,6 +81,10 @@ extern int net_socket_create(int af, int type, int protocol);
*/
extern int net_close(int fd);
extern int net_shutdown_r(int fd);
extern int net_shutdown_w(int fd);
extern int net_shutdown_rw(int fd);
/**
* A wrapper for the accept() function call.
* @param fd socket descriptor

View File

@ -20,35 +20,35 @@
#include "uhub.h"
int route_message(struct user* u, struct adc_message* msg)
int route_message(struct hub_info* hub, struct user* u, struct adc_message* msg)
{
struct user* target = NULL;
switch (msg->cache[0])
{
case 'B': /* Broadcast to all logged in clients */
route_to_all(u->hub, msg);
route_to_all(hub, msg);
break;
case 'D':
target = uman_get_user_by_sid(u->hub, msg->target);
target = uman_get_user_by_sid(hub, msg->target);
if (target)
{
route_to_user(target, msg);
route_to_user(hub, target, msg);
}
break;
case 'E':
target = uman_get_user_by_sid(u->hub, msg->target);
target = uman_get_user_by_sid(hub, msg->target);
if (target)
{
route_to_user(target, msg);
route_to_user(u, msg);
route_to_user(hub, target, msg);
route_to_user(hub, u, msg);
}
break;
case 'F':
route_to_subscribers(u->hub, msg);
route_to_subscribers(hub, msg);
break;
default:
@ -111,7 +111,7 @@ static int check_send_queue(struct user* user, struct adc_message* msg)
return 1;
}
int route_to_user(struct user* user, struct adc_message* msg)
int route_to_user(struct hub_info* hub, struct user* user, struct adc_message* msg)
{
int ret;
@ -141,7 +141,7 @@ int route_to_user(struct user* user, struct adc_message* msg)
else
{
/* A socket error occured */
user_disconnect(user, quit_socket_error);
hub_disconnect_user(hub, user, quit_socket_error);
return 0;
}
}
@ -152,7 +152,7 @@ int route_to_user(struct user* user, struct adc_message* msg)
if (ret == -1)
{
/* User is not able to swallow the data, let's cut our losses and disconnect. */
user_disconnect(user, quit_send_queue);
hub_disconnect_user(hub, user, quit_send_queue);
}
else if (ret == 1)
{
@ -177,7 +177,7 @@ int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate u
struct user* user = (struct user*) list_get_first(hub->users->list);
while (user)
{
route_to_user(user, command);
route_to_user(hub, user, command);
user = (struct user*) list_get_next(hub->users->list);
}
@ -226,7 +226,7 @@ int route_to_subscribers(struct hub_info* hub, struct adc_message* command) /* i
if (do_send)
{
route_to_user(user, command);
route_to_user(hub, user, command);
}
}
user = (struct user*) list_get_next(hub->users->list);
@ -235,11 +235,11 @@ int route_to_subscribers(struct hub_info* hub, struct adc_message* command) /* i
return 0;
}
int route_info_message(struct user* u)
int route_info_message(struct hub_info* hub, struct user* u)
{
if (!user_is_nat_override(u))
{
return route_to_all(u->hub, u->info);
return route_to_all(hub, u->info);
}
else
{
@ -250,15 +250,15 @@ int route_info_message(struct user* u)
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
user = (struct user*) list_get_first(u->hub->users->list);
user = (struct user*) list_get_first(hub->users->list);
while (user)
{
if (user_is_nat_override(user))
route_to_user(user, cmd);
route_to_user(hub, user, cmd);
else
route_to_user(user, u->info);
route_to_user(hub, user, u->info);
user = (struct user*) list_get_next(u->hub->users->list);
user = (struct user*) list_get_next(hub->users->list);
}
adc_msg_free(cmd);
}

View File

@ -23,12 +23,12 @@
/**
* Route a message by sending it to it's final destination.
*/
extern int route_message(struct user* u, struct adc_message* msg);
extern int route_message(struct hub_info* hub, struct user* u, struct adc_message* msg);
/**
* Transmit message directly to one user.
*/
extern int route_to_user(struct user*, struct adc_message* command);
extern int route_to_user(struct hub_info* hub, struct user*, struct adc_message* command);
/**
* Broadcast message to all users.
@ -45,7 +45,7 @@ extern int route_to_subscribers(struct hub_info* hub, struct adc_message* comman
* This will ensure the correct IP is seen by other users
* in case nat override is in use.
*/
extern int route_info_message(struct user* user);
extern int route_info_message(struct hub_info* hub, struct user* user);
#endif /* HAVE_UHUB_ROUTE_H */

View File

@ -232,51 +232,8 @@ void user_support_remove(struct user* user, int fourcc)
user->flags &= ~feature_mask;
}
void user_schedule_destroy(struct user* user)
{
struct event_data post;
memset(&post, 0, sizeof(post));
post.id = UHUB_EVENT_USER_DESTROY;
post.ptr = user;
event_queue_post(user->hub->queue, &post);
}
void user_disconnect(struct user* user, int reason)
{
struct event_data post;
int need_notify = 0;
if (user_is_disconnecting(user))
{
return;
}
/* dont read more data from this user */
if (user->ev_read)
{
event_del(user->ev_read);
hub_free(user->ev_read);
user->ev_read = 0;
}
hub_log(log_trace, "user_disconnect(), user=%p, reason=%d, state=%d", user, reason, user->state);
need_notify = user_is_logged_in(user);
user->quit_reason = reason;
user_set_state(user, state_cleanup);
if (need_notify)
{
memset(&post, 0, sizeof(post));
post.id = UHUB_EVENT_USER_QUIT;
post.ptr = user;
event_queue_post(user->hub->queue, &post);
}
else
{
user->quit_reason = quit_unknown;
user_schedule_destroy(user);
}
}

View File

@ -146,11 +146,6 @@ extern struct user* user_create(struct hub_info* hub, int sd);
*/
extern void user_destroy(struct user* user);
/**
* Will post a message that will delete the user later.
*/
extern void user_schedule_destroy(struct user* user);
/**
* Disconnect a user.
* This will mark the user connection ready for being terminated.

View File

@ -210,20 +210,20 @@ struct user* uman_get_user_by_nick(struct hub_info* hub, const char* nick)
}
int uman_send_user_list(struct user* target)
int uman_send_user_list(struct hub_info* hub, struct user* target)
{
int ret = 1;
user_flag_set(target, flag_user_list);
struct user* user = (struct user*) list_get_first(target->hub->users->list); /* iterate users - only on INF or PAS msg */
struct user* user = (struct user*) list_get_first(hub->users->list); /* iterate users - only on INF or PAS msg */
while (user)
{
if (user_is_logged_in(user))
{
ret = route_to_user(target, user->info);
ret = route_to_user(hub, target, user->info);
if (!ret)
break;
}
user = (struct user*) list_get_next(user->hub->users->list);
user = (struct user*) list_get_next(hub->users->list);
}
if (!target->send_queue_size)
@ -234,7 +234,7 @@ int uman_send_user_list(struct user* target)
}
void uman_send_quit_message(struct user* leaving)
void uman_send_quit_message(struct hub_info* hub, struct user* leaving)
{
struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6);
adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid));
@ -244,7 +244,7 @@ void uman_send_quit_message(struct user* leaving)
adc_msg_add_argument(command, ADC_QUI_FLAG_DISCONNECT);
}
route_to_all(leaving->hub, command);
route_to_all(hub, command);
adc_msg_free(command);
}

View File

@ -105,13 +105,13 @@ extern struct user* uman_get_user_by_nick(struct hub_info* hub, const char* nick
*
* @return 1 if sending the user list succeeded, 0 otherwise.
*/
extern int uman_send_user_list(struct user* user);
extern int uman_send_user_list(struct hub_info* hub, struct user* user);
/**
* Send a quit message to all connected users when 'user' is
* leaving the hub (for whatever reason).
*/
extern void uman_send_quit_message(struct user* user);
extern void uman_send_quit_message(struct hub_info* hub, struct user* user);
#endif /* HAVE_UHUB_USER_MANAGER_H */