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