Ejemplo n.º 1
0
/* send an ack for the given message and message ID */
static void send_ack (int sock, struct allnet_header * hp,
                      unsigned char * message_ack,
                      int send_resend_request, char * contact, keyset kset)
{
  if ((hp->transport & ALLNET_TRANSPORT_ACK_REQ) == 0) {
printf ("packet not requesting an ack, no ack sent\n");
    return;
  }
  int size;
  struct allnet_header * ackp =
    create_ack (hp, message_ack, NULL, ADDRESS_BITS, &size);
  if (ackp == NULL)
    return;
  /* also save in the (very likely) event that we receive our own ack */
  currently_sent_ack = (currently_sent_ack + 1) % NUM_ACKS;
  memcpy (recently_sent_acks [currently_sent_ack], message_ack,
          MESSAGE_ID_SIZE);
#ifdef DEBUG_PRINT
  print_packet ((char *) ackp, size, "sending ack", 1);
#endif /* DEBUG_PRINT */
  send_pipe_message_free (sock, (char *) ackp, size, ALLNET_PRIORITY_LOCAL);
/* after sending the ack, see if we can get any outstanding
 * messages from the peer */
  if (send_resend_request)
    request_and_resend (sock, contact, kset);
}
Ejemplo n.º 2
0
/**
 * Repondre a une requete Initiate
 * @param sock Socket du joueur ayant envoye une demande de connexion
 * @param the_players Liste des joueurs
 * @param recv_frame Trame Initiate recue
 * @return Resultat de l'echange (cf. fonction respond pour plus d'informations)
 */
Result* respond_initiate(int sock, Players the_players, Frame frame) {
    /* Compteur persistant de joueurs connectes */
    static uint16_t nb_connected_players = 0;
    
    /* Resultat de l'echange */
    Result* result = NULL;
    
    /* Acquittement de la requete, negatif par defaut  */ 
    Frame ack_frame = create_ack(0);
    
    /* Verification de la requete du client */
    int format_check = ERROR;
    int constraint_check = ERROR;
    
    constraint_check = check_initiate_constraint(sock, nb_connected_players, the_players);
    format_check = check_initiate_format(frame);
    
    /* Traitement de la requete */
    if(constraint_check == SUCCESS && 
           format_check == SUCCESS) {
        
        /* Verification du nom d'application et de la version du protocole */
        if(check_appname(frame->data[0]->string.content) == SUCCESS &&
           check_version(frame->data[1]->string.content) == SUCCESS) {
            
            /* Creation du resultat de l'echange */
            result = malloc(sizeof(Result));
            result->type = Initiate;
            result->content = NULL;
            
            /* Connexion du nouveau joueur */
            the_players->player[nb_connected_players]->sock = sock;
            the_players->player[nb_connected_players]->is_connected = 1;
            
            nb_connected_players++;
            free_frame(ack_frame);
            ack_frame = create_ack(1);
        }
    }
    
    /* Envoi de l'acquittement */
    send_frame(sock, ack_frame);
    
    return result;
}
void process_frames(){
	if(queue_nitems(receiver) == 0){
		return;
	}
	size_t len = 0;
	FRAME *f = queue_peek(receiver, &len);
	int source_nodenumber = find_nodenumber(f->payload.source);
	if(node_buffer[source_nodenumber].busy){
		free(f);
		return;
	}
	node_buffer[source_nodenumber].busy = true;
	f = queue_remove(receiver, &len);
	//printf("Received frames for message #%d Expecting %d\n", f->payload.mesg_seq_no, node_buffer[source_nodenumber].mesg_seq_no_to_receive);	
	//If ack has not been received at the sender side and an old frame from an old message has been received
	if(f->payload.mesg_seq_no < node_buffer[source_nodenumber].mesg_seq_no_to_receive){
		//printf("Message received is old, dropped :-( Message #%d\n", f->payload.mesg_seq_no);
		node_buffer[source_nodenumber].busy = false;
		free(f);
		process_frames();
		return;
	}
	if(f->payload.mesg_seq_no > node_buffer[source_nodenumber].mesg_seq_no_to_receive){
		queue_add(receiver, f, len);
		//printf("Message received is new, pushed back ;-) Message #%d\n", f->payload.mesg_seq_no);
		node_buffer[source_nodenumber].busy = false;
		free(f);
                //process_frames();
                return;
	}
	int seq_no = f->payload.A;
	char seq_str[5];
	sprintf(seq_str, "%d", seq_no);
	if(seq_no == node_buffer[source_nodenumber].next_seq_number_to_add){
		//send ack here
		create_ack(f->payload);
		// add to the incomplete data object
		//printf("Frame appending %d with length %d | MSG #%d\n",seq_no, f->payload.len, f->payload.mesg_seq_no);
		memcpy(&node_buffer[source_nodenumber].incomplete_data[0] + node_buffer[source_nodenumber].bytes_added, &f->payload.data[0], f->payload.len);
		node_buffer[source_nodenumber].bytes_added += f->payload.len;
		node_buffer[source_nodenumber].next_seq_number_to_add++;
		while(true){
			int next_seq = node_buffer[source_nodenumber].next_seq_number_to_add;
			char next_seq_str[5];
			sprintf(next_seq_str, "%d", next_seq);
			size_t plen;
			PACKET *pkt = hashtable_find(node_buffer[source_nodenumber].ooo_packets, next_seq_str, &plen);
			if(plen == 0)
				break;
			//printf("In While loop:Next frame %d found in HT\n",next_seq);
			pkt = hashtable_remove(node_buffer[source_nodenumber].ooo_packets, next_seq_str, &plen);
			create_ack(*pkt);
			memcpy(&node_buffer[source_nodenumber].incomplete_data[0] + node_buffer[source_nodenumber].bytes_added, &pkt->data, pkt->len);
			node_buffer[source_nodenumber].bytes_added += pkt->len;
			node_buffer[source_nodenumber].next_seq_number_to_add++;
		}
		// check for the last packet
		if(f->payload.flag_offset == 1) {
			//printf("\t\t\t\t\t\tBytes in reconstructed message is %d and is sent by %d\n",node_buffer[source_nodenumber].bytes_added, source_nodenumber);
			CHECK(CNET_write_application((char*)&node_buffer[source_nodenumber].incomplete_data[0], &node_buffer[source_nodenumber].bytes_added));
			node_buffer[source_nodenumber].next_seq_number_to_add = 0;
			memset(node_buffer[source_nodenumber].incomplete_data, '\0', MAX_MESSAGE_SIZE);
			hashtable_free(node_buffer[source_nodenumber].ooo_packets);
			// Overriding default bucket size of 1023
			node_buffer[source_nodenumber].ooo_packets = hashtable_new(256);
			printf("\t\t\t\t\t\tSuccessfully Written to Application. Bytes in the reconstructed message #%d are %d sent by %d.\n", 
				f->payload.mesg_seq_no, node_buffer[source_nodenumber].bytes_added, source_nodenumber);
			node_buffer[source_nodenumber].bytes_added = 0; 		
			node_buffer[source_nodenumber].mesg_seq_no_to_receive++; //= f->payload.mesg_seq_no;
		}
	} else {
		size_t plen;
		hashtable_find(node_buffer[source_nodenumber].ooo_packets, seq_str, &plen);
		if(plen == 0){
			hashtable_add(node_buffer[source_nodenumber].ooo_packets, seq_str, &f->payload, len - sizeof(uint32_t));
		}
	}
	node_buffer[source_nodenumber].busy = false;
	process_frames();
	free(f);
}