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

Generated on Wed Jul 27 2011 16:27:05 for IT++ by Doxygen 1.7.4