예제 #1
0
bool Client::allowChatMessagefromUser(const ChatMessage& message, const string& p_nick)
{
	if (!message.m_from)
	{
		if (!p_nick.empty() && UserManager::isInIgnoreList(p_nick)) // http://code.google.com/p/flylinkdc/issues/detail?id=1432
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (isMe(message.m_from))
	{
		return true;
	}
	else if (message.thirdPerson && BOOLSETTING(NSL_IGNORE_ME))
	{
		return false;
	}
	if (BOOLSETTING(SUPPRESS_MAIN_CHAT) && !isOp())
	{
		return false;
	}
	else if (UserManager::isInIgnoreList(message.m_from->getIdentity().getNick())) // !SMT!-S
	{
		return false;
	}
	else
	{
		return true;
	}
}
예제 #2
0
//{{{ site_failure
void site_failure(int sig) {
	if (_verbose) fprintf (stderr, "/* FAILURE OF A SITE SPOTTED */\n");
	int i=0;
	int sortie = 0;
	msg_t msg;
	time_t timeStart, timeCur;

		pthread_mutex_lock(&mut_check);
		if (check)
			check = 0;
		pthread_mutex_unlock(&mut_check);

	int flags = fcntl(this_site.sdRecv, F_GETFL);
	int flags2 = flags | O_NONBLOCK;
	fcntl(this_site.sdRecv, F_SETFL, flags2);

	// Sends ARE_YOU_ALIVE to other pred
	if (_verbose) fprintf (stdout, "Checking predecessor validity\n");
	for (i=1; i<TOLERANCE+1; i++) {
		if (!strcmp ("0.0.0.0", inet_ntoa(predec[i].sin_addr))) {
			if (_verbose) fprintf (stdout, "Bad ip address\n");
			continue;
		}
		type(msg) = ARE_YOU_ALIVE;
		char *tmp = inet_ntoa(predec[i].sin_addr);
		strncpy (ip(msg), tmp, IPLONG *sizeof(char));
		unsigned long int ipa = (unsigned long int) inet_addr(ip(msg));
		sendMessageWithAdd(msg);

		pthread_mutex_lock(&mut_check);
		if (check)
			check = 0;
		pthread_mutex_unlock(&mut_check);

		timeStart = time(&timeStart);
		timeCur = time(&timeCur);

		while(timeCur - timeStart < (2*TMESG)) {
			timeCur = time(&timeCur);
			memset (&msg, 0, SIZE);

			if(recvMessage(&msg, NULL) == -1) 
				continue;

			// Receive I_AM_ALIVE --> Connection
			if (_verbose) fprintf (stdout, "Received I_AM_ALIVE\n");
			if (type(msg) == I_AM_ALIVE && !isMe(ips(msg))) {
				handleIAmAlive(msg);
				type(msg) = CONNECTION;
				strncpy(ip(msg), ips(msg), IPLONG * sizeof(char));
				sendMessageWithAdd(msg);
				if (_verbose) fprintf (stdout, "Asking for connection\n");
				last = getNeighbour(ipa);
				if (_verbose) fprintf (stdout, "New last after receiving I_AM_ALIVE message : %d\n", last);
				state = IDLE;
				critSectionRequest();
				sortie++;
				break;
			}
			else if (type(msg) == REQUEST) {}
			else
				handleMessage(msg);
		}
	}

	// No pred is alive, broadcast SEARCH_PREV
	fcntl(this_site.sdRecv, F_SETFL, flags);

	if (_verbose) fprintf (stdout, "No alive predecessor found, looking for other sites\n");
	if (!sortie) {
		msg_t min;

		type(msg) = SEARCH_PREV;
		pos(msg) = position;
		if (_verbose) fprintf (stdout, "Broadcasting SEARCH_PREV.\n");
		broadcast(msg);

		fcntl(this_site.sdRecv, F_SETFL, flags2);

		timeStart = time(&timeStart);
		timeCur = time(&timeCur);

		// Wait for ACK_SEARCH_PREV
		while(timeCur - timeStart < (2*TMESG)) {
			timeCur = time(&timeCur);
			memset (&msg, 0, SIZE);

			if(recvMessage(&msg, NULL) == -1) 
				continue;

			pos(min) = -1;
			if (type(msg) == ACK_SEARCH_PREV) {
				if (pos(min) == -1)
					memcpy (&min, &msg, SIZE);
				else if (pos(min) < pos(msg))
					memcpy (&min, &msg, SIZE);
				if (_verbose) fprintf (stdout, "Got an answer.\n");
			}
			else if (type(msg) == REQUEST) {}
			else
				handleMessage(msg);
		}

		fcntl(this_site.sdRecv, F_SETFL, flags);

		// No answers, regenerate the TOKEN
		if (pos(min) == -1) {
			if (_verbose) fprintf (stdout, "No answers, regenerating TOKEN\n");
			tokenPresent = 1;
			last = next;
			takeCriticalSection();
			sortie ++;
		}

		// Got an answer, ask for connection
		if (!sortie) {
			if (_verbose) fprintf (stdout, "Asking for connection\n");
			type(msg) = CONNECTION;
			strncpy(ip(msg), ips(min), IPLONG * sizeof(char));
			last = getNeighbour((unsigned long int)inet_addr(ips(min)));
			sendMessageWithAdd(msg);
			state = IDLE;
			critSectionRequest();
		}
	}
}
예제 #3
0
// {{{ critSectionRequest
// Ask for critical section
int critSectionRequest() {
	msg_t msg;
	type(msg) = REQUEST;
	char *ip_tmp = inet_ntoa(this_site.neighbours[0].sin_addr);
	strncpy (ask(msg), ip_tmp, IPLONG);

	// If already in SC just return -1
	if (state != IDLE) {
		if (_verbose) fprintf (stderr,"Already in critical section.\n");
		return -1;
	}
	state = WAITING;

	// Owns Token ?
	if(tokenPresent) 
		return takeCriticalSection();
	// Sends request to last
	else if(last != -1) {
		// Get ip of last
		char *tmpter = getIPstrFromNb (last);
		if (_verbose) fprintf (stdout, "Last is %d, sending it a request.\n", last);
		strncpy(ip(msg), tmpter, IPLONG);
		free (tmpter);

		strncpy (ask(msg), inet_ntoa(this_site.neighbours[0].sin_addr), IPLONG);

		if(sendMessageWithAdd(msg) == -1){
			if (_verbose) fprintf (stderr, "======> Sending request failure... <======\n");
			return -1;
		}

		// Arms a timer
		time_t timeStart, timeCur;
		int flags = fcntl(this_site.sdRecv, F_GETFL);
		int flags2 = flags | O_NONBLOCK;
		fcntl(this_site.sdRecv, F_SETFL, flags2);

		timeStart = time(&timeStart);
		timeCur = time(&timeCur);

		// Wait for an answer
		if (_verbose) fprintf (stdout, "Waiting for COMMIT.\n");
		while(timeCur - timeStart < (2*TMESG)) {
			timeCur = time(&timeCur);

			if(recvMessage(&msg, NULL) == -1) 
				continue;

			if (type(msg) == COMMIT)
				return handleCommit(msg);
			else {
				// TODO: Work on reaction when receiving request while waiting commit
				if (type(msg) == REQUEST) {
					if (_verbose) fprintf (stdout, "Received a REQUEST instead of a COMMIT.\n");
				}
				else if (type(msg) == TOKEN){
					last = -1;
					return handleToken(msg);
				}
				else
					handleMessage(msg);
			}
		}

		// If receive no answers
		if (_verbose) fprintf (stdout, "I didn't get any COMMIT, looking for the queue...\n");
		fcntl(this_site.sdRecv, F_SETFL, flags);

		memset (&msg, 0, SIZE);
		type(msg) = SEARCH_QUEUE;
		nb_acc(msg) = acces;
		// Broadcast Search_Queue
		if (_verbose) fprintf (stdout, "Broadcasting SEARCH_QUEUE.\n");
		broadcast(msg);

		msg_t max;
		pos(max) = -1;

		fcntl(this_site.sdRecv, F_SETFL, flags2);

		timeStart = time(&timeStart);
		timeCur = time(&timeCur);

		// Wait for ACK_SEARCH_QUEUE
		if (_verbose) fprintf (stdout, "Expecting ACK_SEARCH_QUEUE.\n");
		while(timeCur - timeStart < 2*TMESG) {
			timeCur = time(&timeCur);
			memset (&msg, 0, SIZE);

			if(recvMessage(&msg, NULL) == -1) 
				continue;

			switch(type(msg)) {
				case ACK_SEARCH_QUEUE:
					if (_verbose) fprintf (stdout, "Got an ACK_SEARCH_QUEUE.\n");
					// Save greatest position in the queue
					if (pos(msg) > pos(max)) {
						if (_verbose) fprintf (stdout, "New position in QUEUE : %d.\n", pos(msg));
						memcpy(&max, &msg, SIZE);
					}
					break;
					// Another site discovers the failure
				case SEARCH_QUEUE:
					if (isMe(ips(msg)))
						continue;
					if (_verbose) fprintf (stdout, "Another site discovered the failure.\n");
					// The other site hasn't priority, just continue
					if (nb_acc(msg) > acces) 
						continue;
					// Both of sites have the same numbers of access, defines priority with ip
					if (nb_acc(msg) == acces) {
						char *ip_pers = inet_ntoa(this_site.neighbours[0].sin_addr);
						if (strcmp(ip_pers, ips(msg)) <= 0)
							continue;
					}
					// If the other has the priority, just change last and ask it for CS
					unsigned long int ipa = (unsigned long int) inet_addr(ips(msg));
					last = getNeighbour(ipa);
					if (_verbose) fprintf (stdout, "I don't have priority, changing my last (%d) and asking for CS again.\n", last);
					state = IDLE;
					return critSectionRequest();
					// TODO: Request processing
				case REQUEST:
					break;
				default:
					handleMessage(msg);
					break;
			}
		}

		if (_verbose) fprintf (stdout, "Waiting time passed.\n");

		fcntl(this_site.sdRecv, F_SETFL, flags);

		// No other site in the queue, juste regenerate TOKEN
		if (pos(max) < 0) {
			if (_verbose) fprintf (stdout, "No other sites in the queue, regenerate TOKEN (last = next)\n");
			last = next;
			tokenPresent = 1;
			takeCriticalSection();
		}
		else {
			// Ask for connection to the site with the highest position
			unsigned long int ipa = (unsigned long int) inet_addr(ips(max));
			last = getNeighbour(ipa);
			if (_verbose) fprintf (stdout, "Ask for Connection, new last = %d\n", last);
			strncpy(ip(msg), ips(max),IPLONG *sizeof(char));
			if (next(max)) {
				type(msg) = CONNECTION;
				if (sendMessageWithAdd(msg) == -1)
					return -1;
			}
			state = IDLE;
			critSectionRequest();
		}
	}
	else
		if (_verbose) fprintf (stderr, "======> Last = -1, but don't have TOKEN <======\n");
	return 0;
}
예제 #4
0
// [+] IRainman fix.
bool Client::allowPrivateMessagefromUser(const ChatMessage& message)
{
	if (isMe(message.m_replyTo))
	{
		if (UserManager::expectPasswordFromUser(message.m_to->getUser())
#ifdef IRAINMAN_ENABLE_AUTO_BAN
		        || UploadManager::getInstance()->isBanReply(message.m_to->getUser()) // !SMT!-S
#endif
		   )
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (message.thirdPerson && BOOLSETTING(NSL_IGNORE_ME))
	{
		return false;
	}
	else if (UserManager::isInIgnoreList(message.m_replyTo->getIdentity().getNick())) // !SMT!-S
	{
		return false;
	}
	else if (BOOLSETTING(SUPPRESS_PMS))
	{
#ifdef IRAINMAN_ENABLE_AUTO_BAN
		if (UploadManager::getInstance()->isBanReply(message.m_replyTo->getUser())) // !SMT!-S
		{
			return false;
		}
		else
#endif
			if (FavoriteManager::getInstance()->isNoFavUserOrUserIgnorePrivate(message.m_replyTo->getUser()))
			{
				if (BOOLSETTING(LOG_IF_SUPPRESS_PMS))
				{
					LocalArray<char, 200> l_buf;
					snprintf(l_buf.data(), l_buf.size(), CSTRING(LOG_IF_SUPPRESS_PMS), message.m_replyTo->getIdentity().getNick().c_str(), getHubName().c_str(), getHubUrl().c_str());
					LogManager::getInstance()->message(l_buf.data());
				}
				return false;
			}
			else
			{
				return true;
			}
	}
	else if (message.m_replyTo->getIdentity().isHub())
	{
		if (BOOLSETTING(IGNORE_HUB_PMS) && !isInOperatorList(message.m_replyTo->getIdentity().getNick()))
		{
			fire(ClientListener::StatusMessage(), this, STRING(IGNORED_HUB_BOT_PM) + ": " + message.m_text);
			return false;
		}
		else if (FavoriteManager::getInstance()->hasIgnorePM(message.m_replyTo->getUser()))
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (message.m_replyTo->getIdentity().isBot())
	{
		if (BOOLSETTING(IGNORE_BOT_PMS) && !isInOperatorList(message.m_replyTo->getIdentity().getNick()))
		{
			fire(ClientListener::StatusMessage(), this, STRING(IGNORED_HUB_BOT_PM) + ": " + message.m_text);
			return false;
		}
		else if (FavoriteManager::getInstance()->hasIgnorePM(message.m_replyTo->getUser()))
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	else if (BOOLSETTING(PROTECT_PRIVATE) && !FavoriteManager::getInstance()->hasFreePM(message.m_replyTo->getUser())) // !SMT!-PSW
	{
		switch (UserManager::checkPrivateMessagePassword(message))
		{
			case UserManager::FREE:
			{
				return true;
			}
			case UserManager::WAITING:
			{
				return false;
			}
			case UserManager::FIRST:
			{
				StringMap params;
				params["pm_pass"] = SETTING(PM_PASSWORD);
				privateMessage(message.m_replyTo, Util::formatParams(SETTING(PM_PASSWORD_HINT), params, false), false);
				if (BOOLSETTING(PROTECT_PRIVATE_SAY))
				{
					fire(ClientListener::StatusMessage(), this, STRING(REJECTED_PRIVATE_MESSAGE_FROM) + ": " + message.m_replyTo->getIdentity().getNick());
				}
				return false;
			}
			case UserManager::CHECKED:
			{
				privateMessage(message.m_replyTo, SETTING(PM_PASSWORD_OK_HINT), true);
				
				// TODO needs?
				// const tstring passwordOKMessage = _T('<') + message.m_replyTo->getUser()->getLastNickT() + _T("> ") + TSTRING(PRIVATE_CHAT_PASSWORD_OK_STARTED);
				// PrivateFrame::gotMessage(from, to, replyTo, passwordOKMessage, getHubHint(), myPM, pm.thirdPerson); // !SMT!-S
				
				return true;
			}
			default: // Only for compiler.
			{
				dcassert(0);
				return false;
			}
		}
	}
	else
	{
		if (FavoriteManager::getInstance()->hasIgnorePM(message.m_replyTo->getUser())
#ifdef IRAINMAN_ENABLE_AUTO_BAN
		        || UploadManager::getInstance()->isBanReply(message.m_replyTo->getUser()) // !SMT!-S
#endif
		   )
		{
			return false;
		}
		else
		{
			return true;
		}
	}
}