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; } }
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; }
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; } } }