SimpleUDP Class Reference

#include <SimpleUDP.h>

List of all members.


Detailed Description

Implements the UDP protocol: encapsulates/decapsulates user data into/from UDP.

More info in the NED file.


Public Types

typedef std::list< SockDesc * > SockDescList
 list of socket pointers
typedef std::map< int, SockDesc * > SocketsByIdMap
 list of socket ordered by sockId
typedef std::map< int, SockDescListSocketsByPortMap
 list of sockets ordered by localPort

Public Member Functions

void setNodeEntry (const SimpleNodeEntry &entry)
 set or change the nodeEntry of this module
 SimpleUDP ()
 constructor
virtual ~SimpleUDP ()
 destructor

Protected Member Functions

void updateDisplayString ()
 utility: show current statistics above the icon
void bind (int gateIndex, UDPControlInfo *ctrl)
 bind socket
void connect (int sockId, IPvXAddress addr, int port)
 connect socket
void unbind (int sockId)
 unbind socket
short getEphemeralPort ()
 ephemeral port.
bool matchesSocket (SockDesc *sd, SimpleUDPPacket *udp, IPControlInfo *ctrl)
 decides if a received packet (IPv4) belongs to the specified socket
bool matchesSocket (SockDesc *sd, SimpleUDPPacket *udp, IPv6ControlInfo *ctrl)
 decides if a received packet (IPv6) belongs to the specified socket
bool matchesSocket (SockDesc *sd, const IPvXAddress &localAddr, const IPvXAddress &remoteAddr, short remotePort)
 decides if a socket matches the specified parameters
void sendUp (cMessage *payload, SimpleUDPPacket *udpHeader, IPControlInfo *ctrl, SockDesc *sd)
 sends payload up to the application
void sendUp (cMessage *payload, SimpleUDPPacket *udpHeader, IPv6ControlInfo *ctrl, SockDesc *sd)
 sends payload up to the application
void processUndeliverablePacket (SimpleUDPPacket *udpPacket, cPolymorphic *ctrl)
 handles received packet which destination port is not bound to any socket
void sendUpErrorNotification (SockDesc *sd, int msgkind, const IPvXAddress &localAddr, const IPvXAddress &remoteAddr, short remotePort)
 sends an error up to the application
virtual void processICMPError (cMessage *icmpErrorMsg)
 process an ICMP error packet
virtual void processUDPPacket (SimpleUDPPacket *udpPacket)
 process UDP packets coming from IP
virtual void processMsgFromApp (cMessage *appData)
 process packets from application
virtual void processCommandFromApp (cMessage *msg)
 process commands from application
virtual void initialize (int stage)
 initialise the SimpleUDP module
virtual int numInitStages () const
 returns the number of init stages
virtual void handleMessage (cMessage *msg)
 process received messages

Protected Attributes

SocketsByIdMap socketsByIdMap
 list of socket ordered by sockId
SocketsByPortMap socketsByPortMap
 list of sockets ordered by localPort
short lastEphemeralPort
 last used port (all ports above should be free)
ICMP * icmp
 pointer to a received icmp (IPv4) message
ICMPv6 * icmpv6
 pointer to a received icmp (IPv6) message
int numSent
 number of packets sent to the network
int numPassedUp
 number of packet passed up to applications
int numDroppedWrongPort
 number of dropped packets due to wrong destination port
int numDroppedBadChecksum
 number of dropped packets due to bad checksum
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
BootstrapOraclebootstrapOracle
 pointer to BootstrapOracle
SimpleNodeEntrynodeEntry
 nodeEntry of the overlay node this module belongs to

Classes

struct  SockDesc
 defines a socket More...


Member Typedef Documentation

typedef std::list<SockDesc *> SimpleUDP::SockDescList

list of socket pointers

typedef std::map<int,SockDesc *> SimpleUDP::SocketsByIdMap

list of socket ordered by sockId

typedef std::map<int,SockDescList> SimpleUDP::SocketsByPortMap

list of sockets ordered by localPort


Constructor & Destructor Documentation

SimpleUDP::SimpleUDP (  )  [inline]

constructor

00247     {}

SimpleUDP::~SimpleUDP (  )  [virtual]

destructor

00083 {
00084     for (SocketsByIdMap::iterator i=socketsByIdMap.begin();
00085          i!=socketsByIdMap.end(); ++i)
00086         delete i->second;
00087 
00088     if(nodeEntry)
00089         delete nodeEntry;
00090 }


Member Function Documentation

void SimpleUDP::setNodeEntry ( const SimpleNodeEntry entry  ) 

set or change the nodeEntry of this module

Parameters:
entry the new nodeEntry
00634 {
00635     if(nodeEntry != NULL)
00636         delete nodeEntry;
00637     nodeEntry = new SimpleNodeEntry(entry);
00638 }

void SimpleUDP::updateDisplayString (  )  [protected]

utility: show current statistics above the icon

00247 {
00248     char buf[80];
00249     sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
00250     if (numDroppedWrongPort>0) {
00251         sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
00252         displayString().setTagArg("i",1,"red");
00253     }
00254     displayString().setTagArg("t",0,buf);
00255 }

void SimpleUDP::bind ( int  gateIndex,
UDPControlInfo *  ctrl 
) [protected]

bind socket

Parameters:
gateIndex application gate connected to the socket
ctrl control information for communication
00121 {
00122     // XXX checks could be added, of when the bind should be allowed to proceed
00123 
00124     // create and fill in SockDesc
00125     SockDesc *sd = new SockDesc();
00126     sd->sockId = ctrl->sockId();
00127     sd->userId = ctrl->userId();
00128     sd->appGateIndex = gateIndex;
00129     sd->localAddr = ctrl->srcAddr();
00130     sd->remoteAddr = ctrl->destAddr();
00131     sd->localPort = ctrl->srcPort();
00132     sd->remotePort = ctrl->destPort();
00133     sd->interfaceId = ctrl->interfaceId();
00134 
00135     if (sd->sockId==-1)
00136         error("sockId in BIND message not filled in");
00137     if (sd->localPort==0)
00138         sd->localPort = getEphemeralPort();
00139 
00140     sd->onlyLocalPortIsSet = sd->localAddr.isUnspecified() &&
00141                              sd->remoteAddr.isUnspecified() &&
00142                              sd->remotePort==0 &&
00143                              sd->interfaceId==-1;
00144 
00145     cModule *node = parentModule();
00146     IPvXAddress ip = IPAddressResolver().addressOf(node);
00147     EV << "[SimpleUDP::bind() @ " << ip << "]\n"
00148        << "    Binding socket: " << *sd
00149        << endl;
00150 
00151     // add to socketsByIdMap
00152     ASSERT(socketsByIdMap.find(sd->sockId)==socketsByIdMap.end());
00153     socketsByIdMap[sd->sockId] = sd;
00154 
00155     // add to socketsByPortMap
00156     // create if doesn't exist
00157     SockDescList& list = socketsByPortMap[sd->localPort];
00158     list.push_back(sd);
00159 }

void SimpleUDP::connect ( int  sockId,
IPvXAddress  addr,
int  port 
) [protected]

connect socket

Parameters:
sockId id of the socket to connect
addr IPvXAddress of the remote socket
port port of the remote socket
00162 {
00163     SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00164     if (it==socketsByIdMap.end())
00165         error("socket id=%d doesn't exist (already closed?)", sockId);
00166     if (addr.isUnspecified())
00167         opp_error("connect: unspecified remote address");
00168     if (port<=0 || port>65535)
00169         opp_error("connect: invalid remote port number %d", port);
00170 
00171     SockDesc *sd = it->second;
00172     sd->remoteAddr = addr;
00173     sd->remotePort = port;
00174 
00175     sd->onlyLocalPortIsSet = false;
00176 
00177     EV << "[SimpleUDP::connect() @ " << sd->localAddr << "]\n"
00178        << "    Connecting socket: " << *sd
00179        << endl;
00180 }

void SimpleUDP::unbind ( int  sockId  )  [protected]

unbind socket

Parameters:
sockId id of the socket to unbind
00183 {
00184     // remove from socketsByIdMap
00185     SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00186     if (it==socketsByIdMap.end())
00187         error("socket id=%d doesn't exist (already closed?)", sockId);
00188     SockDesc *sd = it->second;
00189     socketsByIdMap.erase(it);
00190 
00191     EV << "[SimpleUDP::unbind() @ " << sd->localAddr << "]\n"
00192        << "    Unbinding socket: " << *sd
00193        << endl;
00194 
00195     // remove from socketsByPortMap
00196     SockDescList& list = socketsByPortMap[sd->localPort];
00197     for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00198         if (*it == sd) {
00199             list.erase(it);
00200             break;
00201         }
00202     if (list.empty())
00203         socketsByPortMap.erase(sd->localPort);
00204     delete sd;
00205 }

short SimpleUDP::getEphemeralPort (  )  [protected]

ephemeral port.

Returns:
a free ephemeral port, if there is no free port, error is called
00208 {
00209     // start at the last allocated port number + 1, and search for an unused one
00210     short searchUntil = lastEphemeralPort++;
00211     if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END) // wrap
00212         lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00213 
00214     while (socketsByPortMap.find(lastEphemeralPort)!=socketsByPortMap.end()) {
00215         if (lastEphemeralPort == searchUntil) // got back to starting point?
00216             error("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
00217         lastEphemeralPort++;
00218         if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END) // wrap
00219             lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00220     }
00221 
00222     // found a free one, return it
00223     return lastEphemeralPort;
00224 }

bool SimpleUDP::matchesSocket ( SockDesc sd,
SimpleUDPPacket *  udp,
IPControlInfo *  ctrl 
) [protected]

decides if a received packet (IPv4) belongs to the specified socket

Parameters:
sd the socket
udp the received SimpleUDPPacket
ctrl the IPControlInfo of udp
Returns:
true if destination of the SimpleUDPPacket is the specified socket
00258 {
00259     // IPv4 version
00260     if (sd->remotePort!=0 && sd->remotePort!=udp->sourcePort())
00261         return false;
00262     if (!sd->localAddr.isUnspecified() && sd->localAddr.get4()!=ipCtrl->destAddr())
00263         return false;
00264     if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get4()!=ipCtrl->srcAddr())
00265         return false;
00266     if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->interfaceId())
00267         return false;
00268     return true;
00269 }

bool SimpleUDP::matchesSocket ( SockDesc sd,
SimpleUDPPacket *  udp,
IPv6ControlInfo *  ctrl 
) [protected]

decides if a received packet (IPv6) belongs to the specified socket

Parameters:
sd the socket
udp the received SimpleUDPPacket
ctrl the IPControlInfo of udp
Returns:
true if destination of the SimpleUDPPacket is the specified socket
00272 {
00273     // IPv6 version
00274     if (sd->remotePort!=0 && sd->remotePort!=udp->sourcePort())
00275         return false;
00276     if (!sd->localAddr.isUnspecified() && sd->localAddr.get6()!=ipCtrl->destAddr())
00277         return false;
00278     if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get6()!=ipCtrl->srcAddr())
00279         return false;
00280     if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->interfaceId())
00281         return false;
00282     return true;
00283 }

bool SimpleUDP::matchesSocket ( SockDesc sd,
const IPvXAddress &  localAddr,
const IPvXAddress &  remoteAddr,
short  remotePort 
) [protected]

decides if a socket matches the specified parameters

Parameters:
sd the socket
localAddr the specified localAddr
remoteAddr the specified remoteAddr
remotePort the specified remotePort
Returns:
true if specified parameters match the sockets parameters
00286 {
00287     return (sd->remotePort==0 || sd->remotePort!=remotePort) &&
00288            (sd->localAddr.isUnspecified() || sd->localAddr==localAddr) &&
00289            (sd->remoteAddr.isUnspecified() || sd->remoteAddr==remoteAddr);
00290 }

void SimpleUDP::sendUp ( cMessage *  payload,
SimpleUDPPacket *  udpHeader,
IPControlInfo *  ctrl,
SockDesc sd 
) [protected]

sends payload up to the application

Parameters:
payload the payload
udpHeader the udpHeader of the IPv4 message
ctrl the IPControlInfo of the IPv4 message
sd the socket at which the IPv4 message arrived
00293 {
00294     // send payload with UDPControlInfo up to the application -- IPv4 version
00295     UDPControlInfo *udpCtrl = new UDPControlInfo();
00296     udpCtrl->setSockId(sd->sockId);
00297     udpCtrl->setUserId(sd->userId);
00298     udpCtrl->setSrcAddr(ipCtrl->srcAddr());
00299     udpCtrl->setDestAddr(ipCtrl->destAddr());
00300     udpCtrl->setSrcPort(udpHeader->sourcePort());
00301     udpCtrl->setDestPort(udpHeader->destinationPort());
00302     udpCtrl->setInterfaceId(ipCtrl->interfaceId());
00303     payload->setControlInfo(udpCtrl);
00304 
00305     send(payload, "to_app", sd->appGateIndex);
00306     numPassedUp++;
00307 }

void SimpleUDP::sendUp ( cMessage *  payload,
SimpleUDPPacket *  udpHeader,
IPv6ControlInfo *  ctrl,
SockDesc sd 
) [protected]

sends payload up to the application

Parameters:
payload the payload
udpHeader the udpHeader of the IPv6 message
ctrl the IPControlInfo of the IPv6 message
sd the socket at which the IPv6 message arrived
00310 {
00311     // send payload with UDPControlInfo up to the application -- IPv6 version
00312     UDPControlInfo *udpCtrl = new UDPControlInfo();
00313     udpCtrl->setSockId(sd->sockId);
00314     udpCtrl->setUserId(sd->userId);
00315     udpCtrl->setSrcAddr(ipCtrl->srcAddr());
00316     udpCtrl->setDestAddr(ipCtrl->destAddr());
00317     udpCtrl->setSrcPort(udpHeader->sourcePort());
00318     udpCtrl->setDestPort(udpHeader->destinationPort());
00319     udpCtrl->setInterfaceId(ipCtrl->interfaceId());
00320     payload->setControlInfo(udpCtrl);
00321 
00322     send(payload, "to_app", sd->appGateIndex);
00323     numPassedUp++;
00324 }

void SimpleUDP::processUndeliverablePacket ( SimpleUDPPacket *  udpPacket,
cPolymorphic *  ctrl 
) [protected]

handles received packet which destination port is not bound to any socket

Parameters:
udpPacket the SimpleUDPPacket with the wrong port number
ctrl the IPControlInfo of udpPacket
00327 {
00328     numDroppedWrongPort++;
00329 
00330     // send back ICMP PORT_UNREACHABLE
00331     if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) {
00332         if (!icmp)
00333             icmp = ICMPAccess().get();
00334         IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00335         if (!ctrl4->destAddr().isMulticast())
00336             icmp->sendErrorMessage(udpPacket, ctrl4, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PORT_UNREACHABLE);
00337     } else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->controlInfo())
00338                !=NULL) {
00339         if (!icmpv6)
00340             icmpv6 = ICMPv6Access().get();
00341         IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00342         if (!ctrl6->destAddr().isMulticast())
00343             icmpv6->sendErrorMessage(udpPacket, ctrl6, ICMPv6_DESTINATION_UNREACHABLE, PORT_UNREACHABLE);
00344     } else {
00345         error("(%s)%s arrived from lower layer without control info", udpPacket->className(), udpPacket->name());
00346     }
00347 }

void SimpleUDP::sendUpErrorNotification ( SockDesc sd,
int  msgkind,
const IPvXAddress &  localAddr,
const IPvXAddress &  remoteAddr,
short  remotePort 
) [protected]

sends an error up to the application

Parameters:
sd the socket that received the error
msgkind the type of the error notification
localAddr the address from which the faulty message was sent
remoteAddr the address to which the faulty message was sent
remotePort the port to which the faulty message was sent
00423 {
00424     cMessage *notifyMsg = new cMessage("ERROR", msgkind);
00425     UDPControlInfo *udpCtrl = new UDPControlInfo();
00426     udpCtrl->setSockId(sd->sockId);
00427     udpCtrl->setUserId(sd->userId);
00428     udpCtrl->setSrcAddr(localAddr);
00429     udpCtrl->setDestAddr(remoteAddr);
00430     udpCtrl->setSrcPort(sd->localPort);
00431     udpCtrl->setDestPort(remotePort);
00432     notifyMsg->setControlInfo(udpCtrl);
00433 
00434     send(notifyMsg, "to_app", sd->appGateIndex);
00435 }

void SimpleUDP::processICMPError ( cMessage *  icmpErrorMsg  )  [protected, virtual]

process an ICMP error packet

Parameters:
icmpErrorMsg the received icmp Message
00350 {
00351     // extract details from the error message, then try to notify socket that sent bogus packet
00352     int type = 0;
00353     int code = 0;
00354     IPvXAddress localAddr, remoteAddr;
00355     int localPort = 0;
00356     int remotePort = 0;
00357 
00358     if (dynamic_cast<ICMPMessage *>(msg)) {
00359         ICMPMessage *icmpMsg = (ICMPMessage *)msg;
00360         type = icmpMsg->getType();
00361         code = icmpMsg->getCode();
00362         icmpMsg->setLength(icmpMsg->encapsulatedMsg()->length()); // trick because payload in ICMP is conceptually truncated
00363         IPDatagram *datagram = check_and_cast<IPDatagram *>(icmpMsg->decapsulate());
00364         localAddr = datagram->srcAddress();
00365         remoteAddr = datagram->destAddress();
00366         SimpleUDPPacket *packet = check_and_cast<SimpleUDPPacket *>(datagram->decapsulate());
00367         localPort = packet->sourcePort();
00368         remotePort = packet->destinationPort();
00369         delete icmpMsg;
00370         delete datagram;
00371         delete packet;
00372     } else if (dynamic_cast<ICMPv6Message *>(msg)) {
00373         ICMPv6Message *icmpMsg = (ICMPv6Message *)msg;
00374         type = icmpMsg->type();
00375         code = -1; // FIXME this is dependent on type()...
00376         IPv6Datagram *datagram = check_and_cast<IPv6Datagram *>(icmpMsg->decapsulate());
00377         localAddr = datagram->srcAddress();
00378         remoteAddr = datagram->destAddress();
00379         SimpleUDPPacket *packet = check_and_cast<SimpleUDPPacket *>(datagram->decapsulate());
00380         localPort = packet->sourcePort();
00381         remotePort = packet->destinationPort();
00382         delete icmpMsg;
00383         delete datagram;
00384         delete packet;
00385     }
00386     EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00387        << "    ICMP error received: type=" << type << " code=" << code
00388        << "\n    about packet " << localAddr << ":" << localPort << " --> "
00389        << "    " << remoteAddr << ":" << remotePort
00390        << endl;
00391 
00392     // identify socket and report error to it
00393     SocketsByPortMap::iterator it = socketsByPortMap.find(localPort);
00394     if (it==socketsByPortMap.end()) {
00395         EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00396            << "    No socket on that local port, ignoring ICMP error"
00397            << endl;
00398         return;
00399     }
00400     SockDescList& list = it->second;
00401     SockDesc *srcSocket = NULL;
00402     for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00403         SockDesc *sd = *it;
00404         if (sd->onlyLocalPortIsSet || matchesSocket(sd, localAddr, remoteAddr, remotePort)) {
00405             srcSocket = sd; // FIXME what to do if there's more than one matching socket ???
00406         }
00407     }
00408     if (!srcSocket) {
00409         EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00410            << "    No matching socket, ignoring ICMP error"
00411            << endl;
00412         return;
00413     }
00414 
00415     // send UDP_I_ERROR to socket
00416     EV << "[SimpleUDP::processICMPError() @ " << localAddr << "]\n"
00417        << "    Source socket is sockId=" << srcSocket->sockId << ", notifying"
00418        << endl;
00419     sendUpErrorNotification(srcSocket, UDP_I_ERROR, localAddr, remoteAddr, remotePort);
00420 }

void SimpleUDP::processUDPPacket ( SimpleUDPPacket *  udpPacket  )  [protected, virtual]

process UDP packets coming from IP

Parameters:
udpPacket the received packet
00438 {
00439     cModule *node = parentModule();
00440     IPvXAddress ip = IPAddressResolver().addressOf(node);
00441 
00442     // simulate checksum: discard packet if it has bit error
00443     EV << "[SimpleUDP::processUDPPacket() @ " << ip << "]\n"
00444        << "    Packet " << udpPacket->name() << " received from network, dest port " << udpPacket->destinationPort()
00445        << endl;
00446 
00447     if (udpPacket->hasBitError()) {
00448         EV << "[SimpleUDP::processUDPPacket() @ " << ip << "]\n"
00449            << "    Packet has bit error, discarding"
00450            << endl;
00451         delete udpPacket;
00452         numDroppedBadChecksum++;
00453         return;
00454     }
00455 
00456     int destPort = udpPacket->destinationPort();
00457     cPolymorphic *ctrl = udpPacket->removeControlInfo();
00458 
00459     // send back ICMP error if no socket is bound to that port
00460     SocketsByPortMap::iterator it = socketsByPortMap.find(destPort);
00461     if (it==socketsByPortMap.end()) {
00462         EV << "[SimpleUDP::processUDPPacket() @ " << ip << "]\n"
00463            << "    No socket registered on port " << destPort
00464            << endl;
00465         processUndeliverablePacket(udpPacket, ctrl);
00466         return;
00467     }
00468     SockDescList& list = it->second;
00469 
00470     int matches = 0;
00471 
00472     // deliver a copy of the packet to each matching socket
00473     //    cMessage *payload = udpPacket->encapsulatedMsg();
00474     cMessage *payload = udpPacket->decapsulate();
00475     if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) {
00476         IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00477         for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00478             SockDesc *sd = *it;
00479             if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4)) {
00480 //              EV << "[SimpleUDP::processUDPPacket() @ " << ip << "]\n"
00481 //                 << "    Socket sockId=" << sd->sockId << " matches, sending up a copy"
00482 //                 << endl;
00483 //              sendUp((cMessage*)payload->dup(), udpPacket, ctrl4, sd);
00484 //              ib: speed hack
00485                 
00486                 if (matches == 0) {
00487                     sendUp(payload, udpPacket, ctrl4, sd);
00488                 } else
00489                     opp_error("Edit SimpleUDP.cc to support multibinding.");
00490                 matches++;
00491             }
00492         }
00493     } else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->controlInfo())
00494                !=NULL) {
00495         IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00496         for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00497             SockDesc *sd = *it;
00498             if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6)) {
00499                 EV << "[SimpleUDP::processUDPPacket() @ " << ip << "]\n"
00500                    << "    Socket sockId=" << sd->sockId << " matches, sending up a copy"
00501                    << endl;
00502                 sendUp((cMessage*)payload->dup(), udpPacket, ctrl6, sd);
00503                 matches++;
00504             }
00505         }
00506     } else {
00507         error("(%s)%s arrived from lower layer without control info", udpPacket->className(), udpPacket->name());
00508     }
00509 
00510     // send back ICMP error if there is no matching socket
00511     if (matches==0) {
00512         EV << "[SimpleUDP::processUDPPacket() @ " << ip << "]\n"
00513            << "    None of the sockets on port " << destPort << " matches the packet"
00514            << endl;
00515         processUndeliverablePacket(udpPacket, ctrl)
00516         ;
00517         return;
00518     }
00519 
00520     delete udpPacket;
00521     delete ctrl;
00522 }

void SimpleUDP::processMsgFromApp ( cMessage *  appData  )  [protected, virtual]

process packets from application

Parameters:
appData the data that has to be sent
00526 {
00527     cModule *node = parentModule();
00528     IPvXAddress ip = IPAddressResolver().addressOf(node);
00529         
00530     IPvXAddress srcAddr, destAddr;
00531     //cGate* destGate;
00532 
00533     UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo());
00534 
00535     SimpleUDPPacket *udpPacket = new SimpleUDPPacket(appData->name());
00536 
00537     //
00538     udpPacket->setByteLength(UDP_HEADER_BYTES + IP_HEADER_BYTES);
00539     udpPacket->encapsulate(appData);
00540 
00541     // set source and destination port
00542     udpPacket->setSourcePort(udpCtrl->srcPort());
00543     udpPacket->setDestinationPort(udpCtrl->destPort());
00544 
00545     srcAddr = udpCtrl->srcAddr();
00546     destAddr = udpCtrl->destAddr();
00547     if (!udpCtrl->destAddr().isIPv6()) {
00548         // send to IPv4
00549         //EV << "[SimpleUDP::processMsgFromApp() @ " << ip << "]\n"
00550         //<< "    Sending app packet " << appData->name() << " over IPv4"
00551         //<< endl;
00552         IPControlInfo *ipControlInfo = new IPControlInfo();
00553         ipControlInfo->setProtocol(IP_PROT_UDP);
00554         ipControlInfo->setSrcAddr(srcAddr.get4());
00555         ipControlInfo->setDestAddr(destAddr.get4());
00556         ipControlInfo->setInterfaceId(udpCtrl->interfaceId());
00557         udpPacket->setControlInfo(ipControlInfo);
00558         delete udpCtrl;
00559     } else {
00560         // send to IPv6
00561         //EV << "[SimpleUDP::processMsgFromApp() @ " << ip << "]\n"
00562         //<< "    Sending app packet " << appData->name() << " over IPv6"
00563         //<< endl;
00564         IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
00565         ipControlInfo->setProtocol(IP_PROT_UDP);
00566         ipControlInfo->setSrcAddr(srcAddr.get6());
00567         ipControlInfo->setDestAddr(destAddr.get6());
00568         // ipControlInfo->setInterfaceId(udpCtrl->InterfaceId()); FIXME extend IPv6 with this!!!
00569         udpPacket->setControlInfo(ipControlInfo);
00570         delete udpCtrl;
00571     }
00572 
00573     SimpleInfo* info = dynamic_cast<SimpleInfo*>(bootstrapOracle->getPeerInfo(destAddr));
00574     numSent++;
00575     if(info == NULL) {
00576         EV << "[SimpleUDP::processMsgFromApp() @ " << ip << "]\n"
00577            << "    No route to host " << destAddr
00578            << endl;
00579         delete udpPacket->removeControlInfo();
00580         delete udpPacket;
00581         return;
00582     }
00583 
00584     SimpleNodeEntry* destEntry = info->getEntry();
00585 
00586     // calculate delay
00587     float totalDelay = 0;
00588     if(srcAddr != destAddr) {
00589         if (useCoordinateBasedDelay == true) {
00590             SimpleNodeEntry::SimpleDelay temp = nodeEntry->calcDelay(*udpPacket, *destEntry);
00591             if (temp.second == false) {
00592                 EV << "[SimpleUDP::processMsgFromApp() @ " << ip << "]\n"
00593                    << "    Send queue full/send error: packet " << udpPacket << " dropped"
00594                    << endl;
00595                 delete udpPacket;
00596                 udpPacket = NULL;
00597             } else
00598                 totalDelay = temp.first;
00599         } else
00600             totalDelay = constantDelay;
00601     }
00602 
00603     if(udpPacket != NULL) {
00604         EV << "[SimpleUDP::processMsgFromApp() @ " << ip << "]\n"
00605            << "    Packet " << udpPacket << " sent with delay = " << totalDelay
00606            << endl;
00607         sendDirect(udpPacket, totalDelay, destEntry->getGate());
00608     }
00609 }

void SimpleUDP::processCommandFromApp ( cMessage *  msg  )  [protected, virtual]

process commands from application

Parameters:
msg the command message
00612 {
00613     UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
00614     switch (msg->kind()) {
00615     case UDP_C_BIND:
00616         bind(msg->arrivalGate()->index(), udpCtrl);
00617         break;
00618     case UDP_C_CONNECT:
00619         connect(udpCtrl->sockId(), udpCtrl->destAddr(), udpCtrl->destPort());
00620         break;
00621     case UDP_C_UNBIND:
00622         unbind(udpCtrl->sockId());
00623         break;
00624     default:
00625         error("unknown command code (message kind) %d received from app", msg->kind());
00626     }
00627 
00628     delete udpCtrl;
00629     delete msg;
00630 }

void SimpleUDP::initialize ( int  stage  )  [protected, virtual]

initialise the SimpleUDP module

Parameters:
stage stage of initialisation phase
00093 {
00094     if(stage == MIN_STAGE_UNDERLAY) {
00095         WATCH_PTRMAP(socketsByIdMap);
00096         WATCH_MAP(socketsByPortMap);
00097 
00098         lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00099         icmp = NULL;
00100         icmpv6 = NULL;
00101 
00102         numSent = 0;
00103         numPassedUp = 0;
00104         numDroppedWrongPort = 0;
00105         numDroppedBadChecksum = 0;
00106         WATCH(numSent);
00107         WATCH(numPassedUp);
00108         WATCH(numDroppedWrongPort);
00109         WATCH(numDroppedBadChecksum);
00110 
00111         //} else if (stage == MAX_STAGE_UNDERLAY) {
00112         bootstrapOracle = BootstrapOracleAccess().get();
00113         constantDelay = par("constantDelay");
00114         useCoordinateBasedDelay = par("useCoordinateBasedDelay");
00115         nodeEntry = NULL;
00116         WATCH_PTR(nodeEntry);
00117     }
00118 }

virtual int SimpleUDP::numInitStages ( void   )  const [inline, protected, virtual]

returns the number of init stages

Returns:
the number of init stages
00266     {
00267         return MAX_STAGE_UNDERLAY + 1;
00268     }

void SimpleUDP::handleMessage ( cMessage *  msg  )  [protected, virtual]

process received messages

Parameters:
msg the received message
00227 {
00228     // received from the network layer
00229     if (msg->arrivedOn("network_in")) {
00230         if (dynamic_cast<ICMPMessage *>(msg) || dynamic_cast<ICMPv6Message *>(msg))
00231             processICMPError(msg);
00232         else
00233             processUDPPacket(check_and_cast<SimpleUDPPacket *>(msg));
00234     } else // received from application layer
00235     {
00236         if (msg->kind()==UDP_C_DATA)
00237             processMsgFromApp(msg);
00238         else
00239             processCommandFromApp(msg);
00240     }
00241 
00242     if (ev.isGUI())
00243         updateDisplayString();
00244 }


Member Data Documentation

SocketsByIdMap SimpleUDP::socketsByIdMap [protected]

list of socket ordered by sockId

SocketsByPortMap SimpleUDP::socketsByPortMap [protected]

list of sockets ordered by localPort

short SimpleUDP::lastEphemeralPort [protected]

last used port (all ports above should be free)

ICMP* SimpleUDP::icmp [protected]

pointer to a received icmp (IPv4) message

ICMPv6* SimpleUDP::icmpv6 [protected]

pointer to a received icmp (IPv6) message

int SimpleUDP::numSent [protected]

number of packets sent to the network

int SimpleUDP::numPassedUp [protected]

number of packet passed up to applications

int SimpleUDP::numDroppedWrongPort [protected]

number of dropped packets due to wrong destination port

int SimpleUDP::numDroppedBadChecksum [protected]

number of dropped packets due to bad checksum

simtime_t SimpleUDP::delay [protected]

simulated delay between sending and receiving udp module

simtime_t SimpleUDP::constantDelay [protected]

constant delay between two peers

bool SimpleUDP::useCoordinateBasedDelay [protected]

delay should be calculated from euklidean distance between two peers

BootstrapOracle* SimpleUDP::bootstrapOracle [protected]

pointer to BootstrapOracle

SimpleNodeEntry* SimpleUDP::nodeEntry [protected]

nodeEntry of the overlay node this module belongs to


The documentation for this class was generated from the following files:
Generated on Wed Sep 26 12:13:02 2007 for ITM OverSim by  doxygen 1.5.1