Exemplo n.º 1
0
/**
 * receive the packet, save it into buffer
 * send corresponding ack back
 * @param dl, the handler
 * @param pkt, the received packet
 * @return 0 on success, -1 if fails
 */
int dl_recv(download_t *dl, packet_t *pkt) {
    uint32_t seq;
    size_t offset;

    if (dl->finished) {
        return 0;
    }

    /* do not update rtt until start */
    if (dl->started && !dl->block_update) {
        update_rtt(&dl->rtt, &dl->dev, dl->ts);
    } else { /* record data_len for the first time */
        dl->data_length = GET_DATA_LEN(pkt);
        dl->started = 1;
        dl->block_update = 0;
    }

    seq = GET_SEQ(pkt);
    offset = (seq - 1) * dl->data_length ;
    // discard data packet with seq number not sitting in current receive window
    //   or size exceeds the buffer length.
    if( ! seq_fit_in(&dl->rwin, seq) || offset + GET_DATA_LEN(pkt) > BT_CHUNK_SIZE){
        return -1;
    }

    if(! seq_exist_in(&dl->rwin, seq)){
        memcpy(dl->buffer + offset, GET_DATA(pkt), GET_DATA_LEN(pkt));
        recvwin_mark(&dl->rwin, seq);
    }

    send_ack(dl->p_index, get_ack(dl));

    dl->ts = get_timestamp_now();
    dl->timeout_cnt = 0;

    if ( (dl->next_pkt_expected -1)* dl->data_length >= BT_CHUNK_SIZE) {
        dl->finished = 1;
    }

    return 0;
}
Exemplo n.º 2
0
int process_pong(Header *header, ChordPacketArgs *args, Pong *msg, Node *from)
{
	ChordServer *srv = args->srv;
	Finger *f, *pred, *newpred;
	ulong	 new_rtt;
	int		 fnew;

	if (IN6_IS_ADDR_UNSPECIFIED(&srv->node.addr))
		return CHORD_ADDR_UNDISCOVERED;

	if (!verify_ticket(srv->ticket_salt, srv->ticket_salt_len,
					   srv->ticket_hash_len, msg->ticket.data, msg->ticket.len,
					   "c6sl", CHORD_PING, &from->addr, from->port, msg->time))
		return CHORD_INVALID_TICKET;

	f = insert_finger(srv, &from->id, &from->addr, from->port, &fnew);
	if (!f)
		return CHORD_FINGER_ERROR;

	LOG_PROCESS(&from->id, &from->addr, from->port);

	f->npings = 0;
	new_rtt = get_current_time() - msg->time; /* takes care of overlow */
	update_rtt(&f->rtt_avg, &f->rtt_dev, (long)new_rtt);

	pred = pred_finger(srv);
	activate_finger(srv, f); /* there is a two-way connectivity to this node */
	newpred = pred_finger(srv); /* check whether pred has changed, i.e.,
								 * f has became the new pred
								 */
	assert(newpred || (pred == newpred));

	if (pred != newpred)
		chord_update_range(srv, &newpred->node.id, &srv->node.id);

	return CHORD_NO_ERROR;
}
Exemplo n.º 3
0
Arquivo: hw6.c Projeto: lfcmpi/UIC
void wait_for_ack(int sock) {

	// repeatedly send it until we get an ack
	while(1) {
		fd_set readset;
		FD_ZERO(&readset);
		FD_SET(sock,&readset); 

		struct timeval t;
		if(window[0].sent_at + timeout > current_msec()) {			
			unsigned msec_until_expiry = window[0].sent_at + timeout - current_msec(); 
			msec_to_timeval(msec_until_expiry,&t);
		}
		else {
			msec_to_timeval(10,&t);
		}

		/*		// always allow a 1 msec wait
		if(msec_until_expiry<0) {
			t.tv_sec = 0;
			t.tv_usec = 100;
			//			memset(&t,0,sizeof(t));
			}*/

		int rdy = select(FD_SETSIZE,&readset,0,0,&t);

		char incoming[1400];
		struct hw6_hdr *hdr = (struct hw6_hdr*)incoming;
		if(rdy>0) {
			struct sockaddr_in from_addr;
			unsigned int addrsize = sizeof(from_addr);
			int recv_count=recvfrom(sock,incoming,1400,0,(struct sockaddr*)&from_addr,&addrsize);
			if(recv_count<0) {
				perror("When receiving packet.");
				return;
			}
		}

		// if we timed out, or got a double acknowledgment, double the timeout value and send again
		if(rdy==0 || 
			 // double acknowledgment only triggers retransmission once per round-trip time
			 (ntohl(hdr->ack_number)==ntohl(window[0].data->sequence_number)-1 && 
				((current_msec() - window[0].sent_at) > rtt))) { //last_ack_number) {
			if(rdy==0)
				fprintf(stderr,"\nTimed out on packet %d, msec %u\n",ntohl(window[0].data->sequence_number),timeval_to_msec(&t));//,msec_until_expiry);
			else
				fprintf(stderr,"\nDouble ack indicating loss of packet %d, msec %u\n",ntohl(window[0].data->sequence_number),timeval_to_msec(&t));//,msec_until_expiry);

			fprintf(stderr,"Window packets: ");
			for(int p=0;p<packets_outstanding;p++) {
				fprintf(stderr,"%d, ",ntohl(window[p].data->sequence_number));				
			}
			fprintf(stderr,"\n");

			timeout *= 2;
			if(timeout > MAX_TIMEOUT) 
				timeout = MAX_TIMEOUT;

			window_size /=2;
			if(window_size < 1) 
				window_size=1;
			
			ssthresh = window_size;
			congestion_avoidance = 1;
			ca_last_increase = current_msec();

			for(int i=0;i<packets_outstanding && i<window_size;i++)  {
				fprintf(stderr,"Resending Packet %d with rtt %f dev %f timeout %d ms window %d  to %s         \n",ntohl(window[i].data->sequence_number),rtt, deviation,timeout,window_size,inet_ntoa(peeraddr.sin_addr));
				if(sendto(sock, window[i].data, window[i].len, 0,(struct sockaddr*)&peeraddr,sizeof(peeraddr)) <=0)
						perror("Couldn't send!");
				window[i].retx = 1;
				window[i].sent_at = current_msec(); // update the timestamp
			}
			fprintf(stderr,"Done resending, for now\n");

		}
		else if(rdy==-1) {
			perror("select error");
		}
		else {
			
			/* blow away all the packets acked here */
			// fprintf(stderr,"Got ack for %d, time left %d, rtt %d, retx %d\n",ntohl(hdr->ack_number), timeval_to_msec(&t), current_msec() - window[0].sent_at, window[0].retx);
			int got_ack=0;
			last_ack_number = ntohl(hdr->ack_number);
			while(packets_outstanding > 0 && ntohl(hdr->ack_number) >= ntohl(window[0].data->sequence_number)) {
				if(!window[0].retx)
					update_rtt(current_msec() - window[0].sent_at);
				pop_packet(sock);

				got_ack=1;
			}

			if(got_ack) break;
			
			if(! (hdr->flags & ACK)) {
				// ack whatever we have so far
				struct hw6_hdr ack;
				ack.flags = ACK;
				if(ntohl(hdr->sequence_number) == expected_sequence_number) {
					expected_sequence_number++;
				}
				else {
					fprintf(stderr,"Unexpected non-ACK in rel_send(). Acking what we have so far. \n");
				}
				ack.ack_number = htonl(expected_sequence_number-1);
				sendto(sock, &ack, sizeof(ack), 0,(struct sockaddr*)&peeraddr,sizeof(peeraddr));
			}		 
		}
	}

}
Exemplo n.º 4
0
static void cpg_bm_deliver_fn (
	cpg_handle_t handle_in,
	const struct cpg_name *group_name,
	uint32_t nodeid,
	uint32_t pid,
	void *msg,
	size_t msg_len)
{
	uLong crc=0;
	struct cpghum_header *header = (struct cpghum_header *)msg;
	uLong recv_crc = header->crc & 0xFFFFFFFF;
	unsigned int *dataint = (unsigned int *)((char*)msg + sizeof(struct cpghum_header));
	unsigned int datalen;

	if (nodeid > MAX_NODEID) {
		cpgh_log_printf(CPGH_LOG_ERR, "Got message from invalid nodeid %d (too high for us). Quitting\n", nodeid);
		exit(1);
	}

	packets_recvd++;
	packets_recvd1++;
	g_recv_length = msg_len;
	datalen = header->size - sizeof(struct cpghum_header);

	// Report RTT first in case abort_on_error is set
	if (nodeid == g_our_nodeid) {
		unsigned long rtt_usecs;

		// For flood
		update_rtt(&header->timestamp, packets_recvd1, &interim_min_rtt, &interim_avg_rtt, &interim_max_rtt);

		rtt_usecs = update_rtt(&header->timestamp, g_recv_counter[nodeid], &min_rtt, &avg_rtt, &max_rtt);

		if (report_rtt) {
			if (machine_readable) {
				cpgh_log_printf(CPGH_LOG_RTT, "%ld%c%ld%c%ld%c%ld\n", rtt_usecs, delimiter, min_rtt, delimiter, avg_rtt, delimiter, max_rtt);
			}
			else {
				cpgh_log_printf(CPGH_LOG_RTT, "%s: RTT %ld uS (min/avg/max): %ld/%ld/%ld\n", group_name->value, rtt_usecs, min_rtt, avg_rtt, max_rtt);
			}
		}
	}

	// Basic check, packets should all be the right size
	if (msg_len != header->size) {
		length_errors++;
		cpgh_log_printf(CPGH_LOG_ERR, "%s: message sizes don't match. got %zu, expected %u from node %d\n", group_name->value, msg_len, header->size, nodeid);

		if (abort_on_error) {
			exit(2);
		}
	}
	g_recv_size[nodeid] = msg_len;

	// Sequence counters are incrementing in step?
	if (header->counter != g_recv_counter[nodeid]) {

		/* Don't report the first mismatch or a newly restarted sender, we're just catching up */
		if (g_recv_counter[nodeid] && header->counter) {
			sequence_errors++;
			cpgh_log_printf(CPGH_LOG_ERR, "%s: counters don't match. got %d, expected %d from node %d\n", group_name->value, header->counter, g_recv_counter[nodeid], nodeid);

			if (abort_on_error) {
				exit(2);
			}
		}
		else {
			g_recv_start[nodeid] = header->counter;
		}

		/* Catch up or we'll be printing errors for ever */
		g_recv_counter[nodeid] = header->counter+1;
	}
	else {
		g_recv_counter[nodeid]++;
	}

	/* Check crc */
	crc = crc32(0, NULL, 0);
	crc = crc32(crc, (Bytef *)dataint, datalen) & 0xFFFFFFFF;
	if (crc != recv_crc) {
		crc_errors++;
		cpgh_log_printf(CPGH_LOG_ERR, "%s: CRCs don't match. got %lx, expected %lx from nodeid %d\n", group_name->value, recv_crc, crc, nodeid);

		if (abort_on_error) {
			exit(2);
		}

	}

	g_recv_count++;

}
Exemplo n.º 5
0
void rel_send(int sock, void *buf, int len)
{
    if(user == UNKNOWN){
        user = SENDER;
    }
    int flag_ack_checked;
    int flag_packet_dropped;
 	// make the packet = header + buf
	char packet[1400];
	struct hw7_hdr *hdr = (struct hw7_hdr*)packet;
	flag_ack_checked = 0;
	flag_packet_dropped = 0;
	memset(hdr,0,sizeof(struct hw7_hdr));
	hdr->sequence_number = htonl(sequence_number);
	memcpy(hdr+1,buf,len);

	fprintf(stderr,"\r<SHUBHAM>Sent Packet - %d with rtt %d dev %d timeout - %d ms           \n",sequence_number,rtt, deviation,timeval_to_msec(&timeout));
	sendto(sock, packet, sizeof(struct hw7_hdr)+len, 0,(struct sockaddr*)&peeraddr,sizeof(peeraddr));

	// put packet in queue, flag = ack not rxed, seq_no
    struct senderQelements *s;
    s = calloc(sizeof(struct senderQelements),1);
    s->magic = 'S';
    s->ack_rxed = 0;
    s->retx = 0;
    s->packet_len = sizeof(struct hw7_hdr) + len;
    s->sent_time = current_msec();
    memcpy(s->packet, packet, s->packet_len);
    doQInsert((char *)s);

	// 1. If queue has no. of elements  == window size or if this is the close packet
    if(getCurrentQSize() == window_size || len == 0){
        int ack_count;
        ack_count = 0;
	//      wait for acks from all
        while(ack_count < window_size) {
            if(getCurrentQSize() == 0){ //double check...otherwise we might go in infinite loop //remove
                break;
            }

            fd_set readset;
            FD_ZERO(&readset);
            FD_SET(sock,&readset); 

            struct timeval t = timeout; // select changes the timeout parameter on some platforms, so make a copy

            int rdy = select(FD_SETSIZE,&readset,0,0,&t);

            if(rdy==0) {
                //send all unacked packets again
                send_all_unacked_packets_again(sock);
                flag_packet_dropped = 1;
                // if we timed out, send again double the timeout value
                msec_to_timeval(min(1000,2*timeval_to_msec(&timeout)), &timeout);
                /*
                fprintf(stderr,"\rSent Packet %d with rtt %d dev %d timeout %d ms           ",sequence_number,rtt, deviation,timeval_to_msec(&timeout));
                sendto(sock, packet, sizeof(struct hw7_hdr)+len, 0,(struct sockaddr*)&peeraddr,sizeof(peeraddr));
                //s->retx=1;
                fprintf(stderr,"\r<SHUBHAM>Retransmitting - Packet %d with rtt %d dev %d timeout %d ms           \n",sequence_number,rtt, deviation,timeval_to_msec(&timeout));
                */
            }
            else if(rdy==-1) {
                perror("select error");
            }
            else {
                char incoming[1400];
                struct sockaddr_in from_addr;
                unsigned int addrsize = sizeof(from_addr);
                int recv_count=recvfrom(sock,incoming,1400,0,(struct sockaddr*)&from_addr,&addrsize);
                if(recv_count<0) {
                    perror("When receiving packet.");
                    return;
                }

                struct hw7_hdr *hdr = (struct hw7_hdr*)incoming;
                if(ntohl(hdr->ack_number) >= start_seq_no && ntohl(hdr->ack_number) <= (start_seq_no + window_size - 1)) {
                    fprintf(stderr,"\r<SHUBHAM>Got ack for %d       \n",ntohl(hdr->ack_number));
                    fprintf(stderr,"<SHUBHAM> Ack rxed - %d , start_seq_no , redundant log\n", (ntohl(hdr->ack_number)) - start_seq_no, start_seq_no);
                    struct senderQelements *s;
                    s = getNthElement((ntohl(hdr->ack_number)) - start_seq_no);
                    fprintf(stderr,"<SHUBHAM> nth element in Q packet->seq_no = %d\n", ntohl(((struct hw7_hdr *)s->packet)->sequence_number));
                    if(s->ack_rxed){
                        fprintf(stderr,"<SHUBHAM> RE-Ack rxed - %d , doing nothing\n", (ntohl(hdr->ack_number)) - start_seq_no);
                    }
                    else{
                        ack_count++;
                        if(!s->retx){
                            // if this is an ack for our present packet, update the rtt and exit
                            update_rtt(current_msec() - s->sent_time);
                        }
                    }
                    s->ack_rxed = 1;
                    //break;
                }

                // if it's not an ack, it's the end of the stream. ACK it. 
                // Scenario: 1. Sender sends close, 2. rxer sends ack(it is lost), 3. rxer sends close, 4. sender recives close in rel_send()
                /*SHUBHAM: todo?? Handle the close part here?? */
                if(! (hdr->flags & ACK)) {
                    // ack whatever we have so far
                    struct hw7_hdr ack;
                    ack.flags = ACK;
                    if(ntohl(hdr->sequence_number) == expected_sequence_number) {
                        expected_sequence_number++;
                    }
                    else {
                        fprintf(stderr,"Unexpected non-ACK in rel_send(), size %d. Acking what we have so far. \n",recv_count);
                    }
                    ack.ack_number = htonl(expected_sequence_number-1);
                    fprintf(stderr,"\r<SHUBHAM>Exception: Sending ACK - %d  for a non-ack packet receivd        \n",ntohl(ack.ack_number));
                    sendto(sock, &ack, sizeof(ack), 0,(struct sockaddr*)&peeraddr,sizeof(peeraddr));
                }		 
            }
            flag_ack_checked = 1;
        }
    }
    /*
    else{
        //      return, so that user can send next packet.
        return;
    }
    */
    if(len == 0 && !flag_ack_checked){
        perror("Some problem");
        exit(2);
    }
    if(flag_ack_checked){
        while(getCurrentQSize() > 0){ //make_raghvan_change
            struct senderQelements *s;
            s = doQDelete();
            free(s);
        }
        start_seq_no = start_seq_no + window_size; //make_raghvan_change
	    if(start_seq_no != sequence_number+1){
	        exit(20); //assert_remove
        }
        if(flag_packet_dropped == 1){
            decrease_window_size();
        }
        else{
            increase_window_size();
        }
    }
	sequence_number++;
}