#include <SimpleUDP.h>
More info in the NED file.
Public Types | |
typedef std::list< SockDesc * > | SockDescList |
typedef std::map< int, SockDesc * > | SocketsByIdMap |
typedef std::map< int, SockDescList > | SocketsByPortMap |
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 |
GlobalRoutingHashMap * | routingHashMap |
SimpleNodeEntry * | nodeEntry |
Classes | |
struct | SockDesc |
typedef std::list<SockDesc *> SimpleUDP::SockDescList |
typedef std::map<int,SockDesc *> SimpleUDP::SocketsByIdMap |
typedef std::map<int,SockDescList> SimpleUDP::SocketsByPortMap |
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 }
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] |
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] |
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 }
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] |