|
INET Framework for OMNeT++/OMNEST
|
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