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
Generated on Thu Apr 19 14:14:59 2007 for IT++ by Doxygen 1.5.1