void rel_output (rel_t *r) { if (r->outputEOF) { return; } int buff = conn_bufspace(r->c); int dataOut = 0; while (outputCheck (r, dataOut, buff)) { int currentOut = ntohs(r->receiverBuff->packet->len) - 16 - r->recvBuffOffset; if (currentOut == 0 || currentOut < 0) { break; } if (buff > dataOut + currentOut) { char* start_of_data = r->receiverBuff->packet->data + r->recvBuffOffset; conn_output(r->c, start_of_data, currentOut); dequeue(&r->receiverBuff); dataOut += currentOut; } else{ currentOut = buff - dataOut; char* start_of_data = r->receiverBuff->packet->data + r->recvBuffOffset; conn_output(r->c, start_of_data, currentOut); r->recvBuffOffset += currentOut; dataOut += currentOut; } } }
void rel_output (rel_t *r) { // printf("rel_output\n"); int numPacketsInWindow = r->LAST_PACKET_SENT - r->LAST_PACKET_ACKED; int i; // fprintf(stderr, "lastpacksent: %d, lackPackacked: %d\n", r->LAST_PACKET_SENT, r->LAST_PACKET_ACKED); for (i = 0; i < r->windowSize; i++) { // fprintf(stderr, "Recvpacket of %d has ack %d\n", i, r->recvPackets[i]->acked); if(r->recvPackets[i]->acked == 0) { break; } packet_t *pkt = r->recvPackets[i]->packet; uint16_t packet_len = ntohs(pkt->len); size_t len = conn_bufspace(r->c); // fprintf(stderr, "Packet len: %d\n", (int) packet_len); if(len >= packet_len - HEADER_SIZE) { if(packet_len == HEADER_SIZE) { r->eofRecv = 1; } // fprintf(stderr, "Outputting packet %d from recvPackets \n", i); conn_output(r->c, pkt->data, packet_len - HEADER_SIZE); r->recvPackets[i]->acked = 0; } else { break; } } // fprintf(stderr, "value of i: %d\n", i); // fprintf(stderr, "Next Packet Expected Before: %d\n", r->NEXT_PACKET_EXPECTED ); r->NEXT_PACKET_EXPECTED += i; struct ack_packet *ack = createAckPacket(r, r->NEXT_PACKET_EXPECTED); // fprintf(stderr, "Next Packet Expected: %d\n", r->NEXT_PACKET_EXPECTED); conn_sendpkt(r->c, (packet_t *)ack, ACK_PACKET_SIZE); free(ack); // fprintf(stderr, "reloutput -- numPackets: %d, eofRecv: %d, eofSend: %d\n", numPacketsInWindow, r->eofRecv, r->eofSent); if(numPacketsInWindow == 0 && r->eofRecv == 1 && r->eofSent == 1) { rel_destroy(r); return; } shiftRecvPacketList(r); }
bool processEOF(rel_t* rel) { if (rel && (rel->receiverBuff) && (rel->receiverBuff->packet)) { if (ntohs(rel->receiverBuff->packet->len) == 16) { rel->outputEOF = 1; conn_output(rel->c, NULL, 0); if (rel->c->sender_receiver == RECEIVER) { rel_destroy(rel); return true; } if (rel->pairEOFed && rel->inputEOF && rel->noMoreAck && rel->outputEOF) { fprintf(stderr, "rel_destroy\n"); rel_destroy(rel); } return true; } return false; } return false; }
void rel_output(rel_t *r) { int i; int shift = r->receiver.buffer_position; for (i = shift; i < r->windowSize + shift; i++) { if (r->receiverWindowBuffer[i].isFull == 0) { return; } if (r->receiverWindowBuffer[i].isFull == 1) { if (r->receiverWindowBuffer[i].outputted == 0) { int availableSpace = conn_bufspace(r->c); struct WindowBuffer *packet = malloc(sizeof(struct WindowBuffer)); packet = &r->receiverWindowBuffer[i]; if (availableSpace >= packet->ptr->len) { conn_output(r->c, packet->ptr->data, packet->ptr->len); r->receiver.buffer_position++; r->receiverWindowBuffer[i].outputted = 1; } } } } }
void rel_output (rel_t *r) { size_t left = conn_bufspace(r->c); int index = (r->LSR + 1) % r->window_size; packet_t * cur = &r->recvWindow[index]; int data_len = ntohs(cur->len) - 12; while ((uint16_t)left >= data_len) { conn_output (r->c, cur->data, data_len); r->recvState[index] = 2; r->LSR ++ ; r->LAS = r->LSR + r->RWS; index = (r->LSR + 1) % r->window_size; if (r->recvState[index] == 1) { cur = &r->recvWindow[index]; } else { break; } data_len = ntohs(cur->len) - 12; left = conn_bufspace(r->c); } send_ack(r); }
int rel_output (rel_t *r) { assert(r); int sent_ack = 0; /* If we've already printed an EOF, then we're done. */ if (r->printed_eof) return 0; while (1) { /* Read from the head of the received packets buffer queue, * if we have any received packets waiting */ int rec_seqno = bq_get_head_seq(r->rec_bq); if (!bq_element_buffered(r->rec_bq, rec_seqno)) break; packet_t *pkt = bq_get_element(r->rec_bq, rec_seqno); int bufspace = conn_bufspace(r->c); /* Print the whole packet, then ack */ if (bufspace > pkt->len-12) { conn_output(r->c, pkt->data, pkt->len-12); bq_increase_head_seq_to(r->rec_bq, rec_seqno + 1); sent_ack = pkt->seqno + 1; /* If we just printed out an EOF, update our status */ if (pkt->len == 12) { r->printed_eof = 1; /* If we just printed an EOF, we should be done. */ break; } } /* Edge case: only enough buffer to print part of the packet */ else if (bufspace > 0) { conn_output(r->c, pkt->data, bufspace); /* Shift the packet data over, removing what we've already printed */ memcpy(&(pkt->data[0]), &(pkt->data[bufspace]), pkt->len - bufspace); pkt->len -= bufspace; break; } /* If we have no buffer space left, time to quit */ else if (bufspace == 0) break; } if (sent_ack != 0) rel_send_ack(r, sent_ack); /* We could have just printed an eof, so just in case, * we should try destroying the rel_t. If we do, we return * 1 to prevent our caller from producing a redundant ack. */ if (rel_check_finished(r)) return 1; return sent_ack; }