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 
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 
SourceForge Logo

Generated on Sat May 3 16:10:43 2008 for IT++ by Doxygen 1.5.5