Implements the UDP protocol: encapsulates/decapsulates user data into/from UDP. More...
#include <SimpleUDP.h>
Public Types | |
enum | delayFaultTypeNum { delayFaultUndefined, delayFaultLiveAll, delayFaultLivePlanetlab, delayFaultSimulation } |
Public Member Functions | |
void | setNodeEntry (SimpleNodeEntry *entry) |
set or change the nodeEntry of this module | |
SimpleUDP () | |
virtual | ~SimpleUDP () |
destructor | |
Static Public Attributes | |
static std::string | delayFaultTypeString |
static std::map< std::string, delayFaultTypeNum > | delayFaultTypeMap |
Protected Member Functions | |
void | updateDisplayString () |
utility: show current statistics above the icon | |
virtual void | processMsgFromApp (cPacket *appData) |
process packets from application | |
virtual void | processUDPPacket (UDPPacket *udpPacket) |
virtual void | processUndeliverablePacket (UDPPacket *udpPacket, cPolymorphic *ctrl) |
virtual void | initialize (int stage) |
initialise the SimpleUDP module | |
virtual int | numInitStages () const |
returns the number of init stages | |
void | finish () |
Protected Attributes | |
int | numQueueLost |
number of lost packets due to queue full | |
int | numPartitionLost |
number of lost packets due to network partitions | |
int | numDestUnavailableLost |
number of lost packets due to unavailable destination | |
simtime_t | delay |
simulated delay between sending and receiving udp module | |
simtime_t | constantDelay |
constant delay between two peers | |
bool | useCoordinateBasedDelay |
delay should be calculated from euklidean distance between two peers | |
double | jitter |
amount of jitter in % of total delay | |
bool | faultyDelay |
GlobalNodeList * | globalNodeList |
violate the triangle inequality? | |
GlobalStatistics * | globalStatistics |
pointer to GlobalStatistics | |
SimpleNodeEntry * | nodeEntry |
nodeEntry of the overlay node this module belongs to |
Implements the UDP protocol: encapsulates/decapsulates user data into/from UDP.
More info in the NED file.
Definition at line 59 of file SimpleUDP.h.
Definition at line 65 of file SimpleUDP.h.
{ delayFaultUndefined, delayFaultLiveAll, delayFaultLivePlanetlab, delayFaultSimulation };
SimpleUDP::SimpleUDP | ( | ) |
Definition at line 88 of file SimpleUDP.cc.
{ globalStatistics = NULL; }
SimpleUDP::~SimpleUDP | ( | ) | [virtual] |
void SimpleUDP::finish | ( | ) | [protected] |
Definition at line 149 of file SimpleUDP.cc.
{ globalStatistics->addStdDev("SimpleUDP: Packets sent", numSent); globalStatistics->addStdDev("SimpleUDP: Packets dropped with bad checksum", numDroppedBadChecksum); globalStatistics->addStdDev("SimpleUDP: Packets dropped due to queue overflows", numQueueLost); globalStatistics->addStdDev("SimpleUDP: Packets dropped due to network partitions", numPartitionLost); globalStatistics->addStdDev("SimpleUDP: Packets dropped due to unavailable destination", numDestUnavailableLost); }
void SimpleUDP::initialize | ( | int | stage | ) | [protected, virtual] |
initialise the SimpleUDP module
stage | stage of initialisation phase |
Definition at line 98 of file SimpleUDP.cc.
{ if(stage == MIN_STAGE_UNDERLAY) { WATCH_PTRMAP(socketsByIdMap); WATCH_MAP(socketsByPortMap); lastEphemeralPort = EPHEMERAL_PORTRANGE_START; icmp = NULL; icmpv6 = NULL; numSent = 0; numPassedUp = 0; numDroppedWrongPort = 0; numDroppedBadChecksum = 0; numQueueLost = 0; numPartitionLost = 0; numDestUnavailableLost = 0; WATCH(numSent); WATCH(numPassedUp); WATCH(numDroppedWrongPort); WATCH(numDroppedBadChecksum); WATCH(numQueueLost); WATCH(numPartitionLost); WATCH(numDestUnavailableLost); globalNodeList = GlobalNodeListAccess().get(); globalStatistics = GlobalStatisticsAccess().get(); constantDelay = par("constantDelay"); useCoordinateBasedDelay = par("useCoordinateBasedDelay"); delayFaultTypeString = par("delayFaultType").stdstringValue(); delayFaultTypeMap["live_all"] = delayFaultLiveAll; delayFaultTypeMap["live_planetlab"] = delayFaultLivePlanetlab; delayFaultTypeMap["simulation"] = delayFaultSimulation; switch (delayFaultTypeMap[delayFaultTypeString]) { case SimpleUDP::delayFaultLiveAll: case SimpleUDP::delayFaultLivePlanetlab: case SimpleUDP::delayFaultSimulation: faultyDelay = true; break; default: faultyDelay = false; } jitter = par("jitter"); nodeEntry = NULL; WATCH_PTR(nodeEntry); } }
virtual int SimpleUDP::numInitStages | ( | void | ) | const [inline, protected, virtual] |
returns the number of init stages
Definition at line 134 of file SimpleUDP.h.
{ return MAX_STAGE_UNDERLAY + 1; }
void SimpleUDP::processMsgFromApp | ( | cPacket * | appData | ) | [protected, virtual] |
process packets from application
appData | the data that has to be sent |
Definition at line 274 of file SimpleUDP.cc.
{ cModule *node = getParentModule(); // IPvXAddress ip = IPAddressResolver().addressOf(node); // Speedhack SK IPvXAddress srcAddr, destAddr; //cGate* destGate; UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo()); UDPPacket *udpPacket = createUDPPacket(appData->getName()); // add header byte length for the skipped IP header if (udpCtrl->getDestAddr().isIPv6()) { udpPacket->setByteLength(UDP_HEADER_BYTES + IPv6_HEADER_BYTES); } else { udpPacket->setByteLength(UDP_HEADER_BYTES + IP_HEADER_BYTES); } udpPacket->encapsulate(appData); // set source and destination port udpPacket->setSourcePort(udpCtrl->getSrcPort()); udpPacket->setDestinationPort(udpCtrl->getDestPort()); /* main modifications for SimpleUDP start here */ srcAddr = udpCtrl->getSrcAddr(); destAddr = udpCtrl->getDestAddr(); SimpleInfo* info = dynamic_cast<SimpleInfo*>(globalNodeList->getPeerInfo(destAddr)); numSent++; if (info == NULL) { EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n" << " No route to host " << destAddr << endl; delete udpPacket; delete udpCtrl; numDestUnavailableLost++; return; } SimpleNodeEntry* destEntry = info->getEntry(); // calculate delay simtime_t totalDelay = 0; if (srcAddr != destAddr) { SimpleNodeEntry::SimpleDelay temp; if (faultyDelay) { SimpleInfo* thisInfo = static_cast<SimpleInfo*>(globalNodeList->getPeerInfo(srcAddr)); temp = nodeEntry->calcDelay(udpPacket, *destEntry, !(thisInfo->getNpsLayer() == 0 || info->getNpsLayer() == 0)); //TODO } else { temp = nodeEntry->calcDelay(udpPacket, *destEntry); } if (useCoordinateBasedDelay == false) { totalDelay = constantDelay; } else if (temp.second == false) { EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n" << " Send queue full: packet " << udpPacket << " dropped" << endl; delete udpCtrl; delete udpPacket; numQueueLost++; return; } else { totalDelay = temp.first; } } SimpleInfo* thisInfo = dynamic_cast<SimpleInfo*>(globalNodeList->getPeerInfo(srcAddr)); if (!globalNodeList->areNodeTypesConnected(thisInfo->getTypeID(), info->getTypeID())) { EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n" << " Partition " << thisInfo->getTypeID() << "->" << info->getTypeID() << " is not connected" << endl; delete udpCtrl; delete udpPacket; numPartitionLost++; return; } if (jitter) { // jitter //totalDelay += truncnormal(0, SIMTIME_DBL(totalDelay) * jitter); //workaround (bug in truncnormal(): sometimes returns inf) double temp = truncnormal(0, SIMTIME_DBL(totalDelay) * jitter); while (temp == INFINITY || temp != temp) { // reroll if temp is INF or NaN std::cerr << "\n******* SimpleUDP: truncnormal() -> inf !!\n" << std::endl; temp = truncnormal(0, SIMTIME_DBL(totalDelay) * jitter); } totalDelay += temp; } BaseOverlayMessage* temp = NULL; if (ev.isGUI() && udpPacket->getEncapsulatedPacket()) { if ((temp = dynamic_cast<BaseOverlayMessage*>(udpPacket ->getEncapsulatedPacket()))) { switch (temp->getStatType()) { case APP_DATA_STAT: udpPacket->setKind(1); break; case APP_LOOKUP_STAT: udpPacket->setKind(2); break; case MAINTENANCE_STAT: default: udpPacket->setKind(3); } } else { udpPacket->setKind(1); } } EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n" << " Packet " << udpPacket << " sent with delay = " << totalDelay << endl; //RECORD_STATS(globalStatistics->addStdDev("SimpleUDP: delay", totalDelay)); /* main modifications for SimpleUDP end here */ if (!udpCtrl->getDestAddr().isIPv6()) { // send to IPv4 //EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n" //<< " Sending app packet " << appData->getName() << " over IPv4" //<< endl; IPControlInfo *ipControlInfo = new IPControlInfo(); ipControlInfo->setProtocol(IP_PROT_UDP); ipControlInfo->setSrcAddr(srcAddr.get4()); ipControlInfo->setDestAddr(destAddr.get4()); ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId()); udpPacket->setControlInfo(ipControlInfo); delete udpCtrl; // send directly to IPv4 gate of the destination node sendDirect(udpPacket, totalDelay, 0, destEntry->getUdpIPv4Gate()); } else { // send to IPv6 //EV << "[SimpleUDP::processMsgFromApp() @ " << IPAddressResolver().addressOf(node) << "]\n" //<< " Sending app packet " << appData->getName() << " over IPv6" //<< endl; IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo(); ipControlInfo->setProtocol(IP_PROT_UDP); ipControlInfo->setSrcAddr(srcAddr.get6()); ipControlInfo->setDestAddr(destAddr.get6()); ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId()); //FIXME extend IPv6 with this!!! udpPacket->setControlInfo(ipControlInfo); delete udpCtrl; // send directly to IPv4 gate of the destination node sendDirect(udpPacket, totalDelay, 0, destEntry->getUdpIPv6Gate()); } }
void SimpleUDP::processUDPPacket | ( | UDPPacket * | udpPacket | ) | [protected, virtual] |
Definition at line 188 of file SimpleUDP.cc.
{ // simulate checksum: discard packet if it has bit error EV << "Packet " << udpPacket->getName() << " received from network, dest port " << udpPacket->getDestinationPort() << "\n"; if (udpPacket->hasBitError()) { EV << "Packet has bit error, discarding\n"; delete udpPacket; numDroppedBadChecksum++; return; } int destPort = udpPacket->getDestinationPort(); cPolymorphic *ctrl = udpPacket->removeControlInfo(); // send back ICMP error if no socket is bound to that port SocketsByPortMap::iterator it = socketsByPortMap.find(destPort); if (it==socketsByPortMap.end()) { EV << "No socket registered on port " << destPort << "\n"; processUndeliverablePacket(udpPacket, ctrl); return; } SockDescList& list = it->second; int matches = 0; // deliver a copy of the packet to each matching socket cPacket *payload = udpPacket->decapsulate(); if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) { IPControlInfo *ctrl4 = (IPControlInfo *)ctrl; for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) { SockDesc *sd = *it; if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4)) { //EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n"; //sendUp((cPacket*)payload->dup(), udpPacket, ctrl4, sd); // ib: speed hack if (matches == 0) { sendUp((cPacket*)payload, udpPacket, ctrl4, sd); } else { opp_error("Edit SimpleUDP.cc to support multibinding."); } matches++; } } } else if (dynamic_cast<IPv6ControlInfo *>(ctrl)!=NULL) { IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl; for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) { SockDesc *sd = *it; if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6)) { //EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n"; //sendUp((cPacket*)payload->dup(), udpPacket, ctrl6, sd); // ib: speed hack if (matches == 0) { sendUp((cPacket*)payload, udpPacket, ctrl6, sd); } else { opp_error("Edit SimpleUDP.cc to support multibinding."); } matches++; } } } else { error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName()); } // send back ICMP error if there is no matching socket if (matches==0) { EV << "None of the sockets on port " << destPort << " matches the packet\n"; processUndeliverablePacket(udpPacket, ctrl); return; } delete udpPacket; delete ctrl; }
void SimpleUDP::processUndeliverablePacket | ( | UDPPacket * | udpPacket, | |
cPolymorphic * | ctrl | |||
) | [protected, virtual] |
Definition at line 178 of file SimpleUDP.cc.
Referenced by processUDPPacket().
{ numDroppedWrongPort++; EV << "[SimpleUDP::processUndeliverablePacket()]\n" << " Dropped packet bound to unreserved port, ignoring ICMP error" << endl; delete udpPacket; }
void SimpleUDP::setNodeEntry | ( | SimpleNodeEntry * | entry | ) |
set or change the nodeEntry of this module
entry | the new nodeEntry |
Definition at line 440 of file SimpleUDP.cc.
Referenced by SimpleUnderlayConfigurator::createNode(), and SimpleUnderlayConfigurator::migrateNode().
{ nodeEntry = entry; }
void SimpleUDP::updateDisplayString | ( | ) | [protected] |
utility: show current statistics above the icon
Definition at line 163 of file SimpleUDP.cc.
{ char buf[80]; sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent); if (numDroppedWrongPort>0) { sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort); getDisplayString().setTagArg("i",1,"red"); } if (numQueueLost>0) { sprintf(buf+strlen(buf), "\nlost (queue overflow): %d pks", numQueueLost); getDisplayString().setTagArg("i",1,"red"); } getDisplayString().setTagArg("t",0,buf); }
simtime_t SimpleUDP::constantDelay [protected] |
constant delay between two peers
Definition at line 81 of file SimpleUDP.h.
Referenced by initialize(), and processMsgFromApp().
simtime_t SimpleUDP::delay [protected] |
simulated delay between sending and receiving udp module
Definition at line 79 of file SimpleUDP.h.
std::map< std::string, SimpleUDP::delayFaultTypeNum > SimpleUDP::delayFaultTypeMap [static] |
Definition at line 71 of file SimpleUDP.h.
Referenced by SimpleNodeEntry::getFaultyDelay(), and initialize().
std::string SimpleUDP::delayFaultTypeString [static] |
Definition at line 64 of file SimpleUDP.h.
Referenced by SimpleNodeEntry::getFaultyDelay(), and initialize().
bool SimpleUDP::faultyDelay [protected] |
Definition at line 84 of file SimpleUDP.h.
Referenced by initialize(), and processMsgFromApp().
GlobalNodeList* SimpleUDP::globalNodeList [protected] |
violate the triangle inequality?
pointer to GlobalNodeList
Definition at line 85 of file SimpleUDP.h.
Referenced by initialize(), and processMsgFromApp().
GlobalStatistics* SimpleUDP::globalStatistics [protected] |
pointer to GlobalStatistics
Definition at line 86 of file SimpleUDP.h.
Referenced by finish(), initialize(), and SimpleUDP().
double SimpleUDP::jitter [protected] |
amount of jitter in % of total delay
Definition at line 83 of file SimpleUDP.h.
Referenced by initialize(), and processMsgFromApp().
SimpleNodeEntry* SimpleUDP::nodeEntry [protected] |
nodeEntry of the overlay node this module belongs to
Definition at line 87 of file SimpleUDP.h.
Referenced by initialize(), processMsgFromApp(), and setNodeEntry().
int SimpleUDP::numDestUnavailableLost [protected] |
number of lost packets due to unavailable destination
Definition at line 78 of file SimpleUDP.h.
Referenced by finish(), initialize(), and processMsgFromApp().
int SimpleUDP::numPartitionLost [protected] |
number of lost packets due to network partitions
Definition at line 77 of file SimpleUDP.h.
Referenced by finish(), initialize(), and processMsgFromApp().
int SimpleUDP::numQueueLost [protected] |
number of lost packets due to queue full
Definition at line 76 of file SimpleUDP.h.
Referenced by finish(), initialize(), processMsgFromApp(), and updateDisplayString().
bool SimpleUDP::useCoordinateBasedDelay [protected] |
delay should be calculated from euklidean distance between two peers
Definition at line 82 of file SimpleUDP.h.
Referenced by initialize(), and processMsgFromApp().