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().
1.7.1