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