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 "UDPPacket.h"
00039 #include "SimpleUDP.h"
00040 #include "IPControlInfo.h"
00041 #include "IPv6ControlInfo.h"
00042
00043 #include "IPAddressResolver.h"
00044
00045 #include "IPDatagram_m.h"
00046 #include "IPv6Datagram_m.h"
00047
00048
00049 #define EPHEMERAL_PORTRANGE_START 1024
00050 #define EPHEMERAL_PORTRANGE_END 5000
00051
00052
00053 Define_Module( SimpleUDP );
00054
00055 std::string SimpleUDP::delayFaultTypeString;
00056 std::map<std::string, SimpleUDP::delayFaultTypeNum> SimpleUDP::delayFaultTypeMap;
00057
00058 static std::ostream & operator<<(std::ostream & os,
00059 const SimpleUDP::SockDesc& sd)
00060 {
00061 os << "sockId=" << sd.sockId;
00062 os << " appGateIndex=" << sd.appGateIndex;
00063 os << " userId=" << sd.userId;
00064 os << " localPort=" << sd.localPort;
00065 if (sd.remotePort!=0)
00066 os << " remotePort=" << sd.remotePort;
00067 if (!sd.localAddr.isUnspecified())
00068 os << " localAddr=" << sd.localAddr;
00069 if (!sd.remoteAddr.isUnspecified())
00070 os << " remoteAddr=" << sd.remoteAddr;
00071 if (sd.interfaceId!=-1)
00072 os << " interfaceId=" << sd.interfaceId;
00073
00074 return os;
00075 }
00076
00077 static std::ostream & operator<<(std::ostream & os,
00078 const SimpleUDP::SockDescList& list)
00079 {
00080 for (SimpleUDP::SockDescList::const_iterator i=list.begin();
00081 i!=list.end(); ++i)
00082 os << "sockId=" << (*i)->sockId << " ";
00083 return os;
00084 }
00085
00086
00087
00088 SimpleUDP::SimpleUDP()
00089 {
00090 globalStatistics = NULL;
00091 }
00092
00093 SimpleUDP::~SimpleUDP()
00094 {
00095
00096 }
00097
00098 void SimpleUDP::initialize(int stage)
00099 {
00100 if(stage == MIN_STAGE_UNDERLAY) {
00101 WATCH_PTRMAP(socketsByIdMap);
00102 WATCH_MAP(socketsByPortMap);
00103
00104 lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00105 icmp = NULL;
00106 icmpv6 = NULL;
00107
00108 numSent = 0;
00109 numPassedUp = 0;
00110 numDroppedWrongPort = 0;
00111 numDroppedBadChecksum = 0;
00112 numQueueLost = 0;
00113 numPartitionLost = 0;
00114 numDestUnavailableLost = 0;
00115 WATCH(numSent);
00116 WATCH(numPassedUp);
00117 WATCH(numDroppedWrongPort);
00118 WATCH(numDroppedBadChecksum);
00119 WATCH(numQueueLost);
00120 WATCH(numPartitionLost);
00121 WATCH(numDestUnavailableLost);
00122
00123 globalNodeList = GlobalNodeListAccess().get();
00124 globalStatistics = GlobalStatisticsAccess().get();
00125 constantDelay = par("constantDelay");
00126 useCoordinateBasedDelay = par("useCoordinateBasedDelay");
00127
00128 delayFaultTypeString = par("delayFaultType").stdstringValue();
00129 delayFaultTypeMap["live_all"] = delayFaultLiveAll;
00130 delayFaultTypeMap["live_planetlab"] = delayFaultLivePlanetlab;
00131 delayFaultTypeMap["simulation"] = delayFaultSimulation;
00132
00133 switch (delayFaultTypeMap[delayFaultTypeString]) {
00134 case SimpleUDP::delayFaultLiveAll:
00135 case SimpleUDP::delayFaultLivePlanetlab:
00136 case SimpleUDP::delayFaultSimulation:
00137 faultyDelay = true;
00138 break;
00139 default:
00140 faultyDelay = false;
00141 }
00142
00143 jitter = par("jitter");
00144 nodeEntry = NULL;
00145 WATCH_PTR(nodeEntry);
00146 }
00147 }
00148
00149 void SimpleUDP::finish()
00150 {
00151 globalStatistics->addStdDev("SimpleUDP: Packets sent",
00152 numSent);
00153 globalStatistics->addStdDev("SimpleUDP: Packets dropped with bad checksum",
00154 numDroppedBadChecksum);
00155 globalStatistics->addStdDev("SimpleUDP: Packets dropped due to queue overflows",
00156 numQueueLost);
00157 globalStatistics->addStdDev("SimpleUDP: Packets dropped due to network partitions",
00158 numPartitionLost);
00159 globalStatistics->addStdDev("SimpleUDP: Packets dropped due to unavailable destination",
00160 numDestUnavailableLost);
00161 }
00162
00163 void SimpleUDP::updateDisplayString()
00164 {
00165 char buf[80];
00166 sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
00167 if (numDroppedWrongPort>0) {
00168 sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
00169 getDisplayString().setTagArg("i",1,"red");
00170 }
00171 if (numQueueLost>0) {
00172 sprintf(buf+strlen(buf), "\nlost (queue overflow): %d pks", numQueueLost);
00173 getDisplayString().setTagArg("i",1,"red");
00174 }
00175 getDisplayString().setTagArg("t",0,buf);
00176 }
00177
00178 void SimpleUDP::processUndeliverablePacket(UDPPacket *udpPacket, cPolymorphic *ctrl)
00179 {
00180 numDroppedWrongPort++;
00181 EV << "[SimpleUDP::processUndeliverablePacket()]\n"
00182 << " Dropped packet bound to unreserved port, ignoring ICMP error"
00183 << endl;
00184
00185 delete udpPacket;
00186 }
00187
00188 void SimpleUDP::processUDPPacket(UDPPacket *udpPacket)
00189 {
00190
00191 EV << "Packet " << udpPacket->getName() << " received from network, dest port " << udpPacket->getDestinationPort() << "\n";
00192 if (udpPacket->hasBitError())
00193 {
00194 EV << "Packet has bit error, discarding\n";
00195 delete udpPacket;
00196 numDroppedBadChecksum++;
00197 return;
00198 }
00199
00200 int destPort = udpPacket->getDestinationPort();
00201 cPolymorphic *ctrl = udpPacket->removeControlInfo();
00202
00203
00204 SocketsByPortMap::iterator it = socketsByPortMap.find(destPort);
00205 if (it==socketsByPortMap.end())
00206 {
00207 EV << "No socket registered on port " << destPort << "\n";
00208 processUndeliverablePacket(udpPacket, ctrl);
00209 return;
00210 }
00211 SockDescList& list = it->second;
00212
00213 int matches = 0;
00214
00215
00216 cPacket *payload = udpPacket->decapsulate();
00217 if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL)
00218 {
00219 IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00220 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00221 {
00222 SockDesc *sd = *it;
00223 if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4))
00224 {
00225
00226
00227
00228 if (matches == 0) {
00229 sendUp((cPacket*)payload, udpPacket, ctrl4, sd);
00230 } else {
00231 opp_error("Edit SimpleUDP.cc to support multibinding.");
00232 }
00233 matches++;
00234 }
00235 }
00236 }
00237 else if (dynamic_cast<IPv6ControlInfo *>(ctrl)!=NULL)
00238 {
00239 IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00240 for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00241 {
00242 SockDesc *sd = *it;
00243 if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6))
00244 {
00245
00246
00247
00248 if (matches == 0) {
00249 sendUp((cPacket*)payload, udpPacket, ctrl6, sd);
00250 } else {
00251 opp_error("Edit SimpleUDP.cc to support multibinding.");
00252 }
00253 matches++;
00254 }
00255 }
00256 }
00257 else
00258 {
00259 error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
00260 }
00261
00262
00263 if (matches==0)
00264 {
00265 EV << "None of the sockets on port " << destPort << " matches the packet\n";
00266 processUndeliverablePacket(udpPacket, ctrl);
00267 return;
00268 }
00269
00270 delete udpPacket;
00271 delete ctrl;
00272 }
00273
00274 void SimpleUDP::processMsgFromApp(cPacket *appData)
00275 {
00276 cModule *node = getParentModule();
00277
00278
00279
00280 IPvXAddress srcAddr, destAddr;
00281
00282
00283 UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo());
00284
00285 UDPPacket *udpPacket = createUDPPacket(appData->getName());
00286
00287
00288 if (udpCtrl->getDestAddr().isIPv6()) {
00289 udpPacket->setByteLength(UDP_HEADER_BYTES + IPv6_HEADER_BYTES);
00290 } else {
00291 udpPacket->setByteLength(UDP_HEADER_BYTES + IP_HEADER_BYTES);
00292 }
00293 udpPacket->encapsulate(appData);
00294
00295
00296 udpPacket->setSourcePort(udpCtrl->getSrcPort());
00297 udpPacket->setDestinationPort(udpCtrl->getDestPort());
00298
00299
00300
00301 srcAddr = udpCtrl->getSrcAddr();
00302 destAddr = udpCtrl->getDestAddr();
00303
00304 SimpleInfo* info = dynamic_cast<SimpleInfo*>(globalNodeList->getPeerInfo(destAddr));
00305 numSent++;
00306
00307 if (info == NULL) {
00308 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00309 << " No route to host " << destAddr
00310 << endl;
00311
00312 delete udpPacket;
00313 delete udpCtrl;
00314 numDestUnavailableLost++;
00315 return;
00316 }
00317
00318 SimpleNodeEntry* destEntry = info->getEntry();
00319
00320
00321 simtime_t totalDelay = 0;
00322 if (srcAddr != destAddr) {
00323 SimpleNodeEntry::SimpleDelay temp;
00324 if (faultyDelay) {
00325 SimpleInfo* thisInfo = static_cast<SimpleInfo*>(globalNodeList->getPeerInfo(srcAddr));
00326 temp = nodeEntry->calcDelay(udpPacket, *destEntry,
00327 !(thisInfo->getNpsLayer() == 0 ||
00328 info->getNpsLayer() == 0));
00329 } else {
00330 temp = nodeEntry->calcDelay(udpPacket, *destEntry);
00331 }
00332 if (useCoordinateBasedDelay == false) {
00333 totalDelay = constantDelay;
00334 } else if (temp.second == false) {
00335 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00336 << " Send queue full: packet " << udpPacket << " dropped"
00337 << endl;
00338 delete udpCtrl;
00339 delete udpPacket;
00340 numQueueLost++;
00341 return;
00342 } else {
00343 totalDelay = temp.first;
00344 }
00345 }
00346
00347 SimpleInfo* thisInfo = dynamic_cast<SimpleInfo*>(globalNodeList->getPeerInfo(srcAddr));
00348
00349 if (!globalNodeList->areNodeTypesConnected(thisInfo->getTypeID(), info->getTypeID())) {
00350 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00351 << " Partition " << thisInfo->getTypeID() << "->" << info->getTypeID()
00352 << " is not connected"
00353 << endl;
00354 delete udpCtrl;
00355 delete udpPacket;
00356 numPartitionLost++;
00357 return;
00358 }
00359
00360 if (jitter) {
00361
00362
00363
00364
00365 double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * jitter);
00366 while (temp == INFINITY || temp != temp) {
00367 std::cerr << "\n******* SimpleUDP: truncnormal() -> inf !!\n"
00368 << std::endl;
00369 temp = truncnormal(0, SIMTIME_DBL(totalDelay) * jitter);
00370 }
00371
00372 totalDelay += temp;
00373 }
00374
00375 BaseOverlayMessage* temp = NULL;
00376
00377 if (ev.isGUI() && udpPacket->getEncapsulatedPacket()) {
00378 if ((temp = dynamic_cast<BaseOverlayMessage*>(udpPacket
00379 ->getEncapsulatedPacket()))) {
00380 switch (temp->getStatType()) {
00381 case APP_DATA_STAT:
00382 udpPacket->setKind(1);
00383 break;
00384 case APP_LOOKUP_STAT:
00385 udpPacket->setKind(2);
00386 break;
00387 case MAINTENANCE_STAT:
00388 default:
00389 udpPacket->setKind(3);
00390 }
00391 } else {
00392 udpPacket->setKind(1);
00393 }
00394 }
00395
00396 EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n"
00397 << " Packet " << udpPacket << " sent with delay = " << totalDelay
00398 << endl;
00399
00400
00401
00402
00403
00404 if (!udpCtrl->getDestAddr().isIPv6()) {
00405
00406
00407
00408
00409 IPControlInfo *ipControlInfo = new IPControlInfo();
00410 ipControlInfo->setProtocol(IP_PROT_UDP);
00411 ipControlInfo->setSrcAddr(srcAddr.get4());
00412 ipControlInfo->setDestAddr(destAddr.get4());
00413 ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId());
00414 udpPacket->setControlInfo(ipControlInfo);
00415 delete udpCtrl;
00416
00417
00418 sendDirect(udpPacket, totalDelay, 0, destEntry->getUdpIPv4Gate());
00419
00420 } else {
00421
00422
00423
00424
00425 IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
00426 ipControlInfo->setProtocol(IP_PROT_UDP);
00427 ipControlInfo->setSrcAddr(srcAddr.get6());
00428 ipControlInfo->setDestAddr(destAddr.get6());
00429 ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId());
00430 udpPacket->setControlInfo(ipControlInfo);
00431 delete udpCtrl;
00432
00433
00434 sendDirect(udpPacket, totalDelay, 0, destEntry->getUdpIPv6Gate());
00435 }
00436
00437 }
00438
00439
00440 void SimpleUDP::setNodeEntry(SimpleNodeEntry* entry)
00441 {
00442 nodeEntry = entry;
00443 }