00001 00032 #ifndef TCP_H 00033 #define TCP_H 00034 00035 #include <itpp/base/vec.h> 00036 #include <itpp/base/converters.h> 00037 #include <itpp/protocol/packet.h> 00038 #include <itpp/protocol/events.h> 00039 00040 00041 namespace itpp 00042 { 00043 00045 00046 00061 class Sequence_Number 00062 { 00063 public: 00065 Sequence_Number() : seq(0) { } 00067 Sequence_Number(const Sequence_Number &n) : seq(n.seq) { } 00069 Sequence_Number &operator=(const Sequence_Number &n) { seq = n.seq; return *this; } 00071 Sequence_Number &operator=(const int &rep) { seq = rep; return *this; } 00072 00073 //relational operators 00075 bool operator==(const Sequence_Number &n) const { return seq == n.seq; } 00077 bool operator!=(const Sequence_Number &n) const { return seq != n.seq; } 00079 bool operator>(const Sequence_Number &n) const { return (seq - n.seq) > 0; } 00081 bool operator>=(const Sequence_Number &n) const { return (seq - n.seq) >= 0; } 00083 bool operator<(const Sequence_Number &n) const { return (seq - n.seq) < 0; } 00085 bool operator<=(const Sequence_Number &n) const { return (seq - n.seq) <= 0; } 00086 00087 //addition and subtraction 00089 Sequence_Number operator+(const int n) const { return Sequence_Number(seq + n); } 00091 Sequence_Number &operator+=(const int n) { seq += n; return *this; } 00093 Sequence_Number operator-(const int n) const { return Sequence_Number(seq - n); } 00095 Sequence_Number &operator-=(const int n) { seq -= n; return *this; } 00097 int operator-(const Sequence_Number &n) const { return seq - n.seq; } 00098 00100 int value() const { return seq; } 00101 00103 friend Sequence_Number operator+(const int n1, const Sequence_Number &n2) { return Sequence_Number(n1 + n2.seq); } 00105 friend std::ostream &operator<<(std::ostream &os, const Sequence_Number &n) { os << n.seq; return os; } 00106 00107 protected: 00109 Sequence_Number(int n) : seq(n) {} 00111 int seq; 00112 }; 00113 00115 inline const Sequence_Number & min(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 < n2) ? n1 : n2; } 00117 inline const Sequence_Number & max(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 > n2) ? n1 : n2; } 00118 00119 00120 00135 class TCP_Segment 00136 { 00137 public: 00139 TCP_Segment(); 00141 TCP_Segment(const Sequence_Number &sn_begin, const Sequence_Number &sn_end); 00143 TCP_Segment(const TCP_Segment &segment); 00144 00145 //modification 00147 TCP_Segment &operator=(const TCP_Segment &segment); 00149 void set_begin(const Sequence_Number &sn); 00151 void set_end(const Sequence_Number &sn); 00153 void combine(const TCP_Segment &segment); 00154 00155 //query 00157 bool operator==(const TCP_Segment &segment) const; 00159 bool operator!=(const TCP_Segment &segment) const; 00161 bool can_be_combined(const TCP_Segment &segment) const; 00163 bool is_contained(const TCP_Segment &segment) const; 00165 unsigned length() const; 00167 Sequence_Number begin() const { return seq_begin; } 00169 Sequence_Number end() const { return seq_end; } 00170 00172 friend std::ostream & operator<<(std::ostream &os, const TCP_Segment &segment); 00173 00174 protected: 00175 Sequence_Number seq_begin; 00176 Sequence_Number seq_end; 00177 }; 00178 00179 00201 class TCP_Packet : public itpp::Packet 00202 { 00203 public: 00205 TCP_Packet(); 00207 TCP_Packet(const TCP_Packet &packet); 00209 virtual ~TCP_Packet(); 00211 virtual TCP_Packet &clone() const; 00212 00213 //TCP window mechanism 00215 void set_segment(const TCP_Segment &seg) { fSegment = seg; } 00217 TCP_Segment get_segment() const { return fSegment; } 00219 void set_wnd(unsigned val) { fWnd = val; } 00221 unsigned get_wnd() const { return fWnd; } 00223 void set_ACK(Sequence_Number val) { fACK = val; } 00225 Sequence_Number get_ACK() const { return fACK; } 00226 00227 //session control 00229 void set_session_id(int val) { fSessionId = val; } 00231 int get_session_id() const { return fSessionId; } 00232 00233 //debugging support 00235 void set_destination_port(unsigned val) { fDestinationPort = val; } 00237 unsigned get_destination_port() const { return fDestinationPort; } 00239 void set_source_port(unsigned val) { fSourcePort = val; } 00241 unsigned get_source_port() const { return fSourcePort; } 00243 void set_info(unsigned ssThresh, unsigned recWnd, unsigned cWnd, double estRTT, Sequence_Number sndUna, Sequence_Number sndNxt, bool isRtx); 00245 virtual void print_header(std::ostream &) const; 00246 00247 protected: 00249 unsigned fDestinationPort; 00251 unsigned fSourcePort; 00252 00253 TCP_Segment fSegment; 00254 Sequence_Number fACK; 00255 unsigned fWnd; 00256 int fSessionId; 00258 //Tracing 00259 00261 struct TDebugInfo { 00262 unsigned fSSThresh; 00263 unsigned fRecWnd; 00264 unsigned fCWnd; 00265 double fRTTEstimate; 00266 Sequence_Number fSndUna; 00267 Sequence_Number fSndNxt; 00268 bool fRtxFlag; 00269 }; 00270 00272 TDebugInfo *fInfo; 00273 00275 friend std::ostream & operator<<(std::ostream &, TCP_Packet &); 00276 }; 00277 00278 00313 class TCP_Sender 00314 { 00315 public: 00317 TCP_Sender(int label); 00318 00320 virtual ~TCP_Sender(); 00321 00322 //connection control 00324 virtual void setup(); 00326 virtual void release(std::string trace_filename = ""); 00327 00329 virtual void print_item(std::ostream &, const std::string &); 00330 00332 virtual void set_debug(const bool enable_debug = true); 00334 virtual void set_debug(bool enable_debug, bool enable_signal_debug); 00336 virtual void set_trace(const bool enable_trace = true); 00338 virtual void save_trace(std::string filename); 00339 00341 Signal<itpp::Packet*> tcp_send; 00343 Slot<TCP_Sender, itpp::Packet*> tcp_receive_ack; 00345 Slot<TCP_Sender, itpp::Packet*> tcp_socket_write; 00347 Slot<TCP_Sender, std::string> tcp_release; 00348 00349 00350 //Signal<itpp::Packet*> TcpSendSignal; 00351 //Slot<TCP_Sender, itpp::Packet*> TcpRecvAckSlot; 00352 //Slot<TCP_Sender, itpp::Packet*> SocketWriteSlot; 00353 //Slot<TCP_Sender, string> ReleaseSlot; 00354 00355 private: 00356 std::queue<itpp::Packet*> SocketWriteQueue; 00357 00358 virtual void InitStatistics(); 00359 virtual void HandleACK(TCP_Packet &); 00360 virtual void SendNewData(bool skipSWSA = false); 00361 virtual void UnaRetransmit(); 00362 virtual void FinishFastRecovery(); 00363 virtual void ReduceSSThresh(); 00364 virtual void SendMsg(TCP_Packet & msg); 00365 virtual void HandleRtxTimeout(Ttype); 00366 virtual void IdleCheck(); 00367 virtual void HandleSWSATimeout(Ttype); 00368 virtual unsigned GetNextSegmentSize(const Sequence_Number & begin); 00369 virtual unsigned SendWindow() const; 00370 virtual double CalcRTOValue() const; 00371 virtual void SetRtxTimer(); 00372 virtual void UpdateRTTVariables(double sampleRTT); 00373 virtual void TraceCWnd(); 00374 virtual void TraceSentSeqNo(const Sequence_Number sn); 00375 virtual void TraceACKedSeqNo(const Sequence_Number sn); 00376 virtual void TraceRTTVariables(double sampleRTT); 00377 virtual void TraceSSThresh(); 00378 virtual std::string GenerateFilename(); 00379 00380 void StopTransientPhase(); 00382 enum eTCPVersion {kTahoe, kReno, kNewReno}; 00383 00384 virtual void set_label(int label); 00385 00386 //socket variables 00387 unsigned fLabel; // end point identification also used at receiver 00388 00389 //message handling 00390 virtual void HandleUserMessageIndication(itpp::Packet *user_data); 00391 virtual void ReceiveMessageFromNet(itpp::Packet *msg); 00392 00393 //parameters parsed from input file 00394 eTCPVersion fTCPVersion; // one of Reno, Tahoe, NewReno 00395 unsigned fMSS; // maximum segment size 00396 unsigned fTCPIPHeaderLength; 00397 double fInitialRTT; 00398 unsigned fInitialCWnd; 00399 unsigned fInitialSSThresh; 00400 unsigned fMaxCWnd; 00401 unsigned fDupACKThreshold; 00402 double fTimerGranularity; 00403 double fMaxRTO; // max value of retransmission TO 00404 unsigned fMaxBackoff; 00405 bool fImmediateBackoffReset; 00406 bool fKarn; 00407 bool fGoBackN; 00408 bool fFlightSizeRecovery;// use flight size on fast rec. exit 00409 bool fRenoConservation; 00410 bool fCarefulSSThreshReduction; 00411 bool fIgnoreDupACKOnTORecovery; 00412 bool fCarefulMulFastRtxAvoidance; 00413 bool fNagle; 00414 double fSWSATimerValue; 00415 bool fRestartAfterIdle; 00416 bool fTraceCWnd; // print CWnd trace to cout 00417 bool fTraceSentSeqNo; 00418 bool fTraceACKedSeqNo; 00419 bool fDebug; // print additional information to cout 00420 bool fTrace; // store trace info in vectors 00421 00422 //session identification 00423 int fSessionId; 00425 //TCP flow control (RFC 793) 00426 Sequence_Number fSndUna; // lowest unacknowledged sn 00427 Sequence_Number fSndNxt; // next byte to be sent 00428 Sequence_Number fSndMax; 00429 unsigned fRecWnd; // receiver advertised window 00430 unsigned fMaxRecWnd; 00431 Sequence_Number fUserNxt; // next byte to be received from user 00432 00433 //TCP congestion avoidance (RFC 2581, RFC 2001, RFC 2582) 00434 unsigned fCWnd; // congestion window 00435 unsigned fSSThresh; 00436 unsigned fDupACKCnt; 00437 Sequence_Number fRecoveryDupACK; 00438 Sequence_Number fRecoveryTO; 00440 //TCP timers 00441 TTimer<TCP_Sender> fRtxTimer; 00442 Sequence_Number fTimUna; 00443 TTimer<TCP_Sender> fSWSATimer; 00444 int fBackoff; 00445 bool fPendingBackoffReset; 00446 Ttype fLastSendTime; 00448 //round trip time measurement (RTTM) 00449 double fSRTT; 00450 double fRTTVar; 00451 double fRTTEstimate; 00452 Sequence_Number fRTTMByte; 00453 bool fRTTMPending; 00454 double fRTTMStartTime; 00456 //statistic counters 00457 unsigned long fNumberOfTimeouts; 00458 unsigned long fNumberOfFastRetransmits; 00459 unsigned long fNumberOfRTTMeasurements; 00460 unsigned long fNumberOfReceivedACKs; 00461 unsigned long fNumberOfIdleTimeouts; 00462 00463 vec CWnd_val; 00464 vec CWnd_time; 00465 int CWnd_index; 00466 00467 vec SSThresh_val; 00468 vec SSThresh_time; 00469 int SSThresh_index; 00470 00471 ivec sent_seq_num_val; 00472 vec sent_seq_num_time; 00473 int sent_seq_num_index; 00474 00475 ivec sender_recv_ack_seq_num_val; 00476 vec sender_recv_ack_seq_num_time; 00477 int sender_recv_ack_seq_num_index; 00478 00479 vec RTTEstimate_val; 00480 vec RTTEstimate_time; 00481 int RTTEstimate_index; 00482 00483 vec RTTsample_val; 00484 vec RTTsample_time; 00485 int RTTsample_index; 00486 }; 00487 00488 00509 class TCP_Receiver_Buffer 00510 { 00511 public: 00513 TCP_Receiver_Buffer(); 00515 TCP_Receiver_Buffer(const TCP_Receiver_Buffer &); 00517 ~TCP_Receiver_Buffer(); 00518 00519 void reset(); 00521 void write(TCP_Segment newBlock); 00522 void read(unsigned noOfBytes); 00524 unsigned first_block_size() const; 00525 Sequence_Number first_byte() const; 00526 Sequence_Number last_byte() const; 00527 Sequence_Number next_expected() const; 00528 00529 unsigned window() const; 00530 00531 std::ostream &info(std::ostream &os, int detail = 0) const; 00533 protected: 00534 Sequence_Number fFirstByte; 00536 00537 std::list <TCP_Segment> fBufList; 00538 }; 00539 00540 00541 00542 00572 class TCP_Receiver 00573 { 00574 public: 00575 00577 TCP_Receiver(int label); 00579 virtual ~TCP_Receiver(); 00580 00581 //name connection control 00583 virtual void setup(); 00585 virtual void release(std::string trace_filename = ""); 00586 00587 //message handling 00588 itpp::Packet & get_user_message(); 00589 bool is_user_message_available(); 00591 00592 virtual void set_debug(const bool enable_debug = true); 00594 virtual void set_debug(bool enable_debug, bool enable_signal_debug); 00596 virtual void set_trace(const bool enable_trace = true); 00598 virtual void save_trace(std::string filename); 00599 00601 Signal<itpp::Packet*> tcp_send_ack; 00603 Slot<TCP_Receiver, itpp::Packet*> tcp_receive; 00604 Signal<int> tcp_new_data; 00605 00606 Slot<TCP_Receiver, std::string> tcp_release; 00607 00608 private: 00609 void IndicateUserMessage(); 00610 virtual void ReceiveMessageFromNet(itpp::Packet* msg); 00612 virtual void ReceiveDataPacket(TCP_Packet & packet); 00613 virtual void SendACK(bool); 00614 virtual void ScheduleACKMessage(); 00615 virtual void SendACKMessage(Ttype); 00616 virtual void DelayedACKHandler(Ttype); 00617 virtual void PeriodicACKHandler(Ttype); 00618 virtual void HandleEndOfProcessing(Ttype); 00619 virtual void TraceReceivedSeqNo(const Sequence_Number &sn); 00620 virtual std::string GenerateFilename(); 00621 00622 //basic variables 00623 TCP_Receiver_Buffer fReceiverBuffer; 00624 unsigned fLabel; 00625 00626 //parameters read by the parser 00627 unsigned fTCPIPHeaderLength; 00628 unsigned fMSS; 00629 unsigned fBufferSize; 00630 bool fDelayedACK; 00631 Ttype fACKDelayTime; 00632 bool fSendPeriodicACKs; 00633 bool fStrictPeriodicACKs; 00634 Ttype fPeriodicACKInterval;// interval after which an ACK is repeated 00635 Ttype fACKSchedulingDelay; 00636 bool fACKOnBufferWrite; 00637 bool fACKOnBufferRead; 00638 unsigned fMaxUserBlockSize; 00639 unsigned fMinUserBlockSize; 00640 double fUserBlockProcDelay; 00641 bool fTrace; 00642 bool fDebug; 00644 //specific TCP variables 00645 Sequence_Number fAdvRcvNxt; 00646 unsigned fAdvRcvWnd; 00648 //session management 00649 int fSessionId; 00651 //ACK timers 00652 TTimer<TCP_Receiver> fDelayedACKTimer; 00653 TTimer<TCP_Receiver> fPeriodicACKTimer; 00654 TTimer<TCP_Receiver> fACKSchedulingTimer; 00655 TCP_Packet * fWaitingACKMsg; 00656 00657 //user data delivery 00658 Packet * fUserMessage; 00659 TTimer<TCP_Receiver> fUserBlockProcTimer; 00660 00661 00662 //statistic counters 00663 ivec received_seq_num_val; 00664 vec received_seq_num_time; 00665 int received_seq_num_index; 00666 00667 }; 00668 00669 00670 00671 // ------------------------------- Inline definitions --------------------------------------------- 00672 00673 00674 00675 inline Sequence_Number TCP_Receiver_Buffer::first_byte() const 00676 { 00677 return fFirstByte; 00678 } 00679 00680 00681 inline Sequence_Number TCP_Receiver_Buffer::last_byte() const 00682 { 00683 if (fBufList.empty()) { 00684 return fFirstByte; 00685 } 00686 else { 00687 return fBufList.back().end(); 00688 } 00689 } 00690 00691 00692 inline Sequence_Number TCP_Receiver_Buffer::next_expected() const 00693 { 00694 return fFirstByte + first_block_size(); 00695 } 00696 00697 00698 inline void TCP_Segment::set_begin(const Sequence_Number &sn) 00699 { 00700 seq_begin = sn; 00701 00702 it_assert(seq_begin <= seq_end, "TCP_Segment::begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value())); 00703 } 00704 00705 00706 inline void TCP_Segment::set_end(const Sequence_Number &sn) 00707 { 00708 seq_end = sn; 00709 00710 it_assert(seq_begin <= seq_end, "TCP_Segment::set_begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value())); 00711 } 00712 00713 00714 inline bool TCP_Segment::operator==(const TCP_Segment &segment) const 00715 { 00716 return (this->seq_begin == segment.seq_begin) && (this->seq_end == segment.seq_end); 00717 } 00718 00719 00720 inline bool TCP_Segment::operator!=(const TCP_Segment &segment) const 00721 { 00722 return (this->seq_begin != segment.seq_begin) || (this->seq_end != segment.seq_end); 00723 } 00724 00725 00726 inline bool TCP_Segment::can_be_combined(const TCP_Segment &segment) const 00727 { 00728 return (this->seq_begin <= segment.seq_end) && (segment.seq_begin <= this->seq_end); 00729 } 00730 00731 00732 inline bool TCP_Segment::is_contained(const TCP_Segment &segment) const 00733 { 00734 return (segment.seq_begin <= this->seq_begin) && (this->seq_end <= segment.seq_end); 00735 } 00736 00737 00738 inline unsigned TCP_Segment::length() const 00739 { 00740 return seq_end - seq_begin; 00741 } 00742 00744 00745 00746 } // namespace itpp 00747 00748 #endif // #ifndef TCP_H 00749
Generated on Wed Jul 27 2011 16:27:05 for IT++ by Doxygen 1.7.4