IT++ Logo Newcom Logo

tcp.h

Go to the documentation of this file.
00001 
00036 #ifndef TCP_H
00037 #define TCP_H
00038 
00039 #include <itpp/base/vec.h>
00040 #include <itpp/base/converters.h>
00041 #include <itpp/protocol/packet.h>
00042 #include <itpp/protocol/events.h>
00043 
00044 
00045 namespace itpp {
00046 
00047 
00062   class Sequence_Number {
00063   public:
00064     //construction and assignment
00065     Sequence_Number() : seq(0) { }
00066 
00067                 Sequence_Number(const Sequence_Number &n) : seq(n.seq) { }
00068                 Sequence_Number &operator=(const Sequence_Number &n) { seq = n.seq; return *this; }
00069                 Sequence_Number &operator=(const int &rep) { seq = rep; return *this; }
00070         
00071                 //relational operators
00072                 bool operator==(const Sequence_Number &n) const { return seq == n.seq; }
00073                 bool operator!=(const Sequence_Number &n) const { return seq != n.seq; }
00074                 bool operator>(const Sequence_Number &n) const { return (seq - n.seq) > 0; }
00075                 bool operator>=(const Sequence_Number &n) const { return (seq - n.seq) >= 0; }
00076                 bool operator<(const Sequence_Number &n) const { return (seq - n.seq) < 0; }
00077                 bool operator<=(const Sequence_Number &n) const { return (seq - n.seq) <= 0; }
00078 
00079                 //addition and subtraction
00080                 Sequence_Number operator+(const int n) const { return Sequence_Number(seq + n); }
00081                 Sequence_Number &operator+=(const int n) { seq += n; return *this; }
00082                 Sequence_Number operator-(const int n) const { return Sequence_Number(seq - n); }
00083                 Sequence_Number &operator-=(const int n) { seq -= n; return *this; }
00084                 int operator-(const Sequence_Number &n) const { return seq - n.seq; }
00085    
00086                 //access to internal representation
00087                 int value() const { return seq; }
00088 
00089                 friend Sequence_Number operator+(const int n1, const Sequence_Number &n2) { return Sequence_Number(n1 + n2.seq); }
00090                 friend std::ostream &operator<<(std::ostream &os, const Sequence_Number &n) { os << n.seq; return os; }
00091 
00092   protected:
00093                 Sequence_Number(int n) : seq(n) {}
00094           int seq;
00095   };
00096 
00097 
00098   inline const Sequence_Number & min(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 < n2)? n1 : n2; }
00099   inline const Sequence_Number & max(const Sequence_Number &n1, const Sequence_Number &n2) { return (n1 > n2)? n1 : n2; }
00100   
00101 
00102 
00117   class TCP_Segment {
00118   public:
00119     TCP_Segment();
00120     TCP_Segment(const Sequence_Number &sn_begin, const Sequence_Number &sn_end);
00121     TCP_Segment(const TCP_Segment &segment);
00122 
00123     //modification
00124     TCP_Segment &operator=(const TCP_Segment &segment);
00125     void set_begin(const Sequence_Number &sn);
00126     void set_end(const Sequence_Number &sn);
00127     void combine(const TCP_Segment &segment);
00128 
00129     //query
00130     bool operator==(const TCP_Segment &segment) const;
00131     bool operator!=(const TCP_Segment &segment) const;
00132     bool can_be_combined(const TCP_Segment &segment) const;
00133     bool is_contained(const TCP_Segment &segment) const;
00134     unsigned length() const;
00135     Sequence_Number begin() const { return seq_begin; }
00136     Sequence_Number end() const { return seq_end; }
00137 
00138     friend std::ostream & operator<<(std::ostream &os, const TCP_Segment &segment);
00139 
00140   protected:
00141     Sequence_Number  seq_begin; 
00142     Sequence_Number  seq_end;   
00143   };
00144 
00145 
00167   class TCP_Packet : public itpp::Packet {
00168   public:
00169     TCP_Packet();
00170     TCP_Packet(const TCP_Packet &packet);
00171     virtual ~TCP_Packet();
00172     virtual TCP_Packet &clone() const;
00173 
00174     //TCP window mechanism
00175     void set_segment(const TCP_Segment &seg) {  fSegment = seg; }
00176     TCP_Segment get_segment() const { return fSegment; }
00177     void set_wnd(unsigned val) { fWnd = val; }
00178     unsigned get_wnd() const { return fWnd; }
00179     void set_ACK(Sequence_Number val) { fACK = val; }
00180     Sequence_Number get_ACK() const { return fACK; }
00181 
00182     //session control
00183     void set_session_id(int val) { fSessionId = val; }
00184     int get_session_id() const {  return fSessionId; }
00185 
00186     //debugging support
00187     void set_destination_port(unsigned val) { fDestinationPort = val; }
00188     unsigned get_destination_port() const { return fDestinationPort; }
00189     void set_source_port(unsigned val) { fSourcePort = val; }
00190     unsigned get_source_port() const { return fSourcePort; }
00191     void set_info(unsigned ssThresh, unsigned recWnd, unsigned cWnd, double estRTT, Sequence_Number sndUna, Sequence_Number sndNxt, bool isRtx);
00192     virtual void print_header (std::ostream &out) const;
00193 
00194   protected:
00195     unsigned             fDestinationPort;
00196     unsigned             fSourcePort;
00197 
00198     TCP_Segment                 fSegment;       
00199     Sequence_Number     fACK;           
00200     unsigned            fWnd;           
00201     int                         fSessionId;     
00203     //Tracing
00204 
00205     struct TDebugInfo {
00206       unsigned          fSSThresh;
00207       unsigned          fRecWnd;
00208       unsigned          fCWnd;
00209       double            fRTTEstimate;
00210       Sequence_Number   fSndUna;
00211       Sequence_Number   fSndNxt;
00212       bool              fRtxFlag;
00213     };
00214 
00215     TDebugInfo  *fInfo;
00216 
00217     friend std::ostream & operator<<(std::ostream &, TCP_Packet &);
00218   };
00219 
00220 
00255   class TCP_Sender {
00256   public:
00257     TCP_Sender(int label);
00258 
00259     virtual ~TCP_Sender();
00260 
00261     //connection control
00262     virtual void setup();
00263     virtual void release(std::string trace_filename="");
00264 
00265     // print support
00266     virtual void print_item(std::ostream &, const std::string &);
00267 
00268     virtual void set_debug(const bool enable_debug = true);
00269     virtual void set_debug(bool enable_debug, bool enable_signal_debug);
00270     virtual void set_trace(const bool enable_trace = true);
00271     virtual void save_trace(std::string filename);
00272 
00273     Signal<itpp::Packet*> tcp_send;
00274     Slot<TCP_Sender, itpp::Packet*> tcp_receive_ack;
00275     Slot<TCP_Sender, itpp::Packet*> tcp_socket_write;
00276     Slot<TCP_Sender, std::string> tcp_release;
00277 
00278 
00279     //Signal<itpp::Packet*> TcpSendSignal;
00280     //Slot<TCP_Sender, itpp::Packet*> TcpRecvAckSlot;
00281     //Slot<TCP_Sender, itpp::Packet*> SocketWriteSlot;
00282     //Slot<TCP_Sender, string> ReleaseSlot;
00283 
00284   private:
00285     std::queue<itpp::Packet*> SocketWriteQueue;
00286 
00287     virtual void InitStatistics();            
00288     virtual void HandleACK(TCP_Packet &);      
00289     virtual void SendNewData(bool skipSWSA = false); 
00290     virtual void UnaRetransmit();             
00291     virtual void FinishFastRecovery();        
00292     virtual void ReduceSSThresh();            
00293     virtual void SendMsg(TCP_Packet & msg);    
00294     virtual void HandleRtxTimeout(Ttype);       
00295     virtual void IdleCheck();            
00296     virtual void HandleSWSATimeout(Ttype);      
00297     virtual unsigned GetNextSegmentSize(const Sequence_Number & begin);
00298     virtual unsigned SendWindow() const;          
00299     virtual double CalcRTOValue() const;   
00300     virtual void SetRtxTimer();
00301     virtual void UpdateRTTVariables(double sampleRTT); 
00302     virtual void TraceCWnd();
00303     virtual void TraceSentSeqNo(const Sequence_Number sn);
00304     virtual void TraceACKedSeqNo(const Sequence_Number sn);
00305     virtual void TraceRTTVariables(double sampleRTT);
00306     virtual void TraceSSThresh();
00307     virtual std::string GenerateFilename();
00308 
00309     void StopTransientPhase(); 
00311     enum eTCPVersion {kTahoe, kReno, kNewReno};
00312 
00313     virtual void set_label(int label);
00314 
00315     //socket variables
00316     unsigned fLabel;    // end point identification also used at receiver
00317 
00318     //message handling
00319     virtual void HandleUserMessageIndication(itpp::Packet *user_data);
00320     virtual void ReceiveMessageFromNet(itpp::Packet *msg);
00321 
00322     //parameters parsed from input file
00323     eTCPVersion  fTCPVersion;       // one of Reno, Tahoe, NewReno
00324     unsigned    fMSS;               // maximum segment size
00325     unsigned    fTCPIPHeaderLength; 
00326     double       fInitialRTT;        
00327     unsigned    fInitialCWnd;       
00328     unsigned    fInitialSSThresh;   
00329     unsigned    fMaxCWnd;           
00330     unsigned    fDupACKThreshold;   
00331     double      fTimerGranularity;  
00332     double      fMaxRTO;            // max value of retransmission TO
00333     unsigned    fMaxBackoff;        
00334     bool        fImmediateBackoffReset; 
00335     bool        fKarn;              
00336     bool        fGoBackN;           
00337     bool        fFlightSizeRecovery;// use flight size on fast rec. exit
00338     bool        fRenoConservation;  
00339     bool        fCarefulSSThreshReduction; 
00340     bool        fIgnoreDupACKOnTORecovery; 
00341     bool        fCarefulMulFastRtxAvoidance; 
00342     bool         fNagle;             
00343     double       fSWSATimerValue;    
00344     bool        fRestartAfterIdle;  
00345     bool        fTraceCWnd;         // print CWnd trace to cout
00346     bool        fTraceSentSeqNo;    
00347     bool        fTraceACKedSeqNo;   
00348     bool        fDebug;             // print additional information to cout
00349     bool        fTrace;             // store trace info in vectors
00350 
00351     //session identification
00352     int fSessionId;  
00354     //TCP flow control (RFC 793)
00355     Sequence_Number fSndUna;          // lowest unacknowledged sn
00356     Sequence_Number fSndNxt;          // next byte to be sent
00357     Sequence_Number fSndMax;           
00358     unsigned        fRecWnd;          // receiver advertised window
00359     unsigned        fMaxRecWnd;        
00360     Sequence_Number fUserNxt;         // next byte to be received from user
00361 
00362     //TCP congestion avoidance (RFC 2581, RFC 2001, RFC 2582)
00363     unsigned    fCWnd;          // congestion window
00364     unsigned    fSSThresh;      
00365     unsigned    fDupACKCnt;     
00366     Sequence_Number  fRecoveryDupACK;   
00367     Sequence_Number  fRecoveryTO;       
00369     //TCP timers
00370     TTimer<TCP_Sender>   fRtxTimer;     
00371     Sequence_Number      fTimUna;       
00372     TTimer<TCP_Sender>   fSWSATimer;    
00373     int                 fBackoff;               
00374     bool                fPendingBackoffReset;   
00375     Ttype               fLastSendTime; 
00377     //round trip time measurement (RTTM)
00378     double          fSRTT;               
00379     double          fRTTVar;             
00380     double          fRTTEstimate;        
00381     Sequence_Number fRTTMByte;           
00382     bool            fRTTMPending;        
00383     double          fRTTMStartTime;      
00385     //statistic counters
00386     unsigned long       fNumberOfTimeouts;
00387     unsigned long       fNumberOfFastRetransmits;
00388     unsigned long       fNumberOfRTTMeasurements;
00389     unsigned long       fNumberOfReceivedACKs;
00390     unsigned long       fNumberOfIdleTimeouts;
00391 
00392     vec CWnd_val;
00393     vec CWnd_time;
00394     int CWnd_index;
00395 
00396     vec SSThresh_val;
00397     vec SSThresh_time;
00398     int SSThresh_index;
00399 
00400     ivec sent_seq_num_val;
00401     vec sent_seq_num_time;
00402     int sent_seq_num_index;
00403 
00404     ivec sender_recv_ack_seq_num_val;
00405     vec sender_recv_ack_seq_num_time;
00406     int sender_recv_ack_seq_num_index;
00407 
00408     vec RTTEstimate_val;
00409     vec RTTEstimate_time;
00410     int RTTEstimate_index;
00411 
00412     vec RTTsample_val;
00413     vec RTTsample_time;
00414     int RTTsample_index;
00415   };
00416 
00417 
00438   class TCP_Receiver_Buffer {
00439   public:
00440     TCP_Receiver_Buffer();
00441     TCP_Receiver_Buffer(const TCP_Receiver_Buffer &);
00442     ~TCP_Receiver_Buffer();
00443 
00444     void reset(); 
00446     void write(TCP_Segment newBlock);  
00447     void read(unsigned noOfBytes); 
00449     unsigned first_block_size() const;        
00450     Sequence_Number first_byte() const;      
00451     Sequence_Number last_byte() const;       
00452     Sequence_Number next_expected() const;   
00453     unsigned window() const;
00454 
00455     std::ostream &info(std::ostream &os, int detail = 0) const; 
00457   protected:
00458     Sequence_Number fFirstByte;         
00460     std::list <TCP_Segment> fBufList;
00461   };
00462 
00463 
00464 
00465 
00495   class TCP_Receiver {
00496   public:
00497 
00498     TCP_Receiver(int label);
00499     virtual ~TCP_Receiver ();
00500 
00501     //name  connection control
00502     virtual void setup();
00503     virtual void release(std::string trace_filename="");
00504 
00505     //message handling
00506     itpp::Packet & get_user_message(); 
00507     bool is_user_message_available(); 
00509     virtual void set_debug(const bool enable_debug = true);
00510     virtual void set_debug(bool enable_debug, bool enable_signal_debug);
00511     virtual void set_trace(const bool enable_trace = true);
00512     virtual void save_trace(std::string filename);
00513 
00514     Signal<itpp::Packet*> tcp_send_ack;
00515     Slot<TCP_Receiver, itpp::Packet*> tcp_receive;
00516     Signal<int> tcp_new_data; 
00517     Slot<TCP_Receiver, std::string> tcp_release;
00518 
00519   private:
00520     void IndicateUserMessage(); 
00521     virtual void ReceiveMessageFromNet(itpp::Packet* msg); 
00523     virtual void ReceiveDataPacket(TCP_Packet & packet); 
00524     virtual void SendACK(bool);        
00525     virtual void ScheduleACKMessage(); 
00526     virtual void SendACKMessage(Ttype); 
00527     virtual void DelayedACKHandler(Ttype);    
00528     virtual void PeriodicACKHandler(Ttype);   
00529     virtual void HandleEndOfProcessing(Ttype); 
00530     virtual void TraceReceivedSeqNo(const Sequence_Number &sn);
00531     virtual std::string GenerateFilename();
00532 
00533     //basic variables
00534     TCP_Receiver_Buffer         fReceiverBuffer;
00535     unsigned                    fLabel;
00536 
00537     //parameters read by the parser
00538     unsigned     fTCPIPHeaderLength;  
00539     unsigned     fMSS;               
00540     unsigned    fBufferSize;         
00541     bool         fDelayedACK;         
00542     Ttype       fACKDelayTime;       
00543     bool        fSendPeriodicACKs;   
00544     bool        fStrictPeriodicACKs; 
00545     Ttype       fPeriodicACKInterval;// interval after which an ACK is repeated
00546     Ttype               fACKSchedulingDelay; 
00547     bool        fACKOnBufferWrite;   
00548     bool        fACKOnBufferRead;    
00549     unsigned    fMaxUserBlockSize;   
00550     unsigned    fMinUserBlockSize;   
00551     double      fUserBlockProcDelay; 
00552     bool        fTrace;              
00553     bool         fDebug;              
00555     //specific TCP variables
00556     Sequence_Number fAdvRcvNxt;       
00557     unsigned        fAdvRcvWnd;       
00559     //session management
00560     int fSessionId;  
00562     //ACK timers
00563     TTimer<TCP_Receiver> fDelayedACKTimer; 
00564     TTimer<TCP_Receiver> fPeriodicACKTimer; 
00565     TTimer<TCP_Receiver> fACKSchedulingTimer;
00566     TCP_Packet *                fWaitingACKMsg;
00567 
00568     //user data delivery
00569     Packet * fUserMessage;
00570     TTimer<TCP_Receiver> fUserBlockProcTimer;
00571 
00572 
00573     //statistic counters
00574     ivec received_seq_num_val;
00575     vec received_seq_num_time;
00576     int received_seq_num_index;
00577 
00578   };
00579 
00580 
00581 
00582   // ------------------------------- Inline definitions ---------------------------------------------
00583 
00584 
00585 
00586   inline Sequence_Number TCP_Receiver_Buffer::first_byte() const
00587         {
00588                 return fFirstByte;
00589         }
00590 
00591 
00592   inline Sequence_Number TCP_Receiver_Buffer::last_byte() const
00593         {
00594                 if (fBufList.empty()) {
00595                         return fFirstByte;
00596                 } else {
00597                         return fBufList.back().end();
00598                 }
00599         }
00600 
00601 
00602   inline Sequence_Number TCP_Receiver_Buffer::next_expected() const
00603         {
00604                 return fFirstByte + first_block_size();
00605         }
00606 
00607 
00608   inline void TCP_Segment::set_begin(const Sequence_Number &sn)
00609         {
00610                 seq_begin = sn;
00611 
00612                 it_assert(seq_begin <= seq_end, "TCP_Segment::begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value()));
00613         }
00614 
00615 
00616   inline void TCP_Segment::set_end(const Sequence_Number &sn)
00617         {
00618                 seq_end = sn;
00619 
00620                 it_assert(seq_begin <= seq_end, "TCP_Segment::set_begin, end byte " + to_str(seq_end.value()) + " < begin byte " + to_str(seq_begin.value()));
00621         }
00622 
00623 
00624   inline bool TCP_Segment::operator==(const TCP_Segment &segment) const
00625         {
00626                 return (this->seq_begin == segment.seq_begin) && (this->seq_end == segment.seq_end);
00627         }
00628 
00629 
00630   inline bool TCP_Segment::operator!=(const TCP_Segment &segment) const
00631         {
00632                 return (this->seq_begin != segment.seq_begin) || (this->seq_end != segment.seq_end);
00633         }
00634 
00635 
00636   inline bool TCP_Segment::can_be_combined(const TCP_Segment &segment) const
00637         {
00638                 return (this->seq_begin <= segment.seq_end) && (segment.seq_begin <= this->seq_end);
00639         }
00640 
00641 
00642   inline bool TCP_Segment::is_contained(const TCP_Segment &segment) const
00643         {
00644                 return (segment.seq_begin <= this->seq_begin) && (this->seq_end <= segment.seq_end);
00645         }
00646 
00647 
00648   inline unsigned TCP_Segment::length() const
00649         {
00650                 return seq_end - seq_begin;
00651         }
00652 
00653 
00654 
00655 } // namespace itpp
00656 
00657 #endif // #ifndef TCP_H
00658 
SourceForge Logo

Generated on Fri Jun 8 00:37:34 2007 for IT++ by Doxygen 1.5.2