TCP_NSC_Connection.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Sam Jansen, Andras Varga
00003 //               2009 Zoltan Bojthe
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU 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 General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 
00020 #ifdef WITH_TCP_NSC
00021 
00022 #include "TCP_NSC_Connection.h"
00023 
00024 #include "headers/defs.h"   // for endian macros
00025 #include "IPControlInfo.h"
00026 #include "IPv6ControlInfo.h"
00027 #include <sim_interface.h> // NSC header
00028 #include "headers/tcp.h"
00029 #include "TCP_NSC.h"
00030 #include "TCP_NSC_Queues.h"
00031 #include "TCPCommand_m.h"
00032 #include "TCPIPchecksum.h"
00033 #include "TCPSegment.h"
00034 #include "TCPSerializer.h"
00035 
00036 #include <assert.h>
00037 #include <dlfcn.h>
00038 #include <netinet/in.h>
00039 
00040 // macro for normal ev<< logging (note: deliberately no parens in macro def)
00041 // FIXME
00042 //#define tcpEV (((ev.disable_tracing)||(TCP_NSC::testingS)) ? (std::cout) : (ev))
00043 
00044 #define tcpEV ev
00045 //#define tcpEV std::cout
00046 
00047 
00048 struct nsc_iphdr
00049 {
00050 #if BYTE_ORDER == LITTLE_ENDIAN
00051     unsigned int ihl:4;
00052     unsigned int version:4;
00053 #elif BYTE_ORDER == BIG_ENDIAN
00054     unsigned int version:4;
00055     unsigned int ihl:4;
00056 #else
00057 # error "Please check BYTE_ORDER declaration"
00058 #endif
00059     uint8_t tos;
00060     uint16_t tot_len;
00061     uint16_t id;
00062     uint16_t frag_off;
00063     uint8_t ttl;
00064     uint8_t protocol;
00065     uint16_t check;
00066     uint32_t saddr;
00067     uint32_t daddr;
00068     /*The options start here. */
00069 } __attribute__((packed));
00070 
00071 TCP_NSC_Connection::TCP_NSC_Connection()
00072     :
00073     connIdM(-1),
00074     appGateIndexM(-1),
00075     pNscSocketM(NULL),
00076     sentEstablishedM(false),
00077     onCloseM(false),
00078     isListenerM(false),
00079     tcpWinSizeM(65536),
00080     tcpNscM(NULL),
00081     receiveQueueM(NULL),
00082     sendQueueM(NULL)
00083 {
00084 }
00085 
00086 // create a TCP_I_ESTABLISHED msg
00087 cMessage* TCP_NSC_Connection::createEstablishedMsg()
00088 {
00089     if(sentEstablishedM)
00090         return NULL;
00091 
00092     cMessage *msg = new cMessage("TCP_I_ESTABLISHED");
00093     msg->setKind(TCP_I_ESTABLISHED);
00094 
00095     TCPConnectInfo *tcpConnectInfo = new TCPConnectInfo();
00096 
00097 /*    struct sockaddr_in peerAddr, sockAddr;
00098     size_t peerAddrLen=sizeof(peerAddr),sockAddrLen=sizeof(sockAddr);
00099     pNscSocketM->getpeername((sockaddr*)&peerAddr, &peerAddrLen);
00100     pNscSocketM->getsockname((sockaddr*)&sockAddr, &sockAddrLen);
00101     tcpConnectInfo->setLocalPort(ntohs(sockAddr.sin_port));
00102     tcpConnectInfo->setRemotePort(ntohs(peerAddr.sin_port));
00103 */
00104     tcpConnectInfo->setConnId(connIdM);
00105     tcpConnectInfo->setLocalAddr(inetSockPairM.localM.ipAddrM);
00106     tcpConnectInfo->setRemoteAddr(inetSockPairM.remoteM.ipAddrM);
00107     tcpConnectInfo->setLocalPort(inetSockPairM.localM.portM);
00108     tcpConnectInfo->setRemotePort(inetSockPairM.remoteM.portM);
00109 
00110     msg->setControlInfo(tcpConnectInfo);
00111     //tcpMain->send(estmsg, "appOut", appGateIndex);
00112     return msg;
00113 }
00114 
00115 void TCP_NSC_Connection::connect(INetStack &stackP, SockPair &inetSockPairP, SockPair &nscSockPairP)
00116 {
00117     ASSERT(!pNscSocketM);
00118     pNscSocketM = stackP.new_tcp_socket();
00119     ASSERT(pNscSocketM);
00120 
00121     // TODO NSC not yet implements bind (for setting localport)
00122 
00123     ASSERT(sendQueueM);
00124     ASSERT(receiveQueueM);
00125 
00126     sendQueueM->setConnection(this);
00127     receiveQueueM->setConnection(this);
00128 
00129     onCloseM = false;
00130 
00131     pNscSocketM->connect(nscSockPairM.remoteM.ipAddrM.str().c_str(), nscSockPairM.remoteM.portM);
00132 
00133     struct sockaddr_in sockAddr;
00134     size_t sockAddrLen=sizeof(sockAddr);
00135     pNscSocketM->getsockname((sockaddr*)&sockAddr, &sockAddrLen);
00136     nscSockPairP.localM.ipAddrM.set(sockAddr.sin_addr.s_addr);
00137     nscSockPairP.localM.portM = ntohs(sockAddr.sin_port);
00138 /*
00139     // TODO: getpeername generate an assert!!!
00140     pNscSocketM->getpeername((sockaddr*)&sockAddr, &sockAddrLen);
00141     nscSockPairP.remoteM.ipAddrM.set(sockAddr.sin_addr.s_addr);
00142     nscSockPairP.remoteM.portM = ntohs(sockAddr.sin_port);
00143 */
00144 }
00145 
00146 void TCP_NSC_Connection::listen(INetStack &stackP, SockPair &inetSockPairP, SockPair &nscSockPairP)
00147 {
00148     ASSERT(nscSockPairP.localM.portM != -1);
00149     ASSERT(!pNscSocketM);
00150     ASSERT(sendQueueM);
00151     ASSERT(receiveQueueM);
00152 
00153     isListenerM = true;
00154     pNscSocketM = stackP.new_tcp_socket();
00155     ASSERT(pNscSocketM);
00156 
00157     // TODO NSC not yet implements bind (for setting remote addr)
00158 
00159     sendQueueM->setConnection(this);
00160     receiveQueueM->setConnection(this);
00161 
00162     onCloseM = false;
00163 
00164     pNscSocketM->listen(nscSockPairP.localM.portM);
00165 
00166     struct sockaddr_in sockAddr;
00167     size_t sockAddrLen=sizeof(sockAddr);
00168     pNscSocketM->getsockname((sockaddr*)&sockAddr, &sockAddrLen);
00169 
00170     nscSockPairP.localM.ipAddrM.set(sockAddr.sin_addr.s_addr);
00171     nscSockPairP.localM.portM = ntohs(sockAddr.sin_port);
00172     nscSockPairP.remoteM.ipAddrM = IPvXAddress();
00173     nscSockPairP.remoteM.portM = -1;
00174 }
00175 
00176 void TCP_NSC_Connection::send(cPacket *msgP)
00177 {
00178     ASSERT(sendQueueM);
00179     sendQueueM->enqueueAppData(msgP);
00180 }
00181 
00182 void TCP_NSC_Connection::do_SEND()
00183 {
00184     if(pNscSocketM)
00185     {
00186         ASSERT(sendQueueM);
00187 
00188         char buffer[4096];
00189 
00190         int allsent = 0;
00191         while(1)
00192         {
00193             int bytes = sendQueueM->getNscMsg(buffer, sizeof(buffer));
00194             if(0 == bytes)
00195                 break;
00196 
00197             int sent = pNscSocketM->send_data(buffer, bytes);
00198 
00199             if(sent > 0)
00200             {
00201                 sendQueueM->dequeueNscMsg(sent);
00202                 allsent += sent;
00203             }
00204             else
00205             {
00206                 tcpEV << "TCP_NSC connection: " << connIdM << ": Error do sending, err is " << sent << "\n";
00207                 break;
00208 
00209             }
00210         }
00211 //        tcpEV << "do_SEND(): " << connIdM << " sent:" << allsent << ", unsent:" << sendQueueM->getBytesAvailable() << "\n";
00212     }
00213 }
00214 
00215 void TCP_NSC_Connection::close()
00216 {
00217     onCloseM = true;
00218 }
00219 
00220 void TCP_NSC_Connection::abort()
00221 {
00222     close();
00223 }
00224 
00225 #endif // WITH_TCP_NSC