Ejemplo n.º 1
0
struct list_node *list_check_node(const struct list_node *node,
                                  const char *abortstr) {
	const struct list_node *p, *n;
	int count = 0;

	for (p = node, n = node->next; n != node; p = n, n = n->next) {
		count++;
		if (n->prev != p)
			return corrupt(abortstr, node, n, count);
	}
	/* Check prev on head node. */
	if (node->prev != p)
		return corrupt(abortstr, node, node, 0);

	return (struct list_node *)node;
}
Ejemplo n.º 2
0
void fpage( char_data* ch, const char *text )
{
  char buf [ MAX_STRING_LENGTH ];

  if( ch == NULL || ch->link == NULL )
    return;

  format( buf, text );
  strcat( buf, "\r\n" );
  corrupt( buf, MAX_STRING_LENGTH, "Fpage" );

  page( ch, buf );
}    
Ejemplo n.º 3
0
/*
 * wts_salvage --
 *	Salvage testing.
 */
void
wts_salvage(void)
{
	int ret;

	/* Some data-sources don't support salvage. */
	if (DATASOURCE("helium") || DATASOURCE("kvsbdb"))
		return;

	if (g.c_salvage == 0)
		return;

	/*
	 * Save a copy of the interesting files so we can replay the salvage
	 * step as necessary.
	 */
	if ((ret = system(g.home_salvage_copy)) != 0)
		die(ret, "salvage copy step failed");

	/* Salvage, then verify. */
	wts_open(g.home, 1, &g.wts_conn);
	salvage();
	wts_verify("post-salvage verify");
	wts_close();

	/*
	 * If no records were deleted, dump and compare against Berkeley DB.
	 * (The problem with deleting records is salvage restores deleted
	 * records if a page splits leaving a deleted record on one side of
	 * the split, so we cannot depend on correctness in that case.)
	 */
	if (g.c_delete_pct == 0)
		wts_dump("salvage", SINGLETHREADED);

	/* Corrupt the file randomly, salvage, then verify. */
	if (corrupt()) {
		wts_open(g.home, 1, &g.wts_conn);
		salvage();
		wts_verify("post-corrupt-salvage verify");
		wts_close();
	}
}
Ejemplo n.º 4
0
// Listens for an ack, returning the ack number. Returns -99 if timeout
int listen_for_ack(int sockfd) {
  int recvlen;
  int ack_number = -99;
  struct packet receive;

  if (is_readable(sockfd)) {
    recvlen = recvfrom(sockfd, &receive, sizeof(receive), 0, NULL, NULL);
    if (should_lose_packet()) {
      if (receive.type == TYPE_ACK)
        printf("Simulated loss of ack # %d\n", receive.seq);
      else
        printf("Simulated loss of packet type %d. (Was expecting ACK).\n", receive.type);
      return -99;
    }
    if (should_corrupt_packet()) {
      if (receive.type == TYPE_ACK)
        printf("Simulated corruption of ack # %d\n", receive.seq);
      else
        printf("Simulated corruption of packet type %d. (Was expecting ACK).\n", receive.type);
      return -99;
    }
    if (corrupt(&receive)) {
      printf("Received actual corrupt packet\n");
      return -99;
    }
  }
  else {
    return -99;
  }  

  if (recvlen < 0)
    error("ERROR receiving ack from client");
  if (receive.type != TYPE_ACK) {
    fprintf(stderr, "Expected ACK, received type %d", receive.type);
    return -99;
  }
  ack_number = receive.seq;

  printf("Received ack %d.\n", ack_number);
  return ack_number;
}
Ejemplo n.º 5
0
int main(void)
{
    struct sockaddr_in si_other;
    int s, slen=sizeof(si_other);
	char file_name[30];
	char server[12];
	int read_ret;
	char prog_mode;
	char intentional_corruption;
	int file_length_left;
	int file_length;
	int bytes_written = 0;
	int packet_count;
	int r,c,i,j;
	int random;
	char **data_storage;
	int sequence;
	int prev_sequence;
	FILE* fp;
    WSADATA wsa;
			
	//packet sent preceding the data containing information to initiate the file transfer
	
	

	struct data_packet send_data;
	struct data_packet receive_data;
	struct data_packet ACK0;
	struct data_packet ACK1;
	struct header_packet header;

	//initalize ACK0

	memset(ACK0.data,'+',DATALEN);
	ACK0.sequence_number = 0;
	ACK0.packet_number = -1;
	ACK0.checksum = checksum((char*)&ACK0,sizeof(ACK0));

	//initalize ACK1

	memset(ACK0.data,'+',DATALEN);
	ACK1.sequence_number = 1;
	ACK1.packet_number = -1;
	ACK1.checksum = checksum((char*)&ACK1,sizeof(ACK1));


	//Initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");
     
    //create socket
    if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
    {
        printf("socket() failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
     
	printf("For localhost enter: 127.0.0.1 \n");
	printf("Enter Server IP Address: ");
		scanf("%s", &server);
	


    //setup address structure
    memset((char *) &si_other, 0, sizeof(si_other));
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons(PORT);
    si_other.sin_addr.S_un.S_addr = inet_addr(server);


    //start communication
    while(1)
    {
		bytes_written = 0;
		packet_count = 0;
		sequence = 0;
		prev_sequence = 1;


		printf("Do you want to send a file? <y/n>: ");
		scanf(" %c", &prog_mode);
		printf("Do you want intentional data corruption? <y/n>: ");
		scanf(" %c", &intentional_corruption);
		
		if (intentional_corruption == 'y'){

			printf("Options: \nACK packet bit-error = A\nData packet bit-error = B \n");
			printf("Please enter your selection <A/B>: ");
			scanf(" %c", &intentional_corruption);

		}



		//client will receive a file
			if(prog_mode == 'n'){

				printf("Enter file name to read on server : ");
				scanf("%s",header.file_name);
				printf("Enter file name to write on client : ");
				scanf("%s",file_name);
		

				fp = fopen(file_name,"wb");


				//make first packet (header_packet) requesting file to be sent

		

				header.file_size = 0;
				header.mode = 'n';
				header.packet_number = packet_count;
				header.intentional_corruption = intentional_corruption;
				header.checksum = checksum((char*)&header,sizeof(header));


				printf("\n HEADER INFORMATION \n");
				printf("packet number = %i \n",header.packet_number);
				//mode dictates whether the server should send or receive
				printf("mode = %c \n",header.mode);
				printf("File name = %s \n\n",header.file_name);

		
				//send header packet asking to send file

				send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);


				//wait for ACK for header
				printf("waiting for ACK from server \n");

				receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
					
				
				//in case of corrupt header packet or corrupt ACK 
				while(corrupt(receive_data)||isACK(receive_data,prev_sequence)){
						
					//resend the header packet 
					send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
						
					//look for new ACK from the server
						
					receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
						
				}

				//notification for successful recepit of ACK
				if(isACK(receive_data,sequence) == 1){

					printf("received ACK for header packet from server \n");

				}else{

					printf("ERROR: UNKNOWN DATA RECEIVED \n");
				}



				//wait for return header packet from server indicating the file size

				printf("Waiting for header packet from client...\n");
	
				//get header packet from socket
				receive_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);

				
				//if header packet is corrupt send the previous sequence number ACK
		
				while(corrupt_h(header) == 1){
					//resend the prev_sequence ACK packet
					send_packet((char*)&ACK1,sizeof(struct data_packet),s,&si_other,slen);

					//get a new header packet
					receive_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
				}
	
				//send ack
				printf("sending header acknowledgement \n");
				send_packet((char*)&ACK0,sizeof(struct data_packet),s,&si_other,slen);






				printf("\n HEADER INFORMATION \n");
				printf("packet number = %i \n",header.packet_number);
				printf("mode = %c \n",header.mode);
				printf("File size = %i \n",header.file_size);




				//Allocate array to hold data for packet reordering

				r = ((header.file_size-(header.file_size%(DATALEN)))/(DATALEN));
					
				if((header.file_size%DATALEN)!=0){
					r++;
				}
				
				c = DATALEN;

				data_storage = (char **)malloc(r * sizeof(char*));
				for (i=0; i<r; i++){
					data_storage[i] = (char *)malloc(c * sizeof(char));
				}
	
				//initalize array
				for (i = 0; i <  r; i++)
					for (j = 0; j < c; j++)
						data_storage[i][j] = '+';










				printf("Waiting for data...\n");
				fflush(stdout);
         
        
         
       
				//try to receive some data, stop when you recieve all the data which the file contains

				while(bytes_written < header.file_size){

					//clear out the buffer each time to eliminate extraneous data on the last packet
					memset(receive_data.data,0xFF, DATALEN);

		
					//listen for packet and store into data_packet struct

					receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);


					
					//intentionally corrupt data packet if user selected
					if(header.intentional_corruption == 'B'){

						random = rand() % 10;
						//randomly choose data packets and invalidate the sequence number

						if(random == 7){
							receive_data.sequence_number = 49;
						}

					}

					//if data is corrupt or has the wrong sequence number

					while(corrupt(receive_data)||receive_data.sequence_number == prev_sequence){
						//resend the prev_sequence ACK packet 
						if(prev_sequence == 0){
							send_packet((char*)&ACK0,sizeof(struct data_packet),s,&si_other,slen);

						}else{
							send_packet((char*)&ACK1,sizeof(struct data_packet),s,&si_other,slen);

						}


						//look for new data from client
						receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);

					}


					//If the correct sequence data packet was sucessfully received
					if(receive_data.sequence_number == sequence){

						printf("received data%i from client \n", sequence);

					}else{


						printf("ERROR: UNKNOWN DATA RECEIVED \n");
					}
					

					//send the ACK packet to the client
					if(sequence == 0){
						printf("Sending ACK0 to client \n");
						send_packet((char*)&ACK0,sizeof(struct data_packet),s,&si_other,slen);
						
					}else{
						printf("Sending ACK1 to client \n");
						send_packet((char*)&ACK1,sizeof(struct data_packet),s,&si_other,slen);

					}



					//copy data received into array to reorder packets

					memcpy(data_storage[receive_data.packet_number-1], receive_data.data, (DATALEN));

					printf("packet number = %i \n", receive_data.packet_number);
         
					//print the data received data and origin
		 
					printf("\n\n\nReceived packet from %s:%d \n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
					printf("Data: %s\n\n\n" , receive_data.data);
					bytes_written = bytes_written + DATALEN;



					prev_sequence=sequence;
					sequence++;

					//when sequence number 1 is done go back to sequence number 0
					if(sequence > 1){

						sequence = 0;
					}
	




				}
		

				bytes_written = 0;

				//copy data into file in the correct order until the file is the correct size

				while(bytes_written != header.file_size){

				//copy array

					

					for(i=0; i<r; i++){
						bytes_written = bytes_written + DATALEN;
						printf("Writing Packet#: %i \n", i+1);
						
						if(bytes_written < header.file_size){
							fwrite(data_storage[i],1,DATALEN,fp);
							printf("bytes_written: %i \n",bytes_written);
						
						//special case for the last packet which isen't DATALEN bytes long
						}else{
							bytes_written = bytes_written - (DATALEN);
							printf("bytes_written: %i \n",bytes_written);
							
							fwrite(data_storage[i],1,(header.file_size - bytes_written),fp);
							
							printf("PARTIAL PACKET WRITE \n");
							printf("Wrote: %i \n",(header.file_size - bytes_written));
							bytes_written += (header.file_size - bytes_written);
						}
					
					
					}

				}


				printf("Receive Done. \n");

		
				printf("header File size = %i \n",header.file_size);

				printf("End of Transmission \n");

				fclose(fp);

				//free data storage array
				for (i=0; i<r; i++){
					free(data_storage[i]);
				}
				free(data_storage);


			} 
		
		



			//client will send a file
			if(prog_mode == 'y'){



				// get file name to be sent from user



				printf("Enter file name to read on client : ");
				scanf("%s",file_name);
				printf("Enter file name to write on server : ");
				scanf("%s",header.file_name);


				fp = fopen(file_name,"rb");



				if (fp == NULL){
					printf("Invalid file name \n");
					exit(EXIT_FAILURE);
				}

				//find length of the file
				fseek(fp, 0L, SEEK_END);
				file_length = ftell(fp);
				file_length_left = file_length;
				rewind(fp);

		
				//make first packet (header_packet) containing file length

		

				header.file_size = file_length;
				header.mode = 'y';
				header.packet_number = packet_count;
				header.intentional_corruption = intentional_corruption;
				header.checksum = checksum((char*)&header, sizeof(header));

				printf("\n HEADER INFORMATION \n");
				printf("packet number = %i \n",header.packet_number);
				//mode dictates whether the server should send or receive
				printf("mode = %c \n",header.mode);
				printf("File size = %i \n\n",header.file_size);

		
				//send header packet

				send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);

				//wait for ACK for header
				printf("waiting for ACK from server \n");

				receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
					
				
				//in case of corrupt header packet or corrupt ACK 
					while(corrupt(receive_data)||isACK(receive_data,prev_sequence)){
						
						//resend the header packet 
						send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
						
						//look for new ACK from the server
						
						receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
						
					}

					//notification for successful recepit of ACK
					if(isACK(receive_data,sequence) == 1){

						printf("received ACK for header packet from server \n");

					}else{

						printf("ERROR: UNKNOWN DATA RECEIVED \n");
					}








				//break up message into chunks for UDP packets

				while(file_length_left > 0){
		
					
				
					packet_count++;



					memset(send_data.data,'\0', DATALEN);
					send_data.packet_number = packet_count;

					read_ret=fread(send_data.data, 1, (DATALEN), fp);
			
					if(read_ret != DATALEN && file_length_left>DATALEN){
						printf("\n ERROR, did not read DATALEN \n");
						printf("read_ret = %i \n", read_ret);
					}
			
			

					//insert sequence number
					send_data.sequence_number = sequence;

					//compute and store checksum into packet
					send_data.checksum = checksum((char*)&send_data, sizeof(send_data));

					file_length_left = file_length_left - (DATALEN);
			
					printf("packet number = %i \n",send_data.packet_number);
			
					if(file_length_left > 0){
						printf("file length left: %i \n", file_length_left);
					}else{
						printf("file length left: 0 \n");
					}
			

				



					//send the data_packet struct to the server

					send_packet((char*)&send_data,sizeof(struct data_packet),s,&si_other,slen);
				

	
				
				
					//look for ACK from the server

					printf("waiting for ACK%i from server \n", sequence);

					receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);

					
					//intentionally corrupt the received ACK packet if user selected
					if(intentional_corruption == 'A'){

						random = rand() % 10;
						//randomly choose ACK packets and invalidate the sequence number

						if(random == 7){
						receive_data.sequence_number = 69;
						}

					}
					
					
					//if the ACK packet is corrupted or wrong sequence ACK is received
					while(corrupt(receive_data)||isACK(receive_data,prev_sequence)){
						
						printf("Resending Data packet \n");

						//resend the data packet 
						send_packet((char*)&send_data,sizeof(struct data_packet),s,&si_other,slen);
						

						//look for new ACK from the server

						printf("waiting for ACK%i from server \n", sequence);
						
						receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
						

					}


					//If the correct ACK was sucessfully received
					if(isACK(receive_data,sequence) == 1){

						printf("received ACK%i from server \n", sequence);

					}else{


						printf("ERROR: UNKNOWN DATA RECEIVED \n");
					}




						prev_sequence=sequence;
						sequence++;

					//when sequence number 1 is done go back to sequence number 0
					if(sequence > 1){

						sequence = 0;
					}

				}

			fclose(fp);

			}


		



	}
 
    closesocket(s);
    WSACleanup();
 
    return 0;
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
  int sockfd, newsockfd, portno, recvlen;
  struct sockaddr_in serv_addr, cli_addr;
  socklen_t clilen = sizeof(cli_addr);
  struct packet receive;
  FILE * f;
  char * filename;
  int i;
  int cwndsize;
  struct packet *packets;

  // initialize random number generator
  srand(time(NULL));

  if (argc == 2) {
    portno = atoi(argv[1]);
    cwndsize = 1;
    lossprob = 0;
    corruptprob = 0;
  } else if (argc < 5) {
    fprintf(stderr,"usage: %s <port number> <CWnd size> <loss probability> <corruption probability>\n", argv[0]);
    exit(1);
  } else {
    portno = atoi(argv[1]);
    cwndsize = atoi(argv[2]);
    lossprob = atof(argv[3]);
    corruptprob = atof(argv[4]);
  }

  printf("CWnd size: %d\nProbLoss: %f\nProbCorrupt: %f\nServer listing on port %d...\n\n", cwndsize, lossprob, corruptprob, portno);

  // create UDP socket
  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockfd < 0) 
    error("ERROR opening socket");

  // fill in address info
  memset((char *) &serv_addr, 0, sizeof(serv_addr));  //reset memory
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portno);

  // bind socket to IP address and port number
  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    error("ERROR on binding");
  
  // scan for requests from client
  while (1) {

    // receieve request from client
    recvlen = recvfrom(sockfd, &receive, sizeof(receive), 0, (struct sockaddr *) &cli_addr, &clilen);
    if (should_lose_packet()) {
      if (receive.type == TYPE_REQUEST)
        printf("Simulated loss of request packet\n");
      else 
        printf("Simulated loss of unexpected packet\n");
      continue;
    }
    if (should_corrupt_packet()) {
      if (receive.type == TYPE_REQUEST)
        printf("Simulated corruption of request packet\n");
      else 
        printf("Simulated corruption of unexpected packet\n");
      continue;
    }
    if (corrupt(&receive)) {
      printf("Received actual corrupt packet\n");
      continue;
    }

    if (recvlen < 0)
      error("ERROR receiving data from client");
    printf("Received request (%d bytes) for %s\n", receive.length, receive.data);

    // open file
    if (receive.type == TYPE_REQUEST) {
      f = fopen(receive.data, "r");
      if (f == NULL)
        error("ERROR opening file");
    } else {
      fprintf(stderr, "Packet not of type request\n");
      continue;
    }

    packets = prepare_packets(f);
    rdt_send_packets(packets, sockfd, cli_addr, clilen, cwndsize);
    free(packets);
    
    printf("Finished sending file. Listening for new request...\n\n");
  }
     
  // never reached if we never break out of the loop but whatever
  close(sockfd); 
  return 0; 
}
Ejemplo n.º 7
0
/// \brief Corrupt a buffer with random errors.
///		This is used only for testing to make sure we can cleanly
///		handle corruption of the packets.
///
/// @param factor A divisor to adjust how many errors are created.
///
/// @return nothing
int
Buffer::corrupt()
{
    return corrupt(10);
}
Ejemplo n.º 8
0
MemBlock* MemoryPool::alloc(const size_t length) throw (OOM_EXCEPTION)
{
    MutexLockGuard guard(mutex, "MemoryPool::alloc");

    // If this is a small block, look for it there

    if (length <= threshold)
    {
        unsigned int slot = length / roundingSize;
        MemBlock* block;

        if (threadShared)
        {
            while (block = freeObjects[slot])
            {
                if (freeObjects[slot].compareExchange(block, block->next))
                {
#ifdef MEM_DEBUG
                    if (slot != block->length / roundingSize)
                        corrupt("length trashed for block in slot");
#endif
                    return block;
                }
            }
        }
        else
        {
            block = freeObjects[slot];

            if (block)
            {
                freeObjects[slot] = (MemBlock*) block->pool;

#ifdef MEM_DEBUG
                if (slot != block->length / roundingSize)
                    corrupt("length trashed for block in slot");
#endif
                return block;
            }
        }

        // See if some other hunk has unallocated space to use

        MemSmallHunk* hunk;

        for (hunk = smallHunks; hunk; hunk = hunk->nextHunk)
        {
            if (length <= hunk->spaceRemaining)
            {
                MemBlock* block = (MemBlock*) hunk->memory;
                hunk->memory += length;
                hunk->spaceRemaining -= length;
                block->length = length;

                return block;
            }
        }

        // No good so far.  Time for a new hunk

        hunk = (MemSmallHunk*) allocRaw(minAllocation);
        hunk->length = minAllocation - 16;
        hunk->nextHunk = smallHunks;
        smallHunks = hunk;

        size_t l = ROUNDUP(sizeof(MemSmallHunk), sizeof(double));
        block = (MemBlock*) ((UCHAR*) hunk + l);
        hunk->spaceRemaining = minAllocation - length - l;
        hunk->memory = (UCHAR*) block + length;
        block->length = length;

        return block;
    }

    /*
     *  OK, we've got a "big block" on on hands.  To maximize confusing, the indicated
     *  length of a free big block is the length of MemHeader plus body, explicitly
     *  excluding the MemFreeBlock and MemBigHeader fields.

                         [MemHeader::length]

    	                <---- MemBlock ---->

    	*--------------*----------*---------*
    	| MemBigHeader | MemHeader |  Body  |
    	*--------------*----------*---------*

    	 <---- MemBigObject ----->

    	*--------------*----------*---------------*
    	| MemBigHeader | MemHeader | MemFreeBlock |
    	*--------------*----------*---------------*

    	 <--------------- MemFreeBlock ---------->
     */


    MemFreeBlock* freeBlock;

    for (freeBlock = freeBlocks.nextLarger; freeBlock != &freeBlocks; freeBlock = freeBlock->nextLarger)
    {
        if (freeBlock->memHeader.length >= length)
        {
            remove(freeBlock);
            MemBlock* block = (MemBlock*) &freeBlock->memHeader;

            // Compute length (MemHeader + body) for new free block

            unsigned int tail = block->length - length;

            // If there isn't room to split off a new free block, allocate the whole thing

            if (tail < sizeof(MemFreeBlock))
            {
                block->pool = this;
                return block;
            }

            // Otherwise, chop up the block

            MemBigObject* newBlock = freeBlock;
            freeBlock = (MemFreeBlock*) ((UCHAR*) block + length);
            freeBlock->memHeader.length = tail - sizeof(MemBigObject);
            block->length = length;
            block->pool = this;

            if (freeBlock->next = newBlock->next)
                freeBlock->next->prior = freeBlock;

            newBlock->next = freeBlock;
            freeBlock->prior = newBlock;
            freeBlock->memHeader.pool = NULL;		// indicate block is free
            insert(freeBlock);

            return block;
        }
    }

    // Didn't find existing space -- allocate new hunk

    size_t hunkLength = sizeof(MemBigHunk) + sizeof(MemBigHeader) + length;
    size_t freeSpace = 0;

    // If the hunk size is sufficient below minAllocation, allocate extra space

    if (hunkLength + sizeof(MemBigObject) + threshold < minAllocation)
    {
        hunkLength = minAllocation;
        //freeSpace = hunkLength - 2 * sizeof(MemBigObject) - length;
        freeSpace = hunkLength - sizeof(MemBigHunk) - 2 * sizeof(MemBigHeader) - length;
    }

    // Allocate the new hunk

    MemBigHunk* hunk = (MemBigHunk*) allocRaw(hunkLength);
    hunk->nextHunk = bigHunks;
    bigHunks = hunk;
    hunk->length = hunkLength;

    // Create the new block

    MemBigObject* newBlock = (MemBigObject*) &hunk->blocks;
    newBlock->prior = NULL;
    newBlock->next = NULL;

    MemBlock* block = (MemBlock*) &newBlock->memHeader;
    block->pool = this;
    block->length = length;

    // If there is space left over, create a free block

    if (freeSpace)
    {
        freeBlock = (MemFreeBlock*) ((UCHAR*) block + length);
        freeBlock->memHeader.length = freeSpace;
        freeBlock->memHeader.pool = NULL;
        freeBlock->next = NULL;
        freeBlock->prior = newBlock;
        newBlock->next = freeBlock;
        insert(freeBlock);
    }

    return block;
}
Ejemplo n.º 9
0
TEST(RecordIOTest, Randomized) {
  SCOPED_TRACE(to<std::string>("Random seed is ", FLAGS_random_seed));
  std::mt19937 rnd(FLAGS_random_seed);

  size_t recordCount =
    std::uniform_int_distribution<uint32_t>(30, 300)(rnd);

  std::uniform_int_distribution<uint32_t> recordSizeDist(1, 3 << 16);
  std::uniform_int_distribution<uint32_t> charDist(0, 255);
  std::uniform_int_distribution<uint32_t> junkDist(0, 1 << 20);
  // corrupt 1/5 of all records
  std::uniform_int_distribution<uint32_t> corruptDist(0, 4);

  std::vector<std::pair<fbstring, off_t>> records;
  std::vector<off_t> corruptPositions;
  records.reserve(recordCount);
  TemporaryFile file;

  fbstring record;
  // Recreate the writer multiple times so we test that we create a
  // continuous stream
  for (size_t i = 0; i < 3; ++i) {
    RecordIOWriter writer(File(file.fd()));
    for (size_t j = 0; j < recordCount; ++j) {
      off_t beginPos = writer.filePos();
      record.clear();
      size_t recordSize = recordSizeDist(rnd);
      record.reserve(recordSize);
      for (size_t k = 0; k < recordSize; ++k) {
        record.push_back(charDist(rnd));
      }
      writer.write(iobufs({record}));

      bool corrupt = (corruptDist(rnd) == 0);
      if (corrupt) {
        // Corrupt one random byte in the record (including header)
        std::uniform_int_distribution<uint32_t> corruptByteDist(
            0, recordSize + recordio_helpers::headerSize() - 1);
        off_t corruptRel = corruptByteDist(rnd);
        VLOG(1) << "n=" << records.size() << " bpos=" << beginPos
                << " rsize=" << record.size()
                << " corrupt rel=" << corruptRel
                << " abs=" << beginPos + corruptRel;
        corruptPositions.push_back(beginPos + corruptRel);
      } else {
        VLOG(2) << "n=" << records.size() << " bpos=" << beginPos
                << " rsize=" << record.size()
                << " good";
        records.emplace_back(std::move(record), beginPos);
      }
    }
    VLOG(1) << "n=" << records.size() << " close abs=" << writer.filePos();
  }

  for (auto& pos : corruptPositions) {
    corrupt(file.fd(), pos);
  }

  {
    size_t i = 0;
    RecordIOReader reader(File(file.fd()));
    for (auto& r : reader) {
      SCOPED_TRACE(i);
      ASSERT_LT(i, records.size());
      EXPECT_EQ(records[i].first, sp(r.first));
      EXPECT_EQ(records[i].second, r.second);
      ++i;
    }
    EXPECT_EQ(records.size(), i);
  }
}
Ejemplo n.º 10
0
int main()
{
    SOCKET s;
    struct sockaddr_in server, si_other;
    int slen;
    WSADATA wsa;
	int read_ret;
	int file_length_left;
	int file_length;
	int random;
	int bytes_written = 0;
	int packet_count = 0;
	int r,c,i,j;
	int sequence;
	int prev_sequence;
	char **data_storage;
	FILE* fp;
	
	



	struct data_packet receive_data;
	struct data_packet send_data;
	struct data_packet ACK0;
	struct data_packet ACK1;
	struct header_packet header;

	//initalize ACK0

	memset(ACK0.data,'+',DATALEN);
	ACK0.sequence_number = 0;
	ACK0.packet_number = -1;

	ACK0.checksum = data_CSI(ACK0);

	//initalize ACK1

	memset(ACK1.data,'+',DATALEN);
	ACK1.sequence_number = 1;
	ACK1.packet_number = -1;
	ACK1.checksum = data_CSI(ACK1);
//	ACK1.checksum = checksumAndInvert((char*)&ACK1,sizeof(ACK1));


    slen = sizeof(si_other) ;
     
    //Initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");
     
    //Create a socket
    if((s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP)) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }
    printf("Socket created.\n");
     
    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( PORT );
     
    //Bind
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    puts("Bind done \n");
 



    //keep listening for data
    while(1){
    
       bytes_written = 0;
	   packet_count = 0;
	   sequence = 0;
	   prev_sequence = 1;
	

		//look for header packet from client to determine send/receive
		

		printf("Waiting for header packet from client...\n");
		
		//wait for header packet
		receive_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
		printf("\n HEADER INFORMATION \n");
		printf("packet number = %i \n",header.packet_number);
		//mode dictates whether the server should send or receive
		printf("mode = %c \n",header.mode);
		printf("File name = %s \n\n",header.file_name);
		printf("Computed = %d Checksum = %u\n", header_CSI(header), header.checksum);
		//if header packet is corrupt send the previous sequence number ACK
		
		while(corrupt_h(header) == 1){
			//resend the prev_sequence ACK packet
				send_packet((char*)&ACK1,sizeof(struct data_packet),s,&si_other,slen);

				//get a new header packet
				receive_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
			}
	
		//send ack
		printf("sending header acknowledgement \n");
		send_packet((char*)&ACK0,sizeof(struct data_packet),s,&si_other,slen);


		printf("\n HEADER INFORMATION \n");
		printf("packet number = %i \n",header.packet_number);
		//mode dictates whether the server should send or receive
		printf("mode = %c \n",header.mode);
		printf("File size = %i \n",header.file_size);
				
	
	


		
				
				
				
		//Server will be sending a file		
				
		if(header.mode == 'n'){
		
				// get file name to be sent from header packet

         
			fp = fopen(header.file_name,"rb");



			if (fp == NULL) {
				printf("Invalid file name \n");
				exit(EXIT_FAILURE);
			}

			//find length of the file
			fseek(fp, 0L, SEEK_END);
			file_length = ftell(fp);
			file_length_left = file_length;
			rewind(fp);

		
			//make another packet in response to client's (header_packet) to transmit necessary data for file transfer

		

			header.file_size = file_length;
			header.mode = 'n';
			header.packet_number = packet_count;
			header.checksum = header_CSI(header);

			printf("\n HEADER INFORMATION \n");
			printf("packet number = %i \n",header.packet_number);
			//mode dictates whether the server should send or receive
			printf("mode = %c \n",header.mode);
			printf("File size = %i \n\n",header.file_size);


		
			//send header packet
			send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);

			//wait for ACK for header
			printf("waiting for ACK from client \n");


			receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);		
				
			//in case of corrupt header packet or corrupt/wrong ACK 
			while(corrupt(receive_data)||isACK(receive_data,prev_sequence)){
						
				//resend the header packet 
				send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
						
				//look for new ACK from the server		
				receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);

			}

			//notification for successful recepit of ACK
			if(isACK(receive_data,sequence) == 1){

				printf("received ACK for header packet from client \n");

			}else{

				printf("ERROR: UNKNOWN DATA RECEIVED \n");
			}



			while(file_length_left > 0){
		
				memset(send_data.data,'\0', DATALEN);

				packet_count++;
				send_data.packet_number = packet_count;

				read_ret=fread(send_data.data, 1, DATALEN, fp);
				
				if(read_ret != DATALEN && file_length_left>DATALEN){
					printf("\n ERROR, did not write DATALEN \n");
				}
			
			

				file_length_left = file_length_left - (DATALEN);
			
				printf("packet number = %i \n",send_data.packet_number);
			
				if(file_length_left > 0){
					printf("file length left: %i \n", file_length_left);
				}else{
					printf("file length left: 0 \n");
				}
			

				//insert sequence number
				send_data.sequence_number = sequence;

				//compute and store checksum into packet
				send_data.checksum = data_CSI(send_data);
				

				//send the data packet
				send_packet((char*)&send_data,sizeof(struct data_packet),s,&si_other,slen);
				
				
		 
				//look for ACK from the server

					printf("waiting for ACK%i from server \n", sequence);

					receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
					

					//intentionally corrupt the received ACK packet if user selected
					if(header.intentional_corruption == 'A'){

						random = rand() % 10;
						//randomly choose ACK packets and invalidate the sequence number

						if(random == 7){
						receive_data.sequence_number = 49;
						}

					}

					
					//if the packet is corrupted or wrong sequence ACK is received
					while(corrupt(receive_data)||isACK(receive_data,prev_sequence)){
						
						printf("CORRUPT OR WRONG SEQUENCE ACK PACKET RECEIVED \n");
						printf("Resending Data packet \n \n");
						
						//resend the data packet 
						send_packet((char*)&send_data,sizeof(struct data_packet),s,&si_other,slen);
						

						//look for new ACK from the server

						printf("waiting for ACK%i from server \n", sequence);
						
						receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
						

					}


					//If the correct ACK was sucessfully received
					if(isACK(receive_data,sequence) == 1){

						printf("received ACK%i from client \n", sequence);

					}else{


						printf("ERROR: UNKNOWN DATA RECEIVED \n");
					}




						prev_sequence=sequence;
						sequence++;

					//when sequence number 1 is done go back to sequence number 0
					if(sequence > 1){

						sequence = 0;
					}

				}
		
		
	
		}
		
		




		//server will receive a file
		
		if(header.mode == 'y'){
		

			//Allocate array to hold data for packet reordering

			//calculate rows and columns of array
			r = ((header.file_size-(header.file_size%(DATALEN)))/(DATALEN));
			
			if((header.file_size%DATALEN)!=0){
				r++;
			}
				
			c = DATALEN;

			data_storage = (char **)malloc(r * sizeof(char*));
			
			for (i=0; i<r; i++){
				data_storage[i] = (char *)malloc(c * sizeof(char));
			}
	
			//initalize array
			for (i = 0; i <  r; i++)
				for (j = 0; j < c; j++)
					data_storage[i][j] = '+';
		
		
			fp = fopen(header.file_name,"wb");


			printf("Waiting for data...\n");
			fflush(stdout);
         
        
         
       
			//try to receive some data, stop when you recieve all the data which the file contains

			while(bytes_written < header.file_size){

				//clear out the buffer each time to eliminate extraneous data on the last packet
				memset(receive_data.data,0xFF, DATALEN);

				//look for data from client
				receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);


				//intentionally corrupt data packet if user selected
				if(header.intentional_corruption == 'B'){

					random = rand() % 10;
						//randomly choose data packets and invalidate the sequence number

						if(random == 7){
						receive_data.sequence_number = 49;
						}


				}

				//if data is corrupt or has the previous sequence number

				while(corrupt(receive_data)||receive_data.sequence_number == prev_sequence){
						//resend the prev_sequence ACK packet 
						printf("CORRUPT OR WRONG SEQUENCE DATA PACKET RECEIVED \n");
						printf("RESENDING PREVIOUS ACK \n\n");

					if(prev_sequence == 0){
						send_packet((char*)&ACK0,sizeof(struct data_packet),s,&si_other,slen);

					}else{
						send_packet((char*)&ACK1,sizeof(struct data_packet),s,&si_other,slen);

					}


					//look for new data from client
					receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
					
				}


				//If the correct sequence data packet was sucessfully received
					if(receive_data.sequence_number == sequence){

						printf("received data%i from client \n", sequence);

					}else{


						printf("ERROR: UNKNOWN DATA RECEIVED \n");
					}


					


				//send the ACK packet to the client
				if(sequence == 0){
						printf("Sending ACK0 to client \n");
						send_packet((char*)&ACK0,sizeof(struct data_packet),s,&si_other,slen);
						
					}else{
						printf("Sending ACK1 to client \n");
						send_packet((char*)&ACK1,sizeof(struct data_packet),s,&si_other,slen);

					}




				//copy data received into array to reorder packets

				memcpy(data_storage[receive_data.packet_number-1], receive_data.data, (DATALEN));

				printf("packet_number = %i \n", receive_data.packet_number);
         
				//print the data received and origin
		 
				printf("\n\n\nReceived packet from %s:%d \n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
			    printf("Data: %s\n\n\n" , receive_data.data);
				bytes_written = bytes_written + DATALEN;




				prev_sequence=sequence;
						sequence++;

					//when sequence number 1 is done go back to sequence number 0
				if(sequence > 1){

					sequence = 0;
				}

				


			}
		

			bytes_written = 0;

			while(bytes_written != header.file_size){

				//copy array into file

					

				for(i=0; i<r; i++){
					bytes_written = bytes_written + DATALEN;
					printf("Writing Packet#: %i \n", i+1);
					if(bytes_written < header.file_size){
						fwrite(data_storage[i],1,DATALEN,fp);
						printf("bytes_written: %i \n",bytes_written);
					}else{
						bytes_written = bytes_written - (DATALEN);
						printf("bytes_written: %i \n",bytes_written);
							
						fwrite(data_storage[i],1,(header.file_size - bytes_written),fp);
							
						printf("PARTIAL PACKET WRITE \n");
						printf("Wrote: %i \n",(header.file_size - bytes_written));
						bytes_written += (header.file_size - bytes_written);
					}
				}
			}


			printf("Receive Done. \n");

		
			printf("header File size = %i \n",header.file_size);

			printf("End of Transmission \n");

			fclose(fp);

			//free data storage array
			for (i=0; i<r; i++){
				free(data_storage[i]);
			}
			free(data_storage);


		}

		if(header.mode != 'y' && header.mode != 'n'){

			printf("HEADER ERROR, invalid mode! \n");
			return 0;
		}

       
   }
 
    closesocket(s);
    WSACleanup();
     
    return 0;
}
Ejemplo n.º 11
0
int main()
{
    SOCKET s;
    struct sockaddr_in server, si_other;
    int slen;
    WSADATA wsa;
	int read_ret;
	int file_length_left;
	int file_length;
	int random;
	int sequence;
	int bytes_written = 0;
	int packet_count = 0;
	int r,c,i,j;
	char **data_storage;
	int GBN_lower;
	int GBN_upper;
	struct data_packet* send_packets;
	FILE* fp;
	int* timers;
	int timeout_indicator;
	int corrupt_status;
	int no_ACK_indicator;
	int dropped_count;
	int start_time;
	



	struct data_packet receive_data;
	struct data_packet send_data;
	struct data_packet ACK;
	struct header_packet header;
	int recv_status;

	//initalize ACK

	memset(ACK.data,'+',DATALEN);
	ACK.packet_number = 0;
	ACK.checksum = data_CSI(ACK);

	

    slen = sizeof(si_other) ;
     
    //Initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");
     
    //Create a socket
    if((s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP)) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }
    printf("Socket created.\n");
     
    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( PORT );
     
    //Bind
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    puts("Bind done \n");
 



    //keep listening for data
    while(1){

		if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_0, sizeof(timeout_0)) == SOCKET_ERROR)
	{
		printf("setsockopt() failed with error code : %d" , WSAGetLastError());
	}

		timeout_indicator = 0;
       bytes_written = 0;
	   packet_count = 0;
	   sequence = 0;
	   
	

		//look for header packet from client to determine send/receive
		

		printf("Waiting for header packet from client...\n");
		
		//wait for header packet
		receive_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
		printf("\n HEADER INFORMATION \n");
		printf("packet number = %i \n",header.packet_number);
		//mode dictates whether the server should send or receive
		printf("mode = %c \n",header.mode);
		printf("File name = %s \n\n",header.file_name);

		//if header packet is corrupt do nothing and wait for sender to resend
		
		while(corrupt_h(header) == 1){
			

				//get a new header packet
				receive_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);
			}
	
		//send ack
		printf("sending header acknowledgement \n");
		ACK.packet_number = packet_count;
		ACK.checksum = data_CSI(ACK);
		send_packet((char*)&ACK,sizeof(struct data_packet),s,&si_other,slen);


		printf("\n HEADER INFORMATION \n");
		printf("packet number = %i \n",header.packet_number);
		//mode dictates whether the server should send or receive
		printf("mode = %c \n",header.mode);
		printf("File size = %i \n",header.file_size);
				
	
	

	
		
				
				
				
		//Server will be sending a file		
				
		if(header.mode == 'n'){

			start_time = clock();
		
			//set socket timeout

			if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_1, sizeof(timeout_1)) == SOCKET_ERROR)
				{
					printf("setsockopt() failed with error code : %d" , WSAGetLastError());
				}
         
			// get file name to be sent from header packet

			fp = fopen(header.file_name,"rb");



			if (fp == NULL) {
				printf("Invalid file name \n");
				exit(EXIT_FAILURE);
			}

			//find length of the file
			fseek(fp, 0L, SEEK_END);
			file_length = ftell(fp);
			file_length_left = file_length;
			rewind(fp);

		
			//make another packet in response to client's (header_packet) to transmit necessary data for file transfer

		

			header.file_size = file_length;
			header.mode = 'n';
			header.packet_number = packet_count;
			header.checksum = header_CSI(header);

			printf("\n HEADER INFORMATION \n");
			printf("packet number = %i \n",header.packet_number);
			//mode dictates whether the server should send or receive
			printf("mode = %c \n",header.mode);
			printf("File size = %i \n\n",header.file_size);


			do {
				//send header packet
				send_packet((char*)&header,sizeof(struct header_packet),s,&si_other,slen);

				//wait for ACK for header
				printf("looking for ACK from client \n");

				//in case of corrupt header packet or corrupt/wrong ACK 
			} while(receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen) == -1 ||
				corrupt(receive_data) || !isACK(receive_data,packet_count));

			//notification for successful recepit of ACK
			if(isACK(receive_data,packet_count) == 1){

				printf("received ACK for header packet from client \n");

			}else{

				printf("ERROR: UNKNOWN DATA RECEIVED \n");
			}


			//calculate number of spaces in array needed to hold all the data packets

					r = ((header.file_size-(header.file_size%(DATALEN)))/(DATALEN));
			
					if((header.file_size%DATALEN)!=0){
					r++;
					}


					//make array to hold all the data packets

				send_packets = (struct data_packet*)malloc(r * sizeof(struct data_packet));
				timers = (int*)malloc(r * sizeof(int));

				GBN_lower = 0;
				



			while(file_length_left > 0){
		
				packet_count++;
				
				memset(send_data.data,'\0', DATALEN);
				send_data.packet_number = packet_count;

				read_ret=fread(send_data.data, 1, DATALEN, fp);
				
				if(read_ret != DATALEN && file_length_left>DATALEN){
					printf("\n ERROR, did not write DATALEN \n");
				}
			
				//compute and store checksum into packet
				send_data.checksum = data_CSI(send_data);

				file_length_left = file_length_left - (DATALEN);
			
				printf("packet number = %i \n",send_data.packet_number);
			
				if(file_length_left > 0){
					printf("file length left: %i \n", file_length_left);
				}else{
					printf("file length left: 0 \n");
				}
			

			

				
				

				send_packets[GBN_lower] = send_data;
				
					GBN_lower++;

				}

				packet_count = 1;

				//send all the data packets
				while( receive_data.packet_number != r ){

					if(packet_count == 1){
						
						GBN_lower = 1;
						GBN_upper = header.window;
						printf("Initalized...GBN_lower = %i and GBN_upper = %i \n", GBN_lower, GBN_upper);
					}


					while(packet_count <= GBN_upper){

						send_data = send_packets[packet_count - 1];
				
						printf("Sending Packet %i \n", packet_count);

						//send the data_packet struct to the server
						send_packet((char*)&send_data,sizeof(struct data_packet),s,&si_other,slen);

						
						timers[packet_count - 1] = (int)clock();

						
						packet_count++;
						

						}

					

					//check to see if any of the timers have expired
					for(i=GBN_lower; i<=GBN_upper; i++){
						if( (clock() - timers[i-1]) > header.timer*CLOCKS_PER_SEC ){
							printf("TIMEOUT DETECTED on packet %i, time = %f \n", i,(float)(clock() - timers[i-1])/(float)CLOCKS_PER_SEC);
							timeout_indicator = 1;
						}
					}


					//if the ACK packet is corrupted throw packet away and get new one from socket
					//if the timer for a certain ACK expires resend whole window


						if(timeout_indicator == 1){
							printf("TIMEOUT DETECTED: RESENDING WINDOW\n");

							packet_count = GBN_lower;


							while(packet_count <= GBN_upper){

								send_data = send_packets[packet_count - 1];


								printf("Timeout: Sending Packet %i \n", packet_count);
					
								
								
								
								//send the data_packet struct to the server
								send_packet((char*)&send_data,sizeof(struct data_packet),s,&si_other,slen);
								

								timers[packet_count - 1] = (int)clock();

								packet_count++;

								
							}



						}


						timeout_indicator = 0;


						recv_status=0;
						i=0;
						
						//pull as many ACKs off of the socket as possible and process
					while(recv_status != -1){
						
						

						


						//look for ACK from the server
						recv_status = receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);

					
					

						//intentionally corrupt the received ACK packet if user selected
						if(header.intentional_corruption == 'A'){

							random = rand() % 100;
							//randomly choose ACK packets and invalidate the sequence number

							if(random <= header.corruption && receive_data.packet_number != GBN_upper){
							receive_data.packet_number = 0;
							}

						}

						if(recv_status == -1 && i == 0 && corrupt_status < 2 && no_ACK_indicator < 1 ){
							printf("received no ACK from the server \n");
							no_ACK_indicator++;
						}
						
						if(recv_status > 0){
							printf("received ACK%i from server \n", receive_data.packet_number);
						}

						

						if(corrupt(receive_data)){
							
							
							if(corrupt_status == 0){
							printf("CORRUPT ACK PACKET RECEIVED \n");
							printf("corrupt = %i, sequence = %i \n", corrupt(receive_data), receive_data.packet_number);
							printf("Threw away, looking for new ACK packet \n");
							}
						
							

							corrupt_status++;

						}


							//ACK all packets equal to and less than the ACK# (cumulative ACK)
							//and don't slide the window longer than the bytes in the file
						if( receive_data.packet_number >= GBN_lower && GBN_upper < r){

							GBN_lower = receive_data.packet_number+1;
							GBN_upper = GBN_lower+(header.window-1);

							if(GBN_upper > r){
								GBN_upper = r;
							}
							printf(" GBN_lower = %i, GBN_upper = %i \n", GBN_lower, GBN_upper);
						
							corrupt_status = 0;
							no_ACK_indicator = 0;
							dropped_count = 0;
						}
						
						i++;

					}

					if(corrupt_status < 2 && no_ACK_indicator < 1)
						printf("\n\n\n\n");


				}
		
				free(timers);
				free(send_packets);
				printf("The transfer took %f seconds \n", (float)(clock()-start_time)/(float)CLOCKS_PER_SEC);

			}
		
	
		
		




		//server will receive a file
		
		if(header.mode == 'y'){

			//set socket timeout to zero

			if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_0, sizeof(timeout_0)) == SOCKET_ERROR)
			{
			printf("setsockopt() failed with error code : %d" , WSAGetLastError());
			}
		

			//Allocate array to hold data for packet reordering

			//calculate rows and columns of array
			r = ((header.file_size-(header.file_size%(DATALEN)))/(DATALEN));
			
			if((header.file_size%DATALEN)!=0){
				r++;
			}
				
			c = DATALEN;

			data_storage = (char **)malloc(r * sizeof(char*));
			
			for (i=0; i<r; i++){
				data_storage[i] = (char *)malloc(c * sizeof(char));
			}
	
			//initalize array
			for (i = 0; i <  r; i++)
				for (j = 0; j < c; j++)
					data_storage[i][j] = '+';
		
		
			fp = fopen(header.file_name,"wb");


			printf("Waiting for data...\n");
			fflush(stdout);
         
        
		
			
       

			//try to receive some data, stop when you recieve all the data which the file contains

			while(bytes_written < header.file_size){

				sequence++;


				//clear out the buffer each time to eliminate extraneous data on the last packet
				memset(receive_data.data,0xFF, DATALEN);

				//look for data from client
				receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);


				//intentionally corrupt data packet if user selected
				if(header.intentional_corruption == 'B'){

					random = rand() % 100;
						//randomly choose data packets and invalidate the sequence number

					if(random <= header.corruption){
						receive_data.packet_number = 0;
						}


				}

				//if data is corrupt or has some sequence number other than expected resend previous ACK

				while(corrupt(receive_data)||receive_data.packet_number != sequence){
						
						printf("CORRUPT OR WRONG SEQUENCE DATA PACKET RECEIVED, packet = %i, sequence = %i \n",receive_data.packet_number,sequence);
						printf("RESENDING ACK FOR LAST PACKET \n\n");


						ACK.packet_number = sequence-1;
						ACK.checksum = data_CSI(ACK);
						printf("Sending ACK %i to client \n", sequence-1);
						send_packet((char*)&ACK,sizeof(struct data_packet),s,&si_other,slen);

					
					//look for new data from client
					receive_packet((char*)&receive_data,sizeof(struct data_packet),s,&si_other,slen);
					
				}


				//If the correct sequence data packet was sucessfully received
					if(receive_data.packet_number == sequence){

						printf("received data%i from client \n", sequence);

					}else{


						printf("ERROR: UNKNOWN DATA RECEIVED \n");
					}


					


				//send the ACK packet to the client
						ACK.packet_number = sequence;
						ACK.checksum = data_CSI(ACK);
						printf("Sending ACK %i to client \n", sequence);
						send_packet((char*)&ACK,sizeof(struct data_packet),s,&si_other,slen);
						
					




				//copy data received into array to reorder packets

				memcpy(data_storage[receive_data.packet_number-1], receive_data.data, (DATALEN));

				printf("packet_number = %i \n", receive_data.packet_number);
         
				//print the data received and origin
		 
				printf("\n\n\nReceived packet from %s:%d \n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
			    printf("Data: %s\n\n\n" , receive_data.data);
				bytes_written = bytes_written + DATALEN;






			}
		

			bytes_written = 0;

			while(bytes_written != header.file_size){

				//copy array into file

					

				for(i=0; i<r; i++){
					bytes_written = bytes_written + DATALEN;
					printf("Writing Packet#: %i \n", i+1);
					if(bytes_written < header.file_size){
						fwrite(data_storage[i],1,DATALEN,fp);
						printf("bytes_written: %i \n",bytes_written);
					}else{
						bytes_written = bytes_written - (DATALEN);
						printf("bytes_written: %i \n",bytes_written);
							
						fwrite(data_storage[i],1,(header.file_size - bytes_written),fp);
							
						printf("PARTIAL PACKET WRITE \n");
						printf("Wrote: %i \n",(header.file_size - bytes_written));
						bytes_written += (header.file_size - bytes_written);
					}
				}
			}


			printf("Receive Done. \n");

		
			printf("header File size = %i \n",header.file_size);

			printf("End of Transmission \n");

			fclose(fp);

			//free data storage array
			for (i=0; i<r; i++){
				free(data_storage[i]);
			}
			free(data_storage);


		}

		if(header.mode != 'y' && header.mode != 'n'){

			printf("HEADER ERROR, invalid mode! \n");
			return 0;
		}

       
   }
 
    closesocket(s);
    WSACleanup();
     
    return 0;
}