Ejemplo n.º 1
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);

  Packet *newPkt = newPacketFromBuffer(buf);
  memcpy(&(newPkt->src), &from, fromlen);
  handlePacket(newPkt);

}
Ejemplo n.º 2
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);
  //parsing recvBuf
  unsigned short magic_number = ntohs(*(unsigned short*)buf);
  unsigned char packet_version = *(unsigned char*)(buf+2);
  unsigned char packet_type = *(unsigned char*)(buf+3);
  unsigned short packet_header_len = ntohs(*(unsigned short*)(buf+4));
  unsigned short packet_len = ntohs(*(unsigned short*)(buf+6));
  unsigned int seq_number =ntohl(*(unsigned int*)(buf+8));
  unsigned int ack_number = ntohl(*(unsigned int*)(buf+12));

  printf("%d,%d,%d\n", magic_number, packet_version, packet_type);
  printf("%d,%d\n", packet_header_len, packet_len); 
  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);
  switch(packet_type) {
  	case WHOHAS:
  		printf("receive WHOHAS\n");
  		break;
  	case IHAVE:
  		printf("receive IHAVE\n");
  		break;
  	case GET:
  		printf("receive GET\n");
  		break;
  	case DATA:
  		printf("receive DATA\n");
  		break;
  	case ACK:
  		printf("receive ACK\n");
  		break;
  	case DENIED:
  		printf("receive DENIED\n");
  		break;
  	default:
  		printf("Unexpected packet type!\n");

  }
}
Ejemplo n.º 3
0
void process_inbound_udp(int sock) {
    static char buf[BT_MAX_PKT_SIZE];
    struct sockaddr_in from;
    socklen_t fromlen = sizeof(from);
    
    int ret = spiffy_recvfrom(sock, buf, BT_MAX_PKT_SIZE, 0, (struct sockaddr *) &from, &fromlen);
    buf[ret] = 0;
    data_packet_t packet = * (data_packet_t *) buf;
    packet.data = buf + sizeof(header_t);

    if(packet.header.magicnum != BT_MAGIC){
        printf("Ignoring unrecognizable packet\n");
        return;
    }

    bt_peer_t *p;
    for (p = config.peers; p != NULL; p = p->next) {
        if (!memcmp(&p->addr.sin_addr, &from.sin_addr, sizeof(struct in_addr))
             && p->addr.sin_port == from.sin_port) {
            break;
        }
    }

    if(p == NULL){
        printf("Ignoring packet from unknown peer\n");
        return;
    }
    
    int peer = p->id;

    if(packet.header.packet_type == 1 || packet.header.packet_type == 3 || packet.header.packet_type == 5){
        requestor_packet(&requestor, peer, &packet);
    }else if(packet.header.packet_type == 0 || packet.header.packet_type == 2){
        responser_packet(&responser, peer, &packet);
    }else{
        int i;
        for(i=0; i<BT_MAX_UPLOAD; ++i){
            if(!senders[i].is_idle && senders[i].peer == peer){
                ctl_udp_ack(&senders[i], peer, &packet);
            }
        }
    }
}
Ejemplo n.º 4
0
Archivo: peer.c Proyecto: 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;
    }
}
Ejemplo n.º 5
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);
}
void process_inbound_udp(int sock) {
    struct sockaddr_in from;
    socklen_t fromlen;
    char buf[MAX_PACKET_LENGTH];

    fromlen = sizeof(from);
    int read_result = spiffy_recvfrom(sock, buf, MAX_PACKET_LENGTH, 0, (struct sockaddr *) &from, &fromlen);
    printf("read %d bytes\n", read_result);
    //printf("incoming message from %s:%d\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port));

    /* we just assume we got one packet everytime
     * if there are multiple packets in the buffer (whichi is rare), we just ignore them,
     * and everything will just work fine.
     */
    struct network_packet_s* network_packet = (struct network_packet_s*)buf;
    net_to_host_header(& network_packet->header);
    print_packet_header(&network_packet->header);
    if(validate_packet(& network_packet->header) < 0){
        printf("packet is invalid, skip\n");
        return;
    }
    int packet_type = get_packet_type(& network_packet->header);
    /* get the peer who send this packet*/
    bt_peer_t* peer = search_bt_peer(&config, (struct sockaddr *)&from);
    switch(packet_type) {
        case TYPE_WHOHAS: {
            struct network_packet_s* ihave_packet = malloc_ihave_packet(network_packet);
            /* this node has no such chunk */
            if(ihave_packet == NULL){
                return;
            }
            else{
                //print_ihave_packet(ihave_packet);
                send_packet(ihave_packet, global_socket, (struct sockaddr *) &from);
                free(ihave_packet);
            }
            break;
        }
        case TYPE_IHAVE: {
            if(current_job == NULL){
                return;
            }
            /* receiving a new IHAVE packet */
            /* check whether there is alreay a connection with this peer */
            struct receiver_connection_s* existing_connection = 
                    search_receiver_connection(receiver_connection_head, peer);
            if(existing_connection != NULL){
            /* there is alreay a connection */
                add_ihave_to_receiver_connection(existing_connection, network_packet);
            }
            /* there is no such connection */
            else{
                /* check if the number of connection reached the maximum */
                if(get_receiver_connection_number(receiver_connection_head) >=
                        max_receiver_connection){
                    return;
                }
                /* add add the hash whose chunk is in a CHUNK_STATUS_NOT_FOUND status 
                 * to a new connection
                 */
                else{
                    struct receiver_connection_s*  new_connection = 
                        malloc_receiver_connection(network_packet, peer);
                    /* if every chunk has a provider, the new_connection is NULL */
                    if(new_connection != NULL){
                        add_receiver_connection(new_connection);
                        /* start the new connection */
                        struct network_packet_s* get_packet = start_connection(new_connection);
                        //print_get_packet(get_packet);
                        free(get_packet);
                    }   
                }
            }
            //print_receiver_connection_list(receiver_connection_head);
            break;
        }
        case TYPE_GET: {
            //print_get_packet(network_packet);
            /* check whether there is alreay a connection with this peer */
            if(search_provider_connection(provider_connection_head, peer) != NULL){
                printf("Provider connection already exists with peer %d , ignore GET\n", peer->id);
                return;
            }
            /* do nothing is the number of connection reached the maximum*/
            if(get_provider_connection_number(provider_connection_head) >=
                    max_provider_connection){
                printf("Provider connection reached maximum with peer %d \n", peer->id);
                return;
            }
            struct provider_connection_s* new_connection = 
                    malloc_provider_connection(network_packet, peer);
            if(new_connection != NULL){
                printf("Add new provider connection with peer %d \n", peer->id);
                add_provider_connection(new_connection);
                //print_provider_connection(new_connection);
            }
            //print_provider_connection_list(provider_connection_head);
            break;
        }
        case TYPE_DATA: {
            print_data_packet(network_packet);
            printf("received data packet, seq: %d, ack: %d\n ",
                network_packet->header.seq_number,
                network_packet->header.ack_number);

            /* check whether there is a connection with this peer */
            struct receiver_connection_s* receiver_connection = 
                    search_receiver_connection(receiver_connection_head, peer);
            /* connection does not exist, ignore the data packet */
            if(receiver_connection == NULL){
                return;
            }
            int existing_seq_num = receiver_connection->chunk_list_head->chunk->received_seq_num;
            printf("expected data packet, seq: %d \n", 1 + existing_seq_num);
            int packet_seq_num = network_packet->header.seq_number;
            /* sequence number is illegal */
            if(packet_seq_num < 0){
                return;
            }
            /* old packet arrived, do nothing */
            else if(packet_seq_num  < (existing_seq_num + 1)){
                return;
            } 
            /* latter packet arrived first, send duplicate ACK */
            else if(packet_seq_num  > (existing_seq_num + 1)){
                struct network_packet_s* ack_packet = malloc_ack_packet(existing_seq_num);
                send_packet(ack_packet, global_socket, (struct sockaddr *) &from);
                free(ack_packet);
                return;
            }
            /* the packet expected */
            else{
                gettimeofday(&receiver_connection->last_data_time, NULL);
                receiver_connection->status = RECEIVER_STATUS_RECEIVED_DATA;

                struct network_packet_s* ack_packet = malloc_ack_packet(1 + existing_seq_num);
                send_packet(ack_packet, global_socket, (struct sockaddr *) &from);
                free(ack_packet);
                
                /* save_data_packet */
                save_data_packet(network_packet, receiver_connection);
                /* save the downloading chunk of the connnection, if it finihsed */
                save_chunk(receiver_connection);
                /* continue to download next chunk, if finished first one */
                reset_receiver_connection(receiver_connection);
            } 
            break;
        }
        case TYPE_ACK: {
            //print_ack_packet(network_packet);
            struct provider_connection_s* provider_connection = 
                    search_provider_connection(provider_connection_head, peer);
            if(provider_connection == NULL){
                return;
            }
            provider_control_by_ack(provider_connection, 
                    network_packet->header.ack_number);
            /* check if the data has been all send to a receiver */
            if(provider_connection->last_packet_acked == CHUNK_DATA_NUM){
                /* download finished */
                finish_provider_connection(provider_connection);
            }
            break;
        }
        case TYPE_DENIED: {
            break;
        }
        default:{
            break;
        }
    }
}
Ejemplo n.º 7
0
Archivo: peer.c Proyecto: 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");
      }
    }
  }
}