Esempio n. 1
0
	void search::call_node_callback() {
		std::list<search::key_t> lk;
		std::list<contact_proto>::iterator itc;
		for (itc = short_list.begin(); itc != short_list.end(); ++itc)
			lk.push_back(itc->key());
		node_callback(lk);
	}
/*
*   handles node connection to the manager and message received
*/
void *node_to_manager_handler(void* pvnd_data){

    char buffer[MAX_BUFFER_SIZE];
    int numbytes; 
    
    node_data *nd_data = (node_data*)pvnd_data;
    node_info *node = nd_data->node;
    
	item_list *neighbours_list = nd_data->neighbours;
	item_list *neighbours_cost_list = nd_data->neighbours_cost;
    
    //First contact
    //send contact message and receive information back
    const char delimiters[] = "|";
    
    int num_chars = sprintf(buffer, "%s|req", MESSAGE_CONTACT);
    
    buffer[num_chars] = '\0';
    
    send_message(node->tcp_socketfd, buffer);
 
    while(1){
    
        bzero(buffer, MAX_BUFFER_SIZE);
        
        if ((numbytes = read(node->tcp_socketfd, buffer, sizeof(buffer))) < 0) {
			perror("read");
		    	exit(1);
		}
		
		if(numbytes == 0){
		    //printf("Manager socket closed - exiting.\n");
		    //cleanup(&nd_data);
 
		    break;
		}
		
		char *token, *running;
		running = strdup(buffer);
		
		token = strsep (&running, delimiters);
		
		if (strcmp(token, MESSAGE_TOPO_INFO) == 0){ //info about topo and neighbors
			
			//The message should look like the following
			//MESSAGE_TOPO_INFO|assigned_id|id1:cost1|id2:cost2|id3:cost3|...
			//extract our virtual id
			token = strsep (&running, delimiters);
			node->id = atoi(token);
			
			int port = atoi(NODE_PORT) + node->id; // e.j (7000 + 1) for first node
			int num_port_chars = sprintf(node->port, "%d", port);
			node->port[num_port_chars] = 0; 

			//now that we have the port, start a thread for UDP port communications
			pthread_t thread;
			pthread_create(&thread, NULL, (void*)initialize_udp_listening, (void*)nd_data);
			
			//extract neighbours from the rest of the data
			item_list *nbs = extract_neighbors_info(running);
			
			if (nbs){	
				item_link *p = nbs->head;
				
				while(p){
					neighbour *nb = (neighbour*)p->data;	
					
					add_to_list(neighbours_cost_list, nb);
								
					printf("now linked to node %d with cost %d\n", nb->id, nb->cost);
					p = p->next;
				}
			}
			
			bzero(buffer, MAX_BUFFER_SIZE);
			int numnext = sprintf(buffer,"%s|%s", MESSAGE_ACK, MESSAGE_SEND_INFO );
			buffer[numnext] = '\0';
			
			send_message(node->tcp_socketfd, buffer);
			
		}
		else if (strcmp(token, MESSAGE_NODE_INFO) == 0){ //node info message
			
			
			node_info *nb = extract_node_information(running);
			
			if (!update_neighbours_list(neighbours_list, nb)){
			    free(nb);
			}
			
			if (neighbours_list->count == neighbours_cost_list->count){
				 bzero(buffer, MAX_BUFFER_SIZE);
				 int numnext = sprintf(buffer,"%s|%s", MESSAGE_ACK, MESSAGE_INFO_RECEIVED );
				 buffer[numnext] = '\0';
				
				 send_message(node->tcp_socketfd, buffer);
			}
		}
		else if (strcmp(token, MESSAGE_DATA) == 0){
		    
		    //send ack
		    bzero(buffer, MAX_BUFFER_SIZE);
			int numnext = sprintf(buffer,"%s|ok", MESSAGE_ACK);
			buffer[numnext] = '\0';
			send_message(node->tcp_socketfd, buffer);
			
		    message_router = nd_data->route_message_handler;
		    message_router(running, 0);
		}
		else if (strcmp(token, MESSAGE_START_CONVERGENCE) == 0){

		    node_callback = nd_data->protocol_handler;
		    node_callback();
		}
		else if (strcmp(token, MESSAGE_TOPO_UPDATE) == 0){

			neighbour *nb = extract_neighbor(running);
			
			if (nb->cost >= 0){
			    
			    int exists = update_neighbours_cost(nd_data->neighbours_cost, nb->id, nb->cost);
			    
			    printf("now linked to node %d with cost %d\n", nb->id, nb->cost);
			    
			    if (exists == 0){
			        //request node info for the neighbour we don't have
			        bzero(buffer, MAX_BUFFER_SIZE);
			        int req_numchars = sprintf(buffer,"%s|%d", MESSAGE_REQUEST_NODE_INFO, nb->id);
			        buffer[req_numchars] = '\0';
			        send_message(node->tcp_socketfd, buffer);
			        
			        sleep(1);
			    }
			}
			else
			{
		        //remove link
		        remove_from_neighbours_cost(nd_data->neighbours_cost, nb->id);
		        remove_from_neighbours(nd_data->neighbours, nb->id);
			    printf("no longer linked to node %d\n", nb->id);
			}
			
			bzero(buffer, MAX_BUFFER_SIZE);
			int numnext = sprintf(buffer,"%s|%s", MESSAGE_ACK, MESSAGE_TOPO_UPDATED );
			buffer[numnext] = '\0';
			
			send_message(node->tcp_socketfd, buffer);
		}
		else if (strcmp(token, MESSAGE_FLUSH_TOPO) == 0){
			
		    topology_change_callback = nd_data->topology_change_handler;
		    
		    if (topology_change_callback)
			    topology_change_callback();
			
			//send ack
			bzero(buffer, MAX_BUFFER_SIZE);
			int numnext = sprintf(buffer,"%s|%s", MESSAGE_ACK, MESSAGE_TOPO_FLUSHED );
			buffer[numnext] = '\0';
			
			send_message(node->tcp_socketfd, buffer);
		}
    }
    
    pthread_exit(NULL);
}