IT++ Logo

tcp.h

Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Sat Feb 26 2011 16:06:34 for IT++ by Doxygen 1.7.3