Esempio n. 1
0
/* send packets until window is maxed out */
void sendWindow(chunkEle* cep, int sock){

	// no acks yet, send single packet window
	if( cep->lastAcked == NULL ){
		void* packet = cep->packetList.headp->data;
		unsigned int bufSize = ((packetHead *)packet)->packLen;

		spiffy_sendto(sock, packet, bufSize, 0, (struct sockaddr *) &cep->fromThisPeer->cli_addr, sizeof(cep->fromThisPeer->cli_addr));
		//sendto(sock, packet, bufSize, 0, (struct sockaddr *) &cep->fromThisPeer->cli_addr, sizeof(cep->fromThisPeer->cli_addr));		
	
		cep->lastSent = cep->packetList.headp;
		return;
	}

	//while window isn't exhausted
	while( ( ((packetHead*)cep->lastSent->data)->seqNum - ((packetHead*)cep->lastAcked->data)->seqNum ) < cep->packetList.length - 1 ){
		cep->lastSent = cep->lastSent->prevp; 
		void* packet = cep->lastSent->data;
		unsigned int bufSize = ((packetHead *)packet)->packLen;

		spiffy_sendto(sock, packet, bufSize, 0, (struct sockaddr *) &cep->fromThisPeer->cli_addr, sizeof(cep->fromThisPeer->cli_addr));
		//sendto(sock, packet, bufSize, 0, (struct sockaddr *) &cep->fromThisPeer->cli_addr, sizeof(cep->fromThisPeer->cli_addr));
	}

	return;
}
Esempio n. 2
0
File: peer.c Progetto: SunnyQ/cmu
void sendback_response(int sock, char **haschunk_list, int size,
        struct sockaddr_in from)
{

    int num_chunks, head;
    packet *p;

    p = packet_factory(IHAVE);
    dprintf(STDOUT_FILENO, "Response payload has: \n");
    for (num_chunks = 0; num_chunks < size; num_chunks++)
    {
        head = 4 + num_chunks * BT_CHUNKS_SIZE;
        strncpy(p->payload + head, haschunk_list[num_chunks], BT_CHUNKS_SIZE);
        dprintf(STDOUT_FILENO, "%s\n", haschunk_list[num_chunks]);
    }

    p->packet_length = 20 + num_chunks * BT_CHUNKS_SIZE;
    p->payload[0] = num_chunks;
    p->payload[1] = '\0';
    p->payload[2] = '\0';
    p->payload[3] = '\0';

    spiffy_sendto(sock, p, p->packet_length, 0, (struct sockaddr *) &from,
            sizeof(from));
    free(p);
}
Esempio n. 3
0
File: peer.c Progetto: SunnyQ/cmu
void sendData(struct sockaddr_in from, bt_config_t *config)
{
    packet *p;
    FILE *fp;

    if ((fp = fopen("example/C.tar", "rb")) == NULL )
        return;

    p = packet_factory(DATA);
    p->packet_length = 16 + BT_FULL_DATASIZE;
    p->sequence_num = ++lastSent[nodeInMap];

    // look for the correct position to read the data to packet
    long int offset = BT_CHUNK_SIZE * BT_FULL_DATASIZE * jobs[nodeInMap]
            + BT_FULL_DATASIZE * (p->sequence_num - 1);
    fseek(fp, offset, SEEK_SET);
    fread(p->payload, 1, BT_FULL_DATASIZE, fp);
    fclose(fp);

    spiffy_sendto(config->sock, p, p->packet_length, 0,
            (struct sockaddr *) &from, sizeof(from));
    TTL[nodeInMap][p->sequence_num - 1] = 0;
    dprintf(STDOUT_FILENO, "sending data: %d\n", p->sequence_num);
    free(p);
}
// send one packet
void send_packet(struct packet packet, int socket, struct sockaddr* dst_addr){
  char buffer[MAX_PACKET_SIZE];
  memcpy(buffer, packet.header, 16);
  memcpy(buffer+16, packet.payload, MAX_PAYLOAD_SIZE);
  unsigned short packet_length = ntohs(*(unsigned short*)(packet.header+6));
  spiffy_sendto(socket, buffer, packet_length, 0, dst_addr, sizeof(*dst_addr));
}
Esempio n. 5
0
void process_get(char *chunkfile, char *outputfile) {
	parseChunkFile(chunkfile, &chunkList);
	printChunkList(chunkList);
	
	strcpy(outputFilePath,outputfile);

	if((outputFile = fopen(outputfile, "w")) == NULL){
		fprintf(stderr,"Error opening %s\n",outputfile);
		exit(1);
	}
	
	int i;
	int j;
	/* needed if too many chunks for one packet */
	for(i = 0; i < chunkList.length; i += MAXCHUNKS){
		void* whohasp = whohasCons(&chunkList, i);
		unsigned int bufSize = ((packetHead *)whohasp)->packLen;
		node* itr = peerList.headp;	
		for(j = 0; j < peerList.length; j++){
	      peerEle* thisPeer = (peerEle*)itr->data;
	 		if( thisPeer->id != myId ){
				printf("Send packet to peer %d @  %s:%d\n", thisPeer->id, inet_ntoa(thisPeer->cli_addr.sin_addr) ,ntohs(thisPeer->cli_addr.sin_port));
		  		spiffy_sendto(sock, whohasp, bufSize, 0, (struct sockaddr *) &thisPeer->cli_addr, sizeof(thisPeer->cli_addr));
				//sendto(sock, whohasp, bufSize, 0, (struct sockaddr *) &thisPeer->cli_addr, sizeof(thisPeer->cli_addr));
	  		}
			itr = itr->nextp;
		}
	}
	
  	printf("PROCESS GET SKELETON CODE CALLED.  Fill me in!  (%s, %s)\n", 
	chunkfile, outputfile);
}
Esempio n. 6
0
File: peer.c Progetto: SunnyQ/cmu
void broadcast_query(char **chunk_list, bt_config_t *config)
{
    packet *p;
    int num_chunks, head;
    bt_peer_t *node;

    p = (packet *) malloc(sizeof(packet));

    dprintf(STDOUT_FILENO, "Sending packet payload has:\n");
    p = packet_factory(WHOHAS);
    for (num_chunks = 0; num_chunks < BT_MAX_NUM_CHUNKS; num_chunks++)
    {
        if (chunk_list[num_chunks] == NULL )
            break;
        head = 4 + num_chunks * BT_CHUNKS_SIZE;
        strncpy(p->payload + head, chunk_list[num_chunks], BT_CHUNKS_SIZE);
        dprintf(STDOUT_FILENO, "%s\n", chunk_list[num_chunks]);
    }

    p->packet_length = 20 + num_chunks * BT_CHUNKS_SIZE;
    p->payload[0] = num_chunks;
    p->payload[1] = '\0';
    p->payload[2] = '\0';
    p->payload[3] = '\0';

    for (node = config->peers; node != NULL ; node = node->next)
        if (node->id != config->identity)
            spiffy_sendto(config->sock, p, p->packet_length, 0,
                    (struct sockaddr *) &node->addr, sizeof(node->addr));
}
Esempio n. 7
0
void flushQueue(int sock, queue *sendQueue)
{
  int i = 0;
  int retVal = -1;
  int count = sendQueue->size;
  int noLoss = 0;
  Packet *pkt = dequeue(sendQueue);
  if(pkt == NULL) {
    return;
  }
  peerList_t *list = peerInfo.peerList;
  while(count > 0) {
    if(pkt->dest != NULL) { // IHAVE
      retVal = spiffy_sendto(sock,
			     pkt->payload,
			     getPacketSize(pkt),
			     0,
			     (struct sockaddr *) (pkt->dest),
			     sizeof(*(pkt->dest)));
    } else { // WHOHAS  
      for(i = 0; i < peerInfo.numPeer; i++) {
	if(list[i].isMe == 0) {
	  retVal = spiffy_sendto(sock,
				 pkt->payload,
				 getPacketSize(pkt),
				 0,
				 (struct sockaddr *) & (list[i].addr),
				 sizeof(list[i].addr));
	  if(retVal == -1) {
	    enqueue(sendQueue, pkt);
	    noLoss = 1;
	  }
	}
      }
    }
    if(noLoss == 0) {
      fprintf(stderr,"spiffy_sendto() returned -1. This is broken!");
    } 
    freePacket(pkt);
    pkt = dequeue(sendQueue);
    count--;
  }
}
Esempio n. 8
0
File: peer.c Progetto: SunnyQ/cmu
void sendGetSW(int sock, struct sockaddr_in from)
{
    packet *p;

    // check if the target chunkHash has been transferred by other peers
    // allow concurrent download
    while (queue_contains(peers[nodeInMap]->chunkHash) == EXIT_FAILURE)
    {
        if (peers[nodeInMap]->next == NULL )
        {
            if (queue_empty() == EXIT_SUCCESS)
            {
                dprintf(STDOUT_FILENO, "JOB is done\n");
                numDataMisses[nodeInMap] = -1;
            }
            return;
        }

        linkNode *temp = peers[nodeInMap];
        peers[nodeInMap] = peers[nodeInMap]->next;
        free(temp);
    }

    if (peers[nodeInMap]->chunkHash == NULL )
    {
        dprintf(STDOUT_FILENO, "sending chunk equals zero\n");
        return;
    }

    p = packet_factory(GET);
    p->packet_length = 20 + BT_CHUNKS_SIZE;
    p->ack_num = 0;

    p->payload[0] = 1;
    p->payload[1] = '\0';
    p->payload[2] = '\0';
    p->payload[3] = '\0';

    strncpy(p->payload + 4, peers[nodeInMap]->chunkHash, BT_CHUNKS_SIZE);
    spiffy_sendto(sock, p, p->packet_length, 0, (struct sockaddr *) &from,
            sizeof(from));

    jobs[nodeInMap] = getChunkId(peers[nodeInMap]->chunkHash, chunkf);

    dprintf(STDOUT_FILENO, "Requesting chunk ID: %d from %d\n", jobs[nodeInMap],
            nodeInMap);

    nextExpected[nodeInMap] = 1;
    GETTTL[nodeInMap] = 0;
    free(p);

    // chunk is transferring, remove it from work queue so that
    // other peers won't transfer this again
    queue_remove(getChunkHash(jobs[nodeInMap], chunkf));
}
Esempio n. 9
0
void flushUpload(int sock)
{
  int i = 0;
  Packet *pkt;
  connUp *pool = uploadPool;
  for(i = 0; i < peerInfo.numPeer; i++) {
    int peerID = peerInfo.peerList[i].peerID;
    Packet *ack = peek(pool[peerID].ackWaitQueue);
    if(ack != NULL) {
      struct timeval curTime;
      gettimeofday(&curTime, NULL);
      long dt = diffTimeval(&curTime, &(ack->timestamp));
      if(dt > DATA_TIMEOUT_SEC) {
	pool[peerID].timeoutCount++;
	fprintf(stderr,"Timeout while waiting ACK %d\n", getPacketSeq(ack));
	if(pool[peerID].timeoutCount == 3) {
	  fprintf(stderr,"Receiver ID %d timed out 3 times. Closing connection!\n", peerID);
	  numConnUp--;
	  cleanUpConnUp(&(pool[peerID]));
	  continue;
	}
	fprintf(stderr,"Data timed out. Resizing window.\n");
	shrinkWindow(&(pool[peerID].sw.ctrl));
	mergeAtFront(pool[peerID].ackWaitQueue, pool[peerID].dataQueue);
      }
    }
    pkt = peek(pool[peerID].dataQueue);
    while(pkt != NULL &&
	  (getPacketSeq(pkt) <= pool[peerID].sw.lastPacketAvailable)) {
      peerList_t *p = &(peerInfo.peerList[i]);
      int retVal = spiffy_sendto(sock,
				 pkt->payload,
				 getPacketSize(pkt),
				 0,
				 (struct sockaddr *) & (p->addr),
				 sizeof(p->addr));
      setPacketTime(pkt);
      fprintf(stderr,"Sent data %d. last available %d\n", getPacketSeq(pkt), pool[peerID].sw.lastPacketAvailable);
      if(retVal == -1) { // If spiffy_sendto doesn't f*****g work (AND IT DOESN'T!)
	fprintf(stderr,"spiffy_sendto() returned -1.\n");
	enqueue(pool[peerID].dataQueue, dequeue(pool[peerID].dataQueue));
      } else {
	dequeue(pool[peerID].dataQueue);
	pool[peerID].sw.lastPacketSent = getPacketSeq(pkt);
	enqueue(pool[peerID].ackWaitQueue, pkt);
	pkt = peek(pool[peerID].dataQueue);
      }
    }
  }
}
Esempio n. 10
0
int send_packet(int peer, data_packet_t * packet){
    static char buf[BT_MAX_PKT_SIZE];

    memcpy(buf + sizeof(header_t), packet->data, packet->header.packet_len);
    packet->header.packet_len += sizeof(header_t);
    memcpy(buf, (const char *)&packet->header, sizeof(header_t));

    bt_peer_t * pinfo = bt_peer_info(&config, peer);
    if(pinfo == NULL)
        return -1;

    spiffy_sendto(config.sock_fd, buf, packet->header.packet_len, 0, (struct sockaddr *) &pinfo->addr, sizeof(pinfo->addr));
    return 0;
}
Esempio n. 11
0
/* description: send a packet using sendto */
void send_packet(int socket, char* data, size_t packet_len, int flag,
                 struct sockaddr *dest_addr, socklen_t addr_len) {
    
    /* simulate packet loss */
    if (((double)rand() / (double)RAND_MAX) < PACKET_LOSS_RATIO)
        return;

    int has_send = 0, ret;
    while (has_send < packet_len){
        ret = spiffy_sendto(socket, data + has_send, packet_len - has_send, 0,
                            dest_addr, addr_len);
        if (ret < 0) {
            perror("send packet error");
            exit(-1);
        } else
            has_send += ret;
    }
}
Esempio n. 12
0
File: peer.c Progetto: aglqcs/P2P_CC
/* Broadcast WHOHAS request to all node except myself */
void broadcast(data_packet_t *packet, bt_config_t *config){
    bt_peer_t *node;
    short my_id = config->identity;

    node = config->peers;
    while(node!=NULL){
        // Don't send request to itself
        if(node->id == my_id){
            node = node->next;
            continue;
        }   
        // Send request
        int p = spiffy_sendto(sock, packet, ntohs(packet->header.packet_len), 0, (struct sockaddr *) &node->addr, sizeof(struct sockaddr));
        // Iterate to next node
        if( p < 0 ){
         // printf("Can not broadcast\n");
        }
        node = node->next;
    }         
    //printf("Ending broadcast\n");
    return;
}
Esempio n. 13
0
void sendAfterLastAcked(chunkEle* cep){
	node* cur;

	if(cep->lastSent == NULL)
		return;

	//last acked is head if nothing acked yet
	if(cep->lastAcked == NULL)
		cur = cep->packetList.headp;
	else 
		cur = cep->lastAcked->prevp;

	do{
		void* packet = cur->data;
		unsigned int bufSize = ((packetHead *)packet)->packLen;
		//printf("***Timeout, retrans packet %d\n to peer %d***\n", ((packetHead* )packet)->seqNum, cep->fromThisPeer->id );
		spiffy_sendto(sock, packet, bufSize, 0, (struct sockaddr *) &cep->fromThisPeer->cli_addr, sizeof(cep->fromThisPeer->cli_addr));
		//sendto(sock, ihavep, bufSize, 0, (struct sockaddr *) &from, fromlen);
		cur = cur->prevp;
	}while(cur != cep->lastSent->prevp);

	return;
}
Esempio n. 14
0
File: peer.c Progetto: SunnyQ/cmu
void processData(packet *incomingPacket, bt_config_t *config, int sock,
        struct sockaddr_in from)
{
    FILE * outfile;
    packet *p;

    outfile = fopen(outf, "r+b");
    // look for the correct position to insert the packet data
    long int offset = BT_CHUNK_SIZE * BT_FULL_DATASIZE * jobs[nodeInMap]
            + BT_FULL_DATASIZE * (incomingPacket->sequence_num - 1);
    fseek(outfile, offset, SEEK_SET);
    fwrite(incomingPacket->payload, sizeof(char), BT_FULL_DATASIZE, outfile);
    fclose(outfile);

    p = packet_factory(ACK);
    p->packet_length = 16;
    p->ack_num = incomingPacket->sequence_num;
    spiffy_sendto(sock, p, p->packet_length, 0, (struct sockaddr *) &from,
            sizeof(from));
    dprintf(STDOUT_FILENO, "sending ACK num: %d back to %d\n", p->ack_num,
            nodeInMap);
    free(p);
}
Esempio n. 15
0
int send_packet(int peer_id, int type, int seq, int ack, char* body, int body_len) {
  DPRINTF(DEBUG_SOCKETS, "send packet to peer:%d type:%d seq:%d ack:%d body_len:%d\n",
          peer_id, type, seq, ack, body_len);

  struct io_peer *peer = NULL;
  HASH_FIND(hh_id, peers_id, &peer_id, sizeof(int), peer);
  if (peer == NULL) {
    fprintf(stderr, "Unknown peer id %d\n", peer_id);
    return -1;
  }

  char data[sizeof(struct packet_header) + body_len];
  struct packet_header *header = (struct packet_header *) data;
  header->magic = PACKET_MAGIC;
  header->version = PACKET_VERSION;
  header->header_len = sizeof(struct packet_header);
  header->total_len = (uint16_t) (header->header_len + body_len);
  header->type = (unsigned int) type;
  header->seq = (unsigned int) seq;
  header->ack = (unsigned int) ack;
  if (header->type == PACKET_ACK) {
    --header->ack;
  }
  packet_hton(header);

  if (body && body_len) {
    memcpy(data + sizeof(struct packet_header), body, (size_t) body_len);
  }

  int ret = spiffy_sendto(peer_sockfd, data, sizeof(data), MSG_NOSIGNAL, (const struct sockaddr *) &peer->addr, sizeof(struct sockaddr_in));
  if (ret == -1) {
    DEBUG_PERROR("Cannot send packet\n");
  }

  return ret;
}
Esempio n. 16
0
File: peer.c Progetto: aglqcs/P2P_CC
void peer_run(bt_config_t *config) {
  struct sockaddr_in myaddr;
  fd_set readfds;
  struct user_iobuf *userbuf;
  struct timeval tv;
  tv.tv_sec = 3;
  tv.tv_usec = 0;

  if ((userbuf = create_userbuf()) == NULL) {
    perror("peer_run could not allocate userbuf");
    exit(-1);
  }
  
  if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1) {
    perror("peer_run could not create socket");
    exit(-1);
  }
  
  bzero(&myaddr, sizeof(myaddr));
  myaddr.sin_family = AF_INET;
  myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  myaddr.sin_port = htons(config->myport);
  
  if (bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) {
    perror("peer_run could not bind socket");
    exit(-1);
  }
  
  spiffy_init(config->identity, (struct sockaddr *)&myaddr, sizeof(myaddr));
  
  while (1) {
    int nfds;
    FD_SET(STDIN_FILENO, &readfds);
    FD_SET(sock, &readfds);
    
    nfds = select(sock+1, &readfds, NULL, NULL, &tv);
    
    if (nfds > 0) {
      if (FD_ISSET(sock, &readfds)) {
	process_inbound_udp(sock);
      }
      
      if (FD_ISSET(STDIN_FILENO, &readfds)) {
	process_user_input(STDIN_FILENO, userbuf, handle_user_input,
			   "Currently unused");
      }
    }

    /* loop all the chunks to check if the node for this chunk fails */
    data_packet_list_t *potential_whohas = re_generateWhohas(config);
    if( NULL != potential_whohas){
      printf("=======================\n");
      printf("re_generateWhohas again\n");
      printf("=======================\n");

      potential_whohas = reverseList(potential_whohas);
      data_packet_list_t *p;
      for( p = potential_whohas; p != NULL; p = p->next){
        data_packet_t *who = p->packet;
        broadcast(who, config);
      }
    }

    /* loop all the data packet send and check if packet timeout*/
    packet_tracker_t *head;
    for( head = p_tracker ; head != NULL ;head = head->next ){
      if( -1 == timer_expired(head) ){
        /* retransmit*/
        data_packet_t *packet = head->packet;
        /* ignore dummy head */
        if( head->seq == -441) 
          continue; 
        
        printf("DEBUG timer out seq = %d \n", head->seq);
        packet->header.seq_num = htonl(head->seq);


        int p = spiffy_sendto(sock, packet,  ntohs(packet->header.packet_len), 0, (struct sockaddr *)head->from, sizeof(struct sockaddr));

        if( p < 0){
          printf("Timeout resend error = %d\n", p);
        }
        /* reduce the ssthresh */
        process_packet_loss( head->packet->header.ack_num );
        /* reset timer */
        head->send_time = time(NULL);
      }
    }
  }
}
Esempio n. 17
0
File: peer.c Progetto: SunnyQ/cmu
void process_inbound_udp(int sock, bt_config_t *config)
{
    struct sockaddr_in from;
    socklen_t fromlen;
    char **chunk_list;
    char **haschunk_list;
    packet incomingPacket;
    bt_peer_t *curPeer;
    packet *p;
    int i;
    rttRecord *tempRtt;

    fromlen = sizeof(from);
    spiffy_recvfrom(sock, &incomingPacket, sizeof(incomingPacket), 0,
            (struct sockaddr *) &from, &fromlen);

    // check the node where the packet comes from depending on ip and port
    for (curPeer = config->peers; curPeer != NULL ; curPeer = curPeer->next)
        if (strcmp(inet_ntoa(curPeer->addr.sin_addr), inet_ntoa(from.sin_addr))
                == 0 && ntohs(curPeer->addr.sin_port) == ntohs(from.sin_port))
            nodeInMap = curPeer->id;

    switch (incomingPacket.type)
    {
    case WHOHAS:
        // sender
        dprintf(STDOUT_FILENO, "WHOHAS received\n");
        chunk_list = retrieve_chunk_list(&incomingPacket);
        haschunk_list = has_chunks(config, &incomingPacket, chunk_list);
        if (haschunk_list[0] != NULL )
            sendback_response(sock, haschunk_list, incomingPacket.payload[0],
                    from);
        free_chunks(chunk_list, incomingPacket.payload[0]);
        free_chunks(haschunk_list, incomingPacket.payload[0]);
        break;
    case IHAVE:
        // requester
        dprintf(STDOUT_FILENO, "IHAVE received\n");
        chunk_list = retrieve_chunk_list(&incomingPacket);
        allocate_peer_chunks(chunk_list, incomingPacket.payload[0]);
        sendGetSW(sock, from);
        free_chunks(chunk_list, incomingPacket.payload[0]);
        break;
    case GET:
        // sender
        dprintf(STDOUT_FILENO, "GET received\n");
        chunk_list = retrieve_chunk_list(&incomingPacket);
        jobs[nodeInMap] = getChunkId(chunk_list[0], config->has_chunk_file);
        // send a window to requester
        //congestion control started
        windowSize[nodeInMap] = 1;
        congestionState[nodeInMap] = 0;
        ssthresh[nodeInMap] = 64;
        lastSent[nodeInMap] = 0;
        for (i = 0; i < windowSize[nodeInMap]; i++)
            sendData(from, config);
        recordWindowSize(config);
        free_chunks(chunk_list, incomingPacket.payload[0]);
        break;
    case DATA:
        // requester
        dprintf(STDOUT_FILENO, "DATA received %d from %d\n",
                incomingPacket.sequence_num, nodeInMap);
        GETTTL[nodeInMap] = -1;

        // if sequence_num < expected, ignore as they might be channel-queued packets
        // if sequence_num > expected, something is lost or in wrong order
        if (incomingPacket.sequence_num > nextExpected[nodeInMap]
                && numMismatches < 3)
        {
            p = packet_factory(ACK);
            p->packet_length = 16;
            p->ack_num = nextExpected[nodeInMap] - 1;
            spiffy_sendto(sock, p, p->packet_length, 0,
                    (struct sockaddr *) &from, sizeof(from));
            numMismatches++;
            numDataMisses[nodeInMap] = 0;
        }
        else if (incomingPacket.sequence_num == nextExpected[nodeInMap])
        {
            numDataMisses[nodeInMap] = 0;
            numMismatches = 0;
            processData(&incomingPacket, config, sock, from);
            nextExpected[nodeInMap] = incomingPacket.sequence_num + 1;
            if (incomingPacket.sequence_num == BT_CHUNK_SIZE
                    && peers[nodeInMap]->next != NULL )
            {
                dprintf(STDOUT_FILENO, "Got %s\n", peers[nodeInMap]->chunkHash);
                linkNode *temp = peers[nodeInMap]; //cp1
                peers[nodeInMap] = peers[nodeInMap]->next;
                free(temp);
                sendGetSW(sock, from);
            }
            else if (incomingPacket.sequence_num == BT_CHUNK_SIZE
                    && peers[nodeInMap]->next == NULL )
            {
                dprintf(STDOUT_FILENO, "JOB is done\n");
                numDataMisses[nodeInMap] = -1;
            }
        }
        break;
    case ACK:
        dprintf(STDOUT_FILENO, "ACK received %d\n", incomingPacket.ack_num);
        // sender
        if (lastACKed[nodeInMap] == incomingPacket.ack_num)
            dup_ack[nodeInMap]++;
        // similarly, smaller received ack can be channel queued, ignore
        else if (incomingPacket.ack_num != lastACKed[nodeInMap] + 1)
            return;
        // duplicate acked
        else
            dup_ack[nodeInMap] = 0;

        // clear DATA TTL
        TTL[nodeInMap][incomingPacket.ack_num - 1] = -1;

        // retransmit
        if (dup_ack[nodeInMap] == 3) //loss
        {
            dprintf(STDOUT_FILENO, "dup retransmitting\n");
            congestionControlRetransmit(config); //change windowSize
            lastSent[nodeInMap] = lastACKed[nodeInMap];
            sendData(from, config);
            dup_ack[nodeInMap] = 0;
        }
        else //normal
        {
            congestionControlNormal(&incomingPacket, config);
            lastACKed[nodeInMap] = incomingPacket.ack_num;
            // ok... task finished
            if (incomingPacket.ack_num == BT_CHUNK_SIZE)
            {
                jobs[nodeInMap] = -1;
                lastACKed[nodeInMap] = 0;
                lastSent[nodeInMap] = 0;
                windowSize[nodeInMap] = 0;
                congestionState[nodeInMap] = -1;
                ssthresh[nodeInMap] = 64;
                resetCCRTT();
                dprintf(STDOUT_FILENO, "JOB is done\n");
                numDataMisses[nodeInMap] = -1;
            }
            else
            {
                for (i = lastSent[nodeInMap];
                        i < lastACKed[nodeInMap] + windowSize[nodeInMap]
                                && i < BT_CHUNK_SIZE; i++)
                    sendData(from, config);
                if (congestionState[nodeInMap] == CA) //test the RTT timer
                {
                    if (headRTT != NULL )
                    {
                        for (tempRtt = headRTT; tempRtt->next != NULL ;
                                tempRtt = tempRtt->next)
                            ;
                        tempRtt->next = (rttRecord *) malloc(sizeof(rttRecord));
                        tempRtt->next->seq = lastSent[nodeInMap];
                        tempRtt->next->next = NULL;
                    }
                    else
                    {
                        headRTT = (rttRecord *) malloc(sizeof(rttRecord));
                        headRTT->seq = lastSent[nodeInMap];
                        headRTT->next = NULL;
                    }
                }
            }
        }
        break;
    case DENIED:
        dprintf(STDOUT_FILENO, "DENIED received\n");
        break;
    default:
        perror("Unknown Command: Ignored...\n");
        break;
    }
}
Esempio n. 18
0
void flushDownload(int sock)
{
  int i = 0;
  int idx;
  uint8_t *hash;
  Packet *pkt;
  connDown *pool = downloadPool;
  for(i = 0; i < peerInfo.numPeer; i++) {
    int peerID = peerInfo.peerList[i].peerID;
    Packet *ack = peek(pool[peerID].ackSendQueue);

    while(ack != NULL) {
      peerList_t *p = &(peerInfo.peerList[i]);
      fprintf(stderr,"Sending ACK %d\n", getPacketAck(ack));
      int retVal = spiffy_sendto(sock,
				 ack->payload,
				 getPacketSize(ack),
				 0,
				 (struct sockaddr *) & (p->addr),
				 sizeof(p->addr));
      fprintf(stderr,"Sent ACK %d\n", getPacketAck(ack));
      if(retVal == -1) { // spiffy_sendto() does not work!!
	fprintf(stderr,"spiffy_sendto() returned -1.\n");
	enqueue(pool[peerID].ackSendQueue, dequeue(pool[peerID].ackSendQueue));
      } else {
	dequeue(pool[peerID].ackSendQueue);
	freePacket(ack);
	ack = dequeue(pool[peerID].ackSendQueue);
      }
    }

    switch(pool[peerID].state) {
    case 0: // Ready
      pkt = dequeue(pool[peerID].getQueue);
      while(pkt != NULL) {
	hash = getPacketHash(pkt, 0);
	printHash(hash);
	idx = searchHash(hash, &getChunk, 0);
	if(idx == -1) { // Someone else is sending or has sent this chunk
	  freePacket(pkt);
	  pkt = dequeue(pool[peerID].getQueue);
	} else if(numConnDown < maxConn){
	  getChunk.list[idx].fetchState = 2;
	  if(downloadPool[peerID].connected == 1)
	    fprintf(stderr,"NOT SUPPOSED TO BE CONNECTEED! \n\n\n\n\n\n");
	  downloadPool[peerID].connected = 1;
	  numConnDown++;
	  break;
	} else { // Cannot allow more download connections
	  fprintf(stderr,"->No more download connection allowed!\n");
	  pool[peerID].state = 2;
	  break;
	}
      }
      if(pool[peerID].state == 2)
	break;
      
      if(pkt != NULL) {
	fprintf(stderr,"Sending a GET\n");
	peerList_t *p = &(peerInfo.peerList[i]);
	hash = pkt->payload + 16;
	char buf[50];
	bzero(buf, 50);
	binary2hex(hash, 20, buf);
	fprintf(stderr,"GET hash:%s\n", buf);
	pool[peerID].curChunkID = searchHash(hash, &getChunk, -1);
	
	int retVal = spiffy_sendto(sock,
				   pkt->payload,
				   getPacketSize(pkt),
				   0,
				   (struct sockaddr *) & (p->addr),
				   sizeof(p->addr));

	if(retVal == -1) { // Spiffy is broken!
	  fprintf(stderr,"spiffy_snetto() returned -1.\n");
	  newPacketWHOHAS(nonCongestQueue);
	  freePacket(pkt);
	  cleanUpConnDown(&(pool[peerID]));
	  numConnDown--;
	  return;
	}

	setPacketTime(pkt);

	enqueue(pool[peerID].timeoutQueue, pkt);
	pool[peerID].state = 1;
      }
      break;
    case 1: { // Downloading
      pkt = peek(pool[peerID].timeoutQueue);
      struct timeval curTime;
      gettimeofday(&curTime, NULL);
      long dt = diffTimeval(&curTime, &(pkt->timestamp));
      if(dt > GET_TIMEOUT_SEC) {
	pool[peerID].timeoutCount++;
	fprintf(stderr,"GET request timed out %d times!\n", pool[peerID].timeoutCount);
	setPacketTime(pkt);
	if(pool[peerID].timeoutCount == 3) {
	  getChunk.list[pool[peerID].curChunkID].fetchState = 0;
	  pool[peerID].state = 0;
	  newPacketWHOHAS(nonCongestQueue);
	  freePacket(pkt);
	  cleanUpConnDown(&(pool[peerID]));
	  numConnDown--;
	}
      }
      break;
    }
    case 2: {
      break;
    }
    default:
      break;
    }

  }
}
Esempio n. 19
0
File: peer.c Progetto: aglqcs/P2P_CC
void process_inbound_udp(int sock) {
  printf("\n"); // DEBUG
  #define BUFLEN 1500
  struct sockaddr_in from;
  socklen_t fromlen;
  char buf[BUFLEN];

  fromlen = sizeof(from);
  spiffy_recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &from, &fromlen);

 /* printf("PROCESS_INBOUND_UDP SKELETON -- replace!\n"
	 "Incoming message from %s:%d\n%s\n\n", 
	 inet_ntoa(from.sin_addr),
	 ntohs(from.sin_port),
	 buf);
*/
  /* first generate the incoming packet */
  data_packet_t *recv_packet = build_packet_from_buf(buf);
  //recv_packet->header.ack_num = ntohl(recv_packet->header.ack_num);
  //recv_packet->header.seq_num = ntohl(recv_packet->header.seq_num);
  
  /* next parse this packet and build the response packet*/
  bt_peer_t *node;
  short target_id = -1;
  node = config.peers;
  while(node!=NULL){
    if( from.sin_family == node->addr.sin_family
        &&  from.sin_port == node->addr.sin_port
        &&  from.sin_addr.s_addr == node->addr.sin_addr.s_addr) {
        target_id = node->id;
      break;
    }  
    node = node->next;
  }      
  if( target_id == -1){
    printf("Can not locate id %d, %d, %d\n",from.sin_family, from.sin_port, from.sin_addr.s_addr );
    return;
  }
  data_packet_list_t *response_list = handle_packet(recv_packet, &config, (int)target_id, p_tracker);
  
  /* NEW: add parameter socket address from the one who send the packet */
  //data_packet_list_t *response_list = handle_packet(packet, &config, sock, p_tracker);

  /* finally call spiffy_sendto() to send back the packet*/
  if( NULL == response_list ){
    /* can not generate a response or no data avaiable */
    return;
  }
  else{
    data_packet_list_t *head;
    response_list = reverseList(response_list);
    for( head = response_list; head != NULL; head = head->next ){
      data_packet_t *packet = head->packet;
      

      if( packet->header.packet_type == 3 ){
        printf("DEBUG : SEND DATA SEQ = %d\n", packet->header.seq_num);
      }
       if( packet->header.packet_type == 4 ){
        printf("DEBUG : SEND ACK ACK = %d\n", packet->header.ack_num);
      }
     
      /* check timer if already send and within timeout , then dont send */
      packet_tracker_t *head;
      int find = 0;
      for( head = p_tracker ; head != NULL ;head = head->next ){
        if( head->packet->header.seq_num == packet->header.seq_num && head->packet->header.ack_num == packet->header.ack_num){
          if( -1 == timer_expired(head) ){
            find = 1;
          }
        }
      }
      if( find == 0){
        if( packet->header.packet_type == 3){
          p_tracker = create_timer(p_tracker, packet, (int)target_id, &from);
        }

        packet_tracker_t * p = p_tracker;
        while( p != NULL){
          printf("(%d,%d) - ",p->seq, p->sock);
          p = p->next;
        }
        printf("\n");
        int r = rand();
        if( r % 20 < -5 &&( packet->header.packet_type == 3 || packet->header.packet_type == 4)){
        /* use a random number to simulate the packet loss , currently it is 100% deliver */ 
           printf("RANDOM DISCARD THIS PACKET\n");
           continue;
        }
        else{
          packet->header.ack_num = ntohl(packet->header.ack_num);
          packet->header.seq_num = ntohl(packet->header.seq_num);
          int ret = spiffy_sendto(sock, packet,  ntohs(packet->header.packet_len), 0, (struct sockaddr *) &from, sizeof(struct sockaddr));
          if( ret <= 0 )  printf("Inbound_udp send to sock %d ret = %d", sock, ret);  
        }
          
      }
      else if( find == 1){
          if( packet->header.packet_type != 3){
            int ret = spiffy_sendto(sock, packet,  ntohs(packet->header.packet_len), 0, (struct sockaddr *) &from, sizeof(struct sockaddr));
            if( ret <= 0 )  printf("Inbound_udp send to sock %d ret = %d", sock, ret);  
          }
          printf("Not timeout dont send this packet or not find");
      }
    }
  }
}
Esempio n. 20
0
void process_inbound_udp(int sock) {
  #define BUFLEN 1500
  struct sockaddr_in from;
  socklen_t fromlen;
  char buf[BUFLEN];

  fromlen = sizeof(from);
  spiffy_recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &from, &fromlen);
	//recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &from, &fromlen);
  packetHead* pHead = (packetHead* )buf;
  peerEle* peer = resolvePeer(from, peerList);

  
  switch(pHead->type){
	case WHOHAS:{
		printf("Recieve WHOHAS request\n");
		void* ihavep = ihaveCons(buf, &haschunkList);
		if( ihavep!= NULL){
			unsigned int bufSize = ((packetHead *)ihavep)->packLen;
			spiffy_sendto(sock, ihavep, bufSize, 0, (struct sockaddr *) &from, fromlen);
			//sendto(sock, ihavep, bufSize, 0, (struct sockaddr *) &from, fromlen);
			time(&start);
		}
		break;
	}
	case IHAVE:{
		printf("Receieve IHAVE request\n");
		printf("packet length is %u\n", pHead->packLen);
		char tmp[sizeofHash];
		memcpy(tmp, (buf+20), sizeofHash);
		printf("chunk hash: %s\n", tmp);
		peerEle* thisPeer = resolvePeer(from, peerList);
		time_t finish;
		time(&finish);
		if( thisPeer == NULL ){
			printf("RESOLVE FAILED\n");
		}
		thisPeer->rtt = difftime(finish, start);
		AddResponses(thisPeer, buf, &chunkList, sock);
		printChunkList(chunkList);
		break;
	}
	case GET:{
		printf("Receive GET Request\n");
		printf("packet length is %u\n", pHead->packLen);
		
		//check for free connections
		printf("maxcon:%d id: %d numout: %d\n",maxCon,mePeer->id,mePeer->numOut);
		if(mePeer->numOut == maxCon){
			chunkEle* dcp = lookupChunkHash((buf+20),&haschunkList);
			void* deniedp = deniedCons(dcp->chunkId);
			spiffy_sendto(sock, deniedp, headerSize, 0, (struct sockaddr *) &peer->cli_addr, sizeof(peer->cli_addr));
			//sendto(sock, deniedp, headerSize, 0, (struct sockaddr *) &peer->cli_addr, sizeof(peer->cli_addr));
			break;
		}
		

		chunkEle* thisWindow = buildNewWindow(&windowSets, &haschunkList, peer, masterDataFilePath, buf);

		// send first element, no need to clean or fill
		sendWindow(thisWindow, sock);
		mePeer->numOut++;//increase num
		break;
	}
	case DATA:{
		unsigned int bufSize = ((packetHead *)buf)->packLen;
		void* newBuf = malloc(bufSize);
		memcpy(newBuf,buf,bufSize);
		chunkEle* cep = resolveChunk(peer, chunkList);
		
		getRetryTimer = 0;

		// reject packets from finished chunk
		if(cep && (cep->chunkId != ((packetHead*)buf)->ackNum)){
			printf("Wrong chunk!\n");
			break;
		}

		orderedAdd(cep,newBuf);

		printf("Receive data packet %d, with size %d \n", ((packetHead *)buf)->seqNum, ((packetHead *)buf)->packLen - headerSize);

		findMex(cep);
		printPacketList(cep->packetList);
		void* packet = ackCons(cep->nextExpectedSeq - 1);

		printf("Send Ack %d\n", cep->nextExpectedSeq - 1);
		spiffy_sendto(sock, packet, headerSize, 0, (struct sockaddr *) &peer->cli_addr, sizeof(peer->cli_addr));
		//sendto(sock, packet, headerSize, 0, (struct sockaddr *) &peer->cli_addr, sizeof(peer->cli_addr));
		printf("bytes read for hash %s : %d\n",cep->chunkHash, cep->bytesRead);
		//check if finish receiving the whole chunk
		if(cep->bytesRead == chunkSize ){
			if ( cep->fromThisPeer->inUse == 1){
			printf("Sucessfully receive the chunk %s\n", cep->chunkHash);
			chunkList.finished ++;
			cep->fromThisPeer->inUse = 0;
			cep->inProgress = 0;
			mePeer->numOut--;
			}
			printf("FINISHED %d\n", chunkList.finished);
			if(chunkList.finished == chunkList.length){
				printf("Finish receiving the whole file\n");
				// merge the chunks and write to the corresponding output file
				buildOuputFile(outputFile, &chunkList);
				fclose(outputFile);
				printf("GOT %s\n",outputFilePath);
			}else{
				// try to send rest of pending get requests 
				// they are deferred to make sure no concurrent downloading from the same peer
				sendPendingGetRequest(&chunkList, sock);
			}
		}
		
		break;
	}
	case ACK:{
		chunkEle* cep = resolveChunk(peer, windowSets);

		if ( cep->inProgress == 0){
			break;
		}
		//check which wether SLOWSTART or CONGAVOID
		if(cep->mode == SLOWSTART){
			cep->windowSize++;
			printf("####in slow start\n");
		}
		else
			printf("@@@@in cong avoid rtt: %f\n",cep->fromThisPeer->rtt);
		//check if enough to enter cong avoid
		if(cep->windowSize == cep->ssthresh)
			cep->mode = CONGAVOID;

		//check for no ack in rtt
		if((cep->mode == CONGAVOID) && (cep->haveACK == 0)){
			cep->windowSize++;
			printf("IIIIincreasing in cong avoid\n");
		}

		//set ack
		cep->haveACK = 1;

		printf("Receive Ack %d\n", *(int*)(buf+12));
		if( (cep->lastAcked) && ((packetHead* )(cep->lastAcked->data))->seqNum == ((packetHead* )(buf))->ackNum ){
			cep->lastAckedCount ++;
			printf("Incrementing last ack counter for %d to %d\n", ((packetHead* )(buf))->ackNum,cep->lastAckedCount);
			if( cep->lastAckedCount  == 3 ){
				//cut ssthresh in half and set window 1
				cep->ssthresh = halve(cep->windowSize);
				cep->windowSize = 1;
				cep->mode = SLOWSTART;

				//reset this ones time
				time(&cep->afterLastAckedTime);

				//try retrasmit
				cep->lastAckedCount = 0;
				node* retry = cep->lastAcked->prevp;
				printf("Retramsmit packet %d\n", ((packetHead* )retry->data)->seqNum);
				spiffy_sendto(sock, retry->data, ((packetHead* )retry->data)->packLen, 0, (struct sockaddr *) &peer->cli_addr, sizeof(peer->cli_addr));
				break;
			}

		}else{
			cep->lastAcked = resolveLastPacketAcked( ((packetHead*)buf)->ackNum, cep);
			cleanList(cep);
			time(&cep->afterLastAckedTime);
		}
		
		//check if finish sending the whole chunk
		if( cep->bytesRead == chunkSize ){
			printf("Successfully send the chunk %s\n", cep->chunkHash);
			if(cep->lastAcked == cep->lastSent){
				// some clear below
				printf("All sent packets have been acked\n");
				cep->inProgress = 0;
				mePeer->numOut--;
			}else{
				printf("lastAcked:%d, lastSent:%d\n",((packetHead*)cep->lastAcked->data)->seqNum, ((packetHead*)cep->lastSent->data)->seqNum );
			}
			
		}else{
			cleanList(cep);
			fillWindow(cep);
			sendWindow(cep, sock);
		}

		printPacketList(cep->packetList);
		printf("window: %d, ssthresh: %d, mode: %d\n",cep->windowSize, cep->ssthresh,
			cep->mode);
		break;
	}
	case DENIED:{
		printf("Received a denied ack!\n");
		chunkEle* cep = resolveChunk(peer, chunkList);
		//fclose(outputFile);
		time(&getRetryTimer);
		cep->fromThisPeer->inUse = 0;
		break;
	}

	}

  printf("PROCESS_INBOUND_UDP SKELETON -- replace!\n"
	 "Incoming message from %s:%d\n%s\n\n", 
	 inet_ntoa(from.sin_addr),
	 ntohs(from.sin_port),
	 buf);
}
Esempio n. 21
0
void process_get(char *chunkfile, char *outputfile) {
  printf("PROCESS GET SKELETON CODE CALLED.  Fill me in!  (%s, %s)\n", 
	chunkfile, outputfile);

  char *sendBuf = (char*) malloc(BUFLEN);

  unsigned short packet_length = ntohs(*(unsigned short*)(sendBuf+6));

  FILE *f = fopen(chunkfile, "r");
  char line[255];
  char chunk_count = 0;
  unsigned int id;
  uint8_t hash[SHA1_HASH_SIZE*2+1];
  uint8_t binary_hash[SHA1_HASH_SIZE];
  struct bt_peer_s* peer;
  struct sockaddr* dst_addr;
  // printf("len:%d, %s\n", packet_length, sendBuf);

  while (fgets(line, 255, f) != NULL) {
    if (line[0] == '#'){
      continue;
    }
    sscanf(line, "%d %s", &id, hash);
    hex2binary((char*)hash, SHA1_HASH_SIZE*2, binary_hash);
    memcpy(sendBuf + 20 + 20 * chunk_count, (char*)binary_hash, sizeof(binary_hash));
    chunk_count++;
    if(chunk_count >= 74 ) { //reached the maximum size of a packet
    	printf("WHOHAS packet has 74 chunks\n");
    	fill_header(sendBuf, WHOHAS, 1500, 0, 0);
    	*(sendBuf + 16) = chunk_count;
    	peer = config.peers;
	    while(peer!=NULL) {
	        if(peer->id==config.identity){
	          peer = peer->next;
	        }
	        else{
	          dst_addr = (struct sockaddr*)&peer->addr;
	          spiffy_sendto(sock, sendBuf, 1500, 0, dst_addr, sizeof(*dst_addr));
	          peer = peer->next;
	        }
	    }
	    memset(sendBuf, 0, BUFLEN);
    	chunk_count = 0;
    }
  }
  fclose(f);
  *(sendBuf + 16) = chunk_count;
  // printf("chunk_count:%d, %s\n", sendBuf[16], sendBuf);
  	peer = config.peers;
    while(peer!=NULL) {
        if(peer->id==config.identity){
          peer = peer->next;
        }
        else{
          dst_addr = (struct sockaddr*)&peer->addr;
          spiffy_sendto(sock, sendBuf, packet_length, 0, dst_addr, sizeof(*dst_addr));
          peer = peer->next;
        }
    }
    free(sendBuf);
}