void handleAddressQuery(char *commandName, unsigned int key, unsigned int value, unsigned long responseAddress, unsigned int responsePort) {
	if(key == 2){
		forwardQuery(commandName, 1, value, responseAddress, responsePort);
	}else if(key == 1){	
		unsigned char buffer[INTERNAL_BUFFER_LENGTH];
		struct sockaddr_in requester_addr;
		socklen_t requester_addrlen;
		int sockfd;
	
		requester_addr.sin_family = AF_INET;
		requester_addr.sin_port = htons(responsePort);
		requester_addr.sin_addr.s_addr = responseAddress;
		memset(requester_addr.sin_zero, '\0', sizeof requester_addr.sin_zero);
		requester_addrlen = sizeof(requester_addr);
		
		if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
			printf("Socket not created!");
			exit(1);
		}
	
		packDataForInternal(buffer, commandName, 0, value, server_ip, server_port);
		printf("FORWARD> [%s] %d:%d (origin: %lu:%d)\n", commandName, key, value, responseAddress, responsePort);
	
		if(sendto(sockfd, buffer, sizeof(buffer), 0, (const struct sockaddr *)&requester_addr, requester_addrlen) < 0){
			printf("FATAL: sending error.");
		}
	
		close(sockfd);
		
	}else{
		printf("got succ_successor (addr: %lu:%d)\n", responseAddress, responsePort);
		succ_successor_addr.sin_family = AF_INET;
		succ_successor_addr.sin_port = htons(responsePort);
		succ_successor_addr.sin_addr.s_addr = responseAddress;
		memset(succ_successor_addr.sin_zero, '\0', sizeof succ_successor_addr.sin_zero);
		succ_successor_addrlen = sizeof(succ_successor_addr);
	}
}
void handleQuery(char *commandName, unsigned int key, unsigned int value, unsigned long responseAddress, unsigned int responsePort) {	 //, struct hashnode *table
	if(isSetQuery(commandName)) {						// -- process set cmd
		if(hashSet(table, key, value) == -1){
			strcpy(commandName, "err");
			// key = value = 0;
		}else{
			strcpy(commandName, "ok!");
		}
	} else if(isGetQuery(commandName)) {				// -- process get cmd
		int val = hashGet(table, key);

		if(val == -1){
			strcpy(commandName, "nof");
			// key = value = 0;
		}else{
			strcpy(commandName, "val");
			value = val;
		}
	} else if(isDelQuery(commandName)) {				// -- process del cmd
		if(hashDel(table, key) == -1){
			strcpy(commandName, "nof");
			// key = value = 0;
		}else{
			strcpy(commandName, "ok!");
		}
	} else {
		strcpy(commandName, "err");
		// key = value = 0;
	}
	
	printf("Table modification complete.\n");
	
	forwardQuery(commandName, key, value, responseAddress, responsePort);
	
	return;
}
// ------------ MAIN --------------
int main(int argc, char *argv[])
{	
    // usage check / notification
    if(argc != 6) {
        printf("usage Error: use: hashServer serverAddress serverPort offset[0,64,128,196] successorAddress successorPort\n\n");
        exit(1);
    }
	
	// offset
	offset = atoi(argv[3]);
	
	// alloc hashtable
	table = (struct hashnode *) malloc(sizeof(struct hashnode) * 64);
	
	// set up successor	
    successor_port = atoi(argv[5]);
    if ((successor_he = gethostbyname(argv[4])) == NULL) {  // get the host info
        herror("gethostbyname");
        exit(1);
    }
    
    
    successor_their_addr.sin_family = AF_INET;
    successor_their_addr.sin_port = htons(successor_port);
    successor_their_addr.sin_addr = *((struct in_addr *)successor_he->h_addr);
    memset(successor_their_addr.sin_zero, '\0', sizeof successor_their_addr.sin_zero);
	successor_addrlen = sizeof(successor_their_addr);
	
	//set up local port

	int sockfd, status;
    struct sockaddr_in myaddr;  // local address information

    unsigned char buffer[INTERNAL_BUFFER_LENGTH]; // assume longest
    unsigned int key, value;
    char command[4];

	
	// alloc open request table
//	struct client_request *openClientRequests;
//	openClientRequests = (struct client_request *) malloc(sizeof(struct client_request) * 10); // max. ten parallel connections


    // ---------- UDP --------
    // setup UDP address
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
    myaddr.sin_port = htons(atoi(argv[2])); // UDP 

    // init udp sock
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
		printf("FATAL: UDP binding error\n");
    }
	
	
	if ((server_he = gethostbyname(argv[1])) == NULL) {  // get the host info
		herror("gethostbyname");
		exit(1);
	}
	server_addr.sin_addr = *((struct in_addr *)successor_he->h_addr);
	server_ip = server_addr.sin_addr.s_addr;
	server_port = atoi(argv[2]);
	
    
	printf("Post-poning finger-table setup...\n");
	// wait for nodes to load
	sleep(5);
	
	printf("Setup finger-tables:\n");
	// pack getAddress data
	strcpy(command, "xad");
	forceForwardQuery(command, 2, 0, server_ip,  server_port);
	
	printf("Complete.\n\n");

	// ------- CORE LOOP -----------
    while(1) {
		struct sockaddr_storage their_addr;
		socklen_t addr_size;
		
		printf("Waiting ...\n");
		addr_size = sizeof(their_addr);
		status = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&their_addr, &addr_size);
		printf("Recieved query.\n");

        if(status <= 0) {
            printf("Error: receiving");
        } else {
			if (isInternalCommunication(buffer)) {
				unsigned long responseAddress;
				unsigned int responsePort;
				
				unpackDataFromInternal(buffer, command, &key, &value, &responseAddress, &responsePort);
				printf("INTERNAL: [%s] %d:%d (origin: %lu:%d)\n", command, key, value, responseAddress, responsePort);
				
				if (isActiveQuery(command) && canHandleQueryLocally(key)) {
					printf("HANDLE...\n");
					handleQuery(command, key, value, responseAddress, responsePort);
				} else if(isAddressQuery(command)){
					handleAddressQuery(command, key, value, responseAddress, responsePort);
				} else {
					printf("PASS...\n");
					forwardQuery(command, key, value, responseAddress, responsePort);
				}				
			} else {
				unpackData(buffer, command, &key, &value);
				printf("CLIENT: [%s] %d:%d \n", command, key, value);
				
				int requestId = nextFreeRequestId(openClientRequests);
				
				struct client_request request;
				request.socket = *((struct sockaddr *)&their_addr);
				request.socket_addr_len = sizeof(their_addr);
				
				request.active = 1;
				request.key = key;
				
				struct sockaddr_in clientInAddress;
				clientInAddress = *((struct sockaddr_in *) &their_addr);
				request.clientAddress = clientInAddress.sin_addr.s_addr; 
				request.clientPort = clientInAddress.sin_port; //todo
				
				openClientRequests[requestId] = request;
				
				
				if (canHandleQueryLocally(key)) {
					printf("HANDLE...\n");
					handleQuery(command, key, value, request.clientAddress, request.clientPort);
				} else {
					printf("FORCE-FORWARD...\n");
					forceForwardQuery(command, key, value, request.clientAddress, request.clientPort);
					printf("Query entered cluster.\n");
				}
			}
		}
    }
    

    close(sockfd); 


    return 0;
}
Example #4
0
void process_receive(char* recvbuf, int socketNo) {

	P2P_h received_header;
	int iResult[TOTAL_POSSIBLE_NEIGHBOURS];
	char querybuf[64];
	memcpy(&received_header, recvbuf, HLEN);

	if (isGunutellaPackage(received_header)) {

		uint32_t ip = received_header.org_ip;
		struct in_addr ip_addr;
		ip_addr.s_addr = ip;

		char port[15];
		sprintf_s(port, "%u", ntohs(received_header.org_port));

		switch (received_header.msg_type) {

		case MSG_JOIN:
			if (htons(received_header.length) == JOINLEN) {
				printf("A join response was received from %s on port = %s.\n", inet_ntoa(ip_addr), port);
				if (processJoinResponseBody(recvbuf)) {
					if (shouldSendQuery) {

						query_key[sizeof(query_key) - 1] = '\0';
						sendQuery(socketNo, query_key);
						shouldSendQuery = false;
					}
				}
			}
			else {
				printf("A join request was received from %s on port = %s.\n", inet_ntoa(ip_addr), port);
				sendJoinResponse(ntohl(received_header.msg_id), socketNo);
			}
			strcpy(neighbourArray[activeNeighbours].rec_ip, inet_ntoa(ip_addr));
			strcpy(neighbourArray[activeNeighbours].rec_port, port);
			activeNeighbours = activeNeighbours + 1;
			for (int j = 0; j < activeNeighbours; j++) {
				printf("%s -- %s\n", neighbourArray[j].rec_ip, neighbourArray[j].rec_port);
			}
			//sendTypeBPingMessage();
			break;

		case MSG_QHIT:
			
			if (ntohl(received_header.msg_id == msg_id)) {
				printQueryResult(socketNo, recvbuf);
			}
			else {
				
				printf("Received query hit after having forwarded\n");
				forwardQueryHit(recvbuf, received_header);
			}
			break;

		case MSG_QUERY:
			printf("%s on port = %s asked for some data.\n", inet_ntoa(ip_addr), port);
			checkQueryHit(recvbuf, received_header, socketNo);
			if (received_header.ttl > 1) {
				forwardQuery(received_header, recvbuf);
				queries[recentQueryNo].msg_id = received_header.msg_id;
				queries[recentQueryNo].socketNo = socketNo;
				recentQueryNo++;
			}
			break;

		case MSG_PING:
			if (received_header.ttl == 1) {
				printf("PING TYPE A received from %s on port = %s\n", inet_ntoa(ip_addr), port);
				P2P_h pongA = getPongTypeAMessage(htonl(received_header.msg_id));
				send_PongAMessage(pongA, socketNo);
			}
			if (received_header.ttl > 1) {
				printf("PING TYPE B received from %s on port = %s\n", inet_ntoa(ip_addr), port);
				send_PongBMessage(received_header, socketNo);
			}
			break;

		case MSG_PONG:
			handlePongResponse(socketNo, received_header, recvbuf);
			break;
		default:
			printf("OTHER TYPE OF MESG:  \n");
			printf("Length: %u", received_header.length);
			printf("\n");
			printf("MessageType: %u", received_header.msg_type);
			printf("\n");
			printf("0x%02x, ", received_header.msg_type);
			printf("\n");
			printf("Message ID: %u", received_header.msg_id);
			printf("\n");
			printf("TTL: %u", received_header.ttl);
			printf("\n--------------------");
			break;
		}
	}
}