00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025
00026
00027
00028
00029
00030
00031 #include <omnetpp.h>
00032
00033 #include <CommonMessages_m.h>
00034 #include <GlobalNodeListAccess.h>
00035 #include <GlobalStatisticsAccess.h>
00036
00037 #include <SimpleInfo.h>
00038 #include "SimpleUDPPacket.h"
00039 #include "SimpleUDP.h"
00040 #include "IPControlInfo.h"
00041 #include "IPv6ControlInfo.h"
00042 #include "ICMPAccess.h"
00043 #include "ICMPv6Access.h"
00044 #include "IPAddressResolver.h"
00045
00046
00047 #include "ICMPMessage_m.h"
00048 #include "ICMPv6Message_m.h"
00049 #include "IPDatagram_m.h"
00050 #include "IPv6Datagram_m.h"
00051
00052
00053 #define EPHEMERAL_PORTRANGE_START 1024
00054 #define EPHEMERAL_PORTRANGE_END 5000
00055
00056
00057 Define_Module( SimpleUDP );
00058
00059 std::string SimpleUDP::delayFaultTypeString;
00060 std::map<std::string, SimpleUDP::delayFaultTypeNum> SimpleUDP::delayFaultTypeMap;
00061
00062 static std::ostream & operator<<(std::ostream & os,
00063 const SimpleUDP::SockDesc& sd)
00064 {
00065 os << "sockId=" << sd.sockId;
00066 os << " appGateIndex=" << sd.appGateIndex;
00067 os << " userId=" << sd.userId;
00068 os << " localPort=" << sd.localPort;
00069 if (sd.remotePort!=0)
00070 os << " remotePort=" << sd.remotePort;
00071 if (!sd.localAddr.isUnspecified())
00072 os << " localAddr=" << sd.localAddr;
00073 if (!sd.remoteAddr.isUnspecified())
00074 os << " remoteAddr=" << sd.remoteAddr;
00075 if (sd.interfaceId!=-1)
00076 os << " interfaceId=" << sd.interfaceId;
00077
00078 return os;
00079 }
00080
00081 static std::ostream & operator<<(std::ostream & os,
00082 const SimpleUDP::SockDescList& list)
00083 {
00084 for (SimpleUDP::SockDescList::const_iterator i=list.begin();
00085 i!=list.end(); ++i)
00086 os << "sockId=" << (*i)->sockId << " ";
00087 return os;
00088 }
00089
00090
00091
00092 SimpleUDP::SimpleUDP()
00093 {
00094 globalStatistics = NULL;
00095 }
00096
00097 SimpleUDP::~SimpleUDP()
00098 {
00099 for (SocketsByIdMap::iterator i=socketsByIdMap.begin();
00100 i!=socketsByIdMap.end(); ++i)
00101 delete i->second;
00102 }
00103
00104 void SimpleUDP::initialize(int stage)
00105 {
00106 if(stage == MIN_STAGE_UNDERLAY) {
00107 WATCH_PTRMAP(socketsByIdMap);
00108 WATCH_MAP(socketsByPortMap);
00109
00110 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00111 icmp = NULL;
00112 icmpv6 = NULL;
00113
00114 numSent = 0;
00115 numPassedUp = 0;
00116 numDroppedWrongPort = 0;
00117 numDroppedBadChecksum = 0;
00118 numQueueLost = 0;
00119 numPartitionLost = 0;
00120 numDestUnavailableLost = 0;
00121 WATCH(numSent);
00122 WATCH(numPassedUp);
00123 WATCH(numDroppedWrongPort);
00124 WATCH(numDroppedBadChecksum);
00125 WATCH(numQueueLost);
00126 WATCH(numPartitionLost);
00127 WATCH(numDestUnavailableLost);
00128
00129 globalNodeList = GlobalNodeListAccess().get();
00130 globalStatistics = GlobalStatisticsAccess().get();
00131 constantDelay = par("constantDelay");
00132 useCoordinateBasedDelay = par("useCoordinateBasedDelay");
00133
00134 delayFaultTypeString = par("delayFaultType").stdstringValue();
00135 delayFaultTypeMap["live_all"] = delayFaultLiveAll;
00136 delayFaultTypeMap["live_planetlab"] = delayFaultLivePlanetlab;
00137 delayFaultTypeMap["simulation"] = delayFaultSimulation;
00138
00139 switch (delayFaultTypeMap[delayFaultTypeString]) {
00140 case SimpleUDP::delayFaultLiveAll:
00141 case SimpleUDP::delayFaultLivePlanetlab:
00142 case SimpleUDP::delayFaultSimulation:
00143 faultyDelay = true;
00144 break;
00145 default:
00146 faultyDelay = false;
00147 }
00148
00149 jitter = par("jitter");
00150 nodeEntry = NULL;
00151 WATCH_PTR(nodeEntry);
00152 }
00153 }
00154
00155 void SimpleUDP::finish()
00156 {
00157 globalStatistics->addStdDev("SimpleUDP: Packets sent",
00158 numSent);
00159 globalStatistics->addStdDev("SimpleUDP: Packets dropped with bad checksum",
00160 numDroppedBadChecksum);
00161 globalStatistics->addStdDev("SimpleUDP: Packets dropped due to queue overflows",
00162 numQueueLost);
00163 globalStatistics->addStdDev("SimpleUDP: Packets dropped due to network partitions",
00164 numPartitionLost);
00165 globalStatistics->addStdDev("SimpleUDP: Packets dropped due to unavailable destination",
00166 numDestUnavailableLost);
00167 }
00168
00169 void SimpleUDP::bind(int gateIndex, UDPControlInfo *ctrl)
00170 {
00171
00172
00173 if (ctrl->getSrcPort() <= 0 || ctrl->getSrcPort() > 65535)
00174 opp_error("bind: invalid src port number %d", ctrl->getSrcPort());
00175
00176
00177 SockDesc *sd = new SockDesc();
00178 sd->sockId = ctrl->getSockId();
00179 sd->userId = ctrl->getUserId();
00180 sd->appGateIndex = gateIndex;
00181 sd->localAddr = ctrl->getSrcAddr();
00182 sd->remoteAddr = ctrl->getDestAddr();
00183 sd->localPort = ctrl->getSrcPort();
00184 sd->remotePort = ctrl->getDestPort();
00185 sd->interfaceId = ctrl->getInterfaceId();
00186
00187 if (sd->sockId==-1)
00188 error("sockId in BIND message not filled in");
00189 if (sd->localPort==0)
00190 sd->localPort = getEphemeralPort();
00191
00192 sd->onlyLocalPortIsSet = sd->localAddr.isUnspecified() &&
00193 sd->remoteAddr.isUnspecified() &&
00194 sd->remotePort==0 &&
00195 sd->interfaceId==-1;
00196
00197 cModule *node = getParentModule();
00198 IPvXAddress ip = IPAddressResolver().addressOf(node);
00199 EV << "[SimpleUDP::bind() @ " << ip << "]\n"
00200 << " Binding socket: " << *sd
00201 << endl;
00202
00203
00204 ASSERT(socketsByIdMap.find(sd->sockId)==socketsByIdMap.end());
00205 socketsByIdMap[sd->sockId] = sd;
00206
00207
00208
00209 SockDescList& list = socketsByPortMap[sd->localPort];
00210 list.push_back(sd);
00211 }
00212
00213 void SimpleUDP::connect(int sockId, IPvXAddress addr, int port)
00214 {
00215 SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00216 if (it==socketsByIdMap.end())
00217 error("socket id=%d doesn't exist (already closed?)", sockId);
00218 if (addr.isUnspecified())
00219 opp_error("connect: unspecified remote address");
00220 if (port<=0 || port>65535)
00221 opp_error("connect: invalid remote port number %d", port);
00222
00223 SockDesc *sd = it->second;
00224 sd->remoteAddr = addr;
00225 sd->remotePort = port;
00226
00227 sd->onlyLocalPortIsSet = false;
00228
00229 EV << "[SimpleUDP::connect() @ " << sd->localAddr << "]\n"
00230 << " Connecting socket: " << *sd
00231 << endl;
00232 }
00233
00234 void SimpleUDP::unbind(int sockId)
00235 {
00236
00237 SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00238 if (it==socketsByIdMap.end())
00239 error("socket id=%d doesn't exist (already closed?)", sockId);
00240 SockDesc *sd = it->second;
00241 socketsByIdMap.erase(it);
00242
00243 EV << "[SimpleUDP::unbind() @ " << sd->localAddr << "]\n"
00244 << " Unbinding socket: " << *sd
00245 << endl;
00246
00247
00248 SockDescList& list = socketsByPortMap[sd->localPort];
00249 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00250 if (*it == sd) {
00251 list.erase(it);
00252 break;
00253 }
00254 if (list.empty())
00255 socketsByPortMap.erase(sd->localPort);
00256 delete sd;
00257 }
00258
00259 short SimpleUDP::getEphemeralPort()
00260 {
00261
00262 short searchUntil = lastEphemeralPort++;
00263 if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END)
00264 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00265
00266 while (socketsByPortMap.find(lastEphemeralPort)!=socketsByPortMap.end()) {
00267 if (lastEphemeralPort == searchUntil)
00268 error("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
00269 lastEphemeralPort++;
00270 if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END)
00271 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00272 }
00273
00274
00275 return lastEphemeralPort;
00276 }
00277
00278 void SimpleUDP::handleMessage(cMessage *msg)
00279 {
00280
00281 if (msg->arrivedOn("network_in")) {
00282 if (dynamic_cast<ICMPMessage *>(msg) || dynamic_cast<ICMPv6Message *>(msg))
00283 processICMPError(msg);
00284 else
00285 processUDPPacket(check_and_cast<SimpleUDPPacket *>(msg));
00286 } else
00287 {
00288 if (msg->getKind()==UDP_C_DATA)
00289 processMsgFromApp(check_and_cast<cPacket*>(msg));
00290 else
00291 processCommandFromApp(msg);
00292 }
00293
00294 if (ev.isGUI())
00295 updateDisplayString();
00296 }
00297
00298 void SimpleUDP::updateDisplayString()
00299 {
00300 char buf[80];
00301 sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
00302 if (numDroppedWrongPort>0) {
00303 sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
00304 getDisplayString().setTagArg("i",1,"red");
00305 }
00306 if (numQueueLost>0) {
00307 sprintf(buf+strlen(buf), "\nlost (queue overflow): %d pks", numQueueLost);
00308 getDisplayString().setTagArg("i",1,"red");
00309 }
00310 getDisplayString().setTagArg("t",0,buf);
00311 }
00312
00313 bool SimpleUDP::matchesSocket(SockDesc *sd, SimpleUDPPacket *udp, IPControlInfo *ipCtrl)
00314 {
00315
00316 if (sd->remotePort!=0 && sd->remotePort!=udp->getSourcePort())
00317 return false;
00318 if (!sd->localAddr.isUnspecified() && sd->localAddr.get4()!=ipCtrl->getDestAddr())
00319 return false;
00320 if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get4()!=ipCtrl->getSrcAddr())
00321 return false;
00322 if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->getInterfaceId())
00323 return false;
00324 return true;
00325 }
00326
00327 bool SimpleUDP::matchesSocket(SockDesc *sd, SimpleUDPPacket *udp, IPv6ControlInfo *ipCtrl)
00328 {
00329
00330 if (sd->remotePort!=0 && sd->remotePort!=udp->getSourcePort())
00331 return false;
00332 if (!sd->localAddr.isUnspecified() && sd->localAddr.get6()!=ipCtrl->getDestAddr())
00333 return false;
00334 if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get6()!=ipCtrl->getSrcAddr())
00335 return false;
00336 if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->getInterfaceId())
00337 return false;
00338 return true;
00339 }
00340
00341 bool SimpleUDP::matchesSocket(SockDesc *sd, const IPvXAddress& localAddr, const IPvXAddress& remoteAddr, short remotePort)
00342 {
00343 return (sd->remotePort==0 || sd->remotePort!=remotePort) &&
00344 (sd->localAddr.isUnspecified() || sd->localAddr==localAddr) &&
00345 (sd->remoteAddr.isUnspecified() || sd->remoteAddr==remoteAddr);
00346 }
00347
00348 void SimpleUDP::sendUp(cMessage *payload, SimpleUDPPacket *udpHeader, IPControlInfo *ipCtrl, SockDesc *sd)
00349 {
00350
00351 UDPControlInfo *udpCtrl = new UDPControlInfo();
00352 udpCtrl->setSockId(sd->sockId);
00353 udpCtrl->setUserId(sd->userId);
00354 udpCtrl->setSrcAddr(ipCtrl->getSrcAddr());
00355 udpCtrl->setDestAddr(ipCtrl->getDestAddr());
00356 udpCtrl->setSrcPort(udpHeader->getSourcePort());
00357 udpCtrl->setDestPort(udpHeader->getDestinationPort());
00358 udpCtrl->setInterfaceId(ipCtrl->getInterfaceId());
00359 payload->setControlInfo(udpCtrl);
00360
00361 send(payload, "appOut", sd->appGateIndex);
00362 numPassedUp++;
00363 }
00364
00365 void SimpleUDP::sendUp(cMessage *payload, SimpleUDPPacket *udpHeader, IPv6ControlInfo *ipCtrl, SockDesc *sd)
00366 {
00367
00368 UDPControlInfo *udpCtrl = new UDPControlInfo();
00369 udpCtrl->setSockId(sd->sockId);
00370 udpCtrl->setUserId(sd->userId);
00371 udpCtrl->setSrcAddr(ipCtrl->getSrcAddr());
00372 udpCtrl->setDestAddr(ipCtrl->getDestAddr());
00373 udpCtrl->setSrcPort(udpHeader->getSourcePort());
00374 udpCtrl->setDestPort(udpHeader->getDestinationPort());
00375 udpCtrl->setInterfaceId(ipCtrl->getInterfaceId());
00376 payload->setControlInfo(udpCtrl);
00377
00378 send(payload, "appOut", sd->appGateIndex);
00379 numPassedUp++;
00380 }
00381
00382 void SimpleUDP::processUndeliverablePacket(SimpleUDPPacket *udpPacket, cPolymorphic *ctrl)
00383 {
00384 numDroppedWrongPort++;
00385
00386
00387 if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) {
00388
00389
00390
00391
00392
00393
00394 EV << "[SimpleUDP::processUndeliverablePacket()]\n"
00395 << " Dropped packet bound to unreserved port, ignoring ICMP error"
00396 << endl;
00397 } else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->getControlInfo())
00398 !=NULL) {
00399
00400
00401
00402
00403
00404
00405 EV << "[SimpleUDP::processUndeliverablePacket()]\n"
00406 << " Dropped packet bound to unreserved port, ignoring ICMP error"
00407 << endl;
00408 } else {
00409 error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
00410 }
00411 }
00412
00413 void SimpleUDP::processICMPError(cMessage *msg)
00414 {
00415
00416 int type = 0;
00417 int code = 0;
00418 IPvXAddress localAddr, remoteAddr;
00419 int localPort = 0;
00420 int remotePort = 0;
00421
00422 if (dynamic_cast<ICMPMessage *>(msg)) {
00423 ICMPMessage *icmpMsg = (ICMPMessage *)msg;
00424 type = icmpMsg->getType();
00425 code = icmpMsg->getCode();
00426 icmpMsg->setBitLength(icmpMsg->getEncapsulatedPacket()->getBitLength());
00427 IPDatagram *datagram = check_and_cast<IPDatagram *>(icmpMsg->decapsulate());
00428 localAddr = datagram->getSrcAddress();
00429 remoteAddr = datagram->getDestAddress();
00430 SimpleUDPPacket *packet = check_and_cast<SimpleUDPPacket *>(datagram->decapsulate());
00431 localPort = packet->getSourcePort();
00432 remotePort = packet->getDestinationPort();
00433 delete icmpMsg;
00434 delete datagram;
00435 delete packet;
00436 } else if (dynamic_cast<ICMPv6Message *>(msg)) {
00437 ICMPv6Message *icmpMsg = (ICMPv6Message *)msg;
00438 type = icmpMsg->getType();
00439 code = -1;
00440 IPv6Datagram *datagram = check_and_cast<IPv6Datagram *>(icmpMsg->decapsulate());
00441 localAddr = datagram->getSrcAddress();
00442 remoteAddr = datagram->getDestAddress();
00443 SimpleUDPPacket *packet = check_and_cast<SimpleUDPPacket *>(datagram->decapsulate());
00444 localPort = packet->getSourcePort();
00445 remotePort = packet->getDestinationPort();
00446 delete icmpMsg;
00447 delete datagram;
00448 delete packet;
00449 }
00450 EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00451 << " ICMP error received: type=" << type << " code=" << code
00452 << "\n about packet " << localAddr << ":" << localPort << " --> "
00453 << " " << remoteAddr << ":" << remotePort
00454 << endl;
00455
00456
00457 SocketsByPortMap::iterator it = socketsByPortMap.find(localPort);
00458 if (it==socketsByPortMap.end()) {
00459 EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00460 << " No socket on that local port, ignoring ICMP error"
00461 << endl;
00462 return;
00463 }
00464 SockDescList& list = it->second;
00465 SockDesc *srcSocket = NULL;
00466 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00467 SockDesc *sd = *it;
00468 if (sd->onlyLocalPortIsSet || matchesSocket(sd, localAddr, remoteAddr, remotePort)) {
00469 srcSocket = sd;
00470 }
00471 }
00472 if (!srcSocket) {
00473 EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00474 << " No matching socket, ignoring ICMP error"
00475 << endl;
00476 return;
00477 }
00478
00479
00480 EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00481 << " Source socket is sockId=" << srcSocket->sockId << ", notifying"
00482 << endl;
00483 sendUpErrorNotification(srcSocket, UDP_I_ERROR, localAddr, remoteAddr, remotePort);
00484 }
00485
00486 void SimpleUDP::sendUpErrorNotification(SockDesc *sd, int msgkind, const IPvXAddress& localAddr, const IPvXAddress& remoteAddr, short remotePort)
00487 {
00488 cMessage *notifyMsg = new cMessage("ERROR", msgkind);
00489 UDPControlInfo *udpCtrl = new UDPControlInfo();
00490 udpCtrl->setSockId(sd->sockId);
00491 udpCtrl->setUserId(sd->userId);
00492 udpCtrl->setSrcAddr(localAddr);
00493 udpCtrl->setDestAddr(remoteAddr);
00494 udpCtrl->setSrcPort(sd->localPort);
00495 udpCtrl->setDestPort(remotePort);
00496 notifyMsg->setControlInfo(udpCtrl);
00497
00498 send(notifyMsg, "appOut", sd->appGateIndex);
00499 }
00500
00501 void SimpleUDP::processUDPPacket(SimpleUDPPacket *udpPacket)
00502 {
00503 cModule *node = getParentModule();
00504
00505
00506
00507
00508 EV << "[SimpleUDP::processUDPPacket() @ " << IPAddressResolver().addressOf(node) << "]\n"
00509 << " Packet " << udpPacket->getName() << " received from network, dest port " << udpPacket->getDestinationPort()
00510 << endl;
00511
00512 if (udpPacket->hasBitError()) {
00513 EV << "[SimpleUDP::processUDPPacket() @ " << IPAddressResolver().addressOf(node) << "]\n"
00514 << " Packet has bit error, discarding"
00515 << endl;
00516 delete udpPacket;
00517 numDroppedBadChecksum++;
00518 return;
00519 }
00520
00521 int destPort = udpPacket->getDestinationPort();
00522 cPolymorphic *ctrl = udpPacket->removeControlInfo();
00523
00524
00525 SocketsByPortMap::iterator it = socketsByPortMap.find(destPort);
00526 if (it==socketsByPortMap.end()) {
00527 EV << "[SimpleUDP::processUDPPacket() @ " << IPAddressResolver().addressOf(node) << "]\n"
00528 << " No socket registered on port " << destPort
00529 << endl;
00530 processUndeliverablePacket(udpPacket, ctrl);
00531 return;
00532 }
00533 SockDescList& list = it->second;
00534
00535 int matches = 0;
00536
00537
00538
00539 cMessage *payload = udpPacket->decapsulate();
00540 if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) {
00541 IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00542 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00543 SockDesc *sd = *it;
00544 if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4)) {
00545
00546
00547
00548
00549
00550
00551 if (matches == 0) {
00552 sendUp(payload, udpPacket, ctrl4, sd);
00553 } else
00554 opp_error("Edit SimpleUDP.cc to support multibinding.");
00555 matches++;
00556 }
00557 }
00558 } else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->getControlInfo())
00559 !=NULL) {
00560 IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00561 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00562 SockDesc *sd = *it;
00563 if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6)) {
00564 EV << "[SimpleUDP::processUDPPacket() @ " << IPAddressResolver().addressOf(node) << "]\n"
00565 << " Socket sockId=" << sd->sockId << " matches, sending up a copy"
00566 << endl;
00567 sendUp((cMessage*)payload->dup(), udpPacket, ctrl6, sd);
00568 matches++;
00569 }
00570 }
00571 } else {
00572 error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
00573 }
00574
00575
00576 if (matches==0) {
00577 EV << "[SimpleUDP::processUDPPacket() @ " << IPAddressResolver().addressOf(node) << "]\n"
00578 << " None of the sockets on port " << destPort << " matches the packet"
00579 << endl;
00580 processUndeliverablePacket(udpPacket, ctrl)
00581 ;
00582 return;
00583 }
00584
00585 delete udpPacket;
00586 delete ctrl;
00587 }
00588
00589
00590 void SimpleUDP::processMsgFromApp(cPacket *appData)
00591 {
00592 cModule *node = getParentModule();
00593
00594
00595
00596 IPvXAddress srcAddr, destAddr;
00597
00598
00599 UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo());
00600
00601 SimpleUDPPacket *udpPacket = new SimpleUDPPacket(appData->getName());
00602
00603
00604 udpPacket->setByteLength(UDP_HEADER_BYTES + IP_HEADER_BYTES);
00605 udpPacket->encapsulate(appData);
00606
00607
00608 udpPacket->setSourcePort(udpCtrl->getSrcPort());
00609 udpPacket->setDestinationPort(udpCtrl->getDestPort());
00610
00611 srcAddr = udpCtrl->getSrcAddr();
00612 destAddr = udpCtrl->getDestAddr();
00613 if (!udpCtrl->getDestAddr().isIPv6()) {
00614
00615
00616
00617
00618 IPControlInfo *ipControlInfo = new IPControlInfo();
00619 ipControlInfo->setProtocol(IP_PROT_UDP);
00620 ipControlInfo->setSrcAddr(srcAddr.get4());
00621 ipControlInfo->setDestAddr(destAddr.get4());
00622 ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId());
00623 udpPacket->setControlInfo(ipControlInfo);
00624 delete udpCtrl;
00625 } else {
00626
00627
00628
00629
00630 IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
00631 ipControlInfo->setProtocol(IP_PROT_UDP);
00632 ipControlInfo->setSrcAddr(srcAddr.get6());
00633 ipControlInfo->setDestAddr(destAddr.get6());
00634
00635 udpPacket->setControlInfo(ipControlInfo);
00636 delete udpCtrl;
00637 }
00638
00639 SimpleInfo* info = dynamic_cast<SimpleInfo*>(globalNodeList->getPeerInfo(destAddr));
00640 numSent++;
00641
00642 if (info == NULL) {
00643 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00644 << " No route to host " << destAddr
00645 << endl;
00646
00647 delete udpPacket;
00648 numDestUnavailableLost++;
00649 return;
00650 }
00651
00652 SimpleNodeEntry* destEntry = info->getEntry();
00653
00654
00655 simtime_t totalDelay = 0;
00656 if (srcAddr != destAddr) {
00657 SimpleNodeEntry::SimpleDelay temp;
00658 if (faultyDelay) {
00659 SimpleInfo* thisInfo = static_cast<SimpleInfo*>(globalNodeList->getPeerInfo(srcAddr));
00660 temp = nodeEntry->calcDelay(udpPacket, *destEntry,
00661 !(thisInfo->getNpsLayer() == 0 ||
00662 info->getNpsLayer() == 0));
00663 } else {
00664 temp = nodeEntry->calcDelay(udpPacket, *destEntry);
00665 }
00666 if (useCoordinateBasedDelay == false) {
00667 totalDelay = constantDelay;
00668 } else if (temp.second == false) {
00669 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00670 << " Send queue full: packet " << udpPacket << " dropped"
00671 << endl;
00672 delete udpPacket;
00673 numQueueLost++;
00674 return;
00675 } else {
00676 totalDelay = temp.first;
00677 }
00678 }
00679
00680 SimpleInfo* thisInfo = dynamic_cast<SimpleInfo*>(globalNodeList->getPeerInfo(srcAddr));
00681
00682 if (!globalNodeList->areNodeTypesConnected(thisInfo->getTypeID(), info->getTypeID())) {
00683 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00684 << " Partition " << thisInfo->getTypeID() << "->" << info->getTypeID()
00685 << " is not connected"
00686 << endl;
00687 delete udpPacket;
00688 numPartitionLost++;
00689 return;
00690 }
00691
00692 if (jitter) {
00693
00694
00695
00696
00697 double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * jitter);
00698 while (temp == INFINITY || temp != temp) {
00699 std::cerr << "\n******* SimpleUDP: truncnormal() -> inf !!\n"
00700 << std::endl;
00701 temp = truncnormal(0, SIMTIME_DBL(totalDelay) * jitter);
00702 }
00703
00704 totalDelay += temp;
00705 }
00706
00707 if (udpPacket != NULL) {
00708 BaseOverlayMessage* temp = NULL;
00709
00710 if (ev.isGUI() && udpPacket->getEncapsulatedPacket()) {
00711 if ((temp = dynamic_cast<BaseOverlayMessage*>(udpPacket
00712 ->getEncapsulatedPacket()))) {
00713 switch (temp->getStatType()) {
00714 case APP_DATA_STAT:
00715 udpPacket->setKind(1);
00716 break;
00717 case APP_LOOKUP_STAT:
00718 udpPacket->setKind(2);
00719 break;
00720 case MAINTENANCE_STAT:
00721 default:
00722 udpPacket->setKind(3);
00723 }
00724 } else {
00725 udpPacket->setKind(1);
00726 }
00727 }
00728
00729 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00730 << " Packet " << udpPacket << " sent with delay = " << totalDelay
00731 << endl;
00732
00733
00734
00735 sendDirect(udpPacket, totalDelay, 0, destEntry->getGate());
00736 }
00737 }
00738
00739 void SimpleUDP::processCommandFromApp(cMessage *msg)
00740 {
00741 UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
00742 switch (msg->getKind()) {
00743 case UDP_C_BIND:
00744 bind(msg->getArrivalGate()->getIndex(), udpCtrl);
00745 break;
00746 case UDP_C_CONNECT:
00747 connect(udpCtrl->getSockId(), udpCtrl->getDestAddr(), udpCtrl->getDestPort());
00748 break;
00749 case UDP_C_UNBIND:
00750 unbind(udpCtrl->getSockId());
00751 break;
00752 default:
00753 error("unknown command code (message kind) %d received from app", msg->getKind());
00754 }
00755
00756 delete udpCtrl;
00757 delete msg;
00758 }
00759
00760
00761 void SimpleUDP::setNodeEntry(SimpleNodeEntry* entry)
00762 {
00763 nodeEntry = entry;
00764 }