예제 #1
0
Packet *newPacketIHAVE(Packet *pktWHOHAS)
{
    uint8_t numHash = getPacketNumHash(pktWHOHAS);
    int i = 0;
    int idx;
    uint8_t *hash;
    Packet *thisObj = newPacketDefault();
    incPacketSize(thisObj, 4);
    setPacketType(thisObj, "IHAVE");
    for(i = 0; i < numHash; i++) {
        hash = getPacketHash(pktWHOHAS, i);
        idx = searchHash(hash, &hasChunk, -1);
        if(idx >= 0) {
            printf("Has[%d]", i);
            insertPacketHash(thisObj, hash);
        }
    }

    if(i == 0 || getPacketSize(thisObj) == 20) {
        freePacket(thisObj);
        return NULL;
    } else {
      setPacketDest(thisObj, &(pktWHOHAS->src), sizeof(pktWHOHAS->src));
      return thisObj;
    }
}
예제 #2
0
int newPacketGET(Packet *pkt, queue *getQueue)
{
  int ret = 0;
  uint8_t numHash = getPacketNumHash(pkt);
  int i, idx;
  uint8_t *hash;
  for(i = 0; i < numHash; i++) {
    hash = getPacketHash(pkt, i);
    printHash(hash);
    idx = searchHash(hash, &getChunk, -1);
    printf("idx %d hashSeq %d getState %d\n", idx, getChunk.list[idx].seq, getChunk.list[idx].fetchState);
    //Only GET when chunk hasn't been fetched
    if(idx >= 0 && getChunk.list[idx].fetchState == 0) {
      printf("geting chunk %d\n",getChunk.list[idx].seq);
      Packet *thisObj = newPacketSingleGET(hash);
      enqueue(getQueue, (void *)thisObj);
      ret = 1;
    }
  }
  return ret;
}
예제 #3
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;
    }

  }
}