INET Framework for OMNeT++/OMNEST
inet::UDP Class Reference

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

#include <UDP.h>

Inheritance diagram for inet::UDP:
inet::ILifecycle

Classes

struct  MulticastMembership
 
struct  SockDesc
 

Public Types

enum  PortRange { EPHEMERAL_PORTRANGE_START = 1024, EPHEMERAL_PORTRANGE_END = 5000 }
 
typedef std::vector< MulticastMembership * > MulticastMembershipTable
 
typedef std::list< SockDesc * > SockDescList
 
typedef std::map< int, SockDesc * > SocketsByIdMap
 
typedef std::map< int, SockDescListSocketsByPortMap
 

Public Member Functions

 UDP ()
 
virtual ~UDP ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Member Functions

virtual void refreshDisplay () const override
 
virtual SockDescgetSocketById (int sockId)
 
virtual SockDescgetOrCreateSocket (int sockId, int gateIndex)
 
virtual SockDesccreateSocket (int sockId, int gateIndex, const L3Address &localAddr, int localPort)
 
virtual void bind (int sockId, int gateIndex, const L3Address &localAddr, int localPort)
 
virtual void connect (int sockId, int gateIndex, const L3Address &remoteAddr, int remotePort)
 
virtual void close (int sockId)
 
virtual void clearAllSockets ()
 
virtual void setTimeToLive (SockDesc *sd, int ttl)
 
virtual void setTypeOfService (SockDesc *sd, int typeOfService)
 
virtual void setBroadcast (SockDesc *sd, bool broadcast)
 
virtual void setMulticastOutputInterface (SockDesc *sd, int interfaceId)
 
virtual void setMulticastLoop (SockDesc *sd, bool loop)
 
virtual void setReuseAddress (SockDesc *sd, bool reuseAddr)
 
virtual void joinMulticastGroups (SockDesc *sd, const std::vector< L3Address > &multicastAddresses, const std::vector< int > interfaceIds)
 
virtual void leaveMulticastGroups (SockDesc *sd, const std::vector< L3Address > &multicastAddresses)
 
virtual void blockMulticastSources (SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
 
virtual void unblockMulticastSources (SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
 
virtual void joinMulticastSources (SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
 
virtual void leaveMulticastSources (SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
 
virtual void setMulticastSourceFilter (SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, UDPSourceFilterMode filterMode, const std::vector< L3Address > &sourceList)
 
virtual void addMulticastAddressToInterface (InterfaceEntry *ie, const L3Address &multicastAddr)
 
virtual ushort getEphemeralPort ()
 
virtual SockDescfindSocketForUnicastPacket (const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort)
 
virtual std::vector< SockDesc * > findSocketsForMcastBcastPacket (const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort, bool isMulticast, bool isBroadcast)
 
virtual SockDescfindFirstSocketByLocalAddress (const L3Address &localAddr, ushort localPort)
 
virtual void sendUp (cPacket *payload, SockDesc *sd, const L3Address &srcAddr, ushort srcPort, const L3Address &destAddr, ushort destPort, int interfaceId, int ttl, unsigned char tos)
 
virtual void sendDown (cPacket *appData, const L3Address &srcAddr, ushort srcPort, const L3Address &destAddr, ushort destPort, int interfaceId, bool multicastLoop, int ttl, unsigned char tos)
 
virtual void processUndeliverablePacket (UDPPacket *udpPacket, cObject *ctrl)
 
virtual void sendUpErrorIndication (SockDesc *sd, const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort)
 
virtual void processICMPError (cPacket *icmpErrorMsg)
 
virtual void processUDPPacket (UDPPacket *udpPacket)
 
virtual void processPacketFromApp (cPacket *appData)
 
virtual void processCommandFromApp (cMessage *msg)
 
virtual UDPPacketcreateUDPPacket (const char *name)
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 

Protected Attributes

SocketsByIdMap socketsByIdMap
 
SocketsByPortMap socketsByPortMap
 
ushort lastEphemeralPort = EPHEMERAL_PORTRANGE_START
 
IInterfaceTableift = nullptr
 
ICMPicmp = nullptr
 
ICMPv6icmpv6 = nullptr
 
int numSent = 0
 
int numPassedUp = 0
 
int numDroppedWrongPort = 0
 
int numDroppedBadChecksum = 0
 
bool isOperational = false
 

Static Protected Attributes

static simsignal_t rcvdPkSignal = registerSignal("rcvdPk")
 
static simsignal_t sentPkSignal = registerSignal("sentPk")
 
static simsignal_t passedUpPkSignal = registerSignal("passedUpPk")
 
static simsignal_t droppedPkWrongPortSignal = registerSignal("droppedPkWrongPort")
 
static simsignal_t droppedPkBadChecksumSignal = registerSignal("droppedPkBadChecksum")
 

Detailed Description

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

More info in the NED file.

Member Typedef Documentation

typedef std::list<SockDesc *> inet::UDP::SockDescList
typedef std::map<int, SockDesc *> inet::UDP::SocketsByIdMap
typedef std::map<int, SockDescList> inet::UDP::SocketsByPortMap

Member Enumeration Documentation

Enumerator
EPHEMERAL_PORTRANGE_START 
EPHEMERAL_PORTRANGE_END 
49  {
52  };

Constructor & Destructor Documentation

inet::UDP::UDP ( )
110 {
111 }
inet::UDP::~UDP ( )
virtual
114 {
115  clearAllSockets();
116 }
virtual void clearAllSockets()
Definition: UDP.cc:628

Member Function Documentation

void inet::UDP::addMulticastAddressToInterface ( InterfaceEntry ie,
const L3Address multicastAddr 
)
protectedvirtual

Referenced by joinMulticastGroups().

933 {
934  ASSERT(ie && ie->isMulticast());
935  ASSERT(multicastAddr.isMulticast());
936 
937  if (multicastAddr.getType() == L3Address::IPv4) {
938 #ifdef WITH_IPv4
939  ie->ipv4Data()->joinMulticastGroup(multicastAddr.toIPv4());
940 #endif // ifdef WITH_IPv4
941  }
942  else if (multicastAddr.getType() == L3Address::IPv6) {
943 #ifdef WITH_IPv6
944  ie->ipv6Data()->assignAddress(multicastAddr.toIPv6(), false, SimTime::getMaxTime(), SimTime::getMaxTime());
945 #endif // ifdef WITH_IPv6
946  }
947  else
948  ie->joinMulticastGroup(multicastAddr);
949 }
Definition: L3Address.h:47
Definition: L3Address.h:46
void inet::UDP::bind ( int  sockId,
int  gateIndex,
const L3Address localAddr,
int  localPort 
)
protectedvirtual

Referenced by processCommandFromApp().

536 {
537  if (sockId == -1)
538  throw cRuntimeError("sockId in BIND message not filled in");
539 
540  if (localPort < -1 || localPort > 65535) // -1: ephemeral port
541  throw cRuntimeError("bind: invalid local port number %d", localPort);
542 
543  auto it = socketsByIdMap.find(sockId);
544  SockDesc *sd = it != socketsByIdMap.end() ? it->second : nullptr;
545 
546  // to allow two sockets to bind to the same address/port combination
547  // both of them must have reuseAddr flag set
548  SockDesc *existing = findFirstSocketByLocalAddress(localAddr, localPort);
549  if (existing != nullptr && (!sd || !sd->reuseAddr || !existing->reuseAddr))
550  throw cRuntimeError("bind: local address/port %s:%u already taken", localAddr.str().c_str(), localPort);
551 
552  if (sd) {
553  if (sd->isBound)
554  throw cRuntimeError("bind: socket is already bound (sockId=%d)", sockId);
555 
556  sd->isBound = true;
557  sd->localAddr = localAddr;
558  if (localPort != -1 && sd->localPort != localPort) {
559  socketsByPortMap[sd->localPort].remove(sd);
560  sd->localPort = localPort;
561  socketsByPortMap[sd->localPort].push_back(sd);
562  }
563  }
564  else {
565  sd = createSocket(sockId, gateIndex, localAddr, localPort);
566  sd->isBound = true;
567  }
568 }
virtual SockDesc * findFirstSocketByLocalAddress(const L3Address &localAddr, ushort localPort)
Definition: UDP.cc:660
virtual SockDesc * createSocket(int sockId, int gateIndex, const L3Address &localAddr, int localPort)
Definition: UDP.cc:585
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
void inet::UDP::blockMulticastSources ( SockDesc sd,
InterfaceEntry ie,
L3Address  multicastAddress,
const std::vector< L3Address > &  sourceList 
)
protectedvirtual

Referenced by processCommandFromApp().

985 {
986  ASSERT(ie && ie->isMulticast());
987  ASSERT(multicastAddress.isMulticast());
988 
989  MulticastMembership *membership = sd->findMulticastMembership(multicastAddress, ie->getInterfaceId());
990  if (!membership)
991  throw cRuntimeError("UDP::blockMulticastSources(): not a member of %s group on interface '%s'",
992  multicastAddress.str().c_str(), ie->getFullName());
993 
994  if (membership->filterMode != UDP_EXCLUDE_MCAST_SOURCES)
995  throw cRuntimeError("UDP::blockMulticastSources(): socket was not joined to all sources of %s group on interface '%s'",
996  multicastAddress.str().c_str(), ie->getFullName());
997 
998  std::vector<L3Address> oldSources(membership->sourceList);
999  std::vector<L3Address>& excludedSources = membership->sourceList;
1000  bool changed = false;
1001  for (auto & elem : sourceList) {
1002  const L3Address& sourceAddress = elem;
1003  auto it = std::find(excludedSources.begin(), excludedSources.end(), sourceAddress);
1004  if (it != excludedSources.end()) {
1005  excludedSources.push_back(sourceAddress);
1006  changed = true;
1007  }
1008  }
1009 
1010  if (changed) {
1011  ie->changeMulticastGroupMembership(multicastAddress, MCAST_EXCLUDE_SOURCES, oldSources, MCAST_EXCLUDE_SOURCES, excludedSources);
1012  }
1013 }
Definition: UDPControlInfo_m.h:1132
Definition: InterfaceEntry.h:44
std::vector< T >::iterator find(std::vector< T > &v, const T &a)
Definition: stlutils.h:48
void inet::UDP::clearAllSockets ( )
protectedvirtual

Referenced by handleOperationStage(), and ~UDP().

629 {
630  EV_INFO << "Clear all sockets\n";
631 
632  for (auto & elem : socketsByPortMap) {
633  elem.second.clear();
634  }
635  socketsByPortMap.clear();
636  for (auto & elem : socketsByIdMap)
637  delete elem.second;
638  socketsByIdMap.clear();
639 }
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
void inet::UDP::close ( int  sockId)
protectedvirtual

Referenced by processCommandFromApp().

606 {
607  // remove from socketsByIdMap
608  auto it = socketsByIdMap.find(sockId);
609  if (it == socketsByIdMap.end())
610  throw cRuntimeError("socket id=%d doesn't exist (already closed?)", sockId);
611  SockDesc *sd = it->second;
612  socketsByIdMap.erase(it);
613 
614  EV_INFO << "Closing socket: " << *sd << "\n";
615 
616  // remove from socketsByPortMap
617  SockDescList& list = socketsByPortMap[sd->localPort];
618  for (auto it = list.begin(); it != list.end(); ++it)
619  if (*it == sd) {
620  list.erase(it);
621  break;
622  }
623  if (list.empty())
624  socketsByPortMap.erase(sd->localPort);
625  delete sd;
626 }
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
std::list< SockDesc * > SockDescList
Definition: UDP.h:94
void inet::UDP::connect ( int  sockId,
int  gateIndex,
const L3Address remoteAddr,
int  remotePort 
)
protectedvirtual

Referenced by processCommandFromApp().

571 {
572  if (remoteAddr.isUnspecified())
573  throw cRuntimeError("connect: unspecified remote address");
574  if (remotePort <= 0 || remotePort > 65535)
575  throw cRuntimeError("connect: invalid remote port number %d", remotePort);
576 
577  SockDesc *sd = getOrCreateSocket(sockId, gateIndex);
578  sd->remoteAddr = remoteAddr;
579  sd->remotePort = remotePort;
580  sd->onlyLocalPortIsSet = false;
581 
582  EV_INFO << "Socket connected: " << *sd << "\n";
583 }
virtual SockDesc * getOrCreateSocket(int sockId, int gateIndex)
Definition: UDP.cc:850
UDP::SockDesc * inet::UDP::createSocket ( int  sockId,
int  gateIndex,
const L3Address localAddr,
int  localPort 
)
protectedvirtual

Referenced by bind(), and getOrCreateSocket().

586 {
587  // create and fill in SockDesc
588  SockDesc *sd = new SockDesc(sockId, gateIndex);
589  sd->isBound = false;
590  sd->localAddr = localAddr;
591  sd->localPort = localPort == -1 ? getEphemeralPort() : localPort;
592  sd->onlyLocalPortIsSet = sd->localAddr.isUnspecified();
593 
594  // add to socketsByIdMap
595  socketsByIdMap[sockId] = sd;
596 
597  // add to socketsByPortMap
598  SockDescList& list = socketsByPortMap[sd->localPort]; // create if doesn't exist
599  list.push_back(sd);
600 
601  EV_INFO << "Socket created: " << *sd << "\n";
602  return sd;
603 }
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
virtual ushort getEphemeralPort()
Definition: UDP.cc:641
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
std::list< SockDesc * > SockDescList
Definition: UDP.h:94
UDPPacket * inet::UDP::createUDPPacket ( const char *  name)
protectedvirtual

Referenced by sendDown().

838 {
839  return new UDPPacket(name);
840 }
UDP::SockDesc * inet::UDP::findFirstSocketByLocalAddress ( const L3Address localAddr,
ushort  localPort 
)
protectedvirtual

Referenced by bind().

661 {
662  auto it = socketsByPortMap.find(localPort);
663  if (it == socketsByPortMap.end())
664  return nullptr;
665 
666  SockDescList& list = it->second;
667  for (auto sd : list) {
668  if (sd->localAddr.isUnspecified() || sd->localAddr == localAddr)
669  return sd;
670  }
671  return nullptr;
672 }
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
std::list< SockDesc * > SockDescList
Definition: UDP.h:94
UDP::SockDesc * inet::UDP::findSocketForUnicastPacket ( const L3Address localAddr,
ushort  localPort,
const L3Address remoteAddr,
ushort  remotePort 
)
protectedvirtual

Referenced by processICMPError(), and processUDPPacket().

675 {
676  auto it = socketsByPortMap.find(localPort);
677  if (it == socketsByPortMap.end())
678  return nullptr;
679 
680  // select the socket bound to ANY_ADDR only if there is no socket bound to localAddr
681  SockDescList& list = it->second;
682  SockDesc *socketBoundToAnyAddress = nullptr;
683  for (SockDescList::reverse_iterator it = list.rbegin(); it != list.rend(); ++it) {
684  SockDesc *sd = *it;
685  if (sd->onlyLocalPortIsSet || (
686  (sd->remotePort == -1 || sd->remotePort == remotePort) &&
687  (sd->localAddr.isUnspecified() || sd->localAddr == localAddr) &&
688  (sd->remoteAddr.isUnspecified() || sd->remoteAddr == remoteAddr)))
689  {
690  if (sd->localAddr.isUnspecified())
691  socketBoundToAnyAddress = sd;
692  else
693  return sd;
694  }
695  }
696  return socketBoundToAnyAddress;
697 }
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
std::list< SockDesc * > SockDescList
Definition: UDP.h:94
std::vector< UDP::SockDesc * > inet::UDP::findSocketsForMcastBcastPacket ( const L3Address localAddr,
ushort  localPort,
const L3Address remoteAddr,
ushort  remotePort,
bool  isMulticast,
bool  isBroadcast 
)
protectedvirtual

Referenced by processUDPPacket().

700 {
701  ASSERT(isMulticast || isBroadcast);
702  std::vector<SockDesc *> result;
703  auto it = socketsByPortMap.find(localPort);
704  if (it == socketsByPortMap.end())
705  return result;
706 
707  SockDescList& list = it->second;
708  for (auto sd : list) {
709  if (isBroadcast) {
710  if (sd->isBroadcast) {
711  if ((sd->remotePort == -1 || sd->remotePort == remotePort) &&
712  (sd->remoteAddr.isUnspecified() || sd->remoteAddr == remoteAddr))
713  result.push_back(sd);
714  }
715  }
716  else if (isMulticast) {
717  auto membership = sd->findFirstMulticastMembership(localAddr);
718  if (membership != sd->multicastMembershipTable.end()) {
719  if ((sd->remotePort == -1 || sd->remotePort == remotePort) &&
720  (sd->remoteAddr.isUnspecified() || sd->remoteAddr == remoteAddr) &&
721  (*membership)->isSourceAllowed(remoteAddr))
722  result.push_back(sd);
723  }
724  }
725  }
726  return result;
727 }
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
std::list< SockDesc * > SockDescList
Definition: UDP.h:94
ushort inet::UDP::getEphemeralPort ( )
protectedvirtual

Referenced by createSocket().

642 {
643  // start at the last allocated port number + 1, and search for an unused one
644  ushort searchUntil = lastEphemeralPort++;
647 
648  while (socketsByPortMap.find(lastEphemeralPort) != socketsByPortMap.end()) {
649  if (lastEphemeralPort == searchUntil) // got back to starting point?
650  throw cRuntimeError("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
654  }
655 
656  // found a free one, return it
657  return lastEphemeralPort;
658 }
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
unsigned short ushort
Definition: INETDefs.h:62
ushort lastEphemeralPort
Definition: UDP.h:104
UDP::SockDesc * inet::UDP::getOrCreateSocket ( int  sockId,
int  gateIndex 
)
protectedvirtual

Referenced by connect(), processCommandFromApp(), and processPacketFromApp().

851 {
852  // validate sockId
853  if (sockId == -1)
854  throw cRuntimeError("sockId in UDP command not filled in");
855 
856  auto it = socketsByIdMap.find(sockId);
857  if (it != socketsByIdMap.end())
858  return it->second;
859 
860  return createSocket(sockId, gateIndex, L3Address(), -1);
861 }
virtual SockDesc * createSocket(int sockId, int gateIndex, const L3Address &localAddr, int localPort)
Definition: UDP.cc:585
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
UDP::SockDesc * inet::UDP::getSocketById ( int  sockId)
protectedvirtual
843 {
844  auto it = socketsByIdMap.find(sockId);
845  if (it == socketsByIdMap.end())
846  throw cRuntimeError("socket id=%d doesn't exist (already closed?)", sockId);
847  return it->second;
848 }
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
void inet::UDP::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
152 {
153  if (!isOperational)
154  throw cRuntimeError("Message '%s' received when UDP is OFF", msg->getName());
155 
156  // received from IP layer
157  if (msg->arrivedOn("ipIn")) {
158  if (dynamic_cast<UDPPacket *>(msg) != nullptr)
159  processUDPPacket((UDPPacket *)msg);
160  else
161  processICMPError(PK(msg)); // assume it's an ICMP error
162  }
163  else { // received from application layer
164  if (msg->getKind() == UDP_C_DATA)
165  processPacketFromApp(PK(msg));
166  else
168  }
169 }
virtual void processPacketFromApp(cPacket *appData)
Definition: UDP.cc:289
virtual void processCommandFromApp(cMessage *msg)
Definition: UDP.cc:182
virtual void processICMPError(cPacket *icmpErrorMsg)
Definition: UDP.cc:412
Definition: UDPControlInfo_m.h:58
#define PK(msg)
Definition: INETDefs.h:92
bool isOperational
Definition: UDP.h:115
virtual void processUDPPacket(UDPPacket *udpPacket)
Definition: UDP.cc:311
bool inet::UDP::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

1147 {
1148  Enter_Method_Silent();
1149 
1150  if (dynamic_cast<NodeStartOperation *>(operation)) {
1152  icmp = nullptr;
1153  icmpv6 = nullptr;
1154  isOperational = true;
1155  }
1156  }
1157  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
1159  clearAllSockets();
1160  icmp = nullptr;
1161  icmpv6 = nullptr;
1162  isOperational = false;
1163  }
1164  }
1165  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
1167  clearAllSockets();
1168  icmp = nullptr;
1169  icmpv6 = nullptr;
1170  isOperational = false;
1171  }
1172  }
1173  else {
1174  throw cRuntimeError("Unsupported operation '%s'", operation->getClassName());
1175  }
1176 
1177  return true;
1178 }
ICMP * icmp
Definition: UDP.h:106
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
ICMPv6 * icmpv6
Definition: UDP.h:107
Stage
Definition: NodeOperations.h:46
bool isOperational
Definition: UDP.h:115
Definition: NodeOperations.h:127
virtual void clearAllSockets()
Definition: UDP.cc:628
void inet::UDP::initialize ( int  stage)
overrideprotectedvirtual
119 {
120  cSimpleModule::initialize(stage);
121 
122  if (stage == INITSTAGE_LOCAL) {
123  WATCH_PTRMAP(socketsByIdMap);
124  WATCH_MAP(socketsByPortMap);
125 
127  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
128  icmp = nullptr;
129  icmpv6 = nullptr;
130 
131  numSent = 0;
132  numPassedUp = 0;
135  WATCH(numSent);
136  WATCH(numPassedUp);
137  WATCH(numDroppedWrongPort);
138  WATCH(numDroppedBadChecksum);
139 
140  isOperational = false;
141  }
142  else if (stage == INITSTAGE_TRANSPORT_LAYER) {
143  IPSocket ipSocket(gate("ipOut"));
144  ipSocket.registerProtocol(IP_PROT_UDP);
145 
146  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
147  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
148  }
149 }
Initialization of transport-layer protocols.
Definition: InitStages.h:90
int numPassedUp
Definition: UDP.h:111
IInterfaceTable * ift
Definition: UDP.h:105
SocketsByIdMap socketsByIdMap
Definition: UDP.h:100
ICMP * icmp
Definition: UDP.h:106
SocketsByPortMap socketsByPortMap
Definition: UDP.h:101
int numDroppedBadChecksum
Definition: UDP.h:113
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
int numDroppedWrongPort
Definition: UDP.h:112
ICMPv6 * icmpv6
Definition: UDP.h:107
int numSent
Definition: UDP.h:110
Definition: IPProtocolId_m.h:83
bool isOperational
Definition: UDP.h:115
ushort lastEphemeralPort
Definition: UDP.h:104
Definition: NodeStatus.h:40
void inet::UDP::joinMulticastGroups ( SockDesc sd,
const std::vector< L3Address > &  multicastAddresses,
const std::vector< int >  interfaceIds 
)
protectedvirtual

Referenced by processCommandFromApp().

894 {
895  int multicastAddressesLen = multicastAddresses.size();
896  int interfaceIdsLen = interfaceIds.size();
897  for (int k = 0; k < multicastAddressesLen; k++) {
898  const L3Address& multicastAddr = multicastAddresses[k];
899  int interfaceId = k < interfaceIdsLen ? interfaceIds[k] : -1;
900  ASSERT(multicastAddr.isMulticast());
901 
902  MulticastMembership *membership = sd->findMulticastMembership(multicastAddr, interfaceId);
903  if (membership)
904  throw cRuntimeError("UPD::joinMulticastGroups(): %s group on interface %s is already joined.",
905  multicastAddr.str().c_str(), ift->getInterfaceById(interfaceId)->getFullName());
906 
907  membership = new MulticastMembership();
908  membership->interfaceId = interfaceId;
909  membership->multicastAddress = multicastAddr;
910  membership->filterMode = UDP_EXCLUDE_MCAST_SOURCES;
911  sd->addMulticastMembership(membership);
912 
913  // add the multicast address to the selected interface or all interfaces
914  if (interfaceId != -1) {
915  InterfaceEntry *ie = ift->getInterfaceById(interfaceId);
916  if (!ie)
917  throw cRuntimeError("Interface id=%d does not exist", interfaceId);
918  ASSERT(ie->isMulticast());
919  addMulticastAddressToInterface(ie, multicastAddr);
920  }
921  else {
922  int n = ift->getNumInterfaces();
923  for (int i = 0; i < n; i++) {
924  InterfaceEntry *ie = ift->getInterface(i);
925  if (ie->isMulticast())
926  addMulticastAddressToInterface(ie, multicastAddr);
927  }
928  }
929  }
930 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual void addMulticastAddressToInterface(InterfaceEntry *ie, const L3Address &multicastAddr)
Definition: UDP.cc:932
IInterfaceTable * ift
Definition: UDP.h:105
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
Definition: UDPControlInfo_m.h:1132
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
const double k
Definition: QAM16Modulation.cc:24
void inet::UDP::joinMulticastSources ( SockDesc sd,
InterfaceEntry ie,
L3Address  multicastAddress,
const std::vector< L3Address > &  sourceList 
)
protectedvirtual

Referenced by processCommandFromApp().

1047 {
1048  ASSERT(ie && ie->isMulticast());
1049  ASSERT(multicastAddress.isMulticast());
1050 
1051  MulticastMembership *membership = sd->findMulticastMembership(multicastAddress, ie->getInterfaceId());
1052  if (!membership) {
1053  membership = new MulticastMembership();
1054  membership->interfaceId = ie->getInterfaceId();
1055  membership->multicastAddress = multicastAddress;
1056  membership->filterMode = UDP_INCLUDE_MCAST_SOURCES;
1057  sd->addMulticastMembership(membership);
1058  }
1059 
1060  if (membership->filterMode == UDP_EXCLUDE_MCAST_SOURCES)
1061  throw cRuntimeError("UDP::joinMulticastSources(): socket was joined to all sources of %s group on interface '%s'",
1062  multicastAddress.str().c_str(), ie->getFullName());
1063 
1064  std::vector<L3Address> oldSources(membership->sourceList);
1065  std::vector<L3Address>& includedSources = membership->sourceList;
1066  bool changed = false;
1067  for (auto & elem : sourceList) {
1068  const L3Address& sourceAddress = elem;
1069  auto it = std::find(includedSources.begin(), includedSources.end(), sourceAddress);
1070  if (it != includedSources.end()) {
1071  includedSources.push_back(sourceAddress);
1072  changed = true;
1073  }
1074  }
1075 
1076  if (changed) {
1077  ie->changeMulticastGroupMembership(multicastAddress, MCAST_INCLUDE_SOURCES, oldSources, MCAST_INCLUDE_SOURCES, includedSources);
1078  }
1079 }
Definition: UDPControlInfo_m.h:1131
Definition: UDPControlInfo_m.h:1132
Definition: InterfaceEntry.h:44
std::vector< T >::iterator find(std::vector< T > &v, const T &a)
Definition: stlutils.h:48
void inet::UDP::leaveMulticastGroups ( SockDesc sd,
const std::vector< L3Address > &  multicastAddresses 
)
protectedvirtual

Referenced by processCommandFromApp().

952 {
953  std::vector<L3Address> empty;
954 
955  for (auto & multicastAddresse : multicastAddresses) {
956  auto it = sd->findFirstMulticastMembership(multicastAddresse);
957  while (it != sd->multicastMembershipTable.end()) {
958  MulticastMembership *membership = *it;
959  if (membership->multicastAddress != multicastAddresse)
960  break;
961  it = sd->multicastMembershipTable.erase(it);
962 
963  McastSourceFilterMode oldFilterMode = membership->filterMode == UDP_INCLUDE_MCAST_SOURCES ?
965 
966  if (membership->interfaceId != -1) {
967  InterfaceEntry *ie = ift->getInterfaceById(membership->interfaceId);
968  ie->changeMulticastGroupMembership(membership->multicastAddress,
969  oldFilterMode, membership->sourceList, MCAST_INCLUDE_SOURCES, empty);
970  }
971  else {
972  for (int j = 0; j < ift->getNumInterfaces(); ++j) {
973  InterfaceEntry *ie = ift->getInterface(j);
974  if (ie->isMulticast())
975  ie->changeMulticastGroupMembership(membership->multicastAddress,
976  oldFilterMode, membership->sourceList, MCAST_INCLUDE_SOURCES, empty);
977  }
978  }
979  delete membership;
980  }
981  }
982 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
IInterfaceTable * ift
Definition: UDP.h:105
virtual void changeMulticastGroupMembership(const L3Address &multicastAddress, McastSourceFilterMode oldFilterMode, const std::vector< L3Address > &oldSourceList, McastSourceFilterMode newFilterMode, const std::vector< L3Address > &newSourceList)
Definition: InterfaceEntry.cc:365
Definition: UDPControlInfo_m.h:1131
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
const char empty[]
Definition: ConstType.h:37
Definition: InterfaceEntry.h:44
Definition: InterfaceEntry.h:44
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
McastSourceFilterMode
Definition: InterfaceEntry.h:44
void inet::UDP::leaveMulticastSources ( SockDesc sd,
InterfaceEntry ie,
L3Address  multicastAddress,
const std::vector< L3Address > &  sourceList 
)
protectedvirtual

Referenced by processCommandFromApp().

1082 {
1083  ASSERT(ie && ie->isMulticast());
1084  ASSERT(multicastAddress.isMulticast());
1085 
1086  MulticastMembership *membership = sd->findMulticastMembership(multicastAddress, ie->getInterfaceId());
1087  if (!membership)
1088  throw cRuntimeError("UDP::leaveMulticastSources(): not a member of %s group in interface '%s'",
1089  multicastAddress.str().c_str(), ie->getFullName());
1090 
1091  if (membership->filterMode == UDP_EXCLUDE_MCAST_SOURCES)
1092  throw cRuntimeError("UDP::leaveMulticastSources(): socket was joined to all sources of %s group on interface '%s'",
1093  multicastAddress.str().c_str(), ie->getFullName());
1094 
1095  std::vector<L3Address> oldSources(membership->sourceList);
1096  std::vector<L3Address>& includedSources = membership->sourceList;
1097  bool changed = false;
1098  for (auto & elem : sourceList) {
1099  const L3Address& sourceAddress = elem;
1100  auto it = std::find(includedSources.begin(), includedSources.end(), sourceAddress);
1101  if (it != includedSources.end()) {
1102  includedSources.erase(it);
1103  changed = true;
1104  }
1105  }
1106 
1107  if (changed) {
1108  ie->changeMulticastGroupMembership(multicastAddress, MCAST_EXCLUDE_SOURCES, oldSources, MCAST_EXCLUDE_SOURCES, includedSources);
1109  }
1110 
1111  if (includedSources.empty())
1112  sd->deleteMulticastMembership(membership);
1113 }
Definition: UDPControlInfo_m.h:1132
Definition: InterfaceEntry.h:44
std::vector< T >::iterator find(std::vector< T > &v, const T &a)
Definition: stlutils.h:48
virtual int inet::UDP::numInitStages ( ) const
inlineoverrideprotectedvirtual
186 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::UDP::processCommandFromApp ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

183 {
184  switch (msg->getKind()) {
185  case UDP_C_BIND: {
186  UDPBindCommand *ctrl = check_and_cast<UDPBindCommand *>(msg->getControlInfo());
187  bind(ctrl->getSockId(), msg->getArrivalGate()->getIndex(), ctrl->getLocalAddr(), ctrl->getLocalPort());
188  break;
189  }
190 
191  case UDP_C_CONNECT: {
192  UDPConnectCommand *ctrl = check_and_cast<UDPConnectCommand *>(msg->getControlInfo());
193  connect(ctrl->getSockId(), msg->getArrivalGate()->getIndex(), ctrl->getRemoteAddr(), ctrl->getRemotePort());
194  break;
195  }
196 
197  case UDP_C_CLOSE: {
198  UDPCloseCommand *ctrl = check_and_cast<UDPCloseCommand *>(msg->getControlInfo());
199  close(ctrl->getSockId());
200  break;
201  }
202 
203  case UDP_C_SETOPTION: {
204  UDPSetOptionCommand *ctrl = check_and_cast<UDPSetOptionCommand *>(msg->getControlInfo());
205  SockDesc *sd = getOrCreateSocket(ctrl->getSockId(), msg->getArrivalGate()->getIndex());
206 
207  if (dynamic_cast<UDPSetTimeToLiveCommand *>(ctrl))
208  setTimeToLive(sd, ((UDPSetTimeToLiveCommand *)ctrl)->getTtl());
209  else if (dynamic_cast<UDPSetTypeOfServiceCommand *>(ctrl))
210  setTypeOfService(sd, ((UDPSetTypeOfServiceCommand *)ctrl)->getTos());
211  else if (dynamic_cast<UDPSetBroadcastCommand *>(ctrl))
212  setBroadcast(sd, ((UDPSetBroadcastCommand *)ctrl)->getBroadcast());
213  else if (dynamic_cast<UDPSetMulticastInterfaceCommand *>(ctrl))
214  setMulticastOutputInterface(sd, ((UDPSetMulticastInterfaceCommand *)ctrl)->getInterfaceId());
215  else if (dynamic_cast<UDPSetMulticastLoopCommand *>(ctrl))
216  setMulticastLoop(sd, ((UDPSetMulticastLoopCommand *)ctrl)->getLoop());
217  else if (dynamic_cast<UDPSetReuseAddressCommand *>(ctrl))
218  setReuseAddress(sd, ((UDPSetReuseAddressCommand *)ctrl)->getReuseAddress());
219  else if (dynamic_cast<UDPJoinMulticastGroupsCommand *>(ctrl)) {
220  UDPJoinMulticastGroupsCommand *cmd = (UDPJoinMulticastGroupsCommand *)ctrl;
221  std::vector<L3Address> addresses;
222  std::vector<int> interfaceIds;
223  for (int i = 0; i < (int)cmd->getMulticastAddrArraySize(); i++)
224  addresses.push_back(cmd->getMulticastAddr(i));
225  for (int i = 0; i < (int)cmd->getInterfaceIdArraySize(); i++)
226  interfaceIds.push_back(cmd->getInterfaceId(i));
227  joinMulticastGroups(sd, addresses, interfaceIds);
228  }
229  else if (dynamic_cast<UDPLeaveMulticastGroupsCommand *>(ctrl)) {
230  UDPLeaveMulticastGroupsCommand *cmd = (UDPLeaveMulticastGroupsCommand *)ctrl;
231  std::vector<L3Address> addresses;
232  for (int i = 0; i < (int)cmd->getMulticastAddrArraySize(); i++)
233  addresses.push_back(cmd->getMulticastAddr(i));
234  leaveMulticastGroups(sd, addresses);
235  }
236  else if (dynamic_cast<UDPBlockMulticastSourcesCommand *>(ctrl)) {
237  UDPBlockMulticastSourcesCommand *cmd = (UDPBlockMulticastSourcesCommand *)ctrl;
238  InterfaceEntry *ie = ift->getInterfaceById(cmd->getInterfaceId());
239  std::vector<L3Address> sourceList;
240  for (int i = 0; i < (int)cmd->getSourceListArraySize(); i++)
241  sourceList.push_back(cmd->getSourceList(i));
242  blockMulticastSources(sd, ie, cmd->getMulticastAddr(), sourceList);
243  }
244  else if (dynamic_cast<UDPUnblockMulticastSourcesCommand *>(ctrl)) {
245  UDPUnblockMulticastSourcesCommand *cmd = (UDPUnblockMulticastSourcesCommand *)ctrl;
246  InterfaceEntry *ie = ift->getInterfaceById(cmd->getInterfaceId());
247  std::vector<L3Address> sourceList;
248  for (int i = 0; i < (int)cmd->getSourceListArraySize(); i++)
249  sourceList.push_back(cmd->getSourceList(i));
250  leaveMulticastSources(sd, ie, cmd->getMulticastAddr(), sourceList);
251  }
252  else if (dynamic_cast<UDPJoinMulticastSourcesCommand *>(ctrl)) {
253  UDPJoinMulticastSourcesCommand *cmd = (UDPJoinMulticastSourcesCommand *)ctrl;
254  InterfaceEntry *ie = ift->getInterfaceById(cmd->getInterfaceId());
255  std::vector<L3Address> sourceList;
256  for (int i = 0; i < (int)cmd->getSourceListArraySize(); i++)
257  sourceList.push_back(cmd->getSourceList(i));
258  joinMulticastSources(sd, ie, cmd->getMulticastAddr(), sourceList);
259  }
260  else if (dynamic_cast<UDPLeaveMulticastSourcesCommand *>(ctrl)) {
261  UDPLeaveMulticastSourcesCommand *cmd = (UDPLeaveMulticastSourcesCommand *)ctrl;
262  InterfaceEntry *ie = ift->getInterfaceById(cmd->getInterfaceId());
263  std::vector<L3Address> sourceList;
264  for (int i = 0; i < (int)cmd->getSourceListArraySize(); i++)
265  sourceList.push_back(cmd->getSourceList(i));
266  leaveMulticastSources(sd, ie, cmd->getMulticastAddr(), sourceList);
267  }
268  else if (dynamic_cast<UDPSetMulticastSourceFilterCommand *>(ctrl)) {
269  UDPSetMulticastSourceFilterCommand *cmd = (UDPSetMulticastSourceFilterCommand *)ctrl;
270  InterfaceEntry *ie = ift->getInterfaceById(cmd->getInterfaceId());
271  std::vector<L3Address> sourceList;
272  for (int i = 0; i < (int)cmd->getSourceListArraySize(); i++)
273  sourceList.push_back(cmd->getSourceList(i));
274  setMulticastSourceFilter(sd, ie, cmd->getMulticastAddr(), (UDPSourceFilterMode)cmd->getFilterMode(), sourceList);
275  }
276  else
277  throw cRuntimeError("Unknown subclass of UDPSetOptionCommand received from app: %s", ctrl->getClassName());
278  break;
279  }
280 
281  default: {
282  throw cRuntimeError("Unknown command code (message kind) %d received from app", msg->getKind());
283  }
284  }
285 
286  delete msg; // also deletes control info in it
287 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
Definition: UDPControlInfo_m.h:61
virtual void setMulticastLoop(SockDesc *sd, bool loop)
Definition: UDP.cc:883
UDPSourceFilterMode
Enum generated from inet/transportlayer/contract/udp/UDPControlInfo.msg:331 by nedtool.
Definition: UDPControlInfo_m.h:1130
Definition: UDPControlInfo_m.h:60
IInterfaceTable * ift
Definition: UDP.h:105
virtual void setMulticastSourceFilter(SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, UDPSourceFilterMode filterMode, const std::vector< L3Address > &sourceList)
Definition: UDP.cc:1115
virtual void setTimeToLive(SockDesc *sd, int ttl)
Definition: UDP.cc:863
virtual void close(int sockId)
Definition: UDP.cc:605
virtual void leaveMulticastSources(SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
Definition: UDP.cc:1081
virtual void connect(int sockId, int gateIndex, const L3Address &remoteAddr, int remotePort)
Definition: UDP.cc:570
virtual void setTypeOfService(SockDesc *sd, int typeOfService)
Definition: UDP.cc:868
virtual void joinMulticastSources(SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
Definition: UDP.cc:1046
virtual void setBroadcast(SockDesc *sd, bool broadcast)
Definition: UDP.cc:873
virtual void setReuseAddress(SockDesc *sd, bool reuseAddr)
Definition: UDP.cc:888
virtual void leaveMulticastGroups(SockDesc *sd, const std::vector< L3Address > &multicastAddresses)
Definition: UDP.cc:951
virtual void blockMulticastSources(SockDesc *sd, InterfaceEntry *ie, L3Address multicastAddress, const std::vector< L3Address > &sourceList)
Definition: UDP.cc:984
Definition: UDPControlInfo_m.h:62
virtual void joinMulticastGroups(SockDesc *sd, const std::vector< L3Address > &multicastAddresses, const std::vector< int > interfaceIds)
Definition: UDP.cc:893
virtual void bind(int sockId, int gateIndex, const L3Address &localAddr, int localPort)
Definition: UDP.cc:535
virtual SockDesc * getOrCreateSocket(int sockId, int gateIndex)
Definition: UDP.cc:850
virtual void setMulticastOutputInterface(SockDesc *sd, int interfaceId)
Definition: UDP.cc:878
Definition: UDPControlInfo_m.h:59
void inet::UDP::processICMPError ( cPacket *  icmpErrorMsg)
protectedvirtual

Referenced by handleMessage().

413 {
414  // extract details from the error message, then try to notify socket that sent bogus packet
415 
416  // icmp error packet with fragmented udp maybe contains raw packet
417  // icmp error packet with fragmented udp packet maybe not contains UDPPacket
418  // icmp error packet with fragmented udp packet maybe contains entire UDPPacket, but the real packet not contains udp header
419 
420  int type, code;
421  L3Address localAddr, remoteAddr;
422  ushort localPort, remotePort;
423  bool udpHeaderAvailable = false;
424 
425 #ifdef WITH_IPv4
426  if (ICMPMessage *icmpMsg = dynamic_cast<ICMPMessage *>(pk)) {
427  type = icmpMsg->getType();
428  code = icmpMsg->getCode();
429  // Note: we must NOT use decapsulate() because payload in ICMP is conceptually truncated
430  IPv4Datagram *datagram = check_and_cast<IPv4Datagram *>(icmpMsg->getEncapsulatedPacket());
431  if (datagram->getDontFragment() || datagram->getFragmentOffset() == 0) {
432  UDPPacket *packet = dynamic_cast<UDPPacket *>(datagram->getEncapsulatedPacket());
433  if (packet) {
434  localAddr = datagram->getSrcAddress();
435  remoteAddr = datagram->getDestAddress();
436  localPort = packet->getSourcePort();
437  remotePort = packet->getDestinationPort();
438  udpHeaderAvailable = true;
439  }
440  }
441  }
442  else
443 #endif // ifdef WITH_IPv4
444 #ifdef WITH_IPv6
445  if (ICMPv6Message *icmpMsg = dynamic_cast<ICMPv6Message *>(pk)) {
446  type = icmpMsg->getType();
447  code = -1; // FIXME this is dependent on getType()...
448  // Note: we must NOT use decapsulate() because payload in ICMP is conceptually truncated
449  IPv6Datagram *datagram = check_and_cast<IPv6Datagram *>(icmpMsg->getEncapsulatedPacket());
450  IPv6FragmentHeader *fh = dynamic_cast<IPv6FragmentHeader *>(datagram->findExtensionHeaderByType(IP_PROT_IPv6EXT_FRAGMENT));
451  if (!fh || fh->getFragmentOffset() == 0) {
452  UDPPacket *packet = dynamic_cast<UDPPacket *>(datagram->getEncapsulatedPacket());
453  if (packet) {
454  localAddr = datagram->getSrcAddress();
455  remoteAddr = datagram->getDestAddress();
456  localPort = packet->getSourcePort();
457  remotePort = packet->getDestinationPort();
458  udpHeaderAvailable = true;
459  }
460  }
461  }
462  else
463 #endif // ifdef WITH_IPv6
464  {
465  throw cRuntimeError("Unrecognized packet (%s)%s: not an ICMP error message", pk->getClassName(), pk->getName());
466  }
467 
468  // identify socket and report error to it
469  if (udpHeaderAvailable) {
470  EV_WARN << "ICMP error received: type=" << type << " code=" << code
471  << " about packet " << localAddr << ":" << localPort << " > "
472  << remoteAddr << ":" << remotePort << "\n";
473 
474  SockDesc *sd = findSocketForUnicastPacket(localAddr, localPort, remoteAddr, remotePort);
475  if (sd) {
476  // send UDP_I_ERROR to socket
477  EV_DETAIL << "Source socket is sockId=" << sd->sockId << ", notifying.\n";
478  sendUpErrorIndication(sd, localAddr, localPort, remoteAddr, remotePort);
479  }
480  else {
481  EV_WARN << "No socket on that local port, ignoring ICMP error\n";
482  }
483  }
484  else
485  EV_WARN << "UDP header not available, ignoring ICMP error\n";
486 
487  delete pk;
488 }
virtual void sendUpErrorIndication(SockDesc *sd, const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort)
Definition: UDP.cc:752
virtual SockDesc * findSocketForUnicastPacket(const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort)
Definition: UDP.cc:674
unsigned short ushort
Definition: INETDefs.h:62
Definition: IPProtocolId_m.h:97
void inet::UDP::processPacketFromApp ( cPacket *  appData)
protectedvirtual

Referenced by handleMessage().

290 {
292  UDPSendCommand *ctrl = check_and_cast<UDPSendCommand *>(appData->removeControlInfo());
293 
294  SockDesc *sd = getOrCreateSocket(ctrl->getSockId(), appData->getArrivalGate()->getIndex());
295  const L3Address& destAddr = ctrl->getDestAddr().isUnspecified() ? sd->remoteAddr : ctrl->getDestAddr();
296  int destPort = ctrl->getDestPort() == -1 ? sd->remotePort : ctrl->getDestPort();
297  if (destAddr.isUnspecified() || destPort == -1)
298  throw cRuntimeError("send: missing destination address or port when sending over unconnected port");
299 
300  const L3Address& srcAddr = ctrl->getSrcAddr().isUnspecified() ? sd->localAddr : ctrl->getSrcAddr();
301  int interfaceId = ctrl->getInterfaceId();
302  if (interfaceId == -1 && destAddr.isMulticast()) {
303  auto membership = sd->findFirstMulticastMembership(destAddr);
304  interfaceId = (membership != sd->multicastMembershipTable.end() && (*membership)->interfaceId != -1) ? (*membership)->interfaceId : sd->multicastOutputInterfaceId;
305  }
306  sendDown(appData, srcAddr, sd->localPort, destAddr, destPort, interfaceId, sd->multicastLoop, sd->ttl, sd->typeOfService);
307 
308  delete ctrl; // cannot be deleted earlier, due to destAddr
309 }
L3Address remoteAddr
Definition: UDP.h:78
virtual void sendDown(cPacket *appData, const L3Address &srcAddr, ushort srcPort, const L3Address &destAddr, ushort destPort, int interfaceId, bool multicastLoop, int ttl, unsigned char tos)
Definition: UDP.cc:766
static simsignal_t packetReceivedFromUpperSignal
Definition: LayeredProtocolBase.h:29
bool isUnspecified() const
Definition: L3Address.cc:133
virtual SockDesc * getOrCreateSocket(int sockId, int gateIndex)
Definition: UDP.cc:850
void inet::UDP::processUDPPacket ( UDPPacket udpPacket)
protectedvirtual

Referenced by handleMessage().

312 {
314  emit(rcvdPkSignal, udpPacket);
315 
316  // simulate checksum: discard packet if it has bit error
317  EV_INFO << "Packet " << udpPacket->getName() << " received from network, dest port " << udpPacket->getDestinationPort() << "\n";
318 
319  if (udpPacket->hasBitError()) {
320  EV_WARN << "Packet has bit error, discarding\n";
321  emit(droppedPkBadChecksumSignal, udpPacket);
323  delete udpPacket;
324 
325  return;
326  }
327 
328  L3Address srcAddr;
329  L3Address destAddr;
330  bool isMulticast, isBroadcast;
331  int srcPort = udpPacket->getSourcePort();
332  int destPort = udpPacket->getDestinationPort();
333  int interfaceId;
334  int ttl;
335  unsigned char tos;
336 
337  cObject *ctrl = udpPacket->removeControlInfo();
338  if (dynamic_cast<IPv4ControlInfo *>(ctrl) != nullptr) {
339  IPv4ControlInfo *ctrl4 = (IPv4ControlInfo *)ctrl;
340  srcAddr = ctrl4->getSrcAddr();
341  destAddr = ctrl4->getDestAddr();
342  interfaceId = ctrl4->getInterfaceId();
343  ttl = ctrl4->getTimeToLive();
344  tos = ctrl4->getTypeOfService();
345  isMulticast = ctrl4->getDestAddr().isMulticast();
346  isBroadcast = ctrl4->getDestAddr().isLimitedBroadcastAddress(); // note: we cannot recognize other broadcast addresses (where the host part is all-ones), because here we don't know the netmask
347  }
348  else if (dynamic_cast<IPv6ControlInfo *>(ctrl) != nullptr) {
349  IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
350  srcAddr = ctrl6->getSrcAddr();
351  destAddr = ctrl6->getDestAddr();
352  interfaceId = ctrl6->getInterfaceId();
353  ttl = ctrl6->getHopLimit();
354  tos = ctrl6->getTrafficClass();
355  isMulticast = ctrl6->getDestAddr().isMulticast();
356  isBroadcast = false; // IPv6 has no broadcast, just various multicasts
357  }
358  else if (dynamic_cast<GenericNetworkProtocolControlInfo *>(ctrl) != nullptr) {
359  GenericNetworkProtocolControlInfo *ctrlGeneric = (GenericNetworkProtocolControlInfo *)ctrl;
360  srcAddr = ctrlGeneric->getSourceAddress();
361  destAddr = ctrlGeneric->getDestinationAddress();
362  interfaceId = ctrlGeneric->getInterfaceId();
363  ttl = ctrlGeneric->getHopLimit();
364  tos = 0; // TODO: ctrlGeneric->getTrafficClass();
365  isMulticast = ctrlGeneric->getDestinationAddress().isMulticast();
366  isBroadcast = false; // IPv6 has no broadcast, just various multicasts
367  }
368  else if (ctrl == nullptr) {
369  throw cRuntimeError("(%s)%s arrived from lower layer without control info",
370  udpPacket->getClassName(), udpPacket->getName());
371  }
372  else {
373  throw cRuntimeError("(%s)%s arrived from lower layer with unrecognized control info %s",
374  udpPacket->getClassName(), udpPacket->getName(), ctrl->getClassName());
375  }
376 
377  if (!isMulticast && !isBroadcast) {
378  // unicast packet, there must be only one socket listening
379  SockDesc *sd = findSocketForUnicastPacket(destAddr, destPort, srcAddr, srcPort);
380  if (!sd) {
381  EV_WARN << "No socket registered on port " << destPort << "\n";
382  processUndeliverablePacket(udpPacket, ctrl);
383  return;
384  }
385  else {
386  cPacket *payload = udpPacket->decapsulate();
387  sendUp(payload, sd, srcAddr, srcPort, destAddr, destPort, interfaceId, ttl, tos);
388  delete udpPacket;
389  delete ctrl;
390  }
391  }
392  else {
393  // multicast packet: find all matching sockets, and send up a copy to each
394  std::vector<SockDesc *> sds = findSocketsForMcastBcastPacket(destAddr, destPort, srcAddr, srcPort, isMulticast, isBroadcast);
395  if (sds.empty()) {
396  EV_WARN << "No socket registered on port " << destPort << "\n";
397  processUndeliverablePacket(udpPacket, ctrl);
398  return;
399  }
400  else {
401  cPacket *payload = udpPacket->decapsulate();
402  unsigned int i;
403  for (i = 0; i < sds.size() - 1; i++) // sds.size() >= 1
404  sendUp(payload->dup(), sds[i], srcAddr, srcPort, destAddr, destPort, interfaceId, ttl, tos); // dup() to all but the last one
405  sendUp(payload, sds[i], srcAddr, srcPort, destAddr, destPort, interfaceId, ttl, tos); // send original to last socket
406  delete udpPacket;
407  delete ctrl;
408  }
409  }
410 }
virtual std::vector< SockDesc * > findSocketsForMcastBcastPacket(const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort, bool isMulticast, bool isBroadcast)
Definition: UDP.cc:699
virtual SockDesc * findSocketForUnicastPacket(const L3Address &localAddr, ushort localPort, const L3Address &remoteAddr, ushort remotePort)
Definition: UDP.cc:674
int numDroppedBadChecksum
Definition: UDP.h:113
static simsignal_t rcvdPkSignal
Definition: UDP.h:117
uint8_t tos
Definition: TCP_NSC.cc:83
virtual void processUndeliverablePacket(UDPPacket *udpPacket, cObject *ctrl)
Definition: UDP.cc:490
static simsignal_t droppedPkBadChecksumSignal
Definition: UDP.h:121
virtual void sendUp(cPacket *payload, SockDesc *sd, const L3Address &srcAddr, ushort srcPort, const L3Address &destAddr, ushort destPort, int interfaceId, int ttl, unsigned char tos)
Definition: UDP.cc:729
static simsignal_t packetReceivedFromLowerSignal
Definition: LayeredProtocolBase.h:33
uint8_t ttl
Definition: TCP_NSC.cc:87
void inet::UDP::processUndeliverablePacket ( UDPPacket udpPacket,
cObject *  ctrl 
)
protectedvirtual

Referenced by processUDPPacket().

491 {
492  emit(droppedPkWrongPortSignal, udpPacket);
494 
495  // send back ICMP PORT_UNREACHABLE
496  char buff[80];
497  snprintf(buff, sizeof(buff), "Port %d unreachable", udpPacket->getDestinationPort());
498  udpPacket->setName(buff);
499  if (dynamic_cast<IPv4ControlInfo *>(ctrl) != nullptr) {
500 #ifdef WITH_IPv4
501  IPv4ControlInfo *ctrl4 = (IPv4ControlInfo *)ctrl;
502  if (!icmp)
503  icmp = getModuleFromPar<ICMP>(par("icmpModule"), this);
505 #else // ifdef WITH_IPv4
506  delete udpPacket;
507  delete ctrl;
508 #endif // ifdef WITH_IPv4
509  }
510  else if (dynamic_cast<IPv6ControlInfo *>(ctrl) != nullptr) {
511 #ifdef WITH_IPv6
512  IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
513  if (!icmpv6)
514  icmpv6 = getModuleFromPar<ICMPv6>(par("icmpv6Module"), this);
516 #else // ifdef WITH_IPv6
517  delete udpPacket;
518  delete ctrl;
519 #endif // ifdef WITH_IPv6
520  }
521  else if (dynamic_cast<GenericNetworkProtocolControlInfo *>(ctrl) != nullptr) {
522  delete udpPacket;
523  delete ctrl;
524  }
525  else if (ctrl == nullptr) {
526  throw cRuntimeError("(%s)%s arrived from lower layer without control info",
527  udpPacket->getClassName(), udpPacket->getName());
528  }
529  else {
530  throw cRuntimeError("(%s)%s arrived from lower layer with unrecognized control info %s",
531  udpPacket->getClassName(), udpPacket->getName(), ctrl->getClassName());
532  }
533 }
virtual void sendErrorMessage(IPv4Datagram *datagram, int inputInterfaceId, ICMPType type, ICMPCode code)
This method can be called from other modules to send an ICMP error packet in response to a received b...
Definition: ICMP.cc:66
Definition: ICMPMessage_m.h:66
Definition: ICMPMessage_m.h:170
ICMP * icmp
Definition: UDP.h:106
static simsignal_t droppedPkWrongPortSignal
Definition: UDP.h:120
Definition: ICMPv6Message_m.h:71
int numDroppedWrongPort
Definition: UDP.h:112
ICMPv6 * icmpv6
Definition: UDP.h:107
Definition: ICMPv6Message_m.h:110
virtual void sendErrorMessage(IPv6Datagram *datagram, ICMPv6Type type, int code)
This method can be called from other modules to send an ICMPv6 error packet.
Definition: ICMPv6.cc:188
void inet::UDP::refreshDisplay ( ) const
overrideprotectedvirtual
172 {
173  char buf[80];
174  sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
175  if (numDroppedWrongPort > 0) {
176  sprintf(buf + strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
177  getDisplayString().setTagArg("i", 1, "red");
178  }
179  getDisplayString().setTagArg("t", 0, buf);
180 }
int numPassedUp
Definition: UDP.h:111
int numDroppedWrongPort
Definition: UDP.h:112
int numSent
Definition: UDP.h:110
void inet::UDP::sendDown ( cPacket *  appData,
const L3Address srcAddr,
ushort  srcPort,
const L3Address destAddr,
ushort  destPort,
int  interfaceId,
bool  multicastLoop,
int  ttl,
unsigned char  tos 
)
protectedvirtual

Referenced by processPacketFromApp().

768 {
769  if (destAddr.isUnspecified())
770  throw cRuntimeError("send: unspecified destination address");
771  if (destPort <= 0 || destPort > 65535)
772  throw cRuntimeError("send invalid remote port number %d", destPort);
773 
774  UDPPacket *udpPacket = createUDPPacket(appData->getName());
775  udpPacket->setByteLength(UDP_HEADER_BYTES);
776  udpPacket->encapsulate(appData);
777 
778  // set source and destination port
779  udpPacket->setSourcePort(srcPort);
780  udpPacket->setDestinationPort(destPort);
781 
782  if (destAddr.getType() == L3Address::IPv4) {
783  // send to IPv4
784  EV_INFO << "Sending app packet " << appData->getName() << " over IPv4.\n";
785  IPv4ControlInfo *ipControlInfo = new IPv4ControlInfo();
786  ipControlInfo->setProtocol(IP_PROT_UDP);
787  ipControlInfo->setSrcAddr(srcAddr.toIPv4());
788  ipControlInfo->setDestAddr(destAddr.toIPv4());
789  ipControlInfo->setInterfaceId(interfaceId);
790  ipControlInfo->setMulticastLoop(multicastLoop);
791  ipControlInfo->setTimeToLive(ttl);
792  ipControlInfo->setTypeOfService(tos);
793  udpPacket->setControlInfo(ipControlInfo);
794 
796  emit(sentPkSignal, udpPacket);
797  send(udpPacket, "ipOut");
798  }
799  else if (destAddr.getType() == L3Address::IPv6) {
800  // send to IPv6
801  EV_INFO << "Sending app packet " << appData->getName() << " over IPv6.\n";
802  IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
803  ipControlInfo->setProtocol(IP_PROT_UDP);
804  ipControlInfo->setSrcAddr(srcAddr.toIPv6());
805  ipControlInfo->setDestAddr(destAddr.toIPv6());
806  ipControlInfo->setInterfaceId(interfaceId);
807  ipControlInfo->setMulticastLoop(multicastLoop);
808  ipControlInfo->setHopLimit(ttl);
809  ipControlInfo->setTrafficClass(tos);
810  udpPacket->setControlInfo(ipControlInfo);
811 
813  emit(sentPkSignal, udpPacket);
814  send(udpPacket, "ipOut");
815  }
816  else {
817  // send to generic
818  EV_INFO << "Sending app packet " << appData->getName() << endl;
819  IL3AddressType *addressType = destAddr.getAddressType();
820  INetworkProtocolControlInfo *ipControlInfo = addressType->createNetworkProtocolControlInfo();
821  ipControlInfo->setTransportProtocol(IP_PROT_UDP);
822  ipControlInfo->setSourceAddress(srcAddr);
823  ipControlInfo->setDestinationAddress(destAddr);
824  ipControlInfo->setInterfaceId(interfaceId);
825  //ipControlInfo->setMulticastLoop(multicastLoop);
826  ipControlInfo->setHopLimit(ttl);
827  //ipControlInfo->setTrafficClass(tos);
828  udpPacket->setControlInfo(dynamic_cast<cObject *>(ipControlInfo));
829 
831  emit(sentPkSignal, udpPacket);
832  send(udpPacket, "ipOut");
833  }
834  numSent++;
835 }
virtual void setSourcePort(unsigned int port) override
Definition: UDPPacket.h:45
Definition: L3Address.h:47
static simsignal_t packetSentToLowerSignal
Definition: LayeredProtocolBase.h:32
virtual UDPPacket * createUDPPacket(const char *name)
Definition: UDP.cc:837
uint8_t tos
Definition: TCP_NSC.cc:83
Definition: UDPPacket_m.h:48
static simsignal_t sentPkSignal
Definition: UDP.h:118
int numSent
Definition: UDP.h:110
Definition: IPProtocolId_m.h:83
uint8_t ttl
Definition: TCP_NSC.cc:87
Definition: L3Address.h:46
void inet::UDP::sendUp ( cPacket *  payload,
SockDesc sd,
const L3Address srcAddr,
ushort  srcPort,
const L3Address destAddr,
ushort  destPort,
int  interfaceId,
int  ttl,
unsigned char  tos 
)
protectedvirtual

Referenced by processUDPPacket().

730 {
731  EV_INFO << "Sending payload up to socket sockId=" << sd->sockId << "\n";
732 
733  // send payload with UDPControlInfo up to the application
734  UDPDataIndication *udpCtrl = new UDPDataIndication();
735  udpCtrl->setSockId(sd->sockId);
736  udpCtrl->setSrcAddr(srcAddr);
737  udpCtrl->setDestAddr(destAddr);
738  udpCtrl->setSrcPort(srcPort);
739  udpCtrl->setDestPort(destPort);
740  udpCtrl->setInterfaceId(interfaceId);
741  udpCtrl->setTtl(ttl);
742  udpCtrl->setTypeOfService(tos);
743  payload->setControlInfo(udpCtrl);
744  payload->setKind(UDP_I_DATA);
745 
746  emit(passedUpPkSignal, payload);
748  send(payload, "appOut", sd->appGateIndex);
749  numPassedUp++;
750 }
int numPassedUp
Definition: UDP.h:111
Definition: UDPControlInfo_m.h:83
static simsignal_t passedUpPkSignal
Definition: UDP.h:119
uint8_t tos
Definition: TCP_NSC.cc:83
static simsignal_t packetSentToUpperSignal
Definition: LayeredProtocolBase.h:28
uint8_t ttl
Definition: TCP_NSC.cc:87
void inet::UDP::sendUpErrorIndication ( SockDesc sd,
const L3Address localAddr,
ushort  localPort,
const L3Address remoteAddr,
ushort  remotePort 
)
protectedvirtual

Referenced by processICMPError().

753 {
754  cMessage *notifyMsg = new cMessage("ERROR", UDP_I_ERROR);
755  UDPErrorIndication *udpCtrl = new UDPErrorIndication();
756  udpCtrl->setSockId(sd->sockId);
757  udpCtrl->setSrcAddr(localAddr);
758  udpCtrl->setDestAddr(remoteAddr);
759  udpCtrl->setSrcPort(sd->localPort);
760  udpCtrl->setDestPort(remotePort);
761  notifyMsg->setControlInfo(udpCtrl);
762 
763  send(notifyMsg, "appOut", sd->appGateIndex);
764 }
Definition: UDPControlInfo_m.h:84
void inet::UDP::setBroadcast ( SockDesc sd,
bool  broadcast 
)
protectedvirtual

Referenced by processCommandFromApp().

874 {
875  sd->isBroadcast = broadcast;
876 }
void inet::UDP::setMulticastLoop ( SockDesc sd,
bool  loop 
)
protectedvirtual

Referenced by processCommandFromApp().

884 {
885  sd->multicastLoop = loop;
886 }
void inet::UDP::setMulticastOutputInterface ( SockDesc sd,
int  interfaceId 
)
protectedvirtual

Referenced by processCommandFromApp().

879 {
880  sd->multicastOutputInterfaceId = interfaceId;
881 }
void inet::UDP::setMulticastSourceFilter ( SockDesc sd,
InterfaceEntry ie,
L3Address  multicastAddress,
UDPSourceFilterMode  filterMode,
const std::vector< L3Address > &  sourceList 
)
protectedvirtual

Referenced by processCommandFromApp().

1116 {
1117  ASSERT(ie && ie->isMulticast());
1118  ASSERT(multicastAddress.isMulticast());
1119 
1120  MulticastMembership *membership = sd->findMulticastMembership(multicastAddress, ie->getInterfaceId());
1121  if (!membership) {
1122  membership = new MulticastMembership();
1123  membership->interfaceId = ie->getInterfaceId();
1124  membership->multicastAddress = multicastAddress;
1125  membership->filterMode = UDP_INCLUDE_MCAST_SOURCES;
1126  sd->addMulticastMembership(membership);
1127  }
1128 
1129  bool changed = membership->filterMode != filterMode ||
1130  membership->sourceList.size() != sourceList.size() ||
1131  !equal(sourceList.begin(), sourceList.end(), membership->sourceList.begin());
1132  if (changed) {
1133  std::vector<L3Address> oldSources(membership->sourceList);
1134  McastSourceFilterMode oldFilterMode = membership->filterMode == UDP_INCLUDE_MCAST_SOURCES ?
1136  McastSourceFilterMode newFilterMode = filterMode == UDP_INCLUDE_MCAST_SOURCES ?
1138 
1139  membership->filterMode = filterMode;
1140  membership->sourceList = sourceList;
1141 
1142  ie->changeMulticastGroupMembership(multicastAddress, oldFilterMode, oldSources, newFilterMode, sourceList);
1143  }
1144 }
Definition: UDPControlInfo_m.h:1131
Definition: InterfaceEntry.h:44
Definition: InterfaceEntry.h:44
McastSourceFilterMode
Definition: InterfaceEntry.h:44
void inet::UDP::setReuseAddress ( SockDesc sd,
bool  reuseAddr 
)
protectedvirtual

Referenced by processCommandFromApp().

889 {
890  sd->reuseAddr = reuseAddr;
891 }
void inet::UDP::setTimeToLive ( SockDesc sd,
int  ttl 
)
protectedvirtual

Referenced by processCommandFromApp().

864 {
865  sd->ttl = ttl;
866 }
uint8_t ttl
Definition: TCP_NSC.cc:87
void inet::UDP::setTypeOfService ( SockDesc sd,
int  typeOfService 
)
protectedvirtual

Referenced by processCommandFromApp().

869 {
870  sd->typeOfService = typeOfService;
871 }
void inet::UDP::unblockMulticastSources ( SockDesc sd,
InterfaceEntry ie,
L3Address  multicastAddress,
const std::vector< L3Address > &  sourceList 
)
protectedvirtual
1016 {
1017  ASSERT(ie && ie->isMulticast());
1018  ASSERT(multicastAddress.isMulticast());
1019 
1020  MulticastMembership *membership = sd->findMulticastMembership(multicastAddress, ie->getInterfaceId());
1021  if (!membership)
1022  throw cRuntimeError("UDP::unblockMulticastSources(): not a member of %s group in interface '%s'",
1023  multicastAddress.str().c_str(), ie->getFullName());
1024 
1025  if (membership->filterMode != UDP_EXCLUDE_MCAST_SOURCES)
1026  throw cRuntimeError("UDP::unblockMulticastSources(): socket was not joined to all sources of %s group on interface '%s'",
1027  multicastAddress.str().c_str(), ie->getFullName());
1028 
1029  std::vector<L3Address> oldSources(membership->sourceList);
1030  std::vector<L3Address>& excludedSources = membership->sourceList;
1031  bool changed = false;
1032  for (auto & elem : sourceList) {
1033  const L3Address& sourceAddress = elem;
1034  auto it = std::find(excludedSources.begin(), excludedSources.end(), sourceAddress);
1035  if (it != excludedSources.end()) {
1036  excludedSources.erase(it);
1037  changed = true;
1038  }
1039  }
1040 
1041  if (changed) {
1042  ie->changeMulticastGroupMembership(multicastAddress, MCAST_EXCLUDE_SOURCES, oldSources, MCAST_EXCLUDE_SOURCES, excludedSources);
1043  }
1044 }
Definition: UDPControlInfo_m.h:1132
Definition: InterfaceEntry.h:44
std::vector< T >::iterator find(std::vector< T > &v, const T &a)
Definition: stlutils.h:48

Member Data Documentation

simsignal_t inet::UDP::droppedPkBadChecksumSignal = registerSignal("droppedPkBadChecksum")
staticprotected

Referenced by processUDPPacket().

simsignal_t inet::UDP::droppedPkWrongPortSignal = registerSignal("droppedPkWrongPort")
staticprotected
ICMP* inet::UDP::icmp = nullptr
protected
ICMPv6* inet::UDP::icmpv6 = nullptr
protected
IInterfaceTable* inet::UDP::ift = nullptr
protected
bool inet::UDP::isOperational = false
protected
ushort inet::UDP::lastEphemeralPort = EPHEMERAL_PORTRANGE_START
protected

Referenced by getEphemeralPort(), and initialize().

int inet::UDP::numDroppedBadChecksum = 0
protected

Referenced by initialize(), and processUDPPacket().

int inet::UDP::numDroppedWrongPort = 0
protected
int inet::UDP::numPassedUp = 0
protected

Referenced by initialize(), refreshDisplay(), and sendUp().

int inet::UDP::numSent = 0
protected
simsignal_t inet::UDP::passedUpPkSignal = registerSignal("passedUpPk")
staticprotected

Referenced by sendUp().

simsignal_t inet::UDP::rcvdPkSignal = registerSignal("rcvdPk")
staticprotected

Referenced by processUDPPacket().

simsignal_t inet::UDP::sentPkSignal = registerSignal("sentPk")
staticprotected

Referenced by sendDown().

SocketsByIdMap inet::UDP::socketsByIdMap
protected

The documentation for this class was generated from the following files: