TCPConnection_old.h

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2004 Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #ifndef __INET_TCPCONNECTION_OLD_H
00019 #define __INET_TCPCONNECTION_OLD_H
00020 
00021 #include <omnetpp.h>
00022 #include "INETDefs.h"
00023 #include "IPvXAddress.h"
00024 #include "TCP_old.h"
00025 
00026 class TCPSegment;
00027 class TCPCommand;
00028 class TCPOpenCommand;
00029 
00030 namespace tcp_old {
00031 using namespace tcp_old;
00032 
00033 class TCPSendQueue;
00034 class TCPReceiveQueue;
00035 class TCPAlgorithm;
00036 
00037 //
00038 // TCP FSM states
00039 //
00040 // Brief descriptions (cf RFC 793, page 20):
00041 //
00042 // LISTEN - waiting for a connection request
00043 // SYN-SENT - part of 3-way handshake (waiting for peer's SYN+ACK or SYN)
00044 // SYN-RECEIVED - part of 3-way handshake (we sent SYN too, waiting for it to be acked)
00045 // ESTABLISHED - normal data transfer
00046 // FIN-WAIT-1 - FIN sent, waiting for its ACK (or peer's FIN)
00047 // FIN-WAIT-2 - our side of the connection closed (our FIN acked), waiting for peer's FIN
00048 // CLOSE-WAIT - FIN received and acked, waiting for local user to close
00049 // LAST-ACK - remote side closed, FIN sent, waiting for its ACK
00050 // CLOSING - simultaneous close: sent FIN, then got peer's FIN
00051 // TIME-WAIT - both FIN's acked, waiting for some time to be sure remote TCP received our ACK
00052 // CLOSED - represents no connection state at all.
00053 //
00054 // Note: FIN-WAIT-1, FIN-WAIT-2, CLOSING, TIME-WAIT represents active close (that is,
00055 // local user closes first), and CLOSE-WAIT and LAST-ACK represents passive close.
00056 //
00057 enum TcpState
00058 {
00059     TCP_S_INIT        = 0,
00060     TCP_S_CLOSED      = FSM_Steady(1),
00061     TCP_S_LISTEN      = FSM_Steady(2),
00062     TCP_S_SYN_SENT    = FSM_Steady(3),
00063     TCP_S_SYN_RCVD    = FSM_Steady(4),
00064     TCP_S_ESTABLISHED = FSM_Steady(5),
00065     TCP_S_CLOSE_WAIT  = FSM_Steady(6),
00066     TCP_S_LAST_ACK    = FSM_Steady(7),
00067     TCP_S_FIN_WAIT_1  = FSM_Steady(8),
00068     TCP_S_FIN_WAIT_2  = FSM_Steady(9),
00069     TCP_S_CLOSING     = FSM_Steady(10),
00070     TCP_S_TIME_WAIT   = FSM_Steady(11)
00071 };
00072 
00073 
00074 //
00075 // Event, strictly for the FSM state transition purposes.
00076 // DO NOT USE outside performStateTransition()!
00077 //
00078 enum TCPEventCode
00079 {
00080     TCP_E_IGNORE,
00081 
00082     // app commands
00083     // (note: no RECEIVE command, data are automatically passed up)
00084     TCP_E_OPEN_ACTIVE,
00085     TCP_E_OPEN_PASSIVE,
00086     TCP_E_SEND,
00087     TCP_E_CLOSE,
00088     TCP_E_ABORT,
00089     TCP_E_STATUS,
00090 
00091     // TPDU types
00092     TCP_E_RCV_DATA,
00093     TCP_E_RCV_ACK,
00094     TCP_E_RCV_SYN,
00095     TCP_E_RCV_SYN_ACK,
00096     TCP_E_RCV_FIN,
00097     TCP_E_RCV_FIN_ACK,
00098     TCP_E_RCV_RST,  // covers RST+ACK too
00099 
00100     TCP_E_RCV_UNEXP_SYN,  // unexpected SYN
00101 
00102     // timers
00103     TCP_E_TIMEOUT_2MSL,     // RFC 793, a.k.a. TIME-WAIT timer
00104     TCP_E_TIMEOUT_CONN_ESTAB,
00105     TCP_E_TIMEOUT_FIN_WAIT_2,
00106 
00107     // All other timers (REXMT, PERSIST, DELAYED-ACK, KEEP-ALIVE, etc.),
00108     // are handled in TCPAlgorithm.
00109 };
00110 
00111 
00114 #define TCP_TIMEOUT_CONN_ESTAB    75    // 75 seconds
00115 #define TCP_TIMEOUT_FIN_WAIT_2   600    // 10 minutes
00116 #define TCP_TIMEOUT_2MSL         240    // 2 * 2 minutes
00117 #define TCP_TIMEOUT_SYN_REXMIT     3    // initially 3 seconds
00118 #define TCP_TIMEOUT_SYN_REXMIT_MAX 240  // 4 mins (will only be used with SYN+ACK: with SYN CONN_ESTAB occurs sooner)
00119 
00120 
00121 #define MAX_SYN_REXMIT_COUNT     12     // will only be used with SYN+ACK: with SYN CONN_ESTAB occurs sooner
00122 
00123 #define TCP_MAX_WIN            65535    // largest value (16 bit) for (unscaled) window size
00124 
00127 inline bool seqLess(uint32 a, uint32 b) {return a!=b && b-a<(1UL<<31);}
00128 inline bool seqLE(uint32 a, uint32 b) {return b-a<(1UL<<31);}
00129 inline bool seqGreater(uint32 a, uint32 b) {return a!=b && a-b<(1UL<<31);}
00130 inline bool seqGE(uint32 a, uint32 b) {return a-b<(1UL<<31);}
00132 
00133 
00147 class INET_API TCPStateVariables : public cPolymorphic
00148 {
00149   public:
00150     TCPStateVariables();
00151     virtual std::string info() const;
00152     virtual std::string detailedInfo() const;
00153   public:
00154     bool active;         // set if the connection was initiated by an active open
00155     bool fork;           // if passive and in LISTEN: whether to fork on an incoming connection
00156 
00157     uint snd_mss;        // maximum segment size (without headers, i.e. only segment text)
00158 
00159     // send sequence number variables (see RFC 793, "3.2. Terminology")
00160     uint32 snd_una;      // send unacknowledged
00161     uint32 snd_nxt;      // send next (drops back on retransmission)
00162     uint32 snd_max;      // max seq number sent (needed because snd_nxt is re-set on retransmission)
00163 
00164     uint snd_wnd;        // send window
00165     uint32 snd_up;       // send urgent pointer
00166     uint32 snd_wl1;      // segment sequence number used for last window update
00167     uint32 snd_wl2;      // segment ack. number used for last window update
00168     uint32 iss;          // initial sequence number (ISS)
00169 
00170     // receive sequence number variables
00171     uint32 rcv_nxt;      // receive next
00172     uint32 rcv_wnd;      // receive window
00173     uint32 rcv_up;       // receive urgent pointer;
00174     uint32 irs;          // initial receive sequence number
00175 
00176     // number of consecutive duplicate ACKs (this counter would logically
00177     // belong to TCPAlgorithm, but it's a lot easier to manage here)
00178     short dupacks;
00179 
00180     // SYN, SYN+ACK retransmission variables (handled separately
00181     // because normal rexmit belongs to TCPAlgorithm)
00182     int syn_rexmit_count;   // number of SYN/SYN+ACK retransmissions (=1 after first rexmit)
00183     simtime_t syn_rexmit_timeout; // current SYN/SYN+ACK retransmission timeout
00184 
00185     // whether ACK of our FIN has been received. Needed in FIN bit processing
00186     // to decide between transition to TIME-WAIT and CLOSING (set event code
00187     // TCP_E_RCV_FIN or TCP_E_RCV_FIN_ACK).
00188     bool fin_ack_rcvd;
00189 
00190     bool send_fin;       // true if a user CLOSE command has been "queued"
00191     uint32 snd_fin_seq;  // if send_fin==true: FIN should be sent just before this sequence number
00192 
00193     bool fin_rcvd;       // whether FIN received or not
00194     uint32 rcv_fin_seq;  // if fin_rcvd: sequence number of received FIN
00195 
00196     bool afterRto;       // set when the retransmission timer expires, reset when snd_nxt == snd_max or snd_una == snd_max
00197 
00198     uint32 last_ack_sent;// RFC 1323, page 31: "Last ACK field sent"
00199 
00200     //bool rcv_up_valid;
00201     //uint32 rcv_buf_seq;
00202     //unsigned long rcv_buff;
00203     //double  rcv_buf_usage_thresh;
00204 };
00205 
00206 
00207 
00256 class INET_API TCPConnection
00257 {
00258   public:
00259     // connection identification by apps: appgateIndex+connId
00260     int appGateIndex; // application gate index
00261     int connId;       // identifies connection within the app
00262 
00263     // socket pair
00264     IPvXAddress localAddr;
00265     IPvXAddress remoteAddr;
00266     int localPort;
00267     int remotePort;
00268 
00269   protected:
00270     TCP *tcpMain;  // TCP module
00271 
00272     // TCP state machine
00273     cFSM fsm;
00274 
00275     // variables associated with TCP state
00276     TCPStateVariables *state;
00277 
00278     // TCP queues
00279     TCPSendQueue *sendQueue;
00280     TCPReceiveQueue *receiveQueue;
00281 
00282     // TCP behavior in data transfer state
00283     TCPAlgorithm *tcpAlgorithm;
00284 
00285     // timers
00286     cMessage *the2MSLTimer;
00287     cMessage *connEstabTimer;
00288     cMessage *finWait2Timer;
00289     cMessage *synRexmitTimer;  // for retransmitting SYN and SYN+ACK
00290 
00291     // statistics
00292     cOutVector *sndWndVector;   // snd_wnd
00293     cOutVector *sndNxtVector;   // sent seqNo
00294     cOutVector *sndAckVector;   // sent ackNo
00295     cOutVector *rcvSeqVector;   // received seqNo
00296     cOutVector *rcvAckVector;   // received ackNo (= snd_una)
00297     cOutVector *unackedVector;  // number of bytes unacknowledged
00298 
00299   protected:
00303     virtual TCPEventCode preanalyseAppCommandEvent(int commandCode);
00305     virtual bool performStateTransition(const TCPEventCode& event);
00307     virtual void stateEntered(int state);
00309 
00312     virtual void process_OPEN_ACTIVE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg);
00313     virtual void process_OPEN_PASSIVE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg);
00314     virtual void process_SEND(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg);
00315     virtual void process_CLOSE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg);
00316     virtual void process_ABORT(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg);
00317     virtual void process_STATUS(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg);
00319 
00326     virtual bool tryFastRoute(TCPSegment *tcpseg);
00331     virtual TCPEventCode process_RCV_SEGMENT(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest);
00332     virtual TCPEventCode processSegmentInListen(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest);
00333     virtual TCPEventCode processSegmentInSynSent(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest);
00334     virtual TCPEventCode processSegment1stThru8th(TCPSegment *tcpseg);
00335     virtual TCPEventCode processRstInSynReceived(TCPSegment *tcpseg);
00336     virtual bool processAckInEstabEtc(TCPSegment *tcpseg);
00338 
00341     virtual void process_TIMEOUT_2MSL();
00342     virtual void process_TIMEOUT_CONN_ESTAB();
00343     virtual void process_TIMEOUT_FIN_WAIT_2();
00344     virtual void process_TIMEOUT_SYN_REXMIT(TCPEventCode& event);
00346 
00348     virtual TCPConnection *cloneListeningConnection();
00349 
00351     virtual void initConnection(TCPOpenCommand *openCmd);
00352 
00354     virtual void configureStateVariables();
00355 
00357     virtual void selectInitialSeqNum();
00358 
00360     virtual bool isSegmentAcceptable(TCPSegment *tcpseg);
00361 
00363     virtual void sendSyn();
00364 
00366     virtual void sendSynAck();
00367 
00368   public:
00370     virtual void sendAck();
00371 
00377     virtual bool sendData(bool fullSegmentsOnly, int congestionWindow=-1);
00378 
00380     virtual bool sendProbe();
00381 
00383     virtual void retransmitOneSegment(bool called_at_rto);
00384 
00386     virtual void retransmitData();
00387 
00389     virtual void sendRst(uint32 seqNo);
00391     virtual void sendRst(uint32 seq, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort);
00393     virtual void sendRstAck(uint32 seq, uint32 ack, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort);
00394 
00396     virtual void sendFin();
00397 
00402     virtual void sendSegment(uint32 bytes);
00403 
00405     virtual void sendToIP(TCPSegment *tcpseg);
00406 
00411     virtual TCPSegment *createTCPSegment(const char *name);
00412 
00414     virtual void startSynRexmitTimer();
00415 
00417     virtual void signalConnectionTimeout();
00418 
00420     void scheduleTimeout(cMessage *msg, simtime_t timeout)
00421         {tcpMain->scheduleAt(simTime()+timeout, msg);}
00422 
00423   protected:
00425     cMessage *cancelEvent(cMessage *msg)  {return tcpMain->cancelEvent(msg);}
00426 
00428     static void sendToIP(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest);
00429 
00431     virtual void sendToApp(cMessage *msg);
00432 
00434     virtual void sendIndicationToApp(int code);
00435 
00437     virtual void sendEstabIndicationToApp();
00438 
00439   public:
00441     virtual void printConnBrief();
00443     static void printSegmentBrief(TCPSegment *tcpseg);
00445     static const char *stateName(int state);
00447     static const char *eventName(int event);
00449     static const char *indicationName(int code);
00450 
00451   public:
00455     TCPConnection(TCP *mod, int appGateIndex, int connId);
00456 
00461     TCPConnection();
00462 
00466     virtual ~TCPConnection();
00467 
00474     virtual void segmentArrivalWhileClosed(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest);
00475 
00476     /* @name Various getters */
00478     int getFsmState() const {return fsm.getState();}
00479     TCPStateVariables *getState() {return state;}
00480     TCPSendQueue *getSendQueue() {return sendQueue;}
00481     TCPReceiveQueue *getReceiveQueue() {return receiveQueue;}
00482     TCPAlgorithm *getTcpAlgorithm() {return tcpAlgorithm;}
00483     TCP *getTcpMain() {return tcpMain;}
00485 
00491     virtual bool processTimer(cMessage *msg);
00492 
00498     virtual bool processTCPSegment(TCPSegment *tcpSeg, IPvXAddress srcAddr, IPvXAddress destAddr);
00499 
00505     virtual bool processAppCommand(cMessage *msg);
00506 };
00507 
00508 }
00509 #endif
00510 
00511