00001 00033 #ifndef TCP_H 00034 #define TCP_H 00035 00036 #include <itpp/base/vec.h> 00037 #include <itpp/base/converters.h> 00038 #include <itpp/protocol/packet.h> 00039 #include <itpp/protocol/events.h> 00040 00041 00042 namespace itpp 00043 { 00044 00046 00047 00062 class Sequence_Number 00063 { 00064 public: 00066 Sequence_Number() : seq(0) { } 00068 Sequence_Number(const Sequence_Number &n) : seq(n.seq) { } 00070 Sequence_Number &operator=(const Sequence_Number &n) { seq = n.seq; return *this; } 00072 Sequence_Number &operator=(const int &rep) { seq = rep; return *this; } 00073 00074 //relational operators 00076 bool operator==(const Sequence_Number &n) const { return seq == n.seq; } 00078 bool operator!=(const Sequence_Number &n) const { return seq != n.seq; } 00080 bool operator>(const Sequence_Number &n) const { return (seq - n.seq) > 0; } 00082 bool operator>=(const Sequence_Number &n) const { return (seq - n.seq) >= 0; } 00084 bool operator<(const Sequence_Number &n) const { return (seq - n.seq) < 0; } 00086 bool operator<=(const Sequence_Number &n) const { return (seq - n.seq) <= 0; } 00087 00088 //addition and subtraction 00090 Sequence_Number operator+(const int n) const { return Sequence_Number(seq + n); } 00092 Sequence_Number &operator+=(const int n) { seq += n; return *this; } 00094 Sequence_Number operator-(const int n) const { return Sequence_Number(seq - n); } 00096 Sequence_Number &operator-=(const int n) { seq -= n; return *this; } 00098 int operator-(const Sequence_Number &n) const { return seq - n.seq; } 00099 00101 int value() const { return seq; } 00102 00104 friend Sequence_Number operator+(const int n1, const Sequence_Number &n2) { return Sequence_Number(n1 + n2.seq); } 00106 friend std::ostream &operator<<(std::ostream &os, const Sequence_Number &n) { os << n.seq; return os; } 00107 00108 protected: 00110 Sequence_Number(int n) : seq(n) {} 00112 int seq; 00113 }; 00114 00116 inline const Sequence_Number & min(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 < n2) ? n1 : n2; } 00118 inline const Sequence_Number & max(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 > n2) ? n1 : n2; } 00119 00120 00121 00136 class TCP_Segment 00137 { 00138 public: 00140 TCP_Segment(); 00142 TCP_Segment(const Sequence_Number &sn_begin, const Sequence_Number &sn_end); 00144 TCP_Segment(const TCP_Segment &segment); 00145 00146 //modification 00148 TCP_Segment &operator=(const TCP_Segment &segment); 00150 void set_begin(const Sequence_Number &sn); 00152 void set_end(const Sequence_Number &sn); 00154 void combine(const TCP_Segment &segment); 00155 00156 //query 00158 bool operator==(const TCP_Segment &segment) const; 00160 bool operator!=(const TCP_Segment &segment) const; 00162 bool can_be_combined(const TCP_Segment &segment) const; 00164 bool is_contained(const TCP_Segment &segment) const; 00166 unsigned length() const; 00168 Sequence_Number begin() const { return seq_begin; } 00170 Sequence_Number end() const { return seq_end; } 00171 00173 friend std::ostream & operator<<(std::ostream &os, const TCP_Segment &segment); 00174 00175 protected: 00176 Sequence_Number seq_begin; 00177 Sequence_Number seq_end; 00178 }; 00179 00180 00202 class TCP_Packet : public itpp::Packet 00203 { 00204 public: 00206 TCP_Packet(); 00208 TCP_Packet(const TCP_Packet &packet); 00210 virtual ~TCP_Packet(); 00212 virtual TCP_Packet &clone() const; 00213 00214 //TCP window mechanism 00216 void set_segment(const TCP_Segment &seg) { fSegment = seg; } 00218 TCP_Segment get_segment() const { return fSegment; } 00220 void set_wnd(unsigned val) { fWnd = val; } 00222 unsigned get_wnd() const { return fWnd; } 00224 void set_ACK(Sequence_Number val) { fACK = val; } 00226 Sequence_Number get_ACK() const { return fACK; } 00227 00228 //session control 00230 void set_session_id(int val) { fSessionId = val; } 00232 int get_session_id() const { return fSessionId; } 00233 00234 //debugging support 00236 void set_destination_port(unsigned val) { fDestinationPort = val; } 00238 unsigned get_destination_port() const { return fDestinationPort; } 00240 void set_source_port(unsigned val) { fSourcePort = val; } 00242 unsigned get_source_port() const { return fSourcePort; } 00244 void set_info(unsigned ssThresh, unsigned recWnd, unsigned cWnd, double estRTT, Sequence_Number sndUna, Sequence_Number sndNxt, bool isRtx); 00246 virtual void print_header(std::ostream &) const; 00247 00248 protected: 00250 unsigned fDestinationPort; 00252 unsigned fSourcePort; 00253 00254 TCP_Segment fSegment; 00255 Sequence_Number fACK; 00256 unsigned fWnd; 00257 int fSessionId; 00259 //Tracing 00260 00262 struct TDebugInfo { 00263 unsigned fSSThresh; 00264 unsigned fRecWnd; 00265 unsigned fCWnd; 00266 double fRTTEstimate; 00267 Sequence_Number fSndUna; 00268 Sequence_Number fSndNxt; 00269 bool fRtxFlag; 00270 }; 00271 00273 TDebugInfo *fInfo; 00274 00276 friend std::ostream & operator<<(std::ostream &, TCP_Packet &); 00277 }; 00278 00279 00314 class TCP_Sender 00315 { 00316 public: 00318 TCP_Sender(int label); 00319 00321 virtual ~TCP_Sender(); 00322 00323 //connection control 00325 virtual void setup(); 00327 virtual void release(std::string trace_filename = ""); 00328 00330 virtual void print_item(std::ostream &, const std::string &); 00331 00333 virtual void set_debug(const bool enable_debug = true); 00335 virtual void set_debug(bool enable_debug, bool enable_signal_debug); 00337 virtual void set_trace(const bool enable_trace = true); 00339 virtual void save_trace(std::string filename); 00340 00342 Signal<itpp::Packet*> tcp_send; 00344 Slot<TCP_Sender, itpp::Packet*> tcp_receive_ack; 00346 Slot<TCP_Sender, itpp::Packet*> tcp_socket_write; 00348 Slot<TCP_Sender, std::string> tcp_release; 00349 00350 00351 //Signal<itpp::Packet*> TcpSendSignal; 00352 //Slot<TCP_Sender, itpp::Packet*> TcpRecvAckSlot; 00353 //Slot<TCP_Sender, itpp::Packet*> SocketWriteSlot; 00354 //Slot<TCP_Sender, string> ReleaseSlot; 00355 00356 private: 00357 std::queue<itpp::Packet*> SocketWriteQueue; 00358 00359 virtual void InitStatistics(); 00360 virtual void HandleACK(TCP_Packet &); 00361 virtual void SendNewData(bool skipSWSA = false); 00362 virtual void UnaRetransmit(); 00363 virtual void FinishFastRecovery(); 00364 virtual void ReduceSSThresh(); 00365 virtual void SendMsg(TCP_Packet & msg); 00366 virtual void HandleRtxTimeout(Ttype); 00367 virtual void IdleCheck(); 00368 virtual void HandleSWSATimeout(Ttype); 00369 virtual unsigned GetNextSegmentSize(const Sequence_Number & begin); 00370 virtual unsigned SendWindow() const; 00371 virtual double CalcRTOValue() const; 00372 virtual void SetRtxTimer(); 00373 virtual void UpdateRTTVariables(double sampleRTT); 00374 virtual void TraceCWnd(); 00375 virtual void TraceSentSeqNo(const Sequence_Number sn); 00376 virtual void TraceACKedSeqNo(const Sequence_Number sn); 00377 virtual void TraceRTTVariables(double sampleRTT); 00378 virtual void TraceSSThresh(); 00379 virtual std::string GenerateFilename(); 00380 00381 void StopTransientPhase(); 00383 enum eTCPVersion {kTahoe, kReno, kNewReno}; 00384 00385 virtual void set_label(int label); 00386 00387 //socket variables 00388 unsigned fLabel; // end point identification also used at receiver 00389 00390 //message handling 00391 virtual void HandleUserMessageIndication(itpp::Packet *user_data); 00392 virtual void ReceiveMessageFromNet(itpp::Packet *msg); 00393 00394 //parameters parsed from input file 00395 eTCPVersion fTCPVersion; // one of Reno, Tahoe, NewReno 00396 unsigned fMSS; // maximum segment size 00397 unsigned fTCPIPHeaderLength; 00398 double fInitialRTT; 00399 unsigned fInitialCWnd; 00400 unsigned fInitialSSThresh; 00401 unsigned fMaxCWnd; 00402 unsigned fDupACKThreshold; 00403 double fTimerGranularity; 00404 double fMaxRTO; // max value of retransmission TO 00405 unsigned fMaxBackoff; 00406 bool fImmediateBackoffReset; 00407 bool fKarn; 00408 bool fGoBackN; 00409 bool fFlightSizeRecovery;// use flight size on fast rec. exit 00410 bool fRenoConservation; 00411 bool fCarefulSSThreshReduction; 00412 bool fIgnoreDupACKOnTORecovery; 00413 bool fCarefulMulFastRtxAvoidance; 00414 bool fNagle; 00415 double fSWSATimerValue; 00416 bool fRestartAfterIdle; 00417 bool fTraceCWnd; // print CWnd trace to cout 00418 bool fTraceSentSeqNo; 00419 bool fTraceACKedSeqNo; 00420 bool fDebug; // print additional information to cout 00421 bool fTrace; // store trace info in vectors 00422 00423 //session identification 00424 int fSessionId; 00426 //TCP flow control (RFC 793) 00427 Sequence_Number fSndUna; // lowest unacknowledged sn 00428 Sequence_Number fSndNxt; // next byte to be sent 00429 Sequence_Number fSndMax; 00430 unsigned fRecWnd; // receiver advertised window 00431 unsigned fMaxRecWnd; 00432 Sequence_Number fUserNxt; // next byte to be received from user 00433 00434 //TCP congestion avoidance (RFC 2581, RFC 2001, RFC 2582) 00435 unsigned fCWnd; // congestion window 00436 unsigned fSSThresh; 00437 unsigned fDupACKCnt; 00438 Sequence_Number fRecoveryDupACK; 00439 Sequence_Number fRecoveryTO; 00441 //TCP timers 00442 TTimer<TCP_Sender> fRtxTimer; 00443 Sequence_Number fTimUna; 00444 TTimer<TCP_Sender> fSWSATimer; 00445 int fBackoff; 00446 bool fPendingBackoffReset; 00447 Ttype fLastSendTime; 00449 //round trip time measurement (RTTM) 00450 double fSRTT; 00451 double fRTTVar; 00452 double fRTTEstimate; 00453 Sequence_Number fRTTMByte; 00454 bool fRTTMPending; 00455 double fRTTMStartTime; 00457 //statistic counters 00458 unsigned long fNumberOfTimeouts; 00459 unsigned long fNumberOfFastRetransmits; 00460 unsigned long fNumberOfRTTMeasurements; 00461 unsigned long fNumberOfReceivedACKs; 00462 unsigned long fNumberOfIdleTimeouts; 00463 00464 vec CWnd_val; 00465 vec CWnd_time; 00466 int CWnd_index; 00467 00468 vec SSThresh_val; 00469 vec SSThresh_time; 00470 int SSThresh_index; 00471 00472 ivec sent_seq_num_val; 00473 vec sent_seq_num_time; 00474 int sent_seq_num_index; 00475 00476 ivec sender_recv_ack_seq_num_val; 00477 vec sender_recv_ack_seq_num_time; 00478 int sender_recv_ack_seq_num_index; 00479 00480 vec RTTEstimate_val; 00481 vec RTTEstimate_time; 00482 int RTTEstimate_index; 00483 00484 vec RTTsample_val; 00485 vec RTTsample_time; 00486 int RTTsample_index; 00487 }; 00488 00489 00510 class TCP_Receiver_Buffer 00511 { 00512 public: 00514 TCP_Receiver_Buffer(); 00516 TCP_Receiver_Buffer(const TCP_Receiver_Buffer &); 00518 ~TCP_Receiver_Buffer(); 00519 00520 void reset(); 00522 void write(TCP_Segment newBlock); 00523 void read(unsigned noOfBytes); 00525 unsigned first_block_size() const; 00526 Sequence_Number first_byte() const; 00527 Sequence_Number last_byte() const; 00528 Sequence_Number next_expected() const; 00529 00530 unsigned window() const; 00531 00532 std::ostream &info(std::ostream &os, int detail = 0) const; 00534 protected: 00535 Sequence_Number fFirstByte; 00537 00538 std::list <TCP_Segment> fBufList; 00539 }; 00540 00541 00542 00543 00573 class TCP_Receiver 00574 { 00575 public: 00576 00578 TCP_Receiver(int label); 00580 virtual ~TCP_Receiver(); 00581 00582 //name connection control 00584 virtual void setup(); 00586 virtual void release(std::string trace_filename = ""); 00587 00588 //message handling 00589 itpp::Packet & get_user_message(); 00590 bool is_user_message_available(); 00592 00593 virtual void set_debug(const bool enable_debug = true); 00595 virtual void set_debug(bool enable_debug, bool enable_signal_debug); 00597 virtual void set_trace(const bool enable_trace = true); 00599 virtual void save_trace(std::string filename); 00600 00602 Signal<itpp::Packet*> tcp_send_ack; 00604 Slot<TCP_Receiver, itpp::Packet*> tcp_receive; 00605 Signal<int> tcp_new_data; 00606 00607 Slot<TCP_Receiver, std::string> tcp_release; 00608 00609 private: 00610 void IndicateUserMessage(); 00611 virtual void ReceiveMessageFromNet(itpp::Packet* msg); 00613 virtual void ReceiveDataPacket(TCP_Packet & packet); 00614 virtual void SendACK(bool); 00615 virtual void ScheduleACKMessage(); 00616 virtual void SendACKMessage(Ttype); 00617 virtual void DelayedACKHandler(Ttype); 00618 virtual void PeriodicACKHandler(Ttype); 00619 virtual void HandleEndOfProcessing(Ttype); 00620 virtual void TraceReceivedSeqNo(const Sequence_Number &sn); 00621 virtual std::string GenerateFilename(); 00622 00623 //basic variables 00624 TCP_Receiver_Buffer fReceiverBuffer; 00625 unsigned fLabel; 00626 00627 //parameters read by the parser 00628 unsigned fTCPIPHeaderLength; 00629 unsigned fMSS; 00630 unsigned fBufferSize; 00631 bool fDelayedACK; 00632 Ttype fACKDelayTime; 00633 bool fSendPeriodicACKs; 00634 bool fStrictPeriodicACKs; 00635 Ttype fPeriodicACKInterval;// interval after which an ACK is repeated 00636 Ttype fACKSchedulingDelay; 00637 bool fACKOnBufferWrite; 00638 bool fACKOnBufferRead; 00639 unsigned fMaxUserBlockSize; 00640 unsigned fMinUserBlockSize; 00641 double fUserBlockProcDelay; 00642 bool fTrace; 00643 bool fDebug; 00645 //specific TCP variables 00646 Sequence_Number fAdvRcvNxt; 00647 unsigned fAdvRcvWnd; 00649 //session management 00650 int fSessionId; 00652 //ACK timers 00653 TTimer<TCP_Receiver> fDelayedACKTimer; 00654 TTimer<TCP_Receiver> fPeriodicACKTimer; 00655 TTimer<TCP_Receiver> fACKSchedulingTimer; 00656 TCP_Packet * fWaitingACKMsg; 00657 00658 //user data delivery 00659 Packet * fUserMessage; 00660 TTimer<TCP_Receiver> fUserBlockProcTimer; 00661 00662 00663 //statistic counters 00664 ivec received_seq_num_val; 00665 vec received_seq_num_time; 00666 int received_seq_num_index; 00667 00668 }; 00669 00670 00671 00672 // ------------------------------- Inline definitions --------------------------------------------- 00673 00674 00675 00676 inline Sequence_Number TCP_Receiver_Buffer::first_byte() const 00677 { 00678 return fFirstByte; 00679 } 00680 00681 00682 inline Sequence_Number TCP_Receiver_Buffer::last_byte() const 00683 { 00684 if (fBufList.empty()) { 00685 return fFirstByte; 00686 } 00687 else { 00688 return fBufList.back().end(); 00689 } 00690 } 00691 00692 00693 inline Sequence_Number TCP_Receiver_Buffer::next_expected() const 00694 { 00695 return fFirstByte + first_block_size(); 00696 } 00697 00698 00699 inline void TCP_Segment::set_begin(const Sequence_Number &sn) 00700 { 00701 seq_begin = sn; 00702 00703 it_assert(seq_begin <= seq_end, "TCP_Segment::begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value())); 00704 } 00705 00706 00707 inline void TCP_Segment::set_end(const Sequence_Number &sn) 00708 { 00709 seq_end = sn; 00710 00711 it_assert(seq_begin <= seq_end, "TCP_Segment::set_begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value())); 00712 } 00713 00714 00715 inline bool TCP_Segment::operator==(const TCP_Segment &segment) const 00716 { 00717 return (this->seq_begin == segment.seq_begin) && (this->seq_end == segment.seq_end); 00718 } 00719 00720 00721 inline bool TCP_Segment::operator!=(const TCP_Segment &segment) const 00722 { 00723 return (this->seq_begin != segment.seq_begin) || (this->seq_end != segment.seq_end); 00724 } 00725 00726 00727 inline bool TCP_Segment::can_be_combined(const TCP_Segment &segment) const 00728 { 00729 return (this->seq_begin <= segment.seq_end) && (segment.seq_begin <= this->seq_end); 00730 } 00731 00732 00733 inline bool TCP_Segment::is_contained(const TCP_Segment &segment) const 00734 { 00735 return (segment.seq_begin <= this->seq_begin) && (this->seq_end <= segment.seq_end); 00736 } 00737 00738 00739 inline unsigned TCP_Segment::length() const 00740 { 00741 return seq_end - seq_begin; 00742 } 00743 00745 00746 00747 } // namespace itpp 00748 00749 #endif // #ifndef TCP_H 00750
Generated on Wed Feb 9 2011 13:47:17 for IT++ by Doxygen 1.7.3