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 #include "DumbTCP_old.h" 00019 #include "TCP_old.h" 00020 00021 using namespace tcp_old; 00022 00023 Register_Class(DumbTCP); 00024 00025 // just a dummy value 00026 #define REXMIT_TIMEOUT 2 00027 00028 00029 DumbTCP::DumbTCP() : TCPAlgorithm(), 00030 state((DumbTCPStateVariables *&)TCPAlgorithm::state) 00031 { 00032 rexmitTimer = NULL; 00033 } 00034 00035 DumbTCP::~DumbTCP() 00036 { 00037 // cancel and delete timers 00038 if (rexmitTimer) 00039 delete conn->getTcpMain()->cancelEvent(rexmitTimer); 00040 } 00041 00042 void DumbTCP::initialize() 00043 { 00044 TCPAlgorithm::initialize(); 00045 00046 rexmitTimer = new cMessage("REXMIT"); 00047 rexmitTimer->setContextPointer(conn); 00048 } 00049 00050 void DumbTCP::established(bool active) 00051 { 00052 if (active) 00053 { 00054 // finish connection setup with ACK (possibly piggybacked on data) 00055 tcpEV << "Completing connection setup by sending ACK (possibly piggybacked on data)\n"; 00056 if (!conn->sendData(false)) 00057 conn->sendAck(); 00058 } 00059 } 00060 00061 void DumbTCP::connectionClosed() 00062 { 00063 conn->getTcpMain()->cancelEvent(rexmitTimer); 00064 } 00065 00066 void DumbTCP::processTimer(cMessage *timer, TCPEventCode& event) 00067 { 00068 if (timer!=rexmitTimer) 00069 throw cRuntimeError(timer, "unrecognized timer"); 00070 00071 conn->retransmitData(); 00072 conn->scheduleTimeout(rexmitTimer, REXMIT_TIMEOUT); 00073 } 00074 00075 void DumbTCP::sendCommandInvoked() 00076 { 00077 // start sending 00078 conn->sendData(false); 00079 } 00080 00081 void DumbTCP::receivedOutOfOrderSegment() 00082 { 00083 tcpEV << "Out-of-order segment, sending immediate ACK\n"; 00084 conn->sendAck(); 00085 } 00086 00087 void DumbTCP::receiveSeqChanged() 00088 { 00089 // new data received, ACK immediately (more sophisticated algs should 00090 // wait a little to see if piggybacking is possible) 00091 tcpEV << "rcv_nxt changed to " << state->rcv_nxt << ", sending immediate ACK\n"; 00092 conn->sendAck(); 00093 } 00094 00095 void DumbTCP::receivedDataAck(uint32) 00096 { 00097 // ack may have freed up some room in the window, try sending. 00098 // small segments also OK (Nagle off) 00099 conn->sendData(false); 00100 } 00101 00102 void DumbTCP::receivedDuplicateAck() 00103 { 00104 tcpEV << "Duplicate ACK #" << state->dupacks << "\n"; 00105 } 00106 00107 void DumbTCP::receivedAckForDataNotYetSent(uint32 seq) 00108 { 00109 tcpEV << "ACK acks something not yet sent, sending immediate ACK\n"; 00110 conn->sendAck(); 00111 } 00112 00113 void DumbTCP::ackSent() 00114 { 00115 } 00116 00117 void DumbTCP::dataSent(uint32) 00118 { 00119 if (rexmitTimer->isScheduled()) 00120 conn->getTcpMain()->cancelEvent(rexmitTimer); 00121 conn->scheduleTimeout(rexmitTimer, REXMIT_TIMEOUT); 00122 } 00123 00124 void DumbTCP::restartRexmitTimer() 00125 { 00126 // NO retransmit timer in dumb TCP 00127 } 00128 00129 00130 00131