41 #pragma warning(disable:4355) 51 #define TCP_HEADERLENGTH 40 55 #define TCP_VERSION kReno 57 #define TCP_INITIALCWNDREL 2 // related to MSS 58 #define TCP_INITIALSSTHRESHREL 1 // related to MaxCWnd 59 #define TCP_MAXCWNDREL 32 // related to MSS 61 #define TCP_INITIALRTT 1 62 const double TCP_STIMERGRAN = 0.2;
63 const double TCP_SWSATIMERVALUE = 0.2;
64 #define TCP_MAXBACKOFF 64 66 #define TCP_IMMEDIATEBACKOFFRESET false 67 #define TCP_TIMESTAMPS false 69 #define TCP_NAGLE false 70 #define TCP_GOBACKN true 71 #define TCP_FLIGHTSIZERECOVERY false 72 #define TCP_RENOCONSERVATION true 73 #define TCP_CAREFULSSTHRESHREDUCTION true 74 #define TCP_IGNOREDUPACKONTORECOVERY true 75 #define TCP_CAREFULMULFASTRTXAVOIDANCE true 76 #define TCP_RESTARTAFTERIDLE true 82 #define TCP_DELAYEDACK true 83 const double TCP_ACKDELAYTIME = 0.2;
84 #define TCP_SENDPERIODICACKS false 85 #define TCP_STRICTPERIODICACKS false 86 #define TCP_PERIODICACKINTERVAL 1 87 #define TCP_ACKSCHEDULINGDELAY 0 88 #define TCP_ACKBUFFERWRITE false 89 #define TCP_ACKBUFFERREAD true 91 #define TCP_MINUSERBLOCKSIZE 1 92 #define TCP_USERBLOCKPROCDELAY 0 96 #define TCPGEN_BLOCKSIZE 1460 100 #define TCPAPP_MAXNOOFACTIVEAPPS 500 101 #define TCPAPP_DISTSTATARRAYSIZE 100 102 #define TCPAPP_DISTSTATMAXGOODPUT 1000 103 #define TCPAPP_DISTSTATMAXTRANSFERTIME 10000 104 #define TCPAPP_CONDMEANSTATARRAYSIZE 100 105 #define TCPAPP_CONDMEANSTATMAXREQSIZE 100000 109 inline int min(
int opd1,
int opd2)
111 return (opd1 < opd2) ? opd1 : opd2;
115 inline int max(
int opd1,
int opd2)
117 return (opd1 > opd2) ? opd1 : opd2;
123 inline double round(
const double value,
const double granularity)
125 return (
std::ceil(value / granularity) * granularity);
136 TCP_Segment::TCP_Segment(
const Sequence_Number &sn_begin,
const Sequence_Number &sn_end) :
140 it_assert(seq_begin <= seq_end,
"TCP_Segment::TCP_Segment, end byte " +
to_str(seq_end.value()) +
141 " < begin byte " +
to_str(seq_begin.value()));
145 TCP_Segment::TCP_Segment(
const TCP_Segment &segment) :
146 seq_begin(segment.seq_begin),
147 seq_end(segment.seq_end)
152 TCP_Segment &TCP_Segment::operator=(
const TCP_Segment &segment)
154 this->seq_begin = segment.seq_begin;
155 this->seq_end = segment.seq_end;
161 void TCP_Segment::combine(
const TCP_Segment &segment)
163 it_assert(can_be_combined(segment),
"TCP_Segment::CombineWith, segments cannot be combined");
165 seq_begin =
min(seq_begin, segment.seq_begin);
166 seq_end =
max(seq_end, segment.seq_end);
170 std::ostream &
operator<<(std::ostream &os,
const TCP_Segment &segment)
172 os <<
"(" << segment.seq_begin <<
"," << segment.seq_end <<
")";
178 TCP_Packet::TCP_Packet() :
188 TCP_Packet::TCP_Packet(
const TCP_Packet &packet) :
189 fSegment(packet.fSegment),
192 fSessionId(packet.fSessionId),
195 std::cout <<
"TCP_Packet::TCP_Packet ############" <<
" ";
197 if (packet.fInfo != 0) {
198 std::cout <<
"TCP_Packet::TCP_Packet rhs.fInfo ###########" <<
" ";
199 fInfo =
new TDebugInfo(*packet.fInfo);
204 TCP_Packet::~TCP_Packet()
210 TCP_Packet & TCP_Packet::clone()
const 212 return *
new TCP_Packet(*
this);
216 void TCP_Packet::set_info(
unsigned ssThresh,
unsigned recWnd,
unsigned cWnd,
217 double estRTT, Sequence_Number sndUna,
218 Sequence_Number sndNxt,
bool isRtx)
221 fInfo =
new TDebugInfo;
224 fInfo->fSSThresh = ssThresh;
225 fInfo->fRecWnd = recWnd;
227 fInfo->fRTTEstimate = estRTT;
228 fInfo->fSndUna = sndUna;
229 fInfo->fSndNxt = sndNxt;
230 fInfo->fRtxFlag = isRtx;
234 void TCP_Packet::print_header(std::ostream &)
const 236 std::cout <<
"Hello!\n";
238 std::cout <<
"Ses = " << get_session_id() <<
" ";
240 std::cout <<
"Segment = " << get_segment() <<
" " 241 <<
"ACK = " << get_ACK() <<
" " 242 <<
"Wnd = " << get_wnd() <<
" ";
244 std::cout <<
"DestPort = " << fDestinationPort <<
" " 245 <<
"SourcePort = " << fSourcePort <<
" ";
249 std::cout <<
"SndSSThresh = " << fInfo->fSSThresh <<
" ";
250 std::cout <<
"RecWnd = " << fInfo->fRecWnd <<
" ";
251 std::cout <<
"SndCWnd = " << fInfo->fCWnd <<
" ";
252 std::cout <<
"RTTEstimate = " << fInfo->fRTTEstimate <<
" ";
253 std::cout <<
"RtxFlag = " << fInfo->fRtxFlag;
256 std::cout <<
"fInfo = " << fInfo <<
" ";
258 std::cout << std::endl;
264 std::ostream &
operator<<(std::ostream & out, TCP_Packet & msg)
266 msg.print_header(out);
272 TCP_Sender::TCP_Sender(
int label) :
274 fTCPVersion(TCP_VERSION),
276 fTCPIPHeaderLength(TCP_HEADERLENGTH),
277 fInitialRTT(TCP_INITIALRTT),
281 fDupACKThreshold(TCP_DUPACKS),
282 fTimerGranularity(TCP_STIMERGRAN),
284 fMaxBackoff(TCP_MAXBACKOFF),
285 fImmediateBackoffReset(TCP_IMMEDIATEBACKOFFRESET),
287 fGoBackN(TCP_GOBACKN),
288 fFlightSizeRecovery(TCP_FLIGHTSIZERECOVERY),
289 fRenoConservation(TCP_RENOCONSERVATION),
290 fCarefulSSThreshReduction(TCP_CAREFULSSTHRESHREDUCTION),
291 fIgnoreDupACKOnTORecovery(TCP_IGNOREDUPACKONTORECOVERY),
292 fCarefulMulFastRtxAvoidance(TCP_CAREFULMULFASTRTXAVOIDANCE),
294 fSWSATimerValue(TCP_SWSATIMERVALUE),
295 fRestartAfterIdle(TCP_RESTARTAFTERIDLE),
299 fRtxTimer(*this, &TCP_Sender::HandleRtxTimeout),
300 fSWSATimer(*this, &TCP_Sender::HandleSWSATimeout)
305 fMaxCWnd = (unsigned)(TCP_MAXCWNDREL * fMSS);
307 else if (fMaxCWnd < fMSS) {
312 if (fInitialCWnd == 0) {
313 fInitialCWnd = (unsigned)(TCP_INITIALCWNDREL * fMSS);
315 else if ((fInitialCWnd < fMSS) || (fInitialCWnd > fMaxCWnd)) {
320 if ((fInitialSSThresh == 0) && (fMaxCWnd >= 2 * fMSS)) {
321 fInitialSSThresh = (unsigned)(TCP_INITIALSSTHRESHREL * fMaxCWnd);
323 else if ((fInitialSSThresh < 2*fMSS) || (fInitialCWnd > fMaxCWnd)) {
333 tcp_send.set_name(
"TCP Send");
334 tcp_receive_ack.forward(
this, &TCP_Sender::ReceiveMessageFromNet);
335 tcp_receive_ack.set_name(
"TCP ACK");
336 tcp_socket_write.forward(
this, &TCP_Sender::HandleUserMessageIndication);
337 tcp_socket_write.set_name(
"SocketWrite");
338 tcp_release.forward(
this, &TCP_Sender::release);
339 tcp_release.set_name(
"Release");
344 TCP_Sender::~TCP_Sender()
348 void TCP_Sender::set_debug(
const bool enable_debug)
350 fDebug = enable_debug;
351 tcp_send.set_debug(enable_debug);
354 void TCP_Sender::set_debug(
bool enable_debug,
bool enable_signal_debug)
356 fDebug = enable_debug;
357 tcp_send.set_debug(enable_signal_debug);
360 void TCP_Sender::set_trace(
const bool enable_trace)
362 fTrace = enable_trace;
365 void TCP_Sender::set_label(
int label)
370 void TCP_Sender::setup()
378 fCWnd = fInitialCWnd;
379 fSSThresh = fInitialSSThresh;
386 fPendingBackoffReset =
false;
387 fLastSendTime = Event_Queue::now();
393 fRTTEstimate = fInitialRTT;
394 fRTTMPending =
false;
397 CWnd_val.set_size(1000);
399 CWnd_time.set_size(1000);
401 CWnd_val(0) = fInitialCWnd;
405 SSThresh_val.set_size(1000);
406 SSThresh_val.zeros();
407 SSThresh_time.set_size(1000);
408 SSThresh_time.zeros();
409 SSThresh_val(0) = fInitialSSThresh;
410 SSThresh_time(0) = 0;
413 sent_seq_num_val.set_size(1000);
414 sent_seq_num_val.zeros();
415 sent_seq_num_time.set_size(1000);
416 sent_seq_num_time.zeros();
417 sent_seq_num_val(0) = 0;
418 sent_seq_num_time(0) = 0;
419 sent_seq_num_index = 1;
421 sender_recv_ack_seq_num_val.set_size(1000);
422 sender_recv_ack_seq_num_val.zeros();
423 sender_recv_ack_seq_num_time.set_size(1000);
424 sender_recv_ack_seq_num_time.zeros();
425 sender_recv_ack_seq_num_val(0) = 0;
426 sender_recv_ack_seq_num_time(0) = 0;
427 sender_recv_ack_seq_num_index = 1;
429 RTTEstimate_val.set_size(1000);
430 RTTEstimate_val.zeros();
431 RTTEstimate_time.set_size(1000);
432 RTTEstimate_time.zeros();
433 RTTEstimate_val(0) = fInitialRTT;
434 RTTEstimate_time(0) = 0;
435 RTTEstimate_index = 1;
437 RTTsample_val.set_size(1000);
438 RTTsample_val.zeros();
439 RTTsample_time.set_size(1000);
440 RTTsample_time.zeros();
441 RTTsample_val(0) = 0;
442 RTTsample_time(0) = 0;
447 std::string TCP_Sender::GenerateFilename()
452 timeinfo = localtime(&rawtime);
456 struct tm *timeinfo = &_timeinfo;
457 localtime_s(timeinfo, &rawtime);
459 std::ostringstream filename_stream;
460 filename_stream <<
"trace_tcp_sender_u" << fLabel
461 <<
"_" << 1900 + timeinfo->tm_year
462 <<
"_" << timeinfo->tm_mon
463 <<
"_" << timeinfo->tm_mday
464 <<
"__" << timeinfo->tm_hour
465 <<
"_" << timeinfo->tm_min
466 <<
"_" << timeinfo->tm_sec
468 return filename_stream.str();
472 void TCP_Sender::release(std::string file)
474 std::string filename;
482 filename = GenerateFilename();
486 save_trace(filename);
491 void TCP_Sender::InitStatistics()
493 fNumberOfTimeouts = 0;
494 fNumberOfIdleTimeouts = 0;
495 fNumberOfFastRetransmits = 0;
496 fNumberOfRTTMeasurements = 0;
497 fNumberOfReceivedACKs = 0;
501 void TCP_Sender::StopTransientPhase()
507 void TCP_Sender::HandleUserMessageIndication(
itpp::Packet *user_data_p)
510 std::cout <<
"TCP_Sender::HandleUserMessageIndication" 511 <<
" byte_size=" << user_data_p->
bit_size() / 8
512 <<
" ptr=" << user_data_p
513 <<
" time=" << Event_Queue::now() << std::endl;
516 SocketWriteQueue.push(user_data_p);
523 void TCP_Sender::ReceiveMessageFromNet(
itpp::Packet *msg)
525 TCP_Packet & packet = (TCP_Packet &) * msg;
528 std::cout <<
"TCP_Sender::ReceiveMessageFromNet" 529 <<
" byte_size=" << msg->
bit_size() / 8
531 <<
" time=" << Event_Queue::now() << std::endl;
534 if ((packet.get_session_id() == fSessionId) &&
535 (packet.get_ACK() >= fSndUna)) {
543 void TCP_Sender::HandleACK(TCP_Packet &msg)
545 it_assert(msg.get_ACK() <= fSndMax,
"TCP_Sender::HandleACK, received ACK > SndMax at ");
547 fNumberOfReceivedACKs++;
550 TraceACKedSeqNo(msg.get_ACK());
554 std::cout <<
"sender " << fLabel <<
": " 556 <<
" t = " << Event_Queue::now() <<
", " 561 fRecWnd = msg.get_wnd();
562 fMaxRecWnd =
max(fRecWnd, fMaxRecWnd);
564 if (msg.get_ACK() == fSndUna) {
566 bool ignoreDupACK = (fSndMax == fSndUna);
568 if (fIgnoreDupACKOnTORecovery) {
570 if (fCarefulMulFastRtxAvoidance) {
572 ignoreDupACK = ignoreDupACK || (fSndUna <= fRecoveryTO);
576 ignoreDupACK = ignoreDupACK || (fSndUna < fRecoveryTO);
583 if (fDupACKCnt == fDupACKThreshold) {
585 fNumberOfFastRetransmits++;
587 fRecoveryDupACK = fSndMax;
591 if ((fTCPVersion == kReno) || (fTCPVersion == kNewReno)) {
594 else if (fTCPVersion == kTahoe) {
598 if (fTCPVersion == kReno || fTCPVersion == kNewReno) {
600 if (fRenoConservation) {
601 fCWnd += fDupACKThreshold * fMSS;
604 else if (fTCPVersion == kTahoe) {
612 else if (fDupACKCnt > fDupACKThreshold) {
613 if (fTCPVersion == kReno || fTCPVersion == kNewReno) {
617 if (fRenoConservation) {
625 Sequence_Number oldSndUna = fSndUna;
626 fSndUna = msg.get_ACK();
627 fSndNxt =
max(fSndNxt, fSndUna);
631 if ((fSndUna > fTimUna) && fRtxTimer.IsPending()) {
638 if (fImmediateBackoffReset) {
642 if (fPendingBackoffReset) {
644 fPendingBackoffReset =
false;
646 else if (fBackoff > 1) {
649 fPendingBackoffReset =
true;
655 if ((fSndUna > fRTTMByte) && fRTTMPending) {
656 UpdateRTTVariables(Event_Queue::now() - fRTTMStartTime);
657 fRTTMPending =
false;
662 if (fDupACKCnt >= fDupACKThreshold) {
664 if (fTCPVersion == kNewReno && fSndUna < fRecoveryDupACK) {
666 if (fRenoConservation) {
667 fCWnd =
max(fMSS, fCWnd - (fSndUna - oldSndUna) + fMSS);
672 FinishFastRecovery();
678 if (fCWnd < fSSThresh) {
680 fCWnd =
min(fCWnd + fMSS, fMaxCWnd);
684 fCWnd +=
max(fMSS * fMSS / fCWnd, 1);
685 fCWnd =
min(fCWnd, fMaxCWnd);
699 void TCP_Sender::SendNewData(
bool skipSWSA)
701 unsigned nextSegmentSize;
703 it_assert(fSndUna <= fSndNxt, "TCP_Sender::SendNewData, SndUna > SndNxt in sender
" + to_str(fLabel) + "!
"); 705 if (fRestartAfterIdle) { 709 bool sillyWindowAvoidanceFailed = false; 711 while (!sillyWindowAvoidanceFailed && 712 ((nextSegmentSize = GetNextSegmentSize(fSndNxt)) > 0)) { 713 // there is new data to send and window is large enough 715 // SWSA and Nagle (RFC 1122): assume PUSH to be set 716 unsigned queuedUnsent = fUserNxt - fSndNxt; 717 unsigned usableWindow = max(0, (fSndUna + SendWindow()) - fSndNxt); 719 if (((unsigned)min(queuedUnsent, usableWindow) >= fMSS) || 720 ((!fNagle || (fSndUna == fSndNxt)) && 721 ((queuedUnsent <= usableWindow) || // Silly W. A. 722 ((unsigned)min(queuedUnsent, usableWindow) >= fMaxRecWnd / 2) 727 // Silly Window Syndrome Avoidance (SWSA) and Nagle passed 729 TCP_Segment nextSegment(fSndNxt, fSndNxt + nextSegmentSize); 730 TCP_Packet & msg = * new TCP_Packet(); 732 msg.set_segment(nextSegment); 733 msg.set_session_id(fSessionId); 734 msg.set_destination_port(fLabel); // The dest and src port are set to the same 735 msg.set_source_port(fLabel); // number for simplicity. 736 msg.set_bit_size(8 * (nextSegmentSize + fTCPIPHeaderLength)); 739 std::cout << "TCP_Sender::SendNewData,
" 740 << " nextSegmentSize=
" << nextSegmentSize 741 << " fTCPIPHeaderLength=
" << fTCPIPHeaderLength 742 << " byte_size=
" << msg.bit_size() / 8 744 << " time=
" << Event_Queue::now() << std::endl; 747 // no RTT measurement for retransmitted segments 748 // changes on Dec. 13. 2002 (Ga, Bo, Scharf) 750 if (!fRTTMPending && fSndNxt >= fSndMax) { // ##Bo## 751 fRTTMStartTime = Event_Queue::now(); 752 fRTTMByte = nextSegment.begin(); 756 fSndNxt += nextSegmentSize; 757 fSndMax = max(fSndNxt, fSndMax); 759 // reset SWSA timer if necessary 763 else if (fSWSATimer.IsPending()) { 767 // set rtx timer if necessary 768 if (!fRtxTimer.IsPending()) { 774 msg.set_info(fSSThresh, fRecWnd, fCWnd, fRTTEstimate, 775 fSndUna, fSndNxt, false); 776 std::cout << "sender
" << fLabel 777 << ": send
new data:
" 778 << " t =
" << Event_Queue::now() << ",
" 785 sillyWindowAvoidanceFailed = true; 787 if (!fSWSATimer.IsPending()) { 788 fSWSATimer.Set(fSWSATimerValue); 793 // set timers in case that no new data could have been sent 794 if (!fRtxTimer.IsPending()) { 795 if (fSndMax > fSndUna) { // there is outstanding data 796 if (!fImmediateBackoffReset && fPendingBackoffReset) { 797 // backoff is reset if no new data could have been sent since last 798 // (successfull) retransmission; this is useful in case of 799 // Reno recovery and multiple losses to avoid that in 800 // the (unavoidable) series of timeouts the timer value 801 // increases exponentially as this is not the intention 802 // of the delayed backoff reset in Karn's algorithm 804 fPendingBackoffReset = false; 812 void TCP_Sender::UnaRetransmit() 814 // resend after timeout or fast retransmit 815 unsigned nextSegmentSize = GetNextSegmentSize(fSndUna); 817 if (nextSegmentSize > 0) { 818 TCP_Segment nextSegment(fSndUna, fSndUna + nextSegmentSize); 819 TCP_Packet & msg = *new TCP_Packet(); 820 msg.set_segment(nextSegment); 821 msg.set_session_id(fSessionId); 822 msg.set_destination_port(fLabel); // The dest and src port are set to the same 823 msg.set_source_port(fLabel); // number for simplicity. 824 msg.set_bit_size(8 * (nextSegmentSize + fTCPIPHeaderLength)); 826 fSndNxt = max(fSndNxt, fSndUna + nextSegmentSize); 827 fSndMax = max(fSndNxt, fSndMax); 829 // The RTT measurement is cancelled if the RTTM byte has a sequence 830 // number higher or equal than the first retransmitted byte as 831 // the ACK for the RTTM byte will be delayed by the rtx for at least 833 if (fKarn && (nextSegment.begin() <= fRTTMByte) && fRTTMPending) { 834 fRTTMPending = false; 840 msg.set_info(fSSThresh, fRecWnd, fCWnd, fRTTEstimate, 841 fSndUna, fSndNxt, true); 842 std::cout << "sender
" << fLabel; 843 if (fDupACKCnt >= fDupACKThreshold) { 844 std::cout << ": fast rtx:
"; 847 std::cout << ": TO rtx:
"; 849 std::cout << " t =
" << Event_Queue::now() << ",
" 856 // throw(UL_CException("TCP_Sender::UnaRetransmit
", "no bytes
to send
")); 861 void TCP_Sender::FinishFastRecovery() 863 if (fTCPVersion == kTahoe) { 866 else if (fTCPVersion == kReno) { 867 // Reno fast recovery 869 if (fFlightSizeRecovery) { 870 fCWnd = min(fSndMax - fSndUna + fMSS, fSSThresh); 876 else if (fTCPVersion == kNewReno) { 877 // New Reno fast recovery 878 // "Set CWnd
to ...
min (ssthresh, FlightSize + MSS)
880 if (fFlightSizeRecovery) {
881 fCWnd =
min(fSndMax - fSndUna + fMSS, fSSThresh);
891 void TCP_Sender::ReduceSSThresh()
893 if (fCarefulSSThreshReduction) {
899 fSSThresh =
max(2 * fMSS,
900 min(
min(fCWnd, fSndMax - fSndUna), fRecWnd) / 2);
904 fSSThresh =
max(2 * fMSS,
min(fSndMax - fSndUna, fRecWnd) / 2);
907 it_assert(fSSThresh <= fMaxCWnd, "TCP_Sender::HandleACK, internal error: SndSSThresh is > MaxCWnd
"); 915 void TCP_Sender::SendMsg(TCP_Packet &msg) 918 TraceSentSeqNo(msg.get_segment().end()); 921 if (fRestartAfterIdle) { 922 fLastSendTime = Event_Queue::now(); // needed for idle detection 929 void TCP_Sender::IdleCheck() 931 // idle detection according to Jacobson, SIGCOMM, 1988: 932 // sender is currently idle and nothing has been send since RTO 934 if (fSndMax == fSndUna && Event_Queue::now() - fLastSendTime > CalcRTOValue()) { 935 fCWnd = fInitialCWnd; // see RFC2581 937 fNumberOfIdleTimeouts++; 944 std::cout << "sender
" << fLabel 945 << ": idle timeout:
" 946 << "t =
" << Event_Queue::now() 947 << ", SndNxt =
" << fSndNxt 948 << ", SndUna =
" << fSndUna 949 << ", Backoff =
" << fBackoff 956 void TCP_Sender::HandleRtxTimeout(Ttype) 961 fBackoff = min(fMaxBackoff, fBackoff * 2); 962 if (!fImmediateBackoffReset) { 963 fPendingBackoffReset = false; 966 if (fDupACKCnt >= fDupACKThreshold) { 967 FinishFastRecovery(); // reset dup ACK cnt and CWnd 969 else if (fDupACKCnt > 0) { 970 fDupACKCnt = 0; // don't allow dupack action during TO recovery 973 // update CWnd and SSThresh 974 ReduceSSThresh(); // halve ssthresh (in most cases) 975 fCWnd = fMSS; // not initial CWnd, see RFC 2581 977 it_assert(fSSThresh <= fMaxCWnd, "TCP_Sender::HandleRtxTimeout,
internal error: SndSSThresh is > MaxCWnd
"); 979 fRecoveryTO = fSndMax; 982 // go back N is mainly relevant in the case of multiple losses 983 // which would lead to a series of timeouts without resetting sndnxt 988 std::cout << "sender
" << fLabel 990 << "t =
" << Event_Queue::now() 991 << ", SndNxt =
" << fSndNxt 992 << ", SndUna =
" << fSndUna 1000 UnaRetransmit(); // initiate retransmission 1004 void TCP_Sender::HandleSWSATimeout(Ttype) 1010 unsigned TCP_Sender::GetNextSegmentSize(const Sequence_Number & begin) 1012 // try to get new user messages if available and necessary 1013 while ((fUserNxt < begin + fMSS) && (!SocketWriteQueue.empty())) { 1014 itpp::Packet *packet_p = SocketWriteQueue.front(); 1015 SocketWriteQueue.pop(); 1016 fUserNxt += (unsigned) packet_p->bit_size() / 8; 1020 Sequence_Number end = min(min(fUserNxt, begin + fMSS), 1021 fSndUna + SendWindow()); 1024 std::cout << "TCP_Sender::GetNextSegmentSize,
" 1025 << " fUserNxt=
" << fUserNxt 1026 << " begin_seq_num=
" << begin 1028 << " fSndUna=
" << fSndUna 1029 << " SendWindow()=
" << SendWindow() 1030 << " end_seq_num=
" << end 1031 << " time=
" << Event_Queue::now() << std::endl; 1034 return max(0, end - begin); 1038 unsigned TCP_Sender::SendWindow() const 1040 return min(fRecWnd, min(fMaxCWnd, fCWnd)); 1044 double TCP_Sender::CalcRTOValue() const 1046 static const double factor = 1 + 1e-8; 1047 // to avoid "simultaneous
" TO/receive ACK events in case of const. RTT 1049 double rto = fBackoff * fRTTEstimate * factor; 1051 if (rto > fMaxRTO) { 1059 void TCP_Sender::SetRtxTimer() 1061 double rto = CalcRTOValue(); 1065 std::cout << "sender
" << fLabel 1066 << ":
set rtx timer:
" 1067 << "t =
" << Event_Queue::now() 1068 << ", RTO =
" << rto 1069 << ", Backoff =
" << fBackoff 1070 << ", TimUna =
" << fTimUna 1076 void TCP_Sender::UpdateRTTVariables(double sampleRTT) 1080 fRTTVar = sampleRTT / 2; 1083 // see, e.g., Comer for the values used as weights 1084 fSRTT = 0.875 * fSRTT + 0.125 * sampleRTT; 1085 fRTTVar = 0.75 * fRTTVar + 0.25 * fabs(sampleRTT - fSRTT); 1088 fRTTEstimate = round(fSRTT + 4 * fRTTVar, fTimerGranularity); 1091 TraceRTTVariables(sampleRTT); 1094 fNumberOfRTTMeasurements++; 1098 void TCP_Sender::TraceRTTVariables(double sampleRTT) 1101 std::cout << "sender
" << fLabel 1103 << "t =
" << Event_Queue::now() 1104 << ", sample =
" << sampleRTT 1105 << ", SRTT =
" << fSRTT 1106 << ", RTTVar =
" << fRTTVar 1107 << ", RTTEstimate =
" << fRTTEstimate 1111 if (RTTsample_index >= RTTsample_time.size()) { 1112 RTTsample_time.set_size(2*RTTsample_time.size(), true); 1113 RTTsample_val.set_size(2*RTTsample_val.size(), true); 1115 RTTsample_val(RTTsample_index) = sampleRTT; 1116 RTTsample_time(RTTsample_index) = Event_Queue::now(); 1119 if (RTTEstimate_index >= RTTEstimate_time.size()) { 1120 RTTEstimate_time.set_size(2*RTTEstimate_time.size(), true); 1121 RTTEstimate_val.set_size(2*RTTEstimate_val.size(), true); 1123 RTTEstimate_val(RTTEstimate_index) = fRTTEstimate; 1124 RTTEstimate_time(RTTEstimate_index) = Event_Queue::now(); 1125 RTTEstimate_index++; 1129 void TCP_Sender::TraceCWnd() 1132 std::cout << "sender
" << fLabel 1133 << " t =
" << Event_Queue::now() 1134 << " cwnd =
" << fCWnd << std::endl; 1136 if (CWnd_index >= CWnd_time.size()) { 1137 CWnd_time.set_size(2*CWnd_time.size(), true); 1138 CWnd_val.set_size(2*CWnd_val.size(), true); 1140 CWnd_val(CWnd_index) = fCWnd; 1141 CWnd_time(CWnd_index) = Event_Queue::now(); 1146 void TCP_Sender::TraceSSThresh() 1149 std::cout << "sender
" << fLabel 1150 << " t =
" << Event_Queue::now() 1151 << " cwnd =
" << fSSThresh << std::endl; 1153 if (SSThresh_index >= SSThresh_time.size()) { 1154 SSThresh_time.set_size(2*SSThresh_time.size(), true); 1155 SSThresh_val.set_size(2*SSThresh_val.size(), true); 1157 SSThresh_val(SSThresh_index) = fSSThresh; 1158 SSThresh_time(SSThresh_index) = Event_Queue::now(); 1163 void TCP_Sender::TraceSentSeqNo(const Sequence_Number sn) 1167 std::cout << "sender
" << fLabel 1168 << " t =
" << Event_Queue::now() 1172 if (sent_seq_num_index >= sent_seq_num_time.size()) { 1173 sent_seq_num_time.set_size(2*sent_seq_num_time.size(), true); 1174 sent_seq_num_val.set_size(2*sent_seq_num_val.size(), true); 1176 sent_seq_num_val(sent_seq_num_index) = sn.value(); 1177 sent_seq_num_time(sent_seq_num_index) = Event_Queue::now(); 1178 sent_seq_num_index++; 1182 void TCP_Sender::TraceACKedSeqNo(const Sequence_Number sn) 1185 std::cout << "sender
" << fLabel 1186 << " t =
" << Event_Queue::now() 1191 if (sender_recv_ack_seq_num_index >= sender_recv_ack_seq_num_time.size()) { 1192 sender_recv_ack_seq_num_time.set_size(2*sender_recv_ack_seq_num_time.size(), true); 1193 sender_recv_ack_seq_num_val.set_size(2*sender_recv_ack_seq_num_val.size(), true); 1195 sender_recv_ack_seq_num_val(sender_recv_ack_seq_num_index) = sn.value(); 1196 sender_recv_ack_seq_num_time(sender_recv_ack_seq_num_index) = Event_Queue::now(); 1197 sender_recv_ack_seq_num_index++; 1201 void TCP_Sender::save_trace(std::string filename) 1204 CWnd_val.set_size(CWnd_index, true); 1205 CWnd_time.set_size(CWnd_index, true); 1207 SSThresh_val.set_size(SSThresh_index, true); 1208 SSThresh_time.set_size(SSThresh_index, true); 1210 sent_seq_num_val.set_size(sent_seq_num_index, true); 1211 sent_seq_num_time.set_size(sent_seq_num_index, true); 1213 sender_recv_ack_seq_num_val.set_size(sender_recv_ack_seq_num_index, true); 1214 sender_recv_ack_seq_num_time.set_size(sender_recv_ack_seq_num_index, true); 1216 RTTEstimate_val.set_size(RTTEstimate_index, true); 1217 RTTEstimate_time.set_size(RTTEstimate_index, true); 1219 RTTsample_val.set_size(RTTsample_index, true); 1220 RTTsample_time.set_size(RTTsample_index, true); 1223 std::cout << "CWnd_val
" << CWnd_val << std::endl; 1224 std::cout << "CWnd_time
" << CWnd_time << std::endl; 1225 std::cout << "CWnd_index
" << CWnd_index << std::endl; 1227 std::cout << "SSThresh_val
" << SSThresh_val << std::endl; 1228 std::cout << "SSThresh_time
" << SSThresh_time << std::endl; 1229 std::cout << "SSThresh_index
" << SSThresh_index << std::endl; 1231 std::cout << "sent_seq_num_val
" << sent_seq_num_val << std::endl; 1232 std::cout << "sent_seq_num_time
" << sent_seq_num_time << std::endl; 1233 std::cout << "sent_seq_num_index
" << sent_seq_num_index << std::endl; 1235 std::cout << "sender_recv_ack_seq_num_val
" << sender_recv_ack_seq_num_val << std::endl; 1236 std::cout << "sender_recv_ack_seq_num_time
" << sender_recv_ack_seq_num_time << std::endl; 1237 std::cout << "sender_recv_ack_seq_num_index
" << sender_recv_ack_seq_num_index << std::endl; 1239 std::cout << "RTTEstimate_val
" << RTTEstimate_val << std::endl; 1240 std::cout << "RTTEstimate_time
" << RTTEstimate_time << std::endl; 1241 std::cout << "RTTEstimate_index
" << RTTEstimate_index << std::endl; 1243 std::cout << "RTTsample_val
" << RTTsample_val << std::endl; 1244 std::cout << "RTTsample_time
" << RTTsample_time << std::endl; 1245 std::cout << "RTTsample_index
" << RTTsample_index << std::endl; 1247 std::cout << "TCP_Sender::saving
to file:
" << filename << std::endl; 1253 ff2 << Name("CWnd_val
") << CWnd_val; 1254 ff2 << Name("CWnd_time
") << CWnd_time; 1255 ff2 << Name("CWnd_index
") << CWnd_index; 1257 ff2 << Name("SSThresh_val
") << SSThresh_val; 1258 ff2 << Name("SSThresh_time
") << SSThresh_time; 1259 ff2 << Name("SSThresh_index
") << SSThresh_index; 1261 ff2 << Name("sent_seq_num_val
") << sent_seq_num_val; 1262 ff2 << Name("sent_seq_num_time
") << sent_seq_num_time; 1263 ff2 << Name("sent_seq_num_index
") << sent_seq_num_index; 1265 ff2 << Name("sender_recv_ack_seq_num_val
") << sender_recv_ack_seq_num_val; 1266 ff2 << Name("sender_recv_ack_seq_num_time
") << sender_recv_ack_seq_num_time; 1267 ff2 << Name("sender_recv_ack_seq_num_index
") << sender_recv_ack_seq_num_index; 1269 ff2 << Name("RTTEstimate_val
") << RTTEstimate_val; 1270 ff2 << Name("RTTEstimate_time
") << RTTEstimate_time; 1271 ff2 << Name("RTTEstimate_index
") << RTTEstimate_index; 1273 ff2 << Name("RTTsample_val
") << RTTsample_val; 1274 ff2 << Name("RTTsample_time
") << RTTsample_time; 1275 ff2 << Name("RTTsample_index
") << RTTsample_index; 1282 void TCP_Sender::print_item(std::ostream &, const std::string & keyword) 1284 if (keyword == "Label
") { 1285 std::cout << fLabel; 1287 else if (keyword == "CWnd
") { 1290 else if (keyword == "SSThresh
") { 1291 std::cout << fSSThresh; 1293 else if (keyword == "SRTT
") { 1296 else if (keyword == "RTTvar
") { 1297 std::cout << fRTTVar; 1299 else if (keyword == "Backoff
") { 1300 std::cout << fBackoff; 1302 else if (keyword == "RTO
") { 1303 std::cout << CalcRTOValue(); 1305 else if (keyword == "NoOfFastRets
") { 1306 std::cout << fNumberOfFastRetransmits; 1308 else if (keyword == "NoOfRetTOs
") { 1309 std::cout << fNumberOfTimeouts; 1311 else if (keyword == "NoOfIdleTOs
") { 1312 std::cout << fNumberOfIdleTimeouts; 1314 else if (keyword == "NoOfRTTMs
") { 1315 std::cout << fNumberOfRTTMeasurements; 1317 else if (keyword == "NoOfRecACKs
") { 1318 std::cout << fNumberOfReceivedACKs; 1325 // -------------------- TCP_Receiver_Buffer ---------------------------------------- 1326 TCP_Receiver_Buffer::TCP_Receiver_Buffer() : 1332 TCP_Receiver_Buffer::TCP_Receiver_Buffer(const TCP_Receiver_Buffer & rhs) : 1333 fFirstByte(rhs.fFirstByte), 1334 fBufList(rhs.fBufList) 1339 void TCP_Receiver_Buffer::reset() 1346 TCP_Receiver_Buffer::~TCP_Receiver_Buffer() 1351 void TCP_Receiver_Buffer::write(TCP_Segment newBlock) 1354 it_assert(newBlock.begin() <= newBlock.end(), "TCP_Receiver_Buffer::Write, no valid segment
"); 1356 // cut blocks beginning before fFirstByte 1357 if (newBlock.begin() < fFirstByte) { 1358 if (newBlock.end() > fFirstByte) { 1359 newBlock.set_begin(fFirstByte); 1362 return; //// TODO: Is this strange? 1366 if (newBlock.length() == 0) { // empty block, nothing to do 1370 if (fBufList.empty() || (newBlock.begin() > fBufList.back().end())) { 1371 // new block is behind last block in buffer 1372 fBufList.push_back(newBlock); 1375 // skip list entries if beginning of newBlock > end of current one 1376 // (search for correct list position) 1377 std::list<TCP_Segment>::iterator iter; 1378 iter = fBufList.begin(); 1379 while (newBlock.begin() > iter->end()) { 1381 it_assert(iter != fBufList.end(), "TCP_Receiver_Buffer::Write,
internal error
"); 1384 TCP_Segment & exBlock = *iter; 1386 if (exBlock.can_be_combined(newBlock)) { 1387 // overlapping or contiguous blocks -> combine 1388 exBlock.combine(newBlock); 1390 // check following blocks 1392 while ((iter != fBufList.end()) && 1393 exBlock.can_be_combined(*iter)) { 1394 exBlock.combine(*iter); 1395 iter = fBufList.erase(iter); 1399 // no overlap, newBlock lies between two existing list entries 1400 // new list entry has to be created 1402 fBufList.insert(iter, newBlock); 1406 it_assert(!fBufList.empty() && fBufList.front().begin() >= fFirstByte, "TCP_Receiver_Buffer::Write,
internal error
"); 1411 // The amount of data read from the buffer is given as parameter. It has 1412 // to be less than or equal to the size of the first block stored. This 1413 // mean the caller of Read should first check how much data is available 1414 // by calling FirstBlockSize. 1415 void TCP_Receiver_Buffer::read(unsigned noOfBytes) 1417 it_assert(first_block_size() > 0, "TCP_Receiver_Buffer::Read, No block
to read
"); 1418 it_assert(noOfBytes <= first_block_size(), "TCP_Receiver_Buffer::Read, submitted block
size not valid
"); 1421 if (noOfBytes < first_block_size()) { 1422 fBufList.front().set_begin(fBufList.front().begin() + noOfBytes); 1424 else { // first block will be read completely 1425 fBufList.pop_front(); 1427 fFirstByte += noOfBytes; 1429 it_assert(fBufList.empty() || fBufList.front().begin() >= fFirstByte, "TCP_Receiver_Buffer::Read,
internal error
"); 1433 // FirstBlockSize returns the size of the first block stored in the 1434 // buffer or 0 if the buffer is empty 1435 unsigned TCP_Receiver_Buffer::first_block_size() const 1437 if (!fBufList.empty() && (fBufList.front().begin() == fFirstByte)) { 1438 return fBufList.front().length(); 1446 std::ostream & TCP_Receiver_Buffer::info(std::ostream &os, int detail) const 1448 os << "receiver buffer information
" << std::endl 1449 << "number of blocks:
" << fBufList.size() << std::endl 1450 << "first byte stored:
" << fFirstByte << std::endl 1451 << "last byte stored +1:
" << last_byte() << std::endl 1452 << "next byte expected:
" << next_expected() << std::endl; 1455 os << "segments in receiver buffer:
" << std::endl; 1457 typedef std::list<TCP_Segment>::const_iterator LI; 1458 for (LI i = fBufList.begin(); i != fBufList.end(); ++i) { 1459 const TCP_Segment & block = *i; 1460 os << ". segment:
" << block << std::endl; 1469 // -------------------- TCP_Receiver ---------------------------------------- 1470 TCP_Receiver::TCP_Receiver(int label) : 1473 fTCPIPHeaderLength(TCP_HEADERLENGTH), 1475 fBufferSize(TCP_BUFFERSIZE), 1476 fDelayedACK(TCP_DELAYEDACK), 1477 fACKDelayTime(TCP_ACKDELAYTIME), 1478 fSendPeriodicACKs(TCP_SENDPERIODICACKS), 1479 fStrictPeriodicACKs(TCP_STRICTPERIODICACKS), 1480 fPeriodicACKInterval(TCP_PERIODICACKINTERVAL), 1481 fACKSchedulingDelay(TCP_ACKSCHEDULINGDELAY), 1482 fACKOnBufferWrite(TCP_ACKBUFFERWRITE), 1483 fACKOnBufferRead(TCP_ACKBUFFERREAD), 1484 fMaxUserBlockSize(TCP_MAXUSERBLOCKSIZE), 1485 fMinUserBlockSize(TCP_MINUSERBLOCKSIZE), 1486 fUserBlockProcDelay(TCP_USERBLOCKPROCDELAY), 1490 fDelayedACKTimer(*this, &TCP_Receiver::DelayedACKHandler), 1491 fPeriodicACKTimer(*this, &TCP_Receiver::PeriodicACKHandler), 1492 fACKSchedulingTimer(*this, &TCP_Receiver::SendACKMessage), 1494 fUserBlockProcTimer(*this, &TCP_Receiver::HandleEndOfProcessing) 1496 fUserMessage = NULL; 1499 if (!fACKOnBufferRead && !fACKOnBufferWrite) { 1500 // throw(UL_CException("TCP_Receiver::TCP_Receiver
", 1501 // "ACKs must be sent on buffer read or write or both
")); 1506 tcp_receive.forward(this, &TCP_Receiver::ReceiveMessageFromNet); 1507 tcp_receive.set_name("TCP Receive
"); 1508 tcp_send_ack.set_name("TCP send ACK
"); 1509 tcp_new_data.set_name("TCP New Data
"); 1510 tcp_release.forward(this, &TCP_Receiver::release); 1511 tcp_release.set_name("TCP Release
"); 1516 TCP_Receiver::~TCP_Receiver() 1518 delete fWaitingACKMsg; 1519 delete fUserMessage; 1523 void TCP_Receiver::set_debug(const bool enable_debug) 1525 fDebug = enable_debug; 1526 tcp_send_ack.set_debug(enable_debug); 1527 tcp_new_data.set_debug(); 1530 void TCP_Receiver::set_debug(bool enable_debug, bool enable_signal_debug) 1532 fDebug = enable_debug; 1533 tcp_send_ack.set_debug(enable_signal_debug); 1534 tcp_new_data.set_debug(); 1537 void TCP_Receiver::set_trace(const bool enable_trace) 1539 fTrace = enable_trace; 1544 void TCP_Receiver::setup() 1549 if (fSendPeriodicACKs) { 1550 fPeriodicACKTimer.Set(fPeriodicACKInterval); 1553 fReceiverBuffer.reset(); 1555 received_seq_num_val.set_size(1000); 1556 received_seq_num_val.zeros(); 1557 received_seq_num_time.set_size(1000); 1558 received_seq_num_time.zeros(); 1559 received_seq_num_val(0) = 0; 1560 received_seq_num_time(0) = 0; 1561 received_seq_num_index = 1; 1564 std::string TCP_Receiver::GenerateFilename() 1568 struct tm *timeinfo; 1569 timeinfo = localtime(&rawtime); 1572 struct tm _timeinfo; 1573 struct tm *timeinfo = &_timeinfo; 1574 localtime_s(timeinfo, &rawtime); 1576 std::ostringstream filename_stream; 1577 filename_stream << "trace_tcp_receiver_u
" << fLabel 1578 << "_
" << 1900 + timeinfo->tm_year 1579 << "_
" << timeinfo->tm_mon 1580 << "_
" << timeinfo->tm_mday 1581 << "__
" << timeinfo->tm_hour 1582 << "_
" << timeinfo->tm_min 1583 << "_
" << timeinfo->tm_sec 1585 return filename_stream.str(); 1588 void TCP_Receiver::release(std::string file) 1590 std::string filename; 1593 if (fWaitingACKMsg != 0) { 1594 delete fWaitingACKMsg; 1597 if (fUserMessage != 0) { 1598 delete fUserMessage; 1602 fUserBlockProcTimer.Reset(); 1603 fDelayedACKTimer.Reset(); 1604 fPeriodicACKTimer.Reset(); 1605 fACKSchedulingTimer.Reset(); 1609 filename = GenerateFilename(); 1613 save_trace(filename); 1618 void TCP_Receiver::ReceiveMessageFromNet(itpp::Packet *msg) 1620 TCP_Packet & packet = (TCP_Packet &) * msg; 1621 if (packet.get_destination_port() == fLabel) { 1622 if (packet.get_session_id() == fSessionId) { 1623 ReceiveDataPacket(packet); 1626 it_warning("Received a TCP packet with wrong SessionId
"); 1627 std::cout << "TCP_Receiver::ReceiveMessageFromNet,
" 1628 << "fLabel=
" << fLabel 1629 << "fSessionId=
" << fSessionId << std::endl; 1630 std::cout << "packet=
" << packet 1631 << ", next
exp. =
" << fReceiverBuffer.next_expected() 1637 it_warning("Received a TCP packet with label
"); 1643 void TCP_Receiver::ReceiveDataPacket(TCP_Packet &msg) 1645 TCP_Segment segment = msg.get_segment(); 1647 bool isOutOfOrder = (segment.begin() > fReceiverBuffer.next_expected()) || 1648 (segment.end() <= fReceiverBuffer.next_expected()); 1651 std::cout << "TCP_Receiver::ReceiveDataPacket receiver:
" << fLabel << ":
" 1653 << "t =
" << Event_Queue::now() 1654 << ", next
exp. =
" << fReceiverBuffer.next_expected() 1655 << ",
" << msg << std::endl; 1659 TraceReceivedSeqNo(segment.end()); 1662 it_assert(segment.end() <= fReceiverBuffer.first_byte() + fBufferSize, "TCP_Receiver::ReceiveTCPPacket, packet exceeds window at
"); 1663 it_assert(segment.begin() < segment.end(), "TCP_Receiver::ReceiveTCPPacket, silly packet received at
"); 1665 fReceiverBuffer.write(segment); 1668 SendACK(true); // create dupack conditionless 1671 if (fACKOnBufferWrite) { 1674 IndicateUserMessage(); 1681 void TCP_Receiver::IndicateUserMessage() 1683 if (fUserMessage == 0) { 1685 unsigned noOfBytes = min(fReceiverBuffer.first_block_size(), 1689 std::cout << "TCP_Receiver::IndicateUserMessage
" 1690 << "t =
" << Event_Queue::now() 1691 << " noOfBytes =
" << noOfBytes 1692 << " firstBlock =
" << fReceiverBuffer.first_block_size() 1696 if (noOfBytes >= fMinUserBlockSize) { 1697 fUserMessage = new Packet(); 1698 fUserMessage->set_bit_size(8*noOfBytes); 1699 fUserBlockProcTimer.Set(fUserBlockProcDelay); 1705 bool TCP_Receiver::is_user_message_available() 1707 if (fUserMessage != 0) { 1711 unsigned noOfBytes = min(fReceiverBuffer.first_block_size(), 1714 if (noOfBytes >= fMinUserBlockSize) { 1715 fUserMessage = new Packet(); 1716 fUserMessage->set_bit_size(8*noOfBytes); 1725 itpp::Packet & TCP_Receiver::get_user_message() 1727 it_assert(fUserMessage != 0, "TCP_Receiver::GetUserMessage, no message available
"); 1729 std::cout << "TCP_Receiver::GetUserMessage
" 1730 << "receiver:
" << fLabel << ":
" 1731 << "read from buffer:
" 1732 << "t =
" << Event_Queue::now() 1733 << ", user msg
length =
" << (fUserMessage->bit_size() / 8) 1734 << ", first byte =
" << fReceiverBuffer.first_byte() 1735 << ", first block
size =
" << fReceiverBuffer.first_block_size() 1739 fReceiverBuffer.read(fUserMessage->bit_size() / 8); 1740 if (fACKOnBufferRead) { 1741 SendACK(false); // send acknowledgement 1744 itpp::Packet & msg = *fUserMessage; 1747 if (fReceiverBuffer.first_block_size() > 0) { 1748 IndicateUserMessage(); 1756 void TCP_Receiver::HandleEndOfProcessing(Ttype) 1758 it_assert(fUserMessage != 0, "TCP_Receiver::HandleEndOfProcessing, no message available
"); 1761 tcp_new_data(fLabel); 1765 void TCP_Receiver::DelayedACKHandler(Ttype) 1768 std::cout << "TCP_Receiver::DelayedACKHandler
" 1769 << "receiver
" << fLabel 1771 << "t =
" << Event_Queue::now() << std::endl; 1778 void TCP_Receiver::PeriodicACKHandler(Ttype) 1781 std::cout << "TCP_Receiver::PeriodicACKHandler
" 1782 << "receiver
" << fLabel 1783 << ": periodicACK TO:
" 1784 << "t =
" << Event_Queue::now() << std::endl; 1791 void TCP_Receiver::SendACK(bool sendConditionless) 1793 // sendConditionless is set 1794 // ... if packet was received out of order or 1795 // ... if delayed ACK timer has expired 1797 // Bei eingeschaltetem "delayed ACK
" wird ein ACK nur 1798 // gesendet, wenn das Fenster um 2MSS oder 35% der 1799 // maximalen Fenstergroesse verschoben worden ist 1800 // ... oder nach delayed ACK Timeout 1801 // ... oder wenn es das ACK fur ein Out of Order Segment ist 1802 // ... oder (in der Realitat), wenn ich auch was zu senden habe. 1804 if (sendConditionless || !fDelayedACK || 1805 (fReceiverBuffer.next_expected() - fAdvRcvNxt >= (int)(2 * fMSS)) || 1806 (fReceiverBuffer.next_expected() - fAdvRcvNxt >= 1807 (int)(0.35 * fBufferSize))) { 1808 // Remark: RFC2581 recommends to acknowledge every second 1809 // packet conditionless (without setting this as a requirement) 1810 // in order to avoid excessive ack delays when the receiver MSS 1811 // is larger than the sender MSS. In this uni-directional 1812 // implementation, the receiver's MSS is not actively 1813 // used for sending but only for deciding when acknowledgments 1814 // have to be returned. Thus, the best solution to account for 1815 // RFC2581 is to set the receiver's MSS always equal to the 1818 // Receiver Silly Window Syndrome Avoidance: 1820 if (fAdvRcvNxt + fAdvRcvWnd + min(fBufferSize / 2, fMSS) 1821 <= fReceiverBuffer.first_byte() + fBufferSize) { 1822 // Die rechte Grenze des Empfangerfensters wird nur anders angezeigt 1823 // als beim letzten ACK, wenn sie sich seither um mindestens 1824 // min (BufferSize/ 2, MSS) geandert hat. 1825 fAdvRcvWnd = fBufferSize - fReceiverBuffer.first_block_size(); 1828 fAdvRcvWnd = fAdvRcvNxt + fAdvRcvWnd - fReceiverBuffer.next_expected(); 1831 fAdvRcvNxt = fReceiverBuffer.next_expected(); 1833 if (fSendPeriodicACKs && 1834 (!fStrictPeriodicACKs || !fPeriodicACKTimer.IsPending())) { 1835 fPeriodicACKTimer.Set(fPeriodicACKInterval); 1838 if (fDelayedACK && fDelayedACKTimer.IsPending()) { 1839 fDelayedACKTimer.Reset(); 1842 ScheduleACKMessage(); 1845 if (!fDelayedACKTimer.IsPending()) { 1846 fDelayedACKTimer.Set(fACKDelayTime); 1848 std::cout << "TCP_Receiver::SendACK
" 1849 << "receiver
" << fLabel 1850 << ":
set delACK timer:
" 1851 << "t =
" << Event_Queue::now() << std::endl; 1858 void TCP_Receiver::ScheduleACKMessage() 1860 if (fWaitingACKMsg == 0) { 1861 fWaitingACKMsg = new TCP_Packet; 1864 fWaitingACKMsg->set_ACK(fAdvRcvNxt); 1865 fWaitingACKMsg->set_wnd(fAdvRcvWnd); 1866 fWaitingACKMsg->set_session_id(fSessionId); 1867 fWaitingACKMsg->set_destination_port(fLabel); 1868 fWaitingACKMsg->set_source_port(fLabel); 1869 fWaitingACKMsg->set_bit_size(8*fTCPIPHeaderLength); 1871 if (fACKSchedulingDelay > 0) { 1872 if (!fACKSchedulingTimer.IsPending()) { 1873 fACKSchedulingTimer.Set(fACKSchedulingDelay); 1877 SendACKMessage(Event_Queue::now()); 1882 void TCP_Receiver::SendACKMessage(Ttype) 1884 it_assert(fWaitingACKMsg != 0, "TCP_Receiver::SendACKMessage, no ACK message waiting
"); 1887 std::cout << "TCP_Receiver::SendACKMessage Ack sent
" 1888 << "receiver
" << fLabel 1890 << "t =
" << Event_Queue::now() 1891 << ",
" << (*fWaitingACKMsg) 1892 << " byte_size=
" << fWaitingACKMsg->bit_size() / 8 1893 << " ptr=
" << fWaitingACKMsg << std::endl; 1896 tcp_send_ack(fWaitingACKMsg); 1902 void TCP_Receiver::TraceReceivedSeqNo(const Sequence_Number &sn) 1905 std::cout << "TCP_Receiver::TraceReceivedSeqNo
" 1906 << "receiver
" << fLabel 1907 << " t =
" << Event_Queue::now() 1908 << " sn =
" << sn << std::endl; 1910 if (received_seq_num_index >= received_seq_num_time.size()) { 1911 received_seq_num_time.set_size(2*received_seq_num_time.size(), true); 1912 received_seq_num_val.set_size(2*received_seq_num_val.size(), true); 1914 received_seq_num_val(received_seq_num_index) = sn.value(); 1915 received_seq_num_time(received_seq_num_index) = Event_Queue::now(); 1916 received_seq_num_index++; 1920 void TCP_Receiver::save_trace(std::string filename) 1923 received_seq_num_val.set_size(received_seq_num_index, true); 1924 received_seq_num_time.set_size(received_seq_num_index, true); 1927 std::cout << "received_seq_num_val
" << received_seq_num_val << std::endl; 1928 std::cout << "received_seq_num_time
" << received_seq_num_time << std::endl; 1929 std::cout << "received_seq_num_index
" << received_seq_num_index << std::endl; 1930 std::cout << "TCP_Receiver::saving
to file:
" << filename << std::endl; 1936 ff2 << Name("received_seq_num_val
") << received_seq_num_val; 1937 ff2 << Name("received_seq_num_time
") << received_seq_num_time; 1938 ff2 << Name("received_seq_num_index
") << received_seq_num_index; 1948 #pragma warning(default:4355) std::ostream & operator<<(std::ostream &os, const Array< T > &a)
Output stream for Array<T>. T must have ostream operator<< defined.
TCP_Segment()
ADD DOCUMENTATION HERE.
Definition of classes for the IT++ file format.
int bit_size()
get size of packet in bits
std::string to_str(const T &i)
Convert anything to string.
#define it_assert(t, s)
Abort if t is not true.
int length(const Vec< T > &v)
Length of vector.
ITPP_EXPORT double round(double x)
Round to nearest integer, return result in double.
T min(const Vec< T > &in)
Minimum value of vector.
vec exp(const vec &x)
Exp of the elements of a vector x.
T max(const Vec< T > &v)
Maximum value of vector.
int size(const Vec< T > &v)
Length of vector.
T to(double x)
Convert double to T.
Definition of Transport Control Protocol (TCP)
vec ceil(const vec &x)
Round to nearest upper integer.