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
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
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
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
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
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
00229 void set_session_id(int val) { fSessionId = val; }
00231 int get_session_id() const { return fSessionId; }
00232
00233
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
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
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
00351
00352
00353
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
00387 unsigned fLabel;
00388
00389
00390 virtual void HandleUserMessageIndication(itpp::Packet *user_data);
00391 virtual void ReceiveMessageFromNet(itpp::Packet *msg);
00392
00393
00394 eTCPVersion fTCPVersion;
00395 unsigned fMSS;
00396 unsigned fTCPIPHeaderLength;
00397 double fInitialRTT;
00398 unsigned fInitialCWnd;
00399 unsigned fInitialSSThresh;
00400 unsigned fMaxCWnd;
00401 unsigned fDupACKThreshold;
00402 double fTimerGranularity;
00403 double fMaxRTO;
00404 unsigned fMaxBackoff;
00405 bool fImmediateBackoffReset;
00406 bool fKarn;
00407 bool fGoBackN;
00408 bool fFlightSizeRecovery;
00409 bool fRenoConservation;
00410 bool fCarefulSSThreshReduction;
00411 bool fIgnoreDupACKOnTORecovery;
00412 bool fCarefulMulFastRtxAvoidance;
00413 bool fNagle;
00414 double fSWSATimerValue;
00415 bool fRestartAfterIdle;
00416 bool fTraceCWnd;
00417 bool fTraceSentSeqNo;
00418 bool fTraceACKedSeqNo;
00419 bool fDebug;
00420 bool fTrace;
00421
00422
00423 int fSessionId;
00425
00426 Sequence_Number fSndUna;
00427 Sequence_Number fSndNxt;
00428 Sequence_Number fSndMax;
00429 unsigned fRecWnd;
00430 unsigned fMaxRecWnd;
00431 Sequence_Number fUserNxt;
00432
00433
00434 unsigned fCWnd;
00435 unsigned fSSThresh;
00436 unsigned fDupACKCnt;
00437 Sequence_Number fRecoveryDupACK;
00438 Sequence_Number fRecoveryTO;
00440
00441 TTimer<TCP_Sender> fRtxTimer;
00442 Sequence_Number fTimUna;
00443 TTimer<TCP_Sender> fSWSATimer;
00444 int fBackoff;
00445 bool fPendingBackoffReset;
00446 Ttype fLastSendTime;
00448
00449 double fSRTT;
00450 double fRTTVar;
00451 double fRTTEstimate;
00452 Sequence_Number fRTTMByte;
00453 bool fRTTMPending;
00454 double fRTTMStartTime;
00456
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
00583 virtual void setup();
00585 virtual void release(std::string trace_filename = "");
00586
00587
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
00623 TCP_Receiver_Buffer fReceiverBuffer;
00624 unsigned fLabel;
00625
00626
00627 unsigned fTCPIPHeaderLength;
00628 unsigned fMSS;
00629 unsigned fBufferSize;
00630 bool fDelayedACK;
00631 Ttype fACKDelayTime;
00632 bool fSendPeriodicACKs;
00633 bool fStrictPeriodicACKs;
00634 Ttype fPeriodicACKInterval;
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
00645 Sequence_Number fAdvRcvNxt;
00646 unsigned fAdvRcvWnd;
00648
00649 int fSessionId;
00651
00652 TTimer<TCP_Receiver> fDelayedACKTimer;
00653 TTimer<TCP_Receiver> fPeriodicACKTimer;
00654 TTimer<TCP_Receiver> fACKSchedulingTimer;
00655 TCP_Packet * fWaitingACKMsg;
00656
00657
00658 Packet * fUserMessage;
00659 TTimer<TCP_Receiver> fUserBlockProcTimer;
00660
00661
00662
00663 ivec received_seq_num_val;
00664 vec received_seq_num_time;
00665 int received_seq_num_index;
00666
00667 };
00668
00669
00670
00671
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 }
00747
00748 #endif // #ifndef TCP_H
00749