|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2004 Andras Varga 00003 // Copyright (C) 2009-2010 Thomas Reschka 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 #ifndef __INET_TCPCONNECTION_H 00020 #define __INET_TCPCONNECTION_H 00021 00022 #include <omnetpp.h> 00023 #include "INETDefs.h" 00024 #include "IPvXAddress.h" 00025 #include "TCP.h" 00026 #include "TCPSegment.h" 00027 00028 class TCPSegment; 00029 class TCPCommand; 00030 class TCPOpenCommand; 00031 class TCPSendQueue; 00032 class TCPSACKRexmitQueue; 00033 class TCPReceiveQueue; 00034 class TCPAlgorithm; 00035 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 MAX_SACK_BLOCKS 60 // will only be used with SACK 00124 #define DUPTHRESH 3 // used for TCPTahoe, TCPReno and SACK (RFC 3517) 00125 00126 #define TCP_MAX_WIN 65535 // largest value (16 bit) for (unscaled) window size 00127 00128 #define PAWS_IDLE_TIME_THRESH 24*24*3600 // 24 days in seconds (RFC 1323) 00129 00130 #define TCP_OPTION_TS_SIZE 12 00131 00144 class INET_API TCPStateVariables : public cPolymorphic 00145 { 00146 public: 00147 TCPStateVariables(); 00148 virtual std::string info() const; 00149 virtual std::string detailedInfo() const; 00150 public: 00151 bool active; // set if the connection was initiated by an active open 00152 bool fork; // if passive and in LISTEN: whether to fork on an incoming connection 00153 00154 uint32 snd_mss; // sender maximum segment size (without headers, i.e. only segment text); see RFC 2581, page 1. 00155 // This will be set to the minimum of the local smss parameter and the value specified in the 00156 // MSS option received during connection setup. 00157 00158 // send sequence number variables (see RFC 793, "3.2. Terminology") 00159 uint32 snd_una; // send unacknowledged 00160 uint32 snd_nxt; // send next (drops back on retransmission) 00161 uint32 snd_max; // max seq number sent (needed because snd_nxt is re-set on retransmission) 00162 uint32 snd_wnd; // send window 00163 uint32 snd_up; // send urgent pointer 00164 uint32 snd_wl1; // segment sequence number used for last window update 00165 uint32 snd_wl2; // segment ack. number used for last window update 00166 uint32 iss; // initial sequence number (ISS) 00167 00168 // receive sequence number variables 00169 uint32 rcv_nxt; // receive next 00170 uint32 rcv_wnd; // receive window 00171 uint32 rcv_up; // receive urgent pointer; 00172 uint32 irs; // initial receive sequence number 00173 uint32 rcv_adv; // advertised window 00174 00175 // SYN, SYN+ACK retransmission variables (handled separately 00176 // because normal rexmit belongs to TCPAlgorithm) 00177 int syn_rexmit_count; // number of SYN/SYN+ACK retransmissions (=1 after first rexmit) 00178 simtime_t syn_rexmit_timeout; // current SYN/SYN+ACK retransmission timeout 00179 00180 // whether ACK of our FIN has been received. Needed in FIN bit processing 00181 // to decide between transition to TIME-WAIT and CLOSING (set event code 00182 // TCP_E_RCV_FIN or TCP_E_RCV_FIN_ACK). 00183 bool fin_ack_rcvd; 00184 00185 bool send_fin; // true if a user CLOSE command has been "queued" 00186 uint32 snd_fin_seq; // if send_fin==true: FIN should be sent just before this sequence number 00187 00188 bool fin_rcvd; // whether FIN received or not 00189 uint32 rcv_fin_seq; // if fin_rcvd: sequence number of received FIN 00190 00191 uint32 sentBytes; // amount of user data (in bytes) sent in last segment 00192 00193 bool nagle_enabled; // set if Nagle's algorithm (RFC 896) is enabled 00194 bool delayed_acks_enabled; // set if delayed ACK algorithm (RFC 1122) is enabled 00195 bool limited_transmit_enabled; // set if Limited Transmit algorithm (RFC 3042) is enabled 00196 bool increased_IW_enabled; // set if Increased Initial Window (RFC 3390) is enabled 00197 00198 uint32 full_sized_segment_counter; // this counter is needed for delayed ACK 00199 bool ack_now; // send ACK immediately, needed if delayed_acks_enabled is set 00200 // Based on [Stevens, W.R.: TCP/IP Illustrated, Volume 2, page 861]. 00201 // ack_now should be set when: 00202 // - delayed ACK timer expires 00203 // - an out-of-order segment is received 00204 // - SYN is received during the three-way handshake 00205 // - a persist probe is received 00206 // - FIN is received 00207 00208 bool afterRto; // set at RTO, reset when snd_nxt == snd_max or snd_una == snd_max 00209 00210 // WINDOW_SCALE related variables 00211 bool ws_support; // set if the host supports Window Scale (header option) (RFC 1322) 00212 bool ws_enabled; // set if the connection uses Window Scale (header option) 00213 bool snd_ws; // set if initial WINDOW_SCALE has been sent 00214 bool rcv_ws; // set if initial WINDOW_SCALE has been received 00215 uint rcv_wnd_scale; // RFC 1323, page 31: "Receive window scale power" 00216 uint snd_wnd_scale; // RFC 1323, page 31: "Send window scale power" 00217 00218 // TIMESTAMP related variables 00219 bool ts_support; // set if the host supports Timestamps (header option) (RFC 1322) 00220 bool ts_enabled; // set if the connection uses Window Scale (header option) 00221 bool snd_initial_ts; // set if initial TIMESTAMP has been sent 00222 bool rcv_initial_ts; // set if initial TIMESTAMP has been received 00223 uint32 ts_recent; // RFC 1323, page 31: "Latest received Timestamp" 00224 uint32 last_ack_sent; // RFC 1323, page 31: "Last ACK field sent" 00225 simtime_t time_last_data_sent; // time at which the last data segment was sent (needed to compute the IDLE time for PAWS) 00226 00227 // SACK related variables 00228 bool sack_support; // set if the host supports selective acknowledgment (header option) (RFC 2018, 2883, 3517) 00229 bool sack_enabled; // set if the connection uses selective acknowledgment (header option) 00230 bool snd_sack_perm; // set if SACK_PERMITTED has been sent 00231 bool rcv_sack_perm; // set if SACK_PERMITTED has been received 00232 uint32 start_seqno; // start sequence number of last received out-of-order segment 00233 uint32 end_seqno; // end sequence number of last received out-of-order segment 00234 bool snd_sack; // set if received vaild out-of-order segment or rcv_nxt changed, but receivedQueue is not empty 00235 bool snd_dsack; // set if received duplicated segment (sequenceNo+PLength < rcv_nxt) or (segment is not acceptable) 00236 Sack sacks_array[MAX_SACK_BLOCKS]; // MAX_SACK_BLOCKS is set to 60 00237 uint32 highRxt; // RFC 3517, page 3: ""HighRxt" is the highest sequence number which has been retransmitted during the current loss recovery phase." 00238 uint32 pipe; // RFC 3517, page 3: ""Pipe" is a sender's estimate of the number of bytes outstanding in the network." 00239 uint32 recoveryPoint; // RFC 3517 00240 uint32 sackedBytes; // number of sackedBytes 00241 uint32 sackedBytes_old; // old number of sackedBytes - needed for RFC 3042 to check if last dupAck contained new sack information 00242 bool lossRecovery; // indicates if algorithm is in loss recovery phase 00243 00244 // those counters would logically belong to TCPAlgorithm, but it's a lot easier to manage them here 00245 uint32 dupacks; // current number of received consecutive duplicate ACKs 00246 uint32 snd_sacks; // number of sent sacks 00247 uint32 rcv_sacks; // number of received sacks 00248 uint32 rcv_oooseg; // number of received out-of-order segments 00249 00250 // receiver buffer / receiver queue related variables 00251 uint32 maxRcvBuffer; // maximal amount of bytes in tcp receive queue 00252 uint32 usedRcvBuffer; // current amount of used bytes in tcp receive queue 00253 uint32 freeRcvBuffer; // current amount of free bytes in tcp receive queue 00254 uint32 tcpRcvQueueDrops; // number of drops in tcp receive queue 00255 }; 00256 00257 00258 00307 class INET_API TCPConnection 00308 { 00309 public: 00310 // connection identification by apps: appgateIndex+connId 00311 int appGateIndex; // application gate index 00312 int connId; // identifies connection within the app 00313 00314 // socket pair 00315 IPvXAddress localAddr; 00316 IPvXAddress remoteAddr; 00317 int localPort; 00318 int remotePort; 00319 00320 protected: 00321 TCP *tcpMain; // TCP module 00322 00323 // TCP state machine 00324 cFSM fsm; 00325 00326 // variables associated with TCP state 00327 TCPStateVariables *state; 00328 00329 // TCP queues 00330 TCPSendQueue *sendQueue; 00331 TCPReceiveQueue *receiveQueue; 00332 public: 00333 00334 TCPSACKRexmitQueue *rexmitQueue; 00335 00336 protected: 00337 // TCP behavior in data transfer state 00338 TCPAlgorithm *tcpAlgorithm; 00339 00340 // timers 00341 cMessage *the2MSLTimer; 00342 cMessage *connEstabTimer; 00343 cMessage *finWait2Timer; 00344 cMessage *synRexmitTimer; // for retransmitting SYN and SYN+ACK 00345 00346 // statistics 00347 cOutVector *sndWndVector; // snd_wnd 00348 cOutVector *rcvWndVector; // rcv_wnd 00349 cOutVector *rcvAdvVector; // current advertised window (=rcv_avd) 00350 cOutVector *sndNxtVector; // sent seqNo 00351 cOutVector *sndAckVector; // sent ackNo 00352 cOutVector *rcvSeqVector; // received seqNo 00353 cOutVector *rcvAckVector; // received ackNo (= snd_una) 00354 cOutVector *unackedVector; // number of bytes unacknowledged 00355 00356 cOutVector *dupAcksVector; // current number of received dupAcks 00357 cOutVector *pipeVector; // current sender's estimate of bytes outstanding in the network 00358 cOutVector *sndSacksVector; // number of sent Sacks 00359 cOutVector *rcvSacksVector; // number of received Sacks 00360 cOutVector *rcvOooSegVector; // number of received out-of-order segments 00361 00362 cOutVector *sackedBytesVector; // current number of received sacked bytes 00363 cOutVector *tcpRcvQueueBytesVector; // current amount of used bytes in tcp receive queue 00364 cOutVector *tcpRcvQueueDropsVector; // number of drops in tcp receive queue 00365 00366 protected: 00370 virtual TCPEventCode preanalyseAppCommandEvent(int commandCode); 00372 virtual bool performStateTransition(const TCPEventCode& event); 00374 virtual void stateEntered(int state); 00376 00379 virtual void process_OPEN_ACTIVE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg); 00380 virtual void process_OPEN_PASSIVE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg); 00381 virtual void process_SEND(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg); 00382 virtual void process_CLOSE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg); 00383 virtual void process_ABORT(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg); 00384 virtual void process_STATUS(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg); 00386 00393 virtual bool tryFastRoute(TCPSegment *tcpseg); 00398 virtual TCPEventCode process_RCV_SEGMENT(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest); 00399 virtual TCPEventCode processSegmentInListen(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest); 00400 virtual TCPEventCode processSegmentInSynSent(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest); 00401 virtual TCPEventCode processSegment1stThru8th(TCPSegment *tcpseg); 00402 virtual TCPEventCode processRstInSynReceived(TCPSegment *tcpseg); 00403 virtual bool processAckInEstabEtc(TCPSegment *tcpseg); 00405 00408 virtual bool processMSSOption(TCPSegment *tcpseg, const TCPOption& option); 00409 virtual bool processWSOption(TCPSegment *tcpseg, const TCPOption& option); 00410 virtual bool processSACKPermittedOption(TCPSegment *tcpseg, const TCPOption& option); 00411 virtual bool processSACKOption(TCPSegment *tcpseg, const TCPOption& option); 00412 virtual bool processTSOption(TCPSegment *tcpseg, const TCPOption& option); 00414 00417 virtual void process_TIMEOUT_2MSL(); 00418 virtual void process_TIMEOUT_CONN_ESTAB(); 00419 virtual void process_TIMEOUT_FIN_WAIT_2(); 00420 virtual void process_TIMEOUT_SYN_REXMIT(TCPEventCode& event); 00422 00424 virtual TCPConnection *cloneListeningConnection(); 00425 00427 virtual void initConnection(TCPOpenCommand *openCmd); 00428 00430 virtual void configureStateVariables(); 00431 00433 virtual void selectInitialSeqNum(); 00434 00436 virtual bool isSegmentAcceptable(TCPSegment *tcpseg); 00437 00439 virtual void sendSyn(); 00440 00442 virtual void sendSynAck(); 00443 00445 virtual void readHeaderOptions(TCPSegment *tcpseg); 00446 00448 virtual TCPSegment writeHeaderOptions(TCPSegment *tcpseg); 00449 00451 virtual TCPSegment addSacks(TCPSegment *tcpseg); 00452 00454 virtual uint32 getTSval(TCPSegment *tcpseg); 00455 00457 virtual uint32 getTSecr(TCPSegment *tcpseg); 00458 public: 00460 virtual void sendAck(); 00461 00467 virtual bool sendData(bool fullSegmentsOnly, uint32 congestionWindow); 00468 00470 virtual bool sendProbe(); 00471 00473 virtual void retransmitOneSegment(bool called_at_rto); 00474 00476 virtual void retransmitData(); 00477 00479 virtual void sendRst(uint32 seqNo); 00481 virtual void sendRst(uint32 seq, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort); 00483 virtual void sendRstAck(uint32 seq, uint32 ack, IPvXAddress src, IPvXAddress dest, int srcPort, int destPort); 00484 00486 virtual void sendFin(); 00487 00492 virtual void sendSegment(uint32 bytes); 00493 00495 virtual void sendToIP(TCPSegment *tcpseg); 00496 00501 virtual TCPSegment *createTCPSegment(const char *name); 00502 00504 virtual void startSynRexmitTimer(); 00505 00507 virtual void signalConnectionTimeout(); 00508 00510 void scheduleTimeout(cMessage *msg, simtime_t timeout) 00511 {tcpMain->scheduleAt(simTime()+timeout, msg);} 00512 00513 protected: 00515 cMessage *cancelEvent(cMessage *msg) {return tcpMain->cancelEvent(msg);} 00516 00518 static void sendToIP(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest); 00519 00521 virtual void sendToApp(cMessage *msg); 00522 00524 virtual void sendIndicationToApp(int code); 00525 00527 virtual void sendEstabIndicationToApp(); 00528 00529 public: 00531 virtual void printConnBrief(); 00533 static void printSegmentBrief(TCPSegment *tcpseg); 00535 static const char *stateName(int state); 00537 static const char *eventName(int event); 00539 static const char *indicationName(int code); 00541 static const char *optionName(int option); 00543 virtual void updateRcvQueueVars(); 00544 00548 virtual unsigned short updateRcvWnd(); 00549 00551 virtual void updateWndInfo(TCPSegment *tcpseg, bool doAlways=false); 00552 00553 public: 00557 TCPConnection(TCP *mod, int appGateIndex, int connId); 00558 00563 TCPConnection(); 00564 00568 virtual ~TCPConnection(); 00569 00576 virtual void segmentArrivalWhileClosed(TCPSegment *tcpseg, IPvXAddress src, IPvXAddress dest); 00577 00580 int getFsmState() const {return fsm.getState();} 00581 TCPStateVariables *getState() {return state;} 00582 TCPSendQueue *getSendQueue() {return sendQueue;} 00583 TCPSACKRexmitQueue *getRexmitQueue() {return rexmitQueue;} 00584 TCPReceiveQueue *getReceiveQueue() {return receiveQueue;} 00585 TCPAlgorithm *getTcpAlgorithm() {return tcpAlgorithm;} 00586 TCP *getTcpMain() {return tcpMain;} 00588 00594 virtual bool processTimer(cMessage *msg); 00595 00601 virtual bool processTCPSegment(TCPSegment *tcpSeg, IPvXAddress srcAddr, IPvXAddress destAddr); 00602 00608 virtual bool processAppCommand(cMessage *msg); 00609 00618 virtual bool isLost(uint32 seqNum); 00619 00626 virtual void setPipe(); 00627 00636 virtual uint32 nextSeg(); 00637 00641 virtual void sendDataDuringLossRecoveryPhase(uint32 congestionWindow); 00642 00646 virtual void sendSegmentDuringLossRecoveryPhase(uint32 seqNum); 00647 00651 virtual void sendOneNewSegment(bool fullSegmentsOnly, uint32 congestionWindow); 00652 00656 virtual uint32 convertSimtimeToTS(simtime_t simtime); 00657 00661 virtual simtime_t convertTSToSimtime(uint32 timestamp); 00662 00666 virtual bool isSendQueueEmpty(); 00667 00668 }; 00669 00670 #endif