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; }
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; } } }