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 00045 00046 00061 class Sequence_Number { 00062 public: 00064 Sequence_Number() : seq(0) { } 00066 Sequence_Number(const Sequence_Number &n) : seq(n.seq) { } 00068 Sequence_Number &operator=(const Sequence_Number &n) { seq = n.seq; return *this; } 00070 Sequence_Number &operator=(const int &rep) { seq = rep; return *this; } 00071 00072 //relational operators 00074 bool operator==(const Sequence_Number &n) const { return seq == n.seq; } 00076 bool operator!=(const Sequence_Number &n) const { return seq != n.seq; } 00078 bool operator>(const Sequence_Number &n) const { return (seq - n.seq) > 0; } 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; } 00085 00086 //addition and subtraction 00088 Sequence_Number operator+(const int n) const { return Sequence_Number(seq + n); } 00090 Sequence_Number &operator+=(const int n) { seq += n; return *this; } 00092 Sequence_Number operator-(const int n) const { return Sequence_Number(seq - n); } 00094 Sequence_Number &operator-=(const int n) { seq -= n; return *this; } 00096 int operator-(const Sequence_Number &n) const { return seq - n.seq; } 00097 00099 int value() const { return seq; } 00100 00102 friend Sequence_Number operator+(const int n1, const Sequence_Number &n2) { return Sequence_Number(n1 + n2.seq); } 00104 friend std::ostream &operator<<(std::ostream &os, const Sequence_Number &n) { os << n.seq; return os; } 00105 00106 protected: 00108 Sequence_Number(int n) : seq(n) {} 00110 int seq; 00111 }; 00112 00114 inline const Sequence_Number & min(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 < n2)? n1 : n2; } 00116 inline const Sequence_Number & max(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 > n2)? n1 : n2; } 00117 00118 00119 00134 class TCP_Segment { 00135 public: 00137 TCP_Segment(); 00139 TCP_Segment(const Sequence_Number &sn_begin, const Sequence_Number &sn_end); 00141 TCP_Segment(const TCP_Segment &segment); 00142 00143 //modification 00145 TCP_Segment &operator=(const TCP_Segment &segment); 00147 void set_begin(const Sequence_Number &sn); 00149 void set_end(const Sequence_Number &sn); 00151 void combine(const TCP_Segment &segment); 00152 00153 //query 00155 bool operator==(const TCP_Segment &segment) const; 00157 bool operator!=(const TCP_Segment &segment) const; 00159 bool can_be_combined(const TCP_Segment &segment) const; 00161 bool is_contained(const TCP_Segment &segment) const; 00163 unsigned length() const; 00165 Sequence_Number begin() const { return seq_begin; } 00167 Sequence_Number end() const { return seq_end; } 00168 00170 friend std::ostream & operator<<(std::ostream &os, const TCP_Segment &segment); 00171 00172 protected: 00173 Sequence_Number seq_begin; 00174 Sequence_Number seq_end; 00175 }; 00176 00177 00199 class TCP_Packet : public itpp::Packet { 00200 public: 00202 TCP_Packet(); 00204 TCP_Packet(const TCP_Packet &packet); 00206 virtual ~TCP_Packet(); 00208 virtual TCP_Packet &clone() const; 00209 00210 //TCP window mechanism 00212 void set_segment(const TCP_Segment &seg) { fSegment = seg; } 00214 TCP_Segment get_segment() const { return fSegment; } 00216 void set_wnd(unsigned val) { fWnd = val; } 00218 unsigned get_wnd() const { return fWnd; } 00220 void set_ACK(Sequence_Number val) { fACK = val; } 00222 Sequence_Number get_ACK() const { return fACK; } 00223 00224 //session control 00226 void set_session_id(int val) { fSessionId = val; } 00228 int get_session_id() const { return fSessionId; } 00229 00230 //debugging support 00232 void set_destination_port(unsigned val) { fDestinationPort = val; } 00234 unsigned get_destination_port() const { return fDestinationPort; } 00236 void set_source_port(unsigned val) { fSourcePort = val; } 00238 unsigned get_source_port() const { return fSourcePort; } 00240 void set_info(unsigned ssThresh, unsigned recWnd, unsigned cWnd, double estRTT, Sequence_Number sndUna, Sequence_Number sndNxt, bool isRtx); 00242 virtual void print_header (std::ostream &out) const; 00243 00244 protected: 00246 unsigned fDestinationPort; 00248 unsigned fSourcePort; 00249 00250 TCP_Segment fSegment; 00251 Sequence_Number fACK; 00252 unsigned fWnd; 00253 int fSessionId; 00255 //Tracing 00256 00258 struct TDebugInfo { 00259 unsigned fSSThresh; 00260 unsigned fRecWnd; 00261 unsigned fCWnd; 00262 double fRTTEstimate; 00263 Sequence_Number fSndUna; 00264 Sequence_Number fSndNxt; 00265 bool fRtxFlag; 00266 }; 00267 00269 TDebugInfo *fInfo; 00270 00272 friend std::ostream & operator<<(std::ostream &, TCP_Packet &); 00273 }; 00274 00275 00310 class TCP_Sender { 00311 public: 00313 TCP_Sender(int label); 00314 00316 virtual ~TCP_Sender(); 00317 00318 //connection control 00320 virtual void setup(); 00322 virtual void release(std::string trace_filename=""); 00323 00325 virtual void print_item(std::ostream &, const std::string &); 00326 00328 virtual void set_debug(const bool enable_debug = true); 00330 virtual void set_debug(bool enable_debug, bool enable_signal_debug); 00332 virtual void set_trace(const bool enable_trace = true); 00334 virtual void save_trace(std::string filename); 00335 00337 Signal<itpp::Packet*> tcp_send; 00339 Slot<TCP_Sender, itpp::Packet*> tcp_receive_ack; 00341 Slot<TCP_Sender, itpp::Packet*> tcp_socket_write; 00343 Slot<TCP_Sender, std::string> tcp_release; 00344 00345 00346 //Signal<itpp::Packet*> TcpSendSignal; 00347 //Slot<TCP_Sender, itpp::Packet*> TcpRecvAckSlot; 00348 //Slot<TCP_Sender, itpp::Packet*> SocketWriteSlot; 00349 //Slot<TCP_Sender, string> ReleaseSlot; 00350 00351 private: 00352 std::queue<itpp::Packet*> SocketWriteQueue; 00353 00354 virtual void InitStatistics(); 00355 virtual void HandleACK(TCP_Packet &); 00356 virtual void SendNewData(bool skipSWSA = false); 00357 virtual void UnaRetransmit(); 00358 virtual void FinishFastRecovery(); 00359 virtual void ReduceSSThresh(); 00360 virtual void SendMsg(TCP_Packet & msg); 00361 virtual void HandleRtxTimeout(Ttype); 00362 virtual void IdleCheck(); 00363 virtual void HandleSWSATimeout(Ttype); 00364 virtual unsigned GetNextSegmentSize(const Sequence_Number & begin); 00365 virtual unsigned SendWindow() const; 00366 virtual double CalcRTOValue() const; 00367 virtual void SetRtxTimer(); 00368 virtual void UpdateRTTVariables(double sampleRTT); 00369 virtual void TraceCWnd(); 00370 virtual void TraceSentSeqNo(const Sequence_Number sn); 00371 virtual void TraceACKedSeqNo(const Sequence_Number sn); 00372 virtual void TraceRTTVariables(double sampleRTT); 00373 virtual void TraceSSThresh(); 00374 virtual std::string GenerateFilename(); 00375 00376 void StopTransientPhase(); 00378 enum eTCPVersion {kTahoe, kReno, kNewReno}; 00379 00380 virtual void set_label(int label); 00381 00382 //socket variables 00383 unsigned fLabel; // end point identification also used at receiver 00384 00385 //message handling 00386 virtual void HandleUserMessageIndication(itpp::Packet *user_data); 00387 virtual void ReceiveMessageFromNet(itpp::Packet *msg); 00388 00389 //parameters parsed from input file 00390 eTCPVersion fTCPVersion; // one of Reno, Tahoe, NewReno 00391 unsigned fMSS; // maximum segment size 00392 unsigned fTCPIPHeaderLength; 00393 double fInitialRTT; 00394 unsigned fInitialCWnd; 00395 unsigned fInitialSSThresh; 00396 unsigned fMaxCWnd; 00397 unsigned fDupACKThreshold; 00398 double fTimerGranularity; 00399 double fMaxRTO; // max value of retransmission TO 00400 unsigned fMaxBackoff; 00401 bool fImmediateBackoffReset; 00402 bool fKarn; 00403 bool fGoBackN; 00404 bool fFlightSizeRecovery;// use flight size on fast rec. exit 00405 bool fRenoConservation; 00406 bool fCarefulSSThreshReduction; 00407 bool fIgnoreDupACKOnTORecovery; 00408 bool fCarefulMulFastRtxAvoidance; 00409 bool fNagle; 00410 double fSWSATimerValue; 00411 bool fRestartAfterIdle; 00412 bool fTraceCWnd; // print CWnd trace to cout 00413 bool fTraceSentSeqNo; 00414 bool fTraceACKedSeqNo; 00415 bool fDebug; // print additional information to cout 00416 bool fTrace; // store trace info in vectors 00417 00418 //session identification 00419 int fSessionId; 00421 //TCP flow control (RFC 793) 00422 Sequence_Number fSndUna; // lowest unacknowledged sn 00423 Sequence_Number fSndNxt; // next byte to be sent 00424 Sequence_Number fSndMax; 00425 unsigned fRecWnd; // receiver advertised window 00426 unsigned fMaxRecWnd; 00427 Sequence_Number fUserNxt; // next byte to be received from user 00428 00429 //TCP congestion avoidance (RFC 2581, RFC 2001, RFC 2582) 00430 unsigned fCWnd; // congestion window 00431 unsigned fSSThresh; 00432 unsigned fDupACKCnt; 00433 Sequence_Number fRecoveryDupACK; 00434 Sequence_Number fRecoveryTO; 00436 //TCP timers 00437 TTimer<TCP_Sender> fRtxTimer; 00438 Sequence_Number fTimUna; 00439 TTimer<TCP_Sender> fSWSATimer; 00440 int fBackoff; 00441 bool fPendingBackoffReset; 00442 Ttype fLastSendTime; 00444 //round trip time measurement (RTTM) 00445 double fSRTT; 00446 double fRTTVar; 00447 double fRTTEstimate; 00448 Sequence_Number fRTTMByte; 00449 bool fRTTMPending; 00450 double fRTTMStartTime; 00452 //statistic counters 00453 unsigned long fNumberOfTimeouts; 00454 unsigned long fNumberOfFastRetransmits; 00455 unsigned long fNumberOfRTTMeasurements; 00456 unsigned long fNumberOfReceivedACKs; 00457 unsigned long fNumberOfIdleTimeouts; 00458 00459 vec CWnd_val; 00460 vec CWnd_time; 00461 int CWnd_index; 00462 00463 vec SSThresh_val; 00464 vec SSThresh_time; 00465 int SSThresh_index; 00466 00467 ivec sent_seq_num_val; 00468 vec sent_seq_num_time; 00469 int sent_seq_num_index; 00470 00471 ivec sender_recv_ack_seq_num_val; 00472 vec sender_recv_ack_seq_num_time; 00473 int sender_recv_ack_seq_num_index; 00474 00475 vec RTTEstimate_val; 00476 vec RTTEstimate_time; 00477 int RTTEstimate_index; 00478 00479 vec RTTsample_val; 00480 vec RTTsample_time; 00481 int RTTsample_index; 00482 }; 00483 00484 00505 class TCP_Receiver_Buffer { 00506 public: 00508 TCP_Receiver_Buffer(); 00510 TCP_Receiver_Buffer(const TCP_Receiver_Buffer &); 00512 ~TCP_Receiver_Buffer(); 00513 00514 void reset(); 00516 void write(TCP_Segment newBlock); 00517 void read(unsigned noOfBytes); 00519 unsigned first_block_size() const; 00520 Sequence_Number first_byte() const; 00521 Sequence_Number last_byte() const; 00522 Sequence_Number next_expected() const; 00523 00524 unsigned window() const; 00525 00526 std::ostream &info(std::ostream &os, int detail = 0) const; 00528 protected: 00529 Sequence_Number fFirstByte; 00531 00532 std::list <TCP_Segment> fBufList; 00533 }; 00534 00535 00536 00537 00567 class TCP_Receiver { 00568 public: 00569 00571 TCP_Receiver(int label); 00573 virtual ~TCP_Receiver (); 00574 00575 //name connection control 00577 virtual void setup(); 00579 virtual void release(std::string trace_filename=""); 00580 00581 //message handling 00582 itpp::Packet & get_user_message(); 00583 bool is_user_message_available(); 00585 00586 virtual void set_debug(const bool enable_debug = true); 00588 virtual void set_debug(bool enable_debug, bool enable_signal_debug); 00590 virtual void set_trace(const bool enable_trace = true); 00592 virtual void save_trace(std::string filename); 00593 00595 Signal<itpp::Packet*> tcp_send_ack; 00597 Slot<TCP_Receiver, itpp::Packet*> tcp_receive; 00598 Signal<int> tcp_new_data; 00599 00600 Slot<TCP_Receiver, std::string> tcp_release; 00601 00602 private: 00603 void IndicateUserMessage(); 00604 virtual void ReceiveMessageFromNet(itpp::Packet* msg); 00606 virtual void ReceiveDataPacket(TCP_Packet & packet); 00607 virtual void SendACK(bool); 00608 virtual void ScheduleACKMessage(); 00609 virtual void SendACKMessage(Ttype); 00610 virtual void DelayedACKHandler(Ttype); 00611 virtual void PeriodicACKHandler(Ttype); 00612 virtual void HandleEndOfProcessing(Ttype); 00613 virtual void TraceReceivedSeqNo(const Sequence_Number &sn); 00614 virtual std::string GenerateFilename(); 00615 00616 //basic variables 00617 TCP_Receiver_Buffer fReceiverBuffer; 00618 unsigned fLabel; 00619 00620 //parameters read by the parser 00621 unsigned fTCPIPHeaderLength; 00622 unsigned fMSS; 00623 unsigned fBufferSize; 00624 bool fDelayedACK; 00625 Ttype fACKDelayTime; 00626 bool fSendPeriodicACKs; 00627 bool fStrictPeriodicACKs; 00628 Ttype fPeriodicACKInterval;// interval after which an ACK is repeated 00629 Ttype fACKSchedulingDelay; 00630 bool fACKOnBufferWrite; 00631 bool fACKOnBufferRead; 00632 unsigned fMaxUserBlockSize; 00633 unsigned fMinUserBlockSize; 00634 double fUserBlockProcDelay; 00635 bool fTrace; 00636 bool fDebug; 00638 //specific TCP variables 00639 Sequence_Number fAdvRcvNxt; 00640 unsigned fAdvRcvWnd; 00642 //session management 00643 int fSessionId; 00645 //ACK timers 00646 TTimer<TCP_Receiver> fDelayedACKTimer; 00647 TTimer<TCP_Receiver> fPeriodicACKTimer; 00648 TTimer<TCP_Receiver> fACKSchedulingTimer; 00649 TCP_Packet * fWaitingACKMsg; 00650 00651 //user data delivery 00652 Packet * fUserMessage; 00653 TTimer<TCP_Receiver> fUserBlockProcTimer; 00654 00655 00656 //statistic counters 00657 ivec received_seq_num_val; 00658 vec received_seq_num_time; 00659 int received_seq_num_index; 00660 00661 }; 00662 00663 00664 00665 // ------------------------------- Inline definitions --------------------------------------------- 00666 00667 00668 00669 inline Sequence_Number TCP_Receiver_Buffer::first_byte() const 00670 { 00671 return fFirstByte; 00672 } 00673 00674 00675 inline Sequence_Number TCP_Receiver_Buffer::last_byte() const 00676 { 00677 if (fBufList.empty()) { 00678 return fFirstByte; 00679 } else { 00680 return fBufList.back().end(); 00681 } 00682 } 00683 00684 00685 inline Sequence_Number TCP_Receiver_Buffer::next_expected() const 00686 { 00687 return fFirstByte + first_block_size(); 00688 } 00689 00690 00691 inline void TCP_Segment::set_begin(const Sequence_Number &sn) 00692 { 00693 seq_begin = sn; 00694 00695 it_assert(seq_begin <= seq_end, "TCP_Segment::begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value())); 00696 } 00697 00698 00699 inline void TCP_Segment::set_end(const Sequence_Number &sn) 00700 { 00701 seq_end = sn; 00702 00703 it_assert(seq_begin <= seq_end, "TCP_Segment::set_begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value())); 00704 } 00705 00706 00707 inline bool TCP_Segment::operator==(const TCP_Segment &segment) const 00708 { 00709 return (this->seq_begin == segment.seq_begin) && (this->seq_end == segment.seq_end); 00710 } 00711 00712 00713 inline bool TCP_Segment::operator!=(const TCP_Segment &segment) const 00714 { 00715 return (this->seq_begin != segment.seq_begin) || (this->seq_end != segment.seq_end); 00716 } 00717 00718 00719 inline bool TCP_Segment::can_be_combined(const TCP_Segment &segment) const 00720 { 00721 return (this->seq_begin <= segment.seq_end) && (segment.seq_begin <= this->seq_end); 00722 } 00723 00724 00725 inline bool TCP_Segment::is_contained(const TCP_Segment &segment) const 00726 { 00727 return (segment.seq_begin <= this->seq_begin) && (this->seq_end <= segment.seq_end); 00728 } 00729 00730 00731 inline unsigned TCP_Segment::length() const 00732 { 00733 return seq_end - seq_begin; 00734 } 00735 00737 00738 00739 } // namespace itpp 00740 00741 #endif // #ifndef TCP_H 00742
Generated on Thu Apr 24 13:39:01 2008 for IT++ by Doxygen 1.5.5