|
INET Framework for OMNeT++/OMNEST
|
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