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
typedef std::map< int, SockDesc * > SocketsByIdMap
typedef std::map< int, SockDescListSocketsByPortMap

Public Member Functions

void setNodeEntry (const SimpleNodeEntry &entry)
 SimpleUDP ()
virtual ~SimpleUDP ()

Protected Member Functions

void updateDisplayString ()
void bind (int gateIndex, UDPControlInfo *ctrl)
void connect (int sockId, IPvXAddress addr, int port)
void unbind (int sockId)
short getEphemeralPort ()
bool matchesSocket (SockDesc *sd, SimpleUDPPacket *udp, IPControlInfo *ctrl)
bool matchesSocket (SockDesc *sd, SimpleUDPPacket *udp, IPv6ControlInfo *ctrl)
bool matchesSocket (SockDesc *sd, const IPvXAddress &localAddr, const IPvXAddress &remoteAddr, short remotePort)
void sendUp (cMessage *payload, SimpleUDPPacket *udpHeader, IPControlInfo *ctrl, SockDesc *sd)
void sendUp (cMessage *payload, SimpleUDPPacket *udpHeader, IPv6ControlInfo *ctrl, SockDesc *sd)
void processUndeliverablePacket (SimpleUDPPacket *udpPacket, cPolymorphic *ctrl)
void sendUpErrorNotification (SockDesc *sd, int msgkind, const IPvXAddress &localAddr, const IPvXAddress &remoteAddr, short remotePort)
virtual void processICMPError (cMessage *icmpErrorMsg)
virtual void processUDPPacket (SimpleUDPPacket *udpPacket)
virtual void processMsgFromApp (cMessage *appData)
virtual void processCommandFromApp (cMessage *msg)
virtual void initialize (int stage)
virtual int numInitStages () const
virtual void handleMessage (cMessage *msg)

Protected Attributes

SocketsByIdMap socketsByIdMap
SocketsByPortMap socketsByPortMap
short lastEphemeralPort
ICMP * icmp
ICMPv6 * icmpv6
int numSent
int numPassedUp
int numDroppedWrongPort
int numDroppedBadChecksum
simtime_t delay
simtime_t constantDelay
bool useCoordinateBasedDelay
GlobalRoutingHashMaproutingHashMap
SimpleNodeEntrynodeEntry

Classes

struct  SockDesc


Member Typedef Documentation

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

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

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


Constructor & Destructor Documentation

SimpleUDP::SimpleUDP (  )  [inline]

00134     {}

SimpleUDP::~SimpleUDP (  )  [virtual]

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


Member Function Documentation

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

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

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

00157 {
00158     SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00159     if (it==socketsByIdMap.end())
00160         error("socket id=%d doesn't exist (already closed?)", sockId);
00161     if (addr.isUnspecified())
00162         opp_error("connect: unspecified remote address");
00163     if (port<=0 || port>65535)
00164         opp_error("connect: invalid remote port number %d", port);
00165 
00166     SockDesc *sd = it->second;
00167     sd->remoteAddr = addr;
00168     sd->remotePort = port;
00169 
00170     sd->onlyLocalPortIsSet = false;
00171 
00172     EV << "Connecting socket: " << *sd << "\n";
00173 }

short SimpleUDP::getEphemeralPort (  )  [protected]

00199 {
00200     // start at the last allocated port number + 1, and search for an unused one
00201     short searchUntil = lastEphemeralPort++;
00202     if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END) // wrap
00203         lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00204 
00205     while (socketsByPortMap.find(lastEphemeralPort)!=socketsByPortMap.end()) {
00206         if (lastEphemeralPort == searchUntil) // got back to starting point?
00207             error("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
00208         lastEphemeralPort++;
00209         if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END) // wrap
00210             lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00211     }
00212 
00213     // found a free one, return it
00214     return lastEphemeralPort;
00215 }

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

00218 {
00219     // received from the network layer
00220     if (msg->arrivedOn("network_in")) {
00221         if (dynamic_cast<ICMPMessage *>(msg) || dynamic_cast<ICMPv6Message *>(msg))
00222             processICMPError(msg);
00223         else
00224             processUDPPacket(check_and_cast<SimpleUDPPacket *>(msg));
00225     } else // received from application layer
00226     {
00227         if (msg->kind()==UDP_C_DATA)
00228             processMsgFromApp(msg);
00229         else
00230             processCommandFromApp(msg);
00231     }
00232 
00233     if (ev.isGUI())
00234         updateDisplayString();
00235 }

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

00090 {
00091     if(stage == MIN_STAGE_UNDERLAY) {
00092         WATCH_PTRMAP(socketsByIdMap);
00093         WATCH_MAP(socketsByPortMap);
00094 
00095         lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
00096         icmp = NULL;
00097         icmpv6 = NULL;
00098 
00099         numSent = 0;
00100         numPassedUp = 0;
00101         numDroppedWrongPort = 0;
00102         numDroppedBadChecksum = 0;
00103         WATCH(numSent);
00104         WATCH(numPassedUp);
00105         WATCH(numDroppedWrongPort);
00106         WATCH(numDroppedBadChecksum);
00107 
00108         //} else if (stage == MAX_STAGE_UNDERLAY) {
00109         routingHashMap = GlobalRoutingHashMapAccess().get();
00110         constantDelay = par("constantDelay");
00111         useCoordinateBasedDelay = par("useCoordinateBasedDelay");
00112         nodeEntry = NULL;
00113         WATCH_PTR(nodeEntry);
00114         if (!routingHashMap)
00115             error("Did not find the routingHashMap. Aborting...");
00116     }
00117 }

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

00277 {
00278     return (sd->remotePort==0 || sd->remotePort!=remotePort) &&
00279            (sd->localAddr.isUnspecified() || sd->localAddr==localAddr) &&
00280            (sd->remoteAddr.isUnspecified() || sd->remoteAddr==remoteAddr);
00281 }

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

00263 {
00264     // IPv6 version
00265     if (sd->remotePort!=0 && sd->remotePort!=udp->sourcePort())
00266         return false;
00267     if (!sd->localAddr.isUnspecified() && sd->localAddr.get6()!=ipCtrl->destAddr())
00268         return false;
00269     if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get6()!=ipCtrl->srcAddr())
00270         return false;
00271     if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->interfaceId())
00272         return false;
00273     return true;
00274 }

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

00249 {
00250     // IPv4 version
00251     if (sd->remotePort!=0 && sd->remotePort!=udp->sourcePort())
00252         return false;
00253     if (!sd->localAddr.isUnspecified() && sd->localAddr.get4()!=ipCtrl->destAddr())
00254         return false;
00255     if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get4()!=ipCtrl->srcAddr())
00256         return false;
00257     if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->interfaceId())
00258         return false;
00259     return true;
00260 }

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

00140     {
00141         return MAX_STAGE_UNDERLAY + 1;
00142     }

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

00564 {
00565     UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
00566     switch (msg->kind()) {
00567     case UDP_C_BIND:
00568         bind(msg->arrivalGate()->index(), udpCtrl);
00569         break;
00570     case UDP_C_CONNECT:
00571         connect(udpCtrl->sockId(), udpCtrl->destAddr(), udpCtrl->destPort());
00572         break;
00573     case UDP_C_UNBIND:
00574         unbind(udpCtrl->sockId());
00575         break;
00576     default:
00577         error("unknown command code (message kind) %d received from app", msg->kind());
00578     }
00579 
00580     delete udpCtrl;
00581     delete msg;
00582 }

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

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

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

00492 {
00493     IPvXAddress srcAddr, destAddr;
00494     //cGate* destGate;
00495 
00496     UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo());
00497 
00498     SimpleUDPPacket *udpPacket = new SimpleUDPPacket(appData->name());
00499 
00500     //
00501     udpPacket->setByteLength(UDP_HEADER_BYTES + IP_HEADER_BYTES);
00502     udpPacket->encapsulate(appData);
00503 
00504     // set source and destination port
00505     udpPacket->setSourcePort(udpCtrl->srcPort());
00506     udpPacket->setDestinationPort(udpCtrl->destPort());
00507 
00508     srcAddr = udpCtrl->srcAddr();
00509     destAddr = udpCtrl->destAddr();
00510     if (!udpCtrl->destAddr().isIPv6()) {
00511         // send to IPv4
00512         EV << "Sending app packet " << appData->name() << " over IPv4.\n";
00513         IPControlInfo *ipControlInfo = new IPControlInfo();
00514         ipControlInfo->setProtocol(IP_PROT_UDP);
00515         ipControlInfo->setSrcAddr(srcAddr.get4());
00516         ipControlInfo->setDestAddr(destAddr.get4());
00517         ipControlInfo->setInterfaceId(udpCtrl->interfaceId());
00518         udpPacket->setControlInfo(ipControlInfo);
00519         delete udpCtrl;
00520     } else {
00521         // send to IPv6
00522         EV << "Sending app packet " << appData->name() << " over IPv6.\n";
00523         IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
00524         ipControlInfo->setProtocol(IP_PROT_UDP);
00525         ipControlInfo->setSrcAddr(srcAddr.get6());
00526         ipControlInfo->setDestAddr(destAddr.get6());
00527         // ipControlInfo->setInterfaceId(udpCtrl->InterfaceId()); FIXME extend IPv6 with this!!!
00528         udpPacket->setControlInfo(ipControlInfo);
00529         delete udpCtrl;
00530     }
00531 
00532     SimpleNodeEntry* destEntry = routingHashMap->findEntryForAddress(destAddr);
00533 
00534     numSent++;
00535     if(destEntry == NULL) {
00536         EV << "No route to host " << destAddr << "!\n";
00537         delete udpPacket->removeControlInfo();
00538         delete udpPacket;
00539         return;
00540     }
00541 
00542     // calculate delay
00543     float totalDelay = 0;
00544     if(srcAddr != destAddr) {
00545         if (useCoordinateBasedDelay == true) {
00546             SimpleNodeEntry::SimpleDelay temp = nodeEntry->calcDelay(*udpPacket, *destEntry);
00547             if (temp.second == false) {
00548                 EV << "(SimpleUDP) send queue full/send error: packet " << udpPacket << " dropped!" << endl;
00549                 delete udpPacket;
00550                 udpPacket = NULL;
00551             } else
00552                 totalDelay = temp.first;
00553         } else
00554             totalDelay = constantDelay;
00555     }
00556 
00557     if(udpPacket != NULL) {
00558         EV << "(SimpleUDP) packet " << udpPacket << " sent with delay = " << totalDelay << endl;
00559         sendDirect(udpPacket, totalDelay, destEntry->getGate());
00560     }
00561 }

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

00421 {
00422     // simulate checksum: discard packet if it has bit error
00423     EV << "Packet " << udpPacket->name() << " received from network, dest port " << udpPacket->destinationPort() << "\n";
00424     if (udpPacket->hasBitError()) {
00425         EV << "Packet has bit error, discarding\n";
00426         delete udpPacket;
00427         numDroppedBadChecksum++;
00428         return;
00429     }
00430 
00431     int destPort = udpPacket->destinationPort();
00432     cPolymorphic *ctrl = udpPacket->removeControlInfo();
00433 
00434     // send back ICMP error if no socket is bound to that port
00435     SocketsByPortMap::iterator it = socketsByPortMap.find(destPort);
00436     if (it==socketsByPortMap.end()) {
00437         EV << "No socket registered on port " << destPort << "\n";
00438         processUndeliverablePacket(udpPacket, ctrl);
00439         return;
00440     }
00441     SockDescList& list = it->second;
00442 
00443     int matches = 0;
00444 
00445     // deliver a copy of the packet to each matching socket
00446     //    cMessage *payload = udpPacket->encapsulatedMsg();
00447     cMessage *payload = udpPacket->decapsulate();
00448     if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) {
00449         IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00450         for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00451             SockDesc *sd = *it;
00452             if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4)) {
00453                 //                EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n";
00454                 //                sendUp((cMessage*)payload->dup(), udpPacket, ctrl4, sd);
00455                 // ib: speed hack
00456                 if (matches == 0) {
00457                     sendUp(payload, udpPacket, ctrl4, sd);
00458                 } else
00459                     opp_error("Edit SimpleUDP.cc to support multibinding.");
00460                 matches++;
00461             }
00462         }
00463     } else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->controlInfo())
00464                !=NULL) {
00465         IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00466         for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it) {
00467             SockDesc *sd = *it;
00468             if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6)) {
00469                 //                EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n";
00470                 sendUp((cMessage*)payload->dup(), udpPacket, ctrl6, sd);
00471                 matches++;
00472             }
00473         }
00474     } else {
00475         error("(%s)%s arrived from lower layer without control info", udpPacket->className(), udpPacket->name());
00476     }
00477 
00478     // send back ICMP error if there is no matching socket
00479     if (matches==0) {
00480         EV << "None of the sockets on port " << destPort << " matches the packet\n";
00481         processUndeliverablePacket(udpPacket, ctrl)
00482         ;
00483         return;
00484     }
00485 
00486     delete udpPacket;
00487     delete ctrl;
00488 }

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

00318 {
00319     numDroppedWrongPort++;
00320 
00321     // send back ICMP PORT_UNREACHABLE
00322     if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL) {
00323         if (!icmp)
00324             icmp = ICMPAccess().get();
00325         IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
00326         if (!ctrl4->destAddr().isMulticast())
00327             icmp->sendErrorMessage(udpPacket, ctrl4, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PORT_UNREACHABLE);
00328     } else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->controlInfo())
00329                !=NULL) {
00330         if (!icmpv6)
00331             icmpv6 = ICMPv6Access().get();
00332         IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
00333         if (!ctrl6->destAddr().isMulticast())
00334             icmpv6->sendErrorMessage(udpPacket, ctrl6, ICMPv6_DESTINATION_UNREACHABLE, PORT_UNREACHABLE);
00335     } else {
00336         error("(%s)%s arrived from lower layer without control info", udpPacket->className(), udpPacket->name());
00337     }
00338 }

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

00301 {
00302     // send payload with UDPControlInfo up to the application -- IPv6 version
00303     UDPControlInfo *udpCtrl = new UDPControlInfo();
00304     udpCtrl->setSockId(sd->sockId);
00305     udpCtrl->setUserId(sd->userId);
00306     udpCtrl->setSrcAddr(ipCtrl->srcAddr());
00307     udpCtrl->setDestAddr(ipCtrl->destAddr());
00308     udpCtrl->setSrcPort(udpHeader->sourcePort());
00309     udpCtrl->setDestPort(udpHeader->destinationPort());
00310     udpCtrl->setInterfaceId(ipCtrl->interfaceId());
00311     payload->setControlInfo(udpCtrl);
00312 
00313     send(payload, "to_app", sd->appGateIndex);
00314     numPassedUp++;
00315 }

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

00284 {
00285     // send payload with UDPControlInfo up to the application -- IPv4 version
00286     UDPControlInfo *udpCtrl = new UDPControlInfo();
00287     udpCtrl->setSockId(sd->sockId);
00288     udpCtrl->setUserId(sd->userId);
00289     udpCtrl->setSrcAddr(ipCtrl->srcAddr());
00290     udpCtrl->setDestAddr(ipCtrl->destAddr());
00291     udpCtrl->setSrcPort(udpHeader->sourcePort());
00292     udpCtrl->setDestPort(udpHeader->destinationPort());
00293     udpCtrl->setInterfaceId(ipCtrl->interfaceId());
00294     payload->setControlInfo(udpCtrl);
00295 
00296     send(payload, "to_app", sd->appGateIndex);
00297     numPassedUp++;
00298 }

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

00406 {
00407     cMessage *notifyMsg = new cMessage("ERROR", msgkind);
00408     UDPControlInfo *udpCtrl = new UDPControlInfo();
00409     udpCtrl->setSockId(sd->sockId);
00410     udpCtrl->setUserId(sd->userId);
00411     udpCtrl->setSrcAddr(localAddr);
00412     udpCtrl->setDestAddr(remoteAddr);
00413     udpCtrl->setSrcPort(sd->localPort);
00414     udpCtrl->setDestPort(remotePort);
00415     notifyMsg->setControlInfo(udpCtrl);
00416 
00417     send(notifyMsg, "to_app", sd->appGateIndex);
00418 }

void SimpleUDP::setNodeEntry ( const SimpleNodeEntry entry  ) 

00586 {
00587     if(nodeEntry != NULL)
00588         delete nodeEntry;
00589     nodeEntry = new SimpleNodeEntry(entry);
00590 }

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

00176 {
00177     // remove from socketsByIdMap
00178     SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
00179     if (it==socketsByIdMap.end())
00180         error("socket id=%d doesn't exist (already closed?)", sockId);
00181     SockDesc *sd = it->second;
00182     socketsByIdMap.erase(it);
00183 
00184     EV << "Unbinding socket: " << *sd << "\n";
00185 
00186     // remove from socketsByPortMap
00187     SockDescList& list = socketsByPortMap[sd->localPort];
00188     for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
00189         if (*it == sd) {
00190             list.erase(it);
00191             break;
00192         }
00193     if (list.empty())
00194         socketsByPortMap.erase(sd->localPort);
00195     delete sd;
00196 }

void SimpleUDP::updateDisplayString (  )  [protected]

00238 {
00239     char buf[80];
00240     sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
00241     if (numDroppedWrongPort>0) {
00242         sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
00243         displayString().setTagArg("i",1,"red");
00244     }
00245     displayString().setTagArg("t",0,buf);
00246 }


Member Data Documentation

simtime_t SimpleUDP::constantDelay [protected]

simtime_t SimpleUDP::delay [protected]

ICMP* SimpleUDP::icmp [protected]

ICMPv6* SimpleUDP::icmpv6 [protected]

short SimpleUDP::lastEphemeralPort [protected]

SimpleNodeEntry* SimpleUDP::nodeEntry [protected]

int SimpleUDP::numDroppedBadChecksum [protected]

int SimpleUDP::numDroppedWrongPort [protected]

int SimpleUDP::numPassedUp [protected]

int SimpleUDP::numSent [protected]

GlobalRoutingHashMap* SimpleUDP::routingHashMap [protected]

SocketsByIdMap SimpleUDP::socketsByIdMap [protected]

SocketsByPortMap SimpleUDP::socketsByPortMap [protected]

bool SimpleUDP::useCoordinateBasedDelay [protected]


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:37:06 2007 for ITM OverSim by  doxygen 1.4.7