Esempio n. 1
0
/*
 * Parse incoming data
 * Types of messages and their responses are:
 *					NEW: <from>
 *						Response --> NEW: <status>
 *					CHNAME: <old> : <new>
 *						Response --> CHNAME: <status>
 * 					QUERY: <from>
 *						Response --> ONLINE: <user1> : <user2> : <user3> : ....
 *					SEND: <from> : <to> : <message>
 *						Response --> SENT: <to> : <statusMessage>
 *					BCAST: <from> : <message>
 *						Response --> SENT: <from> : <status>
 *					
 *					/toclient/ RECV: <from> : <message>
 */
void processRequest(int fromSocket, char* stream){
	std::vector<std::string> tokens;

	char* dump = strdup(stream);												/* Create a duplicate stream */
	splitCharStream(dump, DELIM, 1, &tokens);									/* Retrieve the kind of message */
	delete dump;

	std::string reqType = tokens[0];

	int TYPE_FLAG = -1, delimCount=-1;
	if(reqType=="CHNAME"){
		TYPE_FLAG = TYPE_CHNAME;
		delimCount = 1;
	}
	else if(reqType=="NEW"){
		TYPE_FLAG = TYPE_NEW;
		delimCount = 0;
	}
	else if(reqType=="QUERY"){
		TYPE_FLAG = TYPE_QUERY;
		delimCount = 0;
	}
	else if(reqType=="SEND"){
		TYPE_FLAG = TYPE_SEND;
		delimCount = 2;
	}
	else if(reqType=="BCAST"){
		TYPE_FLAG = TYPE_BCAST;
		delimCount = 1;
	}

	if(TYPE_FLAG==-1)
		return;
	
	#ifdef __DEBUG__
	std::cout<<TYPE_FLAG<<" --- ";
	#endif

	splitCharStream(strdup(tokens[1].c_str()), DELIM, delimCount, &tokens);		/* Based on kind retrieve other param list */
	
	std::string fromUser = tokens[0];
	std::string toUser, message;
	if(TYPE_FLAG == TYPE_CHNAME){
		toUser = tokens[1];
		#ifdef __INFO__
		std::cout<<"\""<<fromUser<<"\" changing name to \""<<toUser<<"\"."<<std::endl;
		#endif

		int curSock = getFromConnectionTable(fromUser);
		std::string reply = "CHNAME:"+toUser+":";
		if(curSock==-1){
			reply += "fail";
		}
		else{
			curSock = getFromConnectionTable(toUser);
			if(curSock==-1){
				removeFromConnectionTable(fromSocket);
				addToConnectionTable(toUser, fromSocket);
				reply += "success";
			}
			else{
				reply += "duplicate";
			}
		}
		int s = send(fromSocket, reply.c_str(), reply.length(), 0);
		if(s<0){
			ERROR = E_SEND;
			error_message = "Unable to send query reply.";

			#ifdef __DEBUG__
			std::cout<<error_message<<std::endl;
			#endif
		}	
	}
	else if(TYPE_FLAG == TYPE_NEW){
		#ifdef __INFO__
		std::cout<<"\""<<fromUser<<"\" new registration."<<std::endl;
		#endif

		int oldSock = getFromConnectionTable(fromUser);
		std::string reply = "duplicate";
		if(oldSock==-1){
			addToConnectionTable(fromUser, fromSocket);								/* Add user socket pair to table */
			reply = "registered";
		}
		#ifdef __INFO__
		std::cout<<"\""<<fromUser<<"\" reg. status: "<<reply<<"."<<std::endl;
		#endif
		int s = send(fromSocket, reply.c_str(), reply.length(), 0);
		if(s<0){
			ERROR = E_SEND;
			error_message = "Unable to send query reply.";

			#ifdef __DEBUG__
			std::cout<<error_message<<std::endl;
			#endif
		}	
	}
	else if(TYPE_FLAG == TYPE_QUERY){
		#ifdef __INFO__
		std::cout<<"\""<<fromUser<<"\" queried."<<std::endl;
		#endif

		std::string onlineList = getOnlineList(fromUser);

		int s = send(fromSocket, onlineList.c_str(), onlineList.length(), 0);
		if(s<0){
			ERROR = E_SEND;
			error_message = "Unable to send query reply.";

			#ifdef __DEBUG__
			std::cout<<error_message<<std::endl;
			#endif
		}
	}
	else if(TYPE_FLAG == TYPE_SEND){
		toUser = tokens[1];
		message = tokens[2];

		#ifdef __INFO__
		std::cout<<"\""<<fromUser<<"\" sending message to \""<<toUser<<"\"."<<std::endl;
		#endif

		/* Send message to desired target username */
		int status = sendMessage(toUser, fromUser, message);
				
		std::string reply = "SENT: "+toUser+" : ";
		if(status==-1){
			reply += error_message;

			#ifdef __DEBUG__
			std::cout<<"\""<<fromUser<<"\" could not send a message to \""<<toUser<<"\". "<<std::endl;
			#endif
		}
		else{
			reply += "success";

			#ifdef __DEBUG__
			std::cout<<"\""<<fromUser<<"\" sent a message to \""<<toUser<<"\"."<<std::endl;
			#endif
		}
		/* Report back to the sender */
		int s = send(fromSocket, reply.c_str(), reply.length(), 0);
		if(s<0){
			ERROR = E_SEND;
			error_message = "Unable to send message status.";

			#ifdef __DEBUG__
			std::cout<<error_message<<std::endl;
			#endif
		}
	}
	else if(TYPE_FLAG == TYPE_BCAST){
		message = tokens[1];

		std::string bcast = "RECV:"+fromUser+":"+message;
		#ifdef __INFO__
		std::cout<<"Broadcast from \""+fromUser+"\" : "<<message<<std::endl;
		#endif

		int status;
		Connections::iterator it = conn.begin();
		while(it!=conn.end()){
			if(it->first != fromUser){
				status = send(it->second, bcast.c_str(), bcast.length(), 0 );
			}
			++it;
		}
		std::string reply = "SENT:"+fromUser+":b_success";
		/* Report back to the broadcaster */
		int s = send(fromSocket, reply.c_str(), reply.length(), 0);
		if(s<0){
			ERROR = E_SEND;
			error_message = "Unable to send message status.";

			#ifdef __DEBUG__
			std::cout<<error_message<<std::endl;
			#endif
		}
	}
}
Esempio n. 2
0
void *accepted(void *csd){
	PEER *p = (PEER *) csd;
	DATA *data = malloc(sizeof(DATA));
	DATA *reply = malloc(sizeof(DATA));
	int client_sd = p->client_sd;
	int len, status;
	int id = p->id;
	
	while(1){

		printf("B4 recv data\n");
		data = recv_data(client_sd,(unsigned int *)&len,&status);
		printf("AFTER recv data\n");
		switch(status){
			case -1:
			case -2:
				printf("Status = error(%d)\n", status);
				close(client_sd);
				offline(id);
				printf("[Disconnected] Client %s:%d\n", 
					getClientAddr(&p->client_addr),
					ntohs(p->client_addr.sin_port));
				return 0;
			default:
				break;
		}

		printf("DATA command: %d\n", data->command);

	    switch(data->command){
	    	case LOGIN:
	    		printf("Client %s:%d: [LOGIN] Username="******"\n");
	    		data->arg->ip = ntohl(p->client_addr.sin_addr.s_addr);
	    		status = online(data->arg, id);
	    		if(status >= 0 && status < 10){
	    			reply = newHeader();
	    			reply->command = LOGIN_OK;
	    			reply->length = 1;
					if(!send_data(client_sd,reply,(unsigned int*)&len)) return 0;
	    		}else{
	    			printf("[ERROR] Client %s:%d ", 
						getClientAddr(&p->client_addr),
						ntohs(p->client_addr.sin_port));
	    			reply = newHeader();
	    			reply->command = ERROR;
	    			switch(status){
	    				case -1:
	    					printf("maximum connection exceed!");
	    					reply->error = TOO_MUCH_CONN;
	    					break;
	    				case -2:
	    					printf("duplication of name!");
	    					reply->error = SAME_NAME;
	    					break;
	    				case -3:
	    					printf("duplication of port and IP address!");
	    					reply->error = SAME_CONN;
	    			}
	    			printf("\n");
	    			reply->length = 7;
	    			if(!send_data(client_sd,reply,(unsigned int*)&len)) return 0;
	    			close(client_sd);
					printf("[Disconnected] Client %s:%d\n", 
						getClientAddr(&p->client_addr),
						ntohs(p->client_addr.sin_port));
					return 0;
	    		}
	    		break;
	    	case GET_LIST:
	    		printf("Client %s:%d: GET_LIST\n", 
	    			getClientAddr(&p->client_addr),
	    			ntohs(p->client_addr.sin_port));
	    		reply = newHeader();
	    		reply->command = GET_LIST_OK;
	    		getOnlineList(reply);
	    		reply->length += 7;
				if(!send_data(client_sd,reply,(unsigned int*)&len)) return 0;
	    		break;
	    	default:
	    		printf("Client %s:%d: Unknown command\n", 
	    			getClientAddr(&p->client_addr),
	    			ntohs(p->client_addr.sin_port));
	    		break;
	    }
	}

	if(client_sd) close(client_sd);
	offline(id);
	printOnlineList();
	printf("[Disconnected] Client %s:%d\n", 
		getClientAddr(&p->client_addr),
		p->client_addr.sin_port);

}