Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes

UDP Class Reference

#include <UDP.h>

List of all members.

Classes

struct  SockDesc

Public Types

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

Public Member Functions

 UDP ()
virtual ~UDP ()

Protected Member Functions

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

Protected Attributes

SocketsByIdMap socketsByIdMap
SocketsByPortMap socketsByPortMap
ushort lastEphemeralPort
ICMPicmp
ICMPv6icmpv6
int numSent
int numPassedUp
int numDroppedWrongPort
int numDroppedBadChecksum

Detailed Description

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

More info in the NED file.

Definition at line 46 of file UDP.h.


Member Typedef Documentation

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

Definition at line 62 of file UDP.h.

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

Definition at line 63 of file UDP.h.

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

Definition at line 64 of file UDP.h.


Constructor & Destructor Documentation

UDP::UDP (  )  [inline]

Definition at line 122 of file UDP.h.

{}

UDP::~UDP (  )  [virtual]

Definition at line 75 of file UDP.cc.

{
    for (SocketsByIdMap::iterator i=socketsByIdMap.begin(); i!=socketsByIdMap.end(); ++i)
        delete i->second;
}


Member Function Documentation

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

Definition at line 100 of file UDP.cc.

Referenced by processCommandFromApp().

{
    // XXX checks could be added, of when the bind should be allowed to proceed

    // create and fill in SockDesc
    SockDesc *sd = new SockDesc();
    sd->sockId = ctrl->getSockId();
    sd->userId = ctrl->getUserId();
    sd->appGateIndex = gateIndex;
    sd->localAddr = ctrl->getSrcAddr();
    sd->remoteAddr = ctrl->getDestAddr();
    sd->localPort = ctrl->getSrcPort();
    sd->remotePort = ctrl->getDestPort();
    sd->interfaceId = ctrl->getInterfaceId();

    if (sd->sockId==-1)
        error("sockId in BIND message not filled in");
    if (sd->localPort==0)
        sd->localPort = getEphemeralPort();

    sd->onlyLocalPortIsSet = sd->localAddr.isUnspecified() &&
                             sd->remoteAddr.isUnspecified() &&
                             sd->remotePort==0 &&
                             sd->interfaceId==-1;

    EV << "Binding socket: " << *sd << "\n";

    // add to socketsByIdMap
    ASSERT(socketsByIdMap.find(sd->sockId)==socketsByIdMap.end());
    socketsByIdMap[sd->sockId] = sd;

    // add to socketsByPortMap
    SockDescList& list = socketsByPortMap[sd->localPort]; // create if doesn't exist
    list.push_back(sd);
}

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

Definition at line 136 of file UDP.cc.

Referenced by processCommandFromApp().

{
    SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
    if (it==socketsByIdMap.end())
        error("socket id=%d doesn't exist (already closed?)", sockId);
    if (addr.isUnspecified())
        opp_error("connect: unspecified remote address");
    if (port<=0 || port>65535)
        opp_error("connect: invalid remote port number %d", port);

    SockDesc *sd = it->second;
    sd->remoteAddr = addr;
    sd->remotePort = port;

    sd->onlyLocalPortIsSet = false;

    EV << "Connecting socket: " << *sd << "\n";
}

UDPPacket * UDP::createUDPPacket ( const char *  name  )  [protected, virtual]

Definition at line 526 of file UDP.cc.

Referenced by processMsgFromApp().

{
    return new UDPPacket(name);
}

ushort UDP::getEphemeralPort (  )  [protected, virtual]

Definition at line 176 of file UDP.cc.

Referenced by bind().

{
    // start at the last allocated port number + 1, and search for an unused one
    ushort searchUntil = lastEphemeralPort++;
    if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END) // wrap
        lastEphemeralPort = EPHEMERAL_PORTRANGE_START;

    while (socketsByPortMap.find(lastEphemeralPort)!=socketsByPortMap.end())
    {
        if (lastEphemeralPort == searchUntil) // got back to starting point?
            error("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
        lastEphemeralPort++;
        if (lastEphemeralPort == EPHEMERAL_PORTRANGE_END) // wrap
            lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
    }

    // found a free one, return it
    return lastEphemeralPort;
}

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

Definition at line 196 of file UDP.cc.

{
    // received from IP layer
    if (msg->arrivedOn("ipIn") || msg->arrivedOn("ipv6In"))
    {
        if (dynamic_cast<ICMPMessage *>(msg) || dynamic_cast<ICMPv6Message *>(msg))
            processICMPError(PK(msg));
        else
            processUDPPacket(check_and_cast<UDPPacket *>(msg));
    }
    else // received from application layer
    {
        if (msg->getKind()==UDP_C_DATA)
            processMsgFromApp(PK(msg));
        else
            processCommandFromApp(msg);
    }

    if (ev.isGUI())
        updateDisplayString();
}

void UDP::initialize (  )  [protected, virtual]

Definition at line 81 of file UDP.cc.

{
    WATCH_PTRMAP(socketsByIdMap);
    WATCH_MAP(socketsByPortMap);

    lastEphemeralPort = EPHEMERAL_PORTRANGE_START;
    icmp = NULL;
    icmpv6 = NULL;

    numSent = 0;
    numPassedUp = 0;
    numDroppedWrongPort = 0;
    numDroppedBadChecksum = 0;
    WATCH(numSent);
    WATCH(numPassedUp);
    WATCH(numDroppedWrongPort);
    WATCH(numDroppedBadChecksum);
}

bool UDP::matchesSocket ( SockDesc sd,
const IPvXAddress localAddr,
const IPvXAddress remoteAddr,
ushort  remotePort 
) [protected, virtual]

Definition at line 258 of file UDP.cc.

{
    return (sd->remotePort==0 || sd->remotePort!=remotePort) &&
           (sd->localAddr.isUnspecified() || sd->localAddr==localAddr) &&
           (sd->remoteAddr.isUnspecified() || sd->remoteAddr==remoteAddr);
}

bool UDP::matchesSocket ( SockDesc sd,
UDPPacket *  udp,
IPControlInfo ctrl 
) [protected, virtual]

Definition at line 230 of file UDP.cc.

Referenced by processICMPError(), and processUDPPacket().

{
    // IPv4 version
    if (sd->remotePort!=0 && sd->remotePort!=udp->getSourcePort())
        return false;
    if (!sd->localAddr.isUnspecified() && sd->localAddr.get4()!=ipCtrl->getDestAddr())
        return false;
    if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get4()!=ipCtrl->getSrcAddr())
        return false;
    if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->getInterfaceId())
        return false;
    return true;
}

bool UDP::matchesSocket ( SockDesc sd,
UDPPacket *  udp,
IPv6ControlInfo ctrl 
) [protected, virtual]

Definition at line 244 of file UDP.cc.

{
    // IPv6 version
    if (sd->remotePort!=0 && sd->remotePort!=udp->getSourcePort())
        return false;
    if (!sd->localAddr.isUnspecified() && sd->localAddr.get6()!=ipCtrl->getDestAddr())
        return false;
    if (!sd->remoteAddr.isUnspecified() && sd->remoteAddr.get6()!=ipCtrl->getSrcAddr())
        return false;
    if (sd->interfaceId!=-1 && sd->interfaceId!=ipCtrl->getInterfaceId())
        return false;
    return true;
}

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

Definition at line 531 of file UDP.cc.

Referenced by handleMessage().

{
    UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(msg->removeControlInfo());
    switch (msg->getKind())
    {
        case UDP_C_BIND:
            bind(msg->getArrivalGate()->getIndex(), udpCtrl);
            break;
        case UDP_C_CONNECT:
            connect(udpCtrl->getSockId(), udpCtrl->getDestAddr(), udpCtrl->getDestPort());
            break;
        case UDP_C_UNBIND:
            unbind(udpCtrl->getSockId());
            break;
        default:
            error("unknown command code (message kind) %d received from app", msg->getKind());
    }

    delete udpCtrl;
    delete msg;
}

void UDP::processICMPError ( cPacket *  icmpErrorMsg  )  [protected, virtual]

Definition at line 326 of file UDP.cc.

Referenced by handleMessage().

{
    // extract details from the error message, then try to notify socket that sent bogus packet
    int type, code;
    IPvXAddress localAddr, remoteAddr;
    ushort localPort, remotePort;

    if (dynamic_cast<ICMPMessage *>(msg))
    {
        ICMPMessage *icmpMsg = (ICMPMessage *)msg;
        type = icmpMsg->getType();
        code = icmpMsg->getCode();
        // Note: we must NOT use decapsulate() because payload in ICMP is conceptually truncated
        IPDatagram *datagram = check_and_cast<IPDatagram *>(icmpMsg->getEncapsulatedMsg());
        UDPPacket *packet = check_and_cast<UDPPacket *>(datagram->getEncapsulatedMsg());
        localAddr = datagram->getSrcAddress();
        remoteAddr = datagram->getDestAddress();
        localPort = packet->getSourcePort();
        remotePort = packet->getDestinationPort();
        delete icmpMsg;
    }
    else if (dynamic_cast<ICMPv6Message *>(msg))
    {
        ICMPv6Message *icmpMsg = (ICMPv6Message *)msg;
        type = icmpMsg->getType();
        code = -1; // FIXME this is dependent on getType()...
        // Note: we must NOT use decapsulate() because payload in ICMP is conceptually truncated
        IPv6Datagram *datagram = check_and_cast<IPv6Datagram *>(icmpMsg->getEncapsulatedMsg());
        UDPPacket *packet = check_and_cast<UDPPacket *>(datagram->getEncapsulatedMsg());
        localAddr = datagram->getSrcAddress();
        remoteAddr = datagram->getDestAddress();
        localPort = packet->getSourcePort();
        remotePort = packet->getDestinationPort();
        delete icmpMsg;
    }
    EV << "ICMP error received: type=" << type << " code=" << code
       << " about packet " << localAddr << ":" << localPort << " > "
       << remoteAddr << ":" << remotePort << "\n";

    // identify socket and report error to it
    SocketsByPortMap::iterator it = socketsByPortMap.find(localPort);
    if (it==socketsByPortMap.end())
    {
        EV << "No socket on that local port, ignoring ICMP error\n";
        return;
    }
    SockDescList& list = it->second;
    SockDesc *srcSocket = NULL;
    for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
    {
        SockDesc *sd = *it;
        if (sd->onlyLocalPortIsSet || matchesSocket(sd, localAddr, remoteAddr, remotePort))
        {
            srcSocket = sd; // FIXME what to do if there's more than one matching socket ???
        }
    }
    if (!srcSocket)
    {
        EV << "No matching socket, ignoring ICMP error\n";
        return;
    }

    // send UDP_I_ERROR to socket
    EV << "Source socket is sockId=" << srcSocket->sockId << ", notifying.\n";
    sendUpErrorNotification(srcSocket, UDP_I_ERROR, localAddr, remoteAddr, remotePort);
}

void UDP::processMsgFromApp ( cPacket *  appData  )  [protected, virtual]

Definition at line 483 of file UDP.cc.

Referenced by handleMessage().

{
    UDPControlInfo *udpCtrl = check_and_cast<UDPControlInfo *>(appData->removeControlInfo());

    UDPPacket *udpPacket = createUDPPacket(appData->getName());
    udpPacket->setByteLength(UDP_HEADER_BYTES);
    udpPacket->encapsulate(appData);

    // set source and destination port
    udpPacket->setSourcePort(udpCtrl->getSrcPort());
    udpPacket->setDestinationPort(udpCtrl->getDestPort());

    if (!udpCtrl->getDestAddr().isIPv6())
    {
        // send to IPv4
        EV << "Sending app packet " << appData->getName() << " over IPv4.\n";
        IPControlInfo *ipControlInfo = new IPControlInfo();
        ipControlInfo->setProtocol(IP_PROT_UDP);
        ipControlInfo->setSrcAddr(udpCtrl->getSrcAddr().get4());
        ipControlInfo->setDestAddr(udpCtrl->getDestAddr().get4());
        ipControlInfo->setInterfaceId(udpCtrl->getInterfaceId());
        udpPacket->setControlInfo(ipControlInfo);
        delete udpCtrl;

        send(udpPacket,"ipOut");
    }
    else
    {
        // send to IPv6
        EV << "Sending app packet " << appData->getName() << " over IPv6.\n";
        IPv6ControlInfo *ipControlInfo = new IPv6ControlInfo();
        ipControlInfo->setProtocol(IP_PROT_UDP);
        ipControlInfo->setSrcAddr(udpCtrl->getSrcAddr().get6());
        ipControlInfo->setDestAddr(udpCtrl->getDestAddr().get6());
        // ipControlInfo->setInterfaceId(udpCtrl->InterfaceId()); FIXME extend IPv6 with this!!!
        udpPacket->setControlInfo(ipControlInfo);
        delete udpCtrl;

        send(udpPacket,"ipv6Out");
    }
    numSent++;
}

void UDP::processUDPPacket ( UDPPacket *  udpPacket  )  [protected, virtual]

Definition at line 408 of file UDP.cc.

Referenced by handleMessage().

{
    // simulate checksum: discard packet if it has bit error
    EV << "Packet " << udpPacket->getName() << " received from network, dest port " << udpPacket->getDestinationPort() << "\n";
    if (udpPacket->hasBitError())
    {
        EV << "Packet has bit error, discarding\n";
        delete udpPacket;
        numDroppedBadChecksum++;
        return;
    }

    int destPort = udpPacket->getDestinationPort();
    cPolymorphic *ctrl = udpPacket->removeControlInfo();

    // send back ICMP error if no socket is bound to that port
    SocketsByPortMap::iterator it = socketsByPortMap.find(destPort);
    if (it==socketsByPortMap.end())
    {
        EV << "No socket registered on port " << destPort << "\n";
        processUndeliverablePacket(udpPacket, ctrl);
        return;
    }
    SockDescList& list = it->second;

    int matches = 0;

    // deliver a copy of the packet to each matching socket
    cPacket *payload = udpPacket->getEncapsulatedMsg();
    if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL)
    {
        IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
        for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
        {
            SockDesc *sd = *it;
            if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl4))
            {
                EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n";
                sendUp((cPacket*)payload->dup(), udpPacket, ctrl4, sd);
                matches++;
            }
        }
    }
    else if (dynamic_cast<IPv6ControlInfo *>(ctrl)!=NULL)
    {
        IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
        for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
        {
            SockDesc *sd = *it;
            if (sd->onlyLocalPortIsSet || matchesSocket(sd, udpPacket, ctrl6))
            {
                EV << "Socket sockId=" << sd->sockId << " matches, sending up a copy.\n";
                sendUp((cPacket*)payload->dup(), udpPacket, ctrl6, sd);
                matches++;
            }
        }
    }
    else
    {
        error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
    }

    // send back ICMP error if there is no matching socket
    if (matches==0)
    {
        EV << "None of the sockets on port " << destPort << " matches the packet\n";
        processUndeliverablePacket(udpPacket, ctrl);
        return;
    }

    delete udpPacket;
    delete ctrl;
}

void UDP::processUndeliverablePacket ( UDPPacket *  udpPacket,
cPolymorphic *  ctrl 
) [protected, virtual]

Definition at line 299 of file UDP.cc.

Referenced by processUDPPacket().

{
    numDroppedWrongPort++;

    // send back ICMP PORT_UNREACHABLE
    if (dynamic_cast<IPControlInfo *>(ctrl)!=NULL)
    {
        if (!icmp)
            icmp = ICMPAccess().get();
        IPControlInfo *ctrl4 = (IPControlInfo *)ctrl;
        if (!ctrl4->getDestAddr().isMulticast())
            icmp->sendErrorMessage(udpPacket, ctrl4, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PORT_UNREACHABLE);
    }
    else if (dynamic_cast<IPv6ControlInfo *>(udpPacket->getControlInfo())!=NULL)
    {
        if (!icmpv6)
            icmpv6 = ICMPv6Access().get();
        IPv6ControlInfo *ctrl6 = (IPv6ControlInfo *)ctrl;
        if (!ctrl6->getDestAddr().isMulticast())
            icmpv6->sendErrorMessage(udpPacket, ctrl6, ICMPv6_DESTINATION_UNREACHABLE, PORT_UNREACHABLE);
    }
    else
    {
        error("(%s)%s arrived from lower layer without control info", udpPacket->getClassName(), udpPacket->getName());
    }
}

void UDP::sendUp ( cPacket *  payload,
UDPPacket *  udpHeader,
IPv6ControlInfo ctrl,
SockDesc sd 
) [protected, virtual]

Definition at line 282 of file UDP.cc.

{
    // send payload with UDPControlInfo up to the application -- IPv6 version
    UDPControlInfo *udpCtrl = new UDPControlInfo();
    udpCtrl->setSockId(sd->sockId);
    udpCtrl->setUserId(sd->userId);
    udpCtrl->setSrcAddr(ipCtrl->getSrcAddr());
    udpCtrl->setDestAddr(ipCtrl->getDestAddr());
    udpCtrl->setSrcPort(udpHeader->getSourcePort());
    udpCtrl->setDestPort(udpHeader->getDestinationPort());
    udpCtrl->setInterfaceId(ipCtrl->getInterfaceId());
    payload->setControlInfo(udpCtrl);

    send(payload, "appOut", sd->appGateIndex);
    numPassedUp++;
}

void UDP::sendUp ( cPacket *  payload,
UDPPacket *  udpHeader,
IPControlInfo ctrl,
SockDesc sd 
) [protected, virtual]

Definition at line 265 of file UDP.cc.

Referenced by processUDPPacket().

{
    // send payload with UDPControlInfo up to the application -- IPv4 version
    UDPControlInfo *udpCtrl = new UDPControlInfo();
    udpCtrl->setSockId(sd->sockId);
    udpCtrl->setUserId(sd->userId);
    udpCtrl->setSrcAddr(ipCtrl->getSrcAddr());
    udpCtrl->setDestAddr(ipCtrl->getDestAddr());
    udpCtrl->setSrcPort(udpHeader->getSourcePort());
    udpCtrl->setDestPort(udpHeader->getDestinationPort());
    udpCtrl->setInterfaceId(ipCtrl->getInterfaceId());
    payload->setControlInfo(udpCtrl);

    send(payload, "appOut", sd->appGateIndex);
    numPassedUp++;
}

void UDP::sendUpErrorNotification ( SockDesc sd,
int  msgkind,
const IPvXAddress localAddr,
const IPvXAddress remoteAddr,
ushort  remotePort 
) [protected, virtual]

Definition at line 393 of file UDP.cc.

Referenced by processICMPError().

{
    cPacket *notifyMsg = new cPacket("ERROR", msgkind);
    UDPControlInfo *udpCtrl = new UDPControlInfo();
    udpCtrl->setSockId(sd->sockId);
    udpCtrl->setUserId(sd->userId);
    udpCtrl->setSrcAddr(localAddr);
    udpCtrl->setDestAddr(remoteAddr);
    udpCtrl->setSrcPort(sd->localPort);
    udpCtrl->setDestPort(remotePort);
    notifyMsg->setControlInfo(udpCtrl);

    send(notifyMsg, "appOut", sd->appGateIndex);
}

void UDP::unbind ( int  sockId  )  [protected, virtual]

Definition at line 155 of file UDP.cc.

Referenced by processCommandFromApp().

{
    // remove from socketsByIdMap
    SocketsByIdMap::iterator it = socketsByIdMap.find(sockId);
    if (it==socketsByIdMap.end())
        error("socket id=%d doesn't exist (already closed?)", sockId);
    SockDesc *sd = it->second;
    socketsByIdMap.erase(it);

    EV << "Unbinding socket: " << *sd << "\n";

    // remove from socketsByPortMap
    SockDescList& list = socketsByPortMap[sd->localPort];
    for (SockDescList::iterator it=list.begin(); it!=list.end(); ++it)
        if (*it == sd)
            {list.erase(it); break;}
    if (list.empty())
        socketsByPortMap.erase(sd->localPort);
    delete sd;
}

void UDP::updateDisplayString (  )  [protected, virtual]

Definition at line 218 of file UDP.cc.

Referenced by handleMessage().

{
    char buf[80];
    sprintf(buf, "passed up: %d pks\nsent: %d pks", numPassedUp, numSent);
    if (numDroppedWrongPort>0)
    {
        sprintf(buf+strlen(buf), "\ndropped (no app): %d pks", numDroppedWrongPort);
        getDisplayString().setTagArg("i",1,"red");
    }
    getDisplayString().setTagArg("t",0,buf);
}


Member Data Documentation

ICMP* UDP::icmp [protected]

Definition at line 73 of file UDP.h.

ICMPv6* UDP::icmpv6 [protected]

Definition at line 74 of file UDP.h.

Referenced by initialize(), and processUndeliverablePacket().

Definition at line 72 of file UDP.h.

Referenced by getEphemeralPort(), and initialize().

int UDP::numDroppedBadChecksum [protected]

Definition at line 80 of file UDP.h.

Referenced by initialize(), and processUDPPacket().

int UDP::numDroppedWrongPort [protected]

Definition at line 79 of file UDP.h.

Referenced by initialize(), processUndeliverablePacket(), and updateDisplayString().

int UDP::numPassedUp [protected]

Definition at line 78 of file UDP.h.

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

int UDP::numSent [protected]

Definition at line 77 of file UDP.h.

Referenced by initialize(), processMsgFromApp(), and updateDisplayString().

Definition at line 68 of file UDP.h.

Referenced by bind(), connect(), initialize(), unbind(), and ~UDP().

Definition at line 69 of file UDP.h.

Referenced by bind(), getEphemeralPort(), initialize(), processICMPError(), processUDPPacket(), and unbind().


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