Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string.h>
00020 #include "TCP.h"
00021 #include "TCPConnection.h"
00022 #include "TCPSegment.h"
00023 #include "TCPCommand_m.h"
00024 #include "TCPSendQueue.h"
00025 #include "TCPReceiveQueue.h"
00026 #include "TCPAlgorithm.h"
00027
00028
00029
00030
00031
00032
00033 void TCPConnection::process_OPEN_ACTIVE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg)
00034 {
00035 TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(tcpCommand);
00036 IPvXAddress localAddr, remoteAddr;
00037 int localPort, remotePort;
00038
00039 switch(fsm.getState())
00040 {
00041 case TCP_S_INIT:
00042 initConnection(openCmd);
00043
00044
00045 state->active = true;
00046 localAddr = openCmd->getLocalAddr();
00047 remoteAddr = openCmd->getRemoteAddr();
00048 localPort = openCmd->getLocalPort();
00049 remotePort = openCmd->getRemotePort();
00050
00051 if (remoteAddr.isUnspecified() || remotePort==-1)
00052 opp_error("Error processing command OPEN_ACTIVE: remote address and port must be specified");
00053
00054 if (localPort==-1)
00055 {
00056 localPort = tcpMain->getEphemeralPort();
00057 tcpEV << "Assigned ephemeral port " << localPort << "\n";
00058 }
00059
00060 tcpEV << "OPEN: " << localAddr << ":" << localPort << " --> " << remoteAddr << ":" << remotePort << "\n";
00061
00062 tcpMain->addSockPair(this, localAddr, remoteAddr, localPort, remotePort);
00063
00064
00065 selectInitialSeqNum();
00066 sendSyn();
00067 startSynRexmitTimer();
00068 scheduleTimeout(connEstabTimer, TCP_TIMEOUT_CONN_ESTAB);
00069 break;
00070
00071 default:
00072 opp_error("Error processing command OPEN_ACTIVE: connection already exists");
00073 }
00074
00075 delete openCmd;
00076 delete msg;
00077 }
00078
00079 void TCPConnection::process_OPEN_PASSIVE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg)
00080 {
00081 TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(tcpCommand);
00082 IPvXAddress localAddr;
00083 int localPort;
00084
00085 switch(fsm.getState())
00086 {
00087 case TCP_S_INIT:
00088 initConnection(openCmd);
00089
00090
00091 state->active = false;
00092 state->fork = openCmd->getFork();
00093 localAddr = openCmd->getLocalAddr();
00094 localPort = openCmd->getLocalPort();
00095
00096 if (localPort==-1)
00097 opp_error("Error processing command OPEN_PASSIVE: local port must be specified");
00098
00099 tcpEV << "Starting to listen on: " << localAddr << ":" << localPort << "\n";
00100
00101 tcpMain->addSockPair(this, localAddr, IPvXAddress(), localPort, -1);
00102 break;
00103
00104 default:
00105 opp_error("Error processing command OPEN_PASSIVE: connection already exists");
00106 }
00107
00108 delete openCmd;
00109 delete msg;
00110 }
00111
00112 void TCPConnection::process_SEND(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg)
00113 {
00114 TCPSendCommand *sendCommand = check_and_cast<TCPSendCommand *>(tcpCommand);
00115
00116
00117
00118 switch(fsm.getState())
00119 {
00120 case TCP_S_INIT:
00121 opp_error("Error processing command SEND: connection not open");
00122
00123 case TCP_S_LISTEN:
00124 tcpEV << "SEND command turns passive open into active open, sending initial SYN\n";
00125 state->active = true;
00126 selectInitialSeqNum();
00127 sendSyn();
00128 startSynRexmitTimer();
00129 scheduleTimeout(connEstabTimer, TCP_TIMEOUT_CONN_ESTAB);
00130 sendQueue->enqueueAppData(PK(msg));
00131 tcpEV << sendQueue->getBytesAvailable(state->snd_una) << " bytes in queue\n";
00132 break;
00133
00134 case TCP_S_SYN_RCVD:
00135 case TCP_S_SYN_SENT:
00136 tcpEV << "Queueing up data for sending later.\n";
00137 sendQueue->enqueueAppData(PK(msg));
00138 tcpEV << sendQueue->getBytesAvailable(state->snd_una) << " bytes in queue\n";
00139 break;
00140
00141 case TCP_S_ESTABLISHED:
00142 case TCP_S_CLOSE_WAIT:
00143 sendQueue->enqueueAppData(PK(msg));
00144 tcpEV << sendQueue->getBytesAvailable(state->snd_una) << " bytes in queue, plus "
00145 << (state->snd_max-state->snd_una) << " bytes unacknowledged\n";
00146 tcpAlgorithm->sendCommandInvoked();
00147 break;
00148
00149 case TCP_S_LAST_ACK:
00150 case TCP_S_FIN_WAIT_1:
00151 case TCP_S_FIN_WAIT_2:
00152 case TCP_S_CLOSING:
00153 case TCP_S_TIME_WAIT:
00154 opp_error("Error processing command SEND: connection closing");
00155 }
00156
00157 delete sendCommand;
00158 }
00159
00160 void TCPConnection::process_CLOSE(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg)
00161 {
00162 delete tcpCommand;
00163 delete msg;
00164
00165 switch(fsm.getState())
00166 {
00167 case TCP_S_INIT:
00168 opp_error("Error processing command CLOSE: connection not open");
00169
00170 case TCP_S_LISTEN:
00171
00172 break;
00173
00174 case TCP_S_SYN_SENT:
00175
00176
00177 break;
00178
00179 case TCP_S_SYN_RCVD:
00180 case TCP_S_ESTABLISHED:
00181 case TCP_S_CLOSE_WAIT:
00182
00183
00184
00185
00186
00187
00188
00189 if (state->snd_max==sendQueue->getBufferEndSeq())
00190 {
00191 tcpEV << "No outstanding SENDs, sending FIN right away, advancing snd_nxt over the FIN\n";
00192 state->snd_nxt = state->snd_max;
00193 sendFin();
00194 tcpAlgorithm->restartRexmitTimer();
00195 state->snd_max = ++state->snd_nxt;
00196 if (unackedVector) unackedVector->record(state->snd_max - state->snd_una);
00197
00198
00199 }
00200 else
00201 {
00202 tcpEV << "SEND of " << (sendQueue->getBufferEndSeq()-state->snd_max) <<
00203 " bytes pending, deferring sending of FIN\n";
00204 event = TCP_E_IGNORE;
00205 }
00206 state->send_fin = true;
00207 state->snd_fin_seq = sendQueue->getBufferEndSeq();
00208 break;
00209
00210 case TCP_S_FIN_WAIT_1:
00211 case TCP_S_FIN_WAIT_2:
00212 case TCP_S_CLOSING:
00213 case TCP_S_LAST_ACK:
00214 case TCP_S_TIME_WAIT:
00215
00216
00217 opp_error("Duplicate CLOSE command: connection already closing");
00218 }
00219 }
00220
00221 void TCPConnection::process_ABORT(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg)
00222 {
00223 delete tcpCommand;
00224 delete msg;
00225
00226
00227
00228
00229
00230
00231 switch(fsm.getState())
00232 {
00233 case TCP_S_INIT:
00234 opp_error("Error processing command ABORT: connection not open");
00235
00236 case TCP_S_SYN_RCVD:
00237 case TCP_S_ESTABLISHED:
00238 case TCP_S_FIN_WAIT_1:
00239 case TCP_S_FIN_WAIT_2:
00240 case TCP_S_CLOSE_WAIT:
00241
00242
00243
00244
00245
00246 sendRst(state->snd_nxt);
00247 break;
00248 }
00249
00250 }
00251
00252 void TCPConnection::process_STATUS(TCPEventCode& event, TCPCommand *tcpCommand, cMessage *msg)
00253 {
00254 delete tcpCommand;
00255
00256 if (fsm.getState()==TCP_S_INIT)
00257 opp_error("Error processing command STATUS: connection not open");
00258
00259 TCPStatusInfo *statusInfo = new TCPStatusInfo();
00260
00261 statusInfo->setState(fsm.getState());
00262 statusInfo->setStateName(stateName(fsm.getState()));
00263
00264 statusInfo->setLocalAddr(localAddr);
00265 statusInfo->setRemoteAddr(remoteAddr);
00266 statusInfo->setLocalPort(localPort);
00267 statusInfo->setRemotePort(remotePort);
00268
00269 statusInfo->setSnd_mss(state->snd_mss);
00270 statusInfo->setSnd_una(state->snd_una);
00271 statusInfo->setSnd_nxt(state->snd_nxt);
00272 statusInfo->setSnd_max(state->snd_max);
00273 statusInfo->setSnd_wnd(state->snd_wnd);
00274 statusInfo->setSnd_up(state->snd_up);
00275 statusInfo->setSnd_wl1(state->snd_wl1);
00276 statusInfo->setSnd_wl2(state->snd_wl2);
00277 statusInfo->setIss(state->iss);
00278 statusInfo->setRcv_nxt(state->rcv_nxt);
00279 statusInfo->setRcv_wnd(state->rcv_wnd);
00280 statusInfo->setRcv_up(state->rcv_up);
00281 statusInfo->setIrs(state->irs);
00282 statusInfo->setFin_ack_rcvd(state->fin_ack_rcvd);
00283
00284 msg->setControlInfo(statusInfo);
00285 sendToApp(msg);
00286 }
00287
00288