Пример #1
0
void
rel_timer ()
{

    /* Iterate over all the reliable connections */

    rel_t *r;
    for (r = rel_list; r != NULL; r = r->next) {

        /* Poke the output, just in case it died on us */

        rel_output(r);
    
        /* Send window is [head of buffer queue, head of buffer queue + window size],
         * so we iterate over the send window, and send anything that's timed out. */

        int i = 0;
        for (i = bq_get_head_seq(r->send_bq); rel_seqno_in_send_window(r,i); i++) {

            /* This is just a safety check, in case we haven't read in this part
             * of the send window yet */

            if (!bq_element_buffered(r->send_bq, i)) continue;

            /* Borrowed need_timer_in from rlib: just checks whether it's
             * been r->timeout ms since elem->time_sent */

            send_bq_element_t *elem = bq_get_element(r->send_bq, i);
            if (need_timer_in (&(elem->time_sent), r->timeout) == 0) {
                rel_send_buffered_pkt(r,elem);
            }
        }
    }
}
Пример #2
0
void
rel_recvpkt (rel_t *r, packet_t *pkt, size_t n)
{
    assert(r);
    assert(pkt);
    assert(n >= 0);

    if (!rel_packet_valid(pkt,n)) return;

    /* Do all the endinannness in one place */

    pkt->len = ntohs(pkt->len);
    pkt->seqno = ntohl(pkt->seqno);
    pkt->ackno = ntohl(pkt->ackno);

    /* Read ack nums on all packets, regardless of data or
     * ack. */

    if (rel_recv_ack (r, pkt->ackno)) {

        /* A return of 1 means that that ack was enough for
         * us to close the connection, so our rel_t has been
         * destroyed. Time to quit. */

        return;
    }

    /* Insert all data packets into the read buffer for
     * when we get some space for output. */

    if (n > 8) {
        bq_insert_at(r->rec_bq, pkt->seqno, pkt);

        /* Print try to print the output. If this returns
         * 0, it means that no new ack could be sent, so
         * we should send a duplicate ack, just in case the
         * last one was lost (even though it serves no congestion
         * control purpose in this lab). */

        if (!rel_output(r)) {
            rel_send_ack(r, r->ackno);
        }
    }
}
Пример #3
0
void
rel_recvpkt (rel_t *r, packet_t *pkt, size_t n)
{
  //fprintf(stderr, "\n******************receive!********************\n");
  if (!check_valid(pkt, n)) return;
  //fprintf(stderr, "\n******************pass check!********************\n");
  int i = 0;
  if (ntohs(pkt->len) == 8) {
    // sender side
    // receive ack 
    //fprintf(stderr, "\n******************Receive Ack ack:%d, LAR:%d!********************\n", ntohl(pkt->ackno), r->LAR);
    if (ntohl(pkt->ackno) > r->LAR) {
      for (i=r->LAR; i<ntohl(pkt->ackno); i++) {
        r->sendState[i% r->window_size] = 1; // got ack
      }
      r->LAR = ntohl(pkt->ackno) - 1;
      if (r->SEND_EOF) {
        // receive ack of eof
        r->EOF_ACKED = true;
      }
      rel_read(r);
    }
  } else if (ntohs(pkt->len) >= 12) {
    // receiver side
    if (recv_check(r, pkt)) {
      if (ntohl(pkt->seqno) == r->LSR+1) {
        // right seqno, output buffer and change LSR, LAS and recvState
        if (ntohs(pkt->len) == 12) {
          // receive EOF 
          r->RECV_EOF = true; 
        } 
        addPktToRWindow(r, pkt); // add to buffer first 
        rel_output(r);
      } else if (ntohl(pkt->seqno) <= r->LSR) {
        // old seqno, send current ack
        send_ack(r);
      } else {
        addPktToRWindow(r, pkt); // add to buffer
      }
    } else {
      send_ack(r);
    }
  }
}
Пример #4
0
void processData (rel_t *r, packet_t *pkt, int length){
	if ( r->beginTime.tv_sec == 0 && r->beginTime.tv_usec == 0 ) {
		gettimeofday(&r->beginTime, NULL);
	}
	if (ntohl(pkt->seqno) >= 1) {
		packetQueue* newPkt = new_packet();
		memcpy(newPkt->packet, pkt, length);
		if (ntohl(pkt->seqno) == r->seqIn) {
			r->seqIn = r->seqIn + 1;
		}
		ack(r, r->seqIn);
		processAck(r, (struct ack_packet*) pkt);
		orderlyInsert(&(r->receiverBuff), newPkt);
		if (length == 16) {
			fprintf(stderr, "GET EOF\n");
			r->pairEOFed = 1;
		}
		rel_output(r);
	}
	else{
		fprintf(stderr, " wrong seqno %d \n", ntohl(pkt->seqno));
		return;
	}
}
Пример #5
0
void rel_recvpkt(rel_t *r, packet_t *pkt, size_t n) {

	// Compare checksums to detect packet corruption
	int checksum = pkt->cksum;
	pkt->cksum = 0;
	int compare_checksum = cksum(pkt, ntohs(pkt->len));
	convertPacketFromNetworkByteOrder(pkt);
	if (compare_checksum != checksum) {
		return;
	}

	r->receiver.packet = *pkt;

	// CASE 1: ACK packet
	if (pkt->len == ACK_PACKET_HEADER) {
		int index = pkt->ackno;
		r->senderWindowBuffer[index-1].acknowledged = 1;

		//make sure to acknowledge everything below the most recent ackno
		int i;
		for (i = 0; i < index; i++) {
			r->senderWindowBuffer[i].acknowledged = 1;
		}

		//move the sender's buffer position pointer
		if (pkt->ackno > r->sender.buffer_position) {
			r->sender.buffer_position = pkt->ackno;
		}
	}

	// CASE 2: DATA packet
	if (pkt->len >= DATA_PACKET_HEADER) {

		// You are getting duplicate packets by nature of cumulative ack
		if (r->receiverWindowBuffer[pkt->seqno].isFull == 1) {
			/* If the seqno of packet is less than the max ack the receiver has sent
			 * that means an ack to the sender was dropped. Retransmit.
			 */
			if (pkt->seqno < r->receiver.max_ack) {
				retransmit_ack(r, r->receiver.max_ack);
			}
			return;
		}

		// Alerting the user when the receiver's window buffer is full.
		if (pkt->seqno >= r->windowSize + r->receiver.buffer_position) {
			return;
		}

		// Clear out the old data from the packet buffer
		int j;
		int start = pkt->len - DATA_PACKET_HEADER;
		for (j = start; j < MAX_DATA_SIZE; j++) {
			pkt->data[j] = '\0';
		}

		// Prepare a copy of the packet for the receiver's buffer
		packet_t *receivingPacketCopy = malloc(sizeof (struct packet));
		memcpy(receivingPacketCopy, pkt, sizeof (struct packet));
		struct WindowBuffer *packetBuffer = malloc(sizeof(struct WindowBuffer));
		packetBuffer->isFull = 1;
		packetBuffer->ptr = receivingPacketCopy;
		packetBuffer->timeStamp = timestamp;

		r->receiverWindowBuffer[pkt->seqno] = *packetBuffer;

		/* when you receive the correct seqno you have been expecting,
		 * recompute what the new ack should be */
		if (r->receiver.last_frame_received == pkt->seqno) {
			r->receiver.last_frame_received = compute_LFR(r);
		}

		rel_output(r);

		if (r->receiver.last_frame_received > r->receiver.max_ack) {
			r->receiver.max_ack = r->receiver.last_frame_received;
		}

		// method for transmit or retransmit ack is the same..
		retransmit_ack(r, r->receiver.last_frame_received);
	}
}
Пример #6
0
void
rel_recvpkt (rel_t *r, packet_t *pkt, size_t n)
{
  // printf("rel_recvpkt\n");

  uint16_t len = ntohs(pkt->len);
  uint32_t ackno = ntohl(pkt->ackno);

  int verified = verifyChecksum(r, pkt, n);
  if (!verified || (len != n)) { // Drop packets with bad length
    // fprintf(stderr, "Packet w/ sequence number %d dropped\n", ntohl(pkt->seqno));
    return;
  }

  if (len == ACK_PACKET_SIZE) { // Received packet is an ack packet
    // fprintf(stderr, "Received ack number: %d\n", ackno);
    // fprintf(stderr, "%s\n", "======================RECEIVED ACK  PACKET=========================");
    if (ackno <= r->LAST_PACKET_ACKED + 1) { // Drop duplicate acks
      // fprintf(stderr, "Duplicate ack: %d received\n", ackno);
      return;
    }

    if (ackno == r->LAST_ACK_RECVD) {
      r->LAST_ACK_COUNT++;
    }
    else {
      r->LAST_ACK_RECVD = ackno;
      r->LAST_ACK_COUNT = 1;
    }

    if (r->slowStart) {
      // fprintf(stderr, "window size: %d\n", r->windowSize);
      if (r->windowSize * 2 > r->ssThresh) {
        // START AIMD
        // return;
      } else {
        r->windowSize = r->windowSize * 2;
      }
      // fprintf(stderr, "success? %d\n", r->windowSize);
    } 
    else {
      if (r->windowSize + 1 == r->ssThresh) {

      } else {
        r->windowSize = r->windowSize + 1;
      }
    }

    shiftSentPacketList(r, ackno);

    r->LAST_PACKET_ACKED = ackno - 1;

    rel_read(r);
  }
  else { // data packet
    // fprintf(stderr, "%s\n", "======================RECEIVED DATA PACKET=========================");
    uint32_t seqno = ntohl(pkt->seqno);

    // fprintf(stderr, "Received Data: %s\n", pkt->data);

    // fprintf(stderr, "Received data: %s\n", pkt->data);


    // if (seqno > r->NEXT_PACKET_EXPECTED) {
    //   // Ghetto fix
    //   return;
    // }

    if (seqno < r->NEXT_PACKET_EXPECTED) { // duplicate packet
      // fprintf(stderr, "Received duplicate packet w/ sequence number: %d\n", seqno);
      struct ack_packet *ack = createAckPacket(r, r->NEXT_PACKET_EXPECTED);
      conn_sendpkt(r->c, (packet_t *)ack, ACK_PACKET_SIZE);
      free(ack);
      return;
    }

    if (seqno - r->NEXT_PACKET_EXPECTED > r->windowSize) {  // Packet outside window
      return;
    }

    // fprintf(stderr, "Received sequence number: %d\n", seqno);

    int slot = seqno - r->NEXT_PACKET_EXPECTED;
    // fprintf(stderr, "RecvPacket slot number: %d\n", slot);
    memcpy(r->recvPackets[slot]->packet, pkt, sizeof(packet_t));
    r->recvPackets[slot]->sentTime = getCurrentTime();
    r->recvPackets[slot]->acked = 1;

    rel_output(r);

    // if (seqno == r->NEXT_PACKET_EXPECTED) {
    //   struct ack_packet *ack = createAckPacket(r, r->NEXT_PACKET_EXPECTED + 1);

    //   conn_sendpkt(r->c, (packet_t *)ack, ACK_PACKET_SIZE);
    //   conn_output(r->c, pkt->data, len - HEADER_SIZE);
    //   // rel_output(r);
    //   r->NEXT_PACKET_EXPECTED++;
    //   free(ack);
    // }

  }
}
Пример #7
0
void
rel_recvpkt (rel_t *r, packet_t *pkt, size_t n)
{
  uint16_t len = ntohs(pkt->len);
  uint32_t ackno = ntohl(pkt->ackno);

  int verified = verifyChecksum(r, pkt, n);
  if (!verified || (len != n)) { // Drop packets with bad length
    fprintf(stderr, "Packet w/ sequence number %d dropped\n", ntohl(pkt->seqno));
    return;
  }

  if (len == ACK_PACKET_SIZE) { // Received packet is an ack packet
    fprintf(stderr, "Received ack number: %d\n", ackno);
    if (ackno <= r->LAST_PACKET_ACKED + 1) { // Drop duplicate acks
      fprintf(stderr, "Duplicate ack: %d received\n", ackno);
      return;
    }

    //if (ackno == r->LAST_PACKET_SENT + 1) { // REMOVE THIS AFTER WE FIX ACK SENDING!!!!
      shiftSentPacketList(r, ackno);

      r->LAST_PACKET_ACKED = ackno - 1;

      rel_read(r);
    //}
  }
  else { // data packet
    fprintf(stderr, "%s\n", "======================RECEIVED DATA PACKET=========================");
    uint32_t seqno = ntohl(pkt->seqno);

    // fprintf(stderr, "Received data: %s\n", pkt->data);


    // if (seqno > r->NEXT_PACKET_EXPECTED) {
    //   // Ghetto fix
    //   return;
    // }

    if (seqno < r->NEXT_PACKET_EXPECTED) { // duplicate packet
      fprintf(stderr, "Received duplicate packet w/ sequence number: %d\n", seqno);
      struct ack_packet *ack = createAckPacket(r, r->NEXT_PACKET_EXPECTED);
      conn_sendpkt(r->c, (packet_t *)ack, ACK_PACKET_SIZE);
      free(ack);
      return;
    }

    if (seqno - r->NEXT_PACKET_EXPECTED > r->windowSize) {  // Packet outside window
      return;
    }

    fprintf(stderr, "Received sequence number: %d\n", seqno);

    int slot = seqno - r->NEXT_PACKET_EXPECTED;
    fprintf(stderr, "RecvPacket slot number: %d\n", slot);
    memcpy(r->recvPackets[slot]->packet, pkt, sizeof(packet_t));
    r->recvPackets[slot]->sentTime = getCurrentTime();
    r->recvPackets[slot]->acked = 1;

    rel_output(r);

    // if (seqno == r->NEXT_PACKET_EXPECTED) {
    //   struct ack_packet *ack = createAckPacket(r, r->NEXT_PACKET_EXPECTED + 1);

    //   conn_sendpkt(r->c, (packet_t *)ack, ACK_PACKET_SIZE);
    //   conn_output(r->c, pkt->data, len - HEADER_SIZE);
    //   // rel_output(r);
    //   r->NEXT_PACKET_EXPECTED++;
    //   free(ack);
    // }

  }
}