00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef WITH_TCP_NSC
00021
00022 #include "TCP_NSC.h"
00023
00024 #include "headers/defs.h"
00025
00026 #include "IPControlInfo.h"
00027 #include "IPv6ControlInfo.h"
00028 #include "headers/tcp.h"
00029 #include "TCPCommand_m.h"
00030 #include "TCPIPchecksum.h"
00031 #include "TCP_NSC_Queues.h"
00032 #include "TCPSegment.h"
00033 #include "TCPSerializer.h"
00034
00035 #include <assert.h>
00036 #include <dlfcn.h>
00037 #include <netinet/in.h>
00038
00039
00040 Define_Module(TCP_NSC);
00041
00042
00043
00044 const IPvXAddress TCP_NSC::localInnerIpS("1.0.0.253");
00045 const IPvXAddress TCP_NSC::localInnerMaskS("255.255.255.0");
00046 const IPvXAddress TCP_NSC::localInnerGwS("1.0.0.254");
00047 const IPvXAddress TCP_NSC::remoteFirstInnerIpS("2.0.0.1");
00048
00049 const char * TCP_NSC::stackNameParamNameS = "stackName";
00050
00051 const char * TCP_NSC::bufferSizeParamNameS = "stackBufferSize";
00052
00053 bool TCP_NSC::testingS;
00054 bool TCP_NSC::logverboseS;
00055
00056
00057
00058
00059 #define tcpEV ev
00060
00061
00062 struct nsc_iphdr
00063 {
00064 #if BYTE_ORDER == LITTLE_ENDIAN
00065 unsigned int ihl:4;
00066 unsigned int version:4;
00067 #elif BYTE_ORDER == BIG_ENDIAN
00068 unsigned int version:4;
00069 unsigned int ihl:4;
00070 #else
00071 # error "Please check BYTE_ORDER declaration"
00072 #endif
00073 uint8_t tos;
00074 uint16_t tot_len;
00075 uint16_t id;
00076 uint16_t frag_off;
00077 uint8_t ttl;
00078 uint8_t protocol;
00079 uint16_t check;
00080 uint32_t saddr;
00081 uint32_t daddr;
00082
00083 } __attribute__((packed));
00084
00085 struct nsc_ipv6hdr
00086 {
00087 #if BYTE_ORDER == LITTLE_ENDIAN
00088 uint32_t flow:20;
00089 uint32_t ds:8;
00090 uint32_t version:4;
00091 #elif BYTE_ORDER == BIG_ENDIAN
00092 uint32_t version:4;
00093 uint32_t ds:8;
00094 uint32_t flow:20;
00095 #else
00096 # error "Please check BYTE_ORDER declaration"
00097 #endif
00098 uint16_t len;
00099 uint8_t next_header;
00100 uint8_t hop_limit;
00101 uint16_t id;
00102 uint16_t frag_off;
00103 uint8_t ttl;
00104 uint8_t protocol;
00105 uint16_t check;
00106 uint32_t saddr[4];
00107 uint32_t daddr[4];
00108 } __attribute__((packed));
00109
00110 static char *flags2str(unsigned char flags)
00111 {
00112 static char buf[512];
00113 buf[0]='\0';
00114 if(flags & TH_FIN) strcat(buf, " FIN");
00115 if(flags & TH_SYN) strcat(buf, " SYN");
00116 if(flags & TH_RST) strcat(buf, " RST");
00117 if(flags & TH_PUSH) strcat(buf, " PUSH");
00118 if(flags & TH_ACK) strcat(buf, " ACK");
00119 if(flags & TH_URG) strcat(buf, " URG");
00120
00121
00122
00123 return buf;
00124 }
00125
00126 static std::ostream& operator<<(std::ostream& osP, const TCP_NSC_Connection& connP)
00127 {
00128 osP << "Conn={"
00129 << "connId=" << connP.connIdM
00130 << " appGateIndex=" << connP.appGateIndexM
00131 << " nscsocket=" << connP.pNscSocketM
00132 << " sentEstablishedM=" << connP.sentEstablishedM
00133 << '}';
00134 return osP;
00135 }
00136
00137 static std::ostream& operator<<(std::ostream& osP, const TCP_NSC_Connection::SockAddr& sockAddrP)
00138 {
00139 osP << sockAddrP.ipAddrM << ":" << sockAddrP.portM;
00140 return osP;
00141 }
00142
00143 static std::ostream& operator<<(std::ostream& osP, const TCP_NSC_Connection::SockPair& sockPairP)
00144 {
00145 osP << "{loc=" << sockPairP.localM << ", rem=" << sockPairP.remoteM << "}";
00146 return osP;
00147 }
00148
00149 TCP_NSC::TCP_NSC()
00150 : pStackM(NULL),
00151 pNsiTimerM(NULL),
00152 isAliveM(false),
00153 curAddrCounterM(0),
00154 curConnM(NULL),
00155
00156
00157 sndWndVector(NULL),
00158 rcvWndVector(NULL),
00159 rcvAdvVector(NULL),
00160 sndNxtVector(NULL),
00161 sndAckVector(NULL),
00162 rcvSeqVector(NULL),
00163 rcvAckVector(NULL),
00164 unackedVector(NULL),
00165 dupAcksVector(NULL),
00166 pipeVector(NULL),
00167 sndSacksVector(NULL),
00168 rcvSacksVector(NULL),
00169 rcvOooSegVector(NULL),
00170 sackedBytesVector(NULL),
00171 tcpRcvQueueBytesVector(NULL),
00172 tcpRcvQueueDropsVector(NULL)
00173 {
00174
00175 if (true)
00176 {
00177
00178
00179 sndNxtVector = new cOutVector("sent seq");
00180 sndAckVector = new cOutVector("sent ack");
00181 rcvSeqVector = new cOutVector("rcvd seq");
00182 rcvAckVector = new cOutVector("rcvd ack");
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 }
00193 }
00194
00195
00196
00197 uint32_t TCP_NSC::mapRemote2Nsc(IPvXAddress const& addrP)
00198 {
00199 Remote2NscMap::iterator i = remote2NscMapM.find(addrP);
00200 if (i != remote2NscMapM.end())
00201 {
00202 return i->second;
00203 }
00204
00205
00206 uint32_t ret = remoteFirstInnerIpS.get4().getInt();
00207 Nsc2RemoteMap::iterator j;
00208 for( j = nsc2RemoteMapM.begin(); j != nsc2RemoteMapM.end(); j++)
00209 {
00210 if(j->first > ret)
00211 break;
00212 ret = j->first + 1;
00213 }
00214
00215
00216 remote2NscMapM[addrP] = ret;
00217 nsc2RemoteMapM[ret] = addrP;
00218 ASSERT( remote2NscMapM.find(addrP) != remote2NscMapM.end() );
00219 ASSERT( nsc2RemoteMapM.find(ret) != nsc2RemoteMapM.end() );
00220 return ret;
00221 }
00222
00223
00224
00225
00226 IPvXAddress const & TCP_NSC::mapNsc2Remote(uint32_t nscAddrP)
00227 {
00228 Nsc2RemoteMap::iterator i = nsc2RemoteMapM.find(nscAddrP);
00229 if (i != nsc2RemoteMapM.end())
00230 {
00231 return i->second;
00232 }
00233 ASSERT(0);
00234 exit(1);
00235 }
00236
00237
00238 void TCP_NSC::decode_tcp(const void *packet_data, int hdr_len)
00239 {
00240 struct tcphdr const *tcp = (struct tcphdr const*)packet_data;
00241 char buf[4096];
00242
00243 sprintf(buf, "Src port:%hu Dst port:%hu Seq:%u Ack:%u Off:%hhu %s\n",
00244 ntohs(tcp->th_sport), ntohs(tcp->th_dport), ntohl(tcp->th_seq),
00245 ntohl(tcp->th_ack), (unsigned char)tcp->th_offs,
00246 flags2str(tcp->th_flags)
00247 );
00248 tcpEV << this << ": " << buf;
00249 sprintf(buf, "Win:%hu Sum:%hu Urg:%hu\n",
00250 ntohs(tcp->th_win), ntohs(tcp->th_sum), ntohs(tcp->th_urp));
00251 tcpEV << this << ": " << buf;
00252
00253 if(hdr_len > 20)
00254 {
00255 unsigned char const *opt = (unsigned char const*)packet_data + sizeof(struct tcphdr);
00256
00257 tcpEV << this << ": " << ("Options: ");
00258 while(
00259 (*opt != 0) &&
00260 ((unsigned int)opt < (unsigned int)packet_data + tcp->th_offs*4)
00261 )
00262 {
00263 unsigned char len = opt[1];
00264 if(len == 0 && opt[0] != 1)
00265 {
00266 sprintf(buf, "0-length option(%u)\n", opt[0]);
00267 tcpEV << this << ": " << buf;
00268 break;
00269 }
00270
00271 len -= 2;
00272
00273 switch(*opt)
00274 {
00275 case 1: tcpEV << ("No-Op "); opt++; break;
00276 case 2: { unsigned short mss = 0;
00277
00278 if(len == 2) {
00279 mss = (opt[2] << 8) + (opt[3]);
00280 sprintf(buf, "MSS(%u) ", mss);
00281 tcpEV << buf;
00282 } else {
00283 sprintf(buf, "MSS:l:%u ", len);
00284 tcpEV << buf;
00285 }
00286 opt += opt[1];
00287 break;
00288 }
00289 case 3: {
00290 unsigned char ws = 0;
00291 ASSERT(len == 1);
00292 ws = opt[2];
00293 sprintf(buf, "WS(%u) ", ws);
00294 tcpEV << buf;
00295 opt += opt[1];
00296 break;
00297 }
00298 case 4: {
00299 sprintf(buf, "SACK-Permitted ");
00300 tcpEV << buf;
00301 opt += opt[1];
00302 break;
00303 }
00304 case 5: {
00305 tcpEV << ("SACK ");
00306 opt += opt[1];
00307 break;
00308 }
00309 case 8: {
00310 int i;
00311 tcpEV << ("Timestamp(");
00312 for(i = 0; i < len; i++) {
00313 sprintf(buf, "%02x", opt[2+i]);
00314 tcpEV << buf;
00315 }
00316 tcpEV << (") ");
00317 opt += opt[1];
00318 break;
00319 }
00320 default:{
00321 sprintf(buf, "%u:%u ", opt[0], opt[1]);
00322 tcpEV << buf;
00323 opt += opt[1];
00324 break;
00325 }
00326 };
00327
00328 }
00329 tcpEV << ("\n");
00330 }
00331
00332 }
00333
00334 void TCP_NSC::initialize()
00335 {
00336 tcpEV << this << ": initialize\n";
00337 WATCH_MAP(tcpAppConnMapM);
00338
00339 cModule *netw = simulation.getSystemModule();
00340 testingS = netw->hasPar("testing") && netw->par("testing").boolValue();
00341 logverboseS = !testingS && netw->hasPar("logverbose") && netw->par("logverbose").boolValue();
00342
00343 const char* stackName = this->par(stackNameParamNameS).stringValue();
00344
00345 int bufferSize = (int)(this->par(bufferSizeParamNameS).longValue());
00346
00347 loadStack(stackName, bufferSize);
00348 pStackM->if_attach(localInnerIpS.str().c_str(), localInnerMaskS.str().c_str(), 1500);
00349 pStackM->add_default_gateway(localInnerGwS.str().c_str());
00350
00351 isAliveM = true;
00352 }
00353
00354 TCP_NSC::~TCP_NSC()
00355 {
00356 tcpEV << this << ": destructor\n";
00357 isAliveM = false;
00358 while (!tcpAppConnMapM.empty())
00359 {
00360 TcpAppConnMap::iterator i = tcpAppConnMapM.begin();
00361 delete (*i).second.pNscSocketM;
00362 tcpAppConnMapM.erase(i);
00363 }
00364
00365
00366 delete sndWndVector;
00367 delete rcvWndVector;
00368 delete rcvAdvVector;
00369 delete sndNxtVector;
00370 delete sndAckVector;
00371 delete rcvSeqVector;
00372 delete rcvAckVector;
00373 delete unackedVector;
00374 delete dupAcksVector;
00375 delete sndSacksVector;
00376 delete rcvSacksVector;
00377 delete rcvOooSegVector;
00378 delete tcpRcvQueueBytesVector;
00379 delete tcpRcvQueueDropsVector;
00380 delete pipeVector;
00381 delete sackedBytesVector;
00382 }
00383
00384
00385 void TCP_NSC::sendEstablishedMsg(TCP_NSC_Connection &connP)
00386 {
00387
00388 cMessage *msg = connP.createEstablishedMsg();
00389 if(msg)
00390 {
00391 send(msg, "appOut", connP.appGateIndexM);
00392 connP.sentEstablishedM = true;
00393 }
00394 }
00395
00396 void TCP_NSC::changeAddresses(TCP_NSC_Connection &connP,
00397 const TCP_NSC_Connection::SockPair &inetSockPairP,
00398 const TCP_NSC_Connection::SockPair &nscSockPairP)
00399 {
00400 if (!(connP.inetSockPairM == inetSockPairP))
00401 {
00402 tcpEV << "conn:" << connP << " change inetMap from " << connP.inetSockPairM << " to " << inetSockPairP << "\n";
00403 inetSockPair2ConnIdMapM.erase(connP.inetSockPairM);
00404 connP.inetSockPairM = inetSockPairP;
00405 inetSockPair2ConnIdMapM[connP.inetSockPairM] = connP.connIdM;
00406 }
00407 if (!(connP.nscSockPairM == nscSockPairP))
00408 {
00409 tcpEV << "conn:" << connP << " change nscMap from " << connP.nscSockPairM << " to " << nscSockPairP << "\n";
00410
00411 nscSockPair2ConnIdMapM.erase(connP.nscSockPairM);
00412
00413 connP.nscSockPairM = nscSockPairP;
00414
00415 nscSockPair2ConnIdMapM[connP.nscSockPairM] = connP.connIdM;
00416 }
00417 }
00418
00419 void TCP_NSC::handleIpInputMessage(TCPSegment* tcpsegP)
00420 {
00421
00422 TCP_NSC_Connection::SockPair nscSockPair, inetSockPair, inetSockPairAny;
00423
00424 if (dynamic_cast<IPControlInfo *>(tcpsegP->getControlInfo())!=NULL)
00425 {
00426 IPControlInfo *controlInfo = (IPControlInfo *)tcpsegP->removeControlInfo();
00427 inetSockPair.remoteM.ipAddrM = controlInfo->getSrcAddr();
00428 inetSockPair.localM.ipAddrM = controlInfo->getDestAddr();
00429 delete controlInfo;
00430 }
00431 else if (dynamic_cast<IPv6ControlInfo *>(tcpsegP->getControlInfo())!=NULL)
00432 {
00433 IPv6ControlInfo *controlInfo = (IPv6ControlInfo *)tcpsegP->removeControlInfo();
00434 inetSockPair.remoteM.ipAddrM = controlInfo->getSrcAddr();
00435 inetSockPair.localM.ipAddrM = controlInfo->getDestAddr();
00436 delete controlInfo;
00437 {
00438
00439
00440 unsigned short numOptions = tcpsegP->getOptionsArraySize();
00441 for (unsigned short i=0; i < numOptions; i++)
00442 {
00443 TCPOption& option = tcpsegP->getOptions(i);
00444 if(option.getKind() == TCPOPTION_MAXIMUM_SEGMENT_SIZE)
00445 {
00446 unsigned int value = option.getValues(0);
00447 value -= sizeof(struct nsc_ipv6hdr) - sizeof(struct nsc_iphdr);
00448 option.setValues(0, value);
00449
00450 }
00451 }
00452 }
00453 }
00454 else
00455 {
00456 error("(%s)%s arrived without control info", tcpsegP->getClassName(), tcpsegP->getName());
00457 }
00458
00459
00460 if (rcvSeqVector)
00461 rcvSeqVector->record(tcpsegP->getSequenceNo());
00462 if (rcvAckVector)
00463 rcvAckVector->record(tcpsegP->getAckNo());
00464
00465 inetSockPair.remoteM.portM = tcpsegP->getSrcPort();
00466 inetSockPair.localM.portM = tcpsegP->getDestPort();
00467 nscSockPair.remoteM.portM = tcpsegP->getSrcPort();
00468 nscSockPair.localM.portM = tcpsegP->getDestPort();
00469 inetSockPairAny.localM = inetSockPair.localM;
00470
00471
00472 size_t ipHdrLen = sizeof(nsc_iphdr);
00473 size_t const maxBufferSize = 4096;
00474 char *data = new char[maxBufferSize];
00475 memset(data, 0, maxBufferSize);
00476 uint32_t nscSrcAddr = mapRemote2Nsc(inetSockPair.remoteM.ipAddrM);
00477 nscSockPair.localM.ipAddrM = localInnerIpS;
00478 nscSockPair.remoteM.ipAddrM.set(nscSrcAddr);
00479
00480 tcpEV << this << ": data arrived for interface of stack "
00481 << pStackM << "\n" << "src:"<< inetSockPair.remoteM.ipAddrM <<",dest:"<< inetSockPair.localM.ipAddrM <<"\n";
00482
00483 nsc_iphdr *ih = (nsc_iphdr *)data;
00484 tcphdr *tcph = (tcphdr *)(data + ipHdrLen);
00485
00486 ih->version = 4;
00487 ih->ihl = ipHdrLen/4;
00488 ih->tos = 0;
00489 ih->id = htons(tcpsegP->getSequenceNo());
00490 ih->frag_off = htons(0x4000);
00491 ih->ttl = 64;
00492 ih->protocol = 6;
00493 ih->check = 0;
00494 ih->saddr = htonl(nscSrcAddr);
00495 ih->daddr = htonl(localInnerIpS.get4().getInt());
00496
00497 tcpEV << this << ": modified to: IP " << ih->version << " len " << ih->ihl
00498 << " protocol " << (unsigned int)(ih->protocol)
00499 << " saddr " << (ih->saddr)
00500 << " daddr " << (ih->daddr)
00501 << "\n";
00502
00503 size_t totalTcpLen = maxBufferSize - ipHdrLen;
00504 TCP_NSC_Connection *conn;
00505 conn = findConnByInetSockPair(inetSockPair);
00506 if (!conn)
00507 conn = findConnByInetSockPair(inetSockPairAny);
00508 if(conn)
00509 {
00510 totalTcpLen = conn->receiveQueueM->insertBytesFromSegment(tcpsegP, (void *)tcph, totalTcpLen);
00511 }
00512 else
00513 {
00514 totalTcpLen = TCPSerializer().serialize(tcpsegP, (unsigned char *)tcph, totalTcpLen);
00515
00516 }
00517
00518
00519 tcph->th_sum = 0;
00520 tcph->th_sum = TCPSerializer().checksum(tcph, totalTcpLen, nscSockPair.remoteM.ipAddrM, nscSockPair.localM.ipAddrM);
00521
00522 size_t totalIpLen = ipHdrLen + totalTcpLen;
00523 ih->tot_len = htons(totalIpLen);
00524 ih->check = 0;
00525 ih->check = TCPIPchecksum::checksum(ih, ipHdrLen);
00526
00527 decode_tcp( (void *)tcph, totalTcpLen);
00528
00529
00530
00531 pStackM->if_receive_packet(0, data, totalIpLen);
00532
00533
00534 TcpAppConnMap::iterator j;
00535 int changes = 0;
00536 for(j = tcpAppConnMapM.begin(); j != tcpAppConnMapM.end(); ++j)
00537 {
00538 TCP_NSC_Connection &c = j->second;
00539
00540 if(c.pNscSocketM && c.isListenerM)
00541 {
00542
00543 tcpEV << this << ": NSC: attempting to accept:\n";
00544
00545 INetStreamSocket *sock = NULL;
00546 int err;
00547
00548 err = c.pNscSocketM->accept( &sock );
00549
00550 tcpEV << this << ": accept returned " << err << " , sock is " << sock
00551 << " socket" << c.pNscSocketM << "\n";
00552
00553 if(sock)
00554 {
00555 ASSERT(changes == 0);
00556 ASSERT(c.inetSockPairM.localM.portM == inetSockPair.localM.portM);
00557 ++changes;
00558
00559 TCP_NSC_Connection *conn;
00560 int newConnId = ev.getUniqueNumber();
00561
00562 conn = &tcpAppConnMapM[newConnId];
00563 conn->connIdM = newConnId;
00564 conn->appGateIndexM = c.appGateIndexM;
00565 conn->pNscSocketM = sock;
00566
00567
00568 changeAddresses(*conn, inetSockPair, nscSockPair);
00569
00570
00571 const char *sendQueueClass = c.sendQueueM->getClassName();
00572 conn->sendQueueM = check_and_cast<TCP_NSC_SendQueue *>(createOne(sendQueueClass));
00573 conn->sendQueueM->setConnection(conn);
00574
00575 const char *receiveQueueClass = c.receiveQueueM->getClassName();
00576 conn->receiveQueueM = check_and_cast<TCP_NSC_ReceiveQueue *>(createOne(receiveQueueClass));
00577 conn->receiveQueueM->setConnection(conn);
00578 tcpEV << this << ": NSC: got accept!\n";
00579
00580 sendEstablishedMsg(*conn);
00581 }
00582 }
00583 else if(c.pNscSocketM && c.pNscSocketM->is_connected() )
00584 {
00585 bool hasData = false;
00586 tcpEV << this << ": NSC: attempting to read from socket " << c.pNscSocketM << "\n";
00587
00588 if ((!c.sentEstablishedM) && c.pNscSocketM->is_connected())
00589 {
00590 ASSERT(changes == 0);
00591 hasData = true;
00592 changeAddresses(c, inetSockPair, nscSockPair);
00593 sendEstablishedMsg(c);
00594 }
00595 while(true)
00596 {
00597 static char buf[4096];
00598
00599 int buflen = sizeof(buf);
00600
00601 int err = c.pNscSocketM->read_data(buf, &buflen);
00602
00603 tcpEV << this << ": NSC: read: err " << err << " , buflen " << buflen << "\n";
00604
00605 if(err == 0 && buflen > 0)
00606 {
00607 ASSERT(changes == 0);
00608 if(!hasData)
00609 changeAddresses(c, inetSockPair, nscSockPair);
00610
00611 hasData = true;
00612 c.receiveQueueM->enqueueNscData(buf, buflen);
00613
00614
00615
00616
00617
00618
00619 }
00620 else
00621 break;
00622 }
00623 if(hasData)
00624 {
00625 while(cPacket *dataMsg = c.receiveQueueM->extractBytesUpTo())
00626 {
00627
00628 send(dataMsg, "appOut", c.appGateIndexM);
00629 }
00630 ++changes;
00631 changeAddresses(c, inetSockPair, nscSockPair);
00632 }
00633 }
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 delete [] data;
00646 delete tcpsegP;
00647 }
00648
00649 void TCP_NSC::handleAppMessage(cMessage *msgP)
00650 {
00651 TCPCommand *controlInfo = check_and_cast<TCPCommand *>(msgP->getControlInfo());
00652 int connId = controlInfo->getConnId();
00653
00654 TCP_NSC_Connection *conn = findAppConn(connId);
00655 if (!conn)
00656 {
00657 TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(controlInfo);
00658
00659 conn = &tcpAppConnMapM[connId];
00660 conn->connIdM = connId;
00661 conn->appGateIndexM = msgP->getArrivalGate()->getIndex();
00662 conn->pNscSocketM = NULL;
00663
00664
00665 const char *sendQueueClass = openCmd->getSendQueueClass();
00666 if (!sendQueueClass || !sendQueueClass[0])
00667 sendQueueClass = this->par("sendQueueClass");
00668 conn->sendQueueM = check_and_cast<TCP_NSC_SendQueue *>(createOne(sendQueueClass));
00669 conn->sendQueueM->setConnection(conn);
00670
00671
00672 const char *receiveQueueClass = openCmd->getReceiveQueueClass();
00673 if (!receiveQueueClass || !receiveQueueClass[0])
00674 receiveQueueClass = this->par("receiveQueueClass");
00675 conn->receiveQueueM = check_and_cast<TCP_NSC_ReceiveQueue *>(createOne(receiveQueueClass));
00676 conn->receiveQueueM->setConnection(conn);
00677
00678 tcpEV << this << ": TCP connection created for " << msgP << "\n";
00679 }
00680 processAppCommand(*conn, msgP);
00681 }
00682
00683 void TCP_NSC::handleMessage(cMessage *msgP)
00684 {
00685 if (msgP->isSelfMessage())
00686 {
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 if(msgP == pNsiTimerM )
00698 {
00699 do_SEND_all();
00700
00701 pStackM->increment_ticks();
00702
00703 pStackM->timer_interrupt();
00704
00705 scheduleAt(msgP->getArrivalTime() + 1.0 / (double)pStackM->get_hz(), msgP);
00706 }
00707 }
00708 else if (msgP->arrivedOn("ipIn") || msgP->arrivedOn("ipv6In"))
00709 {
00710 tcpEV << this << ": handle msg: " << msgP->getName() << "\n";
00711
00712 TCPSegment *tcpseg = check_and_cast<TCPSegment *>(msgP);
00713 handleIpInputMessage(tcpseg);
00714
00715 }
00716 else
00717 {
00718 tcpEV << this << ": handle msg: " << msgP->getName() << "\n";
00719 handleAppMessage(msgP);
00720 }
00721
00722 if (ev.isGUI())
00723 updateDisplayString();
00724 }
00725
00726 void TCP_NSC::updateDisplayString()
00727 {
00728
00729 }
00730
00731 TCP_NSC_Connection *TCP_NSC::findAppConn(int connIdP)
00732 {
00733 TcpAppConnMap::iterator i = tcpAppConnMapM.find(connIdP);
00734 return i==tcpAppConnMapM.end() ? NULL : &(i->second);
00735 }
00736
00737 TCP_NSC_Connection *TCP_NSC::findConnByInetSockPair(TCP_NSC_Connection::SockPair const & sockPairP)
00738 {
00739 SockPair2ConnIdMap::iterator i = inetSockPair2ConnIdMapM.find(sockPairP);
00740 return i==inetSockPair2ConnIdMapM.end() ? NULL : findAppConn(i->second);
00741 }
00742
00743 TCP_NSC_Connection *TCP_NSC::findConnByNscSockPair(TCP_NSC_Connection::SockPair const & sockPairP)
00744 {
00745 SockPair2ConnIdMap::iterator i = nscSockPair2ConnIdMapM.find(sockPairP);
00746 return i==nscSockPair2ConnIdMapM.end() ? NULL : findAppConn(i->second);
00747 }
00748
00749 void TCP_NSC::finish()
00750 {
00751 isAliveM = false;
00752 }
00753
00754 void TCP_NSC::removeConnection(int connIdP)
00755 {
00756 TcpAppConnMap::iterator i = tcpAppConnMapM.find(connIdP);
00757 if (i != tcpAppConnMapM.end())
00758 tcpAppConnMapM.erase(i);
00759 }
00760
00761 void TCP_NSC::printConnBrief(TCP_NSC_Connection& connP)
00762 {
00763 tcpEV << this << ": connId=" << connP.connIdM << " appGateIndex=" << connP.appGateIndexM;
00764 tcpEV << " nscsocket=" << connP.pNscSocketM << "\n";
00765 }
00766
00767 void TCP_NSC::loadStack(const char* stacknameP, int bufferSizeP)
00768 {
00769 void *handle = NULL;
00770 FCreateStack create = NULL;
00771
00772 tcpEV << this << ": Loading stack " << stacknameP << "\n";
00773
00774 handle = dlopen(stacknameP, RTLD_NOW);
00775 if(!handle) {
00776 fputs("The loading of NSC stack is unsuccessful: ", stderr);
00777 fputs(dlerror(), stderr);
00778 fputs("\nCheck the LD_LIBRARY_PATH or stackname!\n", stderr);
00779 exit(1);
00780 }
00781
00782 create = (FCreateStack)dlsym(handle, "nsc_create_stack");
00783 if(!create) {
00784 fputs(dlerror(), stderr);
00785 fputs("\n", stderr);
00786 exit(1);
00787 }
00788
00789 pStackM = create(this, this, NULL);
00790
00791 tcpEV << "TCP_NSC " << this << " has stack " << pStackM << "\n";
00792
00793 fprintf(stderr, "Created stack = %p\n", pStackM);
00794
00795 fprintf(stderr, "Initialising stack, name=%s\n", pStackM->get_name());
00796
00797 pStackM->init(pStackM->get_hz());
00798
00799 pStackM->buffer_size(bufferSizeP);
00800
00801 fprintf(stderr, "done.\n");
00802
00803
00804 pNsiTimerM = new cMessage("nsc_nsi_timer");
00805 scheduleAt(1.0 / (double)pStackM->get_hz(), pNsiTimerM);
00806 }
00807
00809 void TCP_NSC::send_callback(const void *dataP, int datalenP)
00810 {
00811 if(!isAliveM)
00812 return;
00813 tcpEV << this << ": NSC: send_callback(" << dataP << ", " << datalenP << ") called\n";
00814
00815 sendToIP(dataP, datalenP);
00816
00817
00818
00819
00820
00821
00822
00823 pStackM->if_send_finish(0);
00824 }
00825
00826
00827
00828
00829
00830
00831
00843 void TCP_NSC::wakeup()
00844 {
00845 if(!isAliveM)
00846 return;
00847 tcpEV << this << ": wakeup() called\n";
00848 }
00849
00850 void TCP_NSC::gettime(unsigned int *secP, unsigned int *usecP)
00851 {
00852 #if OMNETPP_VERSION < 0x0400
00853 simtime_t t = simTime();
00854 *sec = (unsigned int)(t);
00855 *usec = (unsigned int)((t - *sec) * 1000000 + 0.5);
00856 #else
00857 #ifdef USE_DOUBLE_SIMTIME
00858 double t = simTime().dbl();
00859 *sec = (unsigned int)(t);
00860 *usec = (unsigned int)((t - *sec) * 1000000 + 0.5);
00861 #else
00862 simtime_t t = simTime();
00863 int64 raw = t.raw();
00864 int64 scale = t.getScale();
00865 int64 secs = raw / scale;
00866 int64 usecs = (raw - (secs * scale));
00867
00868 if(scale>1000000)
00869 usecs /= (scale / 1000000);
00870 else
00871 usecs *= (1000000 / scale);
00872 *secP = secs;
00873 *usecP = usecs;
00874 #endif
00875 #endif
00876 tcpEV << this << ": gettime(" << *secP << "," << *usecP << ") called\n";
00877 }
00878
00879 void TCP_NSC::sendToIP(const void *dataP, int lenP)
00880 {
00881 IPvXAddress src,dest;
00882 const nsc_iphdr *iph = (const nsc_iphdr *)dataP;
00883
00884 int ipHdrLen = 4 * iph->ihl;
00885 ASSERT(ipHdrLen <= lenP);
00886 int totalLen = ntohs(iph->tot_len);
00887 ASSERT(totalLen == lenP);
00888 tcphdr const *tcph = (tcphdr const*)(((const char *)(iph)) + ipHdrLen);
00889
00890
00891
00892 TCP_NSC_Connection::SockPair nscSockPair;
00893
00894 TCP_NSC_Connection *conn;
00895
00896 nscSockPair.localM.ipAddrM.set(ntohl(iph->saddr));
00897 nscSockPair.localM.portM = ntohs(tcph->th_sport);
00898 nscSockPair.remoteM.ipAddrM.set(ntohl(iph->daddr));
00899 nscSockPair.remoteM.portM = ntohs(tcph->th_dport);
00900
00901 if(curConnM)
00902 {
00903 changeAddresses(*curConnM, curConnM->inetSockPairM, nscSockPair);
00904 conn = curConnM;
00905 }
00906 else
00907 {
00908 conn = findConnByNscSockPair(nscSockPair);
00909 }
00910
00911 TCPSegment *tcpseg;
00912 if(conn)
00913 {
00914 tcpseg = conn->sendQueueM->createSegmentWithBytes(tcph, totalLen-ipHdrLen);
00915 src = conn->inetSockPairM.localM.ipAddrM;
00916 dest = conn->inetSockPairM.remoteM.ipAddrM;
00917 }
00918 else
00919 {
00920 tcpseg = new TCPSegment("tcp-segment");
00921
00922 TCPSerializer().parse((const unsigned char *)tcph, totalLen-ipHdrLen, tcpseg);
00923 dest = mapNsc2Remote(ntohl(iph->daddr));
00924 }
00925 ASSERT(tcpseg);
00926
00927 tcpEV << this << ": Sending: conn=" << conn << ", data: " << dataP << " of len " << lenP << " from " << src
00928 << " to " << dest << "\n";
00929
00930 const char* output;
00931 if (!dest.isIPv6())
00932 {
00933
00934 IPControlInfo *controlInfo = new IPControlInfo();
00935 controlInfo->setProtocol(IP_PROT_TCP);
00936 controlInfo->setSrcAddr(src.get4());
00937 controlInfo->setDestAddr(dest.get4());
00938 tcpseg->setControlInfo(controlInfo);
00939
00940 output = "ipOut";
00941 }
00942 else
00943 {
00944
00945 IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
00946 controlInfo->setProtocol(IP_PROT_TCP);
00947 controlInfo->setSrcAddr(src.get6());
00948 controlInfo->setDestAddr(dest.get6());
00949 tcpseg->setControlInfo(controlInfo);
00950
00951 output ="ipv6Out";
00952 }
00953 if(conn)
00954 {
00955 conn->receiveQueueM->notifyAboutSending(tcpseg);
00956 }
00957
00958
00959 if (sndNxtVector && tcpseg->getPayloadLength()!=0)
00960 sndNxtVector->record(tcpseg->getSequenceNo());
00961 if (sndAckVector)
00962 sndAckVector->record(tcpseg->getAckNo());
00963
00964 send(tcpseg, output);
00965 }
00966
00967 void TCP_NSC::processAppCommand(TCP_NSC_Connection& connP, cMessage *msgP)
00968 {
00969 printConnBrief(connP);
00970
00971
00972 TCPCommand *tcpCommand = (TCPCommand *)(msgP->removeControlInfo());
00973
00974 switch (msgP->getKind())
00975 {
00976 case TCP_C_OPEN_ACTIVE: process_OPEN_ACTIVE(connP, tcpCommand, msgP); break;
00977 case TCP_C_OPEN_PASSIVE: process_OPEN_PASSIVE(connP, tcpCommand, msgP); break;
00978 case TCP_C_SEND: process_SEND(connP, tcpCommand, check_and_cast<cPacket*>(msgP)); break;
00979 case TCP_C_CLOSE: process_CLOSE(connP, tcpCommand, msgP); break;
00980 case TCP_C_ABORT: process_ABORT(connP, tcpCommand, msgP); break;
00981 case TCP_C_STATUS: process_STATUS(connP, tcpCommand, msgP); break;
00982 default: opp_error("wrong command from app: %d", msgP->getKind());
00983 }
00984
00985
00986
00987
00988
00989
00990 }
00991
00992 void TCP_NSC::process_OPEN_ACTIVE(TCP_NSC_Connection& connP, TCPCommand *tcpCommandP, cMessage *msgP)
00993 {
00994 TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(tcpCommandP);
00995
00996 TCP_NSC_Connection::SockPair inetSockPair,nscSockPair;
00997 inetSockPair.localM.ipAddrM = openCmd->getLocalAddr();
00998 inetSockPair.remoteM.ipAddrM = openCmd->getRemoteAddr();
00999 inetSockPair.localM.portM = openCmd->getLocalPort();
01000 inetSockPair.remoteM.portM = openCmd->getRemotePort();
01001
01002 if (inetSockPair.remoteM.ipAddrM.isUnspecified() || inetSockPair.remoteM.portM == -1)
01003 opp_error("Error processing command OPEN_ACTIVE: remote address and port must be specified");
01004
01005 tcpEV << this << ": OPEN: "
01006 << inetSockPair.localM.ipAddrM << ":" << inetSockPair.localM.portM << " --> "
01007 << inetSockPair.remoteM.ipAddrM << ":" << inetSockPair.remoteM.portM << "\n";
01008
01009
01010 uint32_t nscRemoteAddr = mapRemote2Nsc(inetSockPair.remoteM.ipAddrM);
01011
01012 ASSERT(pStackM);
01013
01014 nscSockPair.localM.portM = inetSockPair.localM.portM;
01015 if (nscSockPair.localM.portM == -1)
01016 nscSockPair.localM.portM = 0;
01017 nscSockPair.remoteM.ipAddrM.set(nscRemoteAddr);
01018 nscSockPair.remoteM.portM = inetSockPair.remoteM.portM;
01019
01020 changeAddresses(connP, inetSockPair, nscSockPair);
01021
01022 ASSERT(!curConnM);
01023 curConnM = &connP;
01024 connP.connect(*pStackM, inetSockPair, nscSockPair);
01025 curConnM = NULL;
01026
01027
01028
01029
01030
01031 delete tcpCommandP;
01032 delete msgP;
01033 }
01034
01035 void TCP_NSC::process_OPEN_PASSIVE(TCP_NSC_Connection& connP, TCPCommand *tcpCommandP, cMessage *msgP)
01036 {
01037 ASSERT(pStackM);
01038
01039 TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(tcpCommandP);
01040
01041 ASSERT(openCmd->getFork()==true);
01042
01043 TCP_NSC_Connection::SockPair inetSockPair, nscSockPair;
01044 inetSockPair.localM.ipAddrM = openCmd->getLocalAddr();
01045 inetSockPair.remoteM.ipAddrM = openCmd->getRemoteAddr();
01046 inetSockPair.localM.portM = openCmd->getLocalPort();
01047 inetSockPair.remoteM.portM = openCmd->getRemotePort();
01048
01049 uint32_t nscRemoteAddr = inetSockPair.remoteM.ipAddrM.isUnspecified()
01050 ? ntohl(INADDR_ANY)
01051 : mapRemote2Nsc(inetSockPair.remoteM.ipAddrM);
01052 (void)nscRemoteAddr;
01053
01054 if (inetSockPair.localM.portM == -1)
01055 opp_error("Error processing command OPEN_PASSIVE: local port must be specified");
01056
01057 tcpEV << this << "Starting to listen on: " << inetSockPair.localM.ipAddrM << ":" << inetSockPair.localM.portM << "\n";
01058
01059
01060
01061
01062
01063
01064 nscSockPair.localM.portM = inetSockPair.localM.portM;
01065
01066 changeAddresses(connP, inetSockPair, nscSockPair);
01067
01068 ASSERT(!curConnM);
01069 curConnM = &connP;
01070 connP.listen(*pStackM, inetSockPair, nscSockPair);
01071 curConnM = NULL;
01072
01073 changeAddresses(connP, inetSockPair, nscSockPair);
01074
01075 delete openCmd;
01076 delete msgP;
01077 }
01078
01079 void TCP_NSC::process_SEND(TCP_NSC_Connection& connP, TCPCommand *tcpCommandP, cPacket *msgP)
01080 {
01081 TCPSendCommand *sendCommand = check_and_cast<TCPSendCommand *>(tcpCommandP);
01082 delete sendCommand;
01083
01084 connP.send(msgP);
01085
01086 connP.do_SEND();
01087 }
01088
01089 void TCP_NSC::do_SEND_all()
01090 {
01091 TcpAppConnMap::iterator j = tcpAppConnMapM.begin();
01092 for(; j != tcpAppConnMapM.end(); ++j)
01093 {
01094 TCP_NSC_Connection& conn = j->second;
01095 conn.do_SEND();
01096 }
01097 }
01098
01099 void TCP_NSC::process_CLOSE(TCP_NSC_Connection& connP, TCPCommand *tcpCommandP, cMessage *msgP)
01100 {
01101 tcpEV << this << ": process_CLOSE()\n";
01102
01103 delete tcpCommandP;
01104 delete msgP;
01105
01106 connP.close();
01107 }
01108
01109 void TCP_NSC::process_ABORT(TCP_NSC_Connection& connP, TCPCommand *tcpCommandP, cMessage *msgP)
01110 {
01111 tcpEV << this << ": process_ABORT()\n";
01112
01113 delete tcpCommandP;
01114 delete msgP;
01115
01116 connP.abort();
01117 }
01118
01119 void TCP_NSC::process_STATUS(TCP_NSC_Connection& connP, TCPCommand *tcpCommandP, cMessage *msgP)
01120 {
01121 delete tcpCommandP;
01122
01123 TCPStatusInfo *statusInfo = new TCPStatusInfo();
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 char result[512];
01136
01137 ASSERT(connP.pNscSocketM);
01138
01139 connP.pNscSocketM->get_var("cwnd_", result, sizeof(result));
01140 statusInfo->setSnd_wnd(atoi(result));
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171 msgP->setControlInfo(statusInfo);
01172 send(msgP, "appOut", connP.appGateIndexM);
01173 }
01174
01175 #endif // WITH_TCP_NSC