Example #1
0
File: hub.c Project: q3k/uhub
void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason)
{
	struct event_data post;
	int need_notify = 0;

	/* is user already being disconnected ? */
	if (user_is_disconnecting(user))
	{
		return;
	}

	/* stop reading from user */
	net_shutdown_r(net_con_get_sd(user->connection));
	net_con_close(user->connection);
	user->connection = 0;

	LOG_TRACE("hub_disconnect_user(), user=%p, reason=%d, state=%d", user, reason, user->state);

	need_notify = user_is_logged_in(user) && hub->status == hub_status_running;
	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
	{
		hub_schedule_destroy_user(hub, user);
	}
}
Example #2
0
File: hub.c Project: imobilis/uhub
void hub_disconnect_all(struct hub_info* hub)
{
	struct event_data post;
	memset(&post, 0, sizeof(post));
	post.id = UHUB_EVENT_HUB_SHUTDOWN;
	post.ptr = 0;
	event_queue_post(hub->queue, &post);
}
Example #3
0
int msg_pool_post(msg_pool_t* mp, int ch, void* msg)
{
	int ret;
	if ((ret = event_queue_post(&mp->equeue[ch], msg)) >= 0) {
		if (mp->efd[ch] >= 0) {
			if ((ret = msg_pool_efd_trypost(mp->efd[ch])) < 0) perror("msg_pool_efd_trypost");
		}
	}
	return ret;
}
Example #4
0
File: hub.c Project: imobilis/uhub
void hub_schedule_destroy_user(struct hub_info* hub, struct hub_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);

	if (user->id.sid)
	{
		sid_free(hub->users->sids, user->id.sid);
	}
}
Example #5
0
File: inf.c Project: leejb521/uhub
/*
 * If user is in the connecting state, we need to do fairly
 * strict checking of all arguments.
 * This means we disconnect users when they provide invalid data
 * during the login sequence.
 * When users are merely updating their data after successful login
 * we can just ignore any invalid data and not broadcast it.
 *
 * The data we need to check is:
 * - nick name (valid, not taken, etc)
 * - CID/PID (valid, not taken, etc).
 * - IP addresses (IPv4 and IPv6)
 */
int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct adc_message* cmd_unmodified)
{
	int ret;
	struct adc_message* cmd = adc_msg_copy(cmd_unmodified);
	if (!cmd) return -1; /* OOM */

	cmd->priority = 1;

	hub_handle_info_common(user, cmd);

	/* If user is logging in, perform more checks,
	   otherwise only a few things need to be checked.
	 */
	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;
		}

		ret = hub_handle_info_login(hub, user, cmd);
		if (ret < 0)
		{
			on_login_failure(hub, user, ret);
			adc_msg_free(cmd);
			return -1;
		}
		else
		{
			/* Post a message, the user has joined */
			struct event_data post;
			memset(&post, 0, sizeof(post));
			post.id    = UHUB_EVENT_USER_JOIN;
			post.ptr   = user;
			post.flags = ret; /* 0 - all OK, 1 - need authentication */
			event_queue_post(hub->queue, &post);
			adc_msg_free(cmd);
			return 0;
		}
	}
	else
	{
		/* These must not be allowed updated, let's remove them! */
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);

		/*
		 * If the nick is not accepted, do not relay it.
		 * Otherwise, the nickname will be updated.
		 */
		if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK))
		{
#ifdef ALLOW_CHANGE_NICK
			if (!check_nick(hub, user, cmd))
#endif
				adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK);
		}

		ret = check_limits(hub, user, cmd);
		if (ret < 0)
		{
			on_update_failure(hub, user, ret);
			adc_msg_free(cmd);
			return -1;
		}

		strip_network(user, cmd);
		hub_handle_info_low_bandwidth(hub, user, cmd);

		user_update_info(user, cmd);

		if (!adc_msg_is_empty(cmd))
		{
			route_message(hub, user, cmd);
		}

		adc_msg_free(cmd);
	}

	return 0;
}