INET Framework for OMNeT++/OMNEST
AnsaUDP Class Reference

#include <AnsaUDP.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

 AnsaUDP ()
virtual ~AnsaUDP ()

Protected Member Functions

virtual void updateDisplayString ()
virtual void bind (int gateIndex, AnsaUDPControlInfo *ctrl)
virtual void connect (int sockId, IPvXAddress addr, int port)
virtual void unbind (int sockId)
virtual short 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, short 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, short remotePort)
virtual void processICMPError (cPacket *icmpErrorMsg)
virtual void processUDPPacket (UDPPacket *udpPacket)
virtual void processMsgFromApp (cPacket *appData)
virtual void processCommandFromApp (cMessage *msg)
virtual UDPPacketcreateUDPPacket (const char *name)
virtual void initialize ()
virtual void handleMessage (cMessage *msg)

Protected Attributes

SocketsByIdMap socketsByIdMap
SocketsByPortMap socketsByPortMap
short 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 47 of file AnsaUDP.h.


Member Typedef Documentation

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

Definition at line 63 of file AnsaUDP.h.

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

Definition at line 64 of file AnsaUDP.h.

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

Definition at line 65 of file AnsaUDP.h.


Constructor & Destructor Documentation

AnsaUDP::AnsaUDP ( ) [inline]

Definition at line 123 of file AnsaUDP.h.

{}
AnsaUDP::~AnsaUDP ( ) [virtual]

Definition at line 76 of file AnsaUDP.cc.

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

Member Function Documentation

void AnsaUDP::bind ( int  gateIndex,
AnsaUDPControlInfo ctrl 
) [protected, virtual]

Definition at line 101 of file AnsaUDP.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 AnsaUDP::connect ( int  sockId,
IPvXAddress  addr,
int  port 
) [protected, virtual]

Definition at line 137 of file AnsaUDP.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 * AnsaUDP::createUDPPacket ( const char *  name) [protected, virtual]

Definition at line 532 of file AnsaUDP.cc.

Referenced by processMsgFromApp().

{
    return new UDPPacket(name);
}
short AnsaUDP::getEphemeralPort ( ) [protected, virtual]

Definition at line 177 of file AnsaUDP.cc.

Referenced by bind().

{
    // start at the last allocated port number + 1, and search for an unused one
    short 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 AnsaUDP::handleMessage ( cMessage *  msg) [protected, virtual]

Definition at line 197 of file AnsaUDP.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 AnsaUDP::initialize ( ) [protected, virtual]

Definition at line 82 of file AnsaUDP.cc.

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

Definition at line 231 of file AnsaUDP.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 AnsaUDP::matchesSocket ( SockDesc sd,
UDPPacket udp,
IPv6ControlInfo ctrl 
) [protected, virtual]

Definition at line 245 of file AnsaUDP.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;
}
bool AnsaUDP::matchesSocket ( SockDesc sd,
const IPvXAddress localAddr,
const IPvXAddress remoteAddr,
short  remotePort 
) [protected, virtual]

Definition at line 259 of file AnsaUDP.cc.

{
    return (sd->remotePort==0 || sd->remotePort!=remotePort) &&
           (sd->localAddr.isUnspecified() || sd->localAddr==localAddr) &&
           (sd->remoteAddr.isUnspecified() || sd->remoteAddr==remoteAddr);
}
void AnsaUDP::processCommandFromApp ( cMessage *  msg) [protected, virtual]

Definition at line 537 of file AnsaUDP.cc.

Referenced by handleMessage().

{
    AnsaUDPControlInfo *udpCtrl = check_and_cast<AnsaUDPControlInfo *>(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());
            break;
    }

    delete udpCtrl;
    delete msg;
}
void AnsaUDP::processICMPError ( cPacket *  icmpErrorMsg) [protected, virtual]

Definition at line 327 of file AnsaUDP.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;
    int localPort, remotePort;

    if (dynamic_cast<ICMPMessage *>(msg))
    {
        ICMPMessage *icmpMsg = (ICMPMessage *)msg;
        type = icmpMsg->getType();
        code = icmpMsg->getCode();
        icmpMsg->setBitLength(icmpMsg->getEncapsulatedMsg()->getBitLength()); // trick because payload in ICMP is conceptually truncated
        IPDatagram *datagram = check_and_cast<IPDatagram *>(icmpMsg->decapsulate());
        localAddr = datagram->getSrcAddress();
        remoteAddr = datagram->getDestAddress();
        UDPPacket *packet = check_and_cast<UDPPacket *>(datagram->decapsulate());
        localPort = packet->getSourcePort();
        remotePort = packet->getDestinationPort();
        delete icmpMsg;
        delete datagram;
        delete packet;
    }
    else if (dynamic_cast<ICMPv6Message *>(msg))
    {
        ICMPv6Message *icmpMsg = (ICMPv6Message *)msg;
        type = icmpMsg->getType();
        code = -1; // FIXME this is dependent on getType()...
        IPv6Datagram *datagram = check_and_cast<IPv6Datagram *>(icmpMsg->decapsulate());
        localAddr = datagram->getSrcAddress();
        remoteAddr = datagram->getDestAddress();
        UDPPacket *packet = check_and_cast<UDPPacket *>(datagram->decapsulate());
        localPort = packet->getSourcePort();
        remotePort = packet->getDestinationPort();
        delete icmpMsg;
        delete datagram;
        delete packet;
    }
    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 AnsaUDP::processMsgFromApp ( cPacket *  appData) [protected, virtual]

Definition at line 487 of file AnsaUDP.cc.

Referenced by handleMessage().

{
    AnsaUDPControlInfo *udpCtrl = check_and_cast<AnsaUDPControlInfo *>(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());
        ipControlInfo->setDiffServCodePoint(udpCtrl->getDiffServCodePoint());
        ipControlInfo->setTimeToLive(udpCtrl->getTimeToLive());
        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 AnsaUDP::processUDPPacket ( UDPPacket udpPacket) [protected, virtual]

Definition at line 412 of file AnsaUDP.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 *>(udpPacket->getControlInfo())!=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 AnsaUDP::processUndeliverablePacket ( UDPPacket udpPacket,
cPolymorphic *  ctrl 
) [protected, virtual]

Definition at line 300 of file AnsaUDP.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 AnsaUDP::sendUp ( cPacket *  payload,
UDPPacket udpHeader,
IPControlInfo ctrl,
SockDesc sd 
) [protected, virtual]

Definition at line 266 of file AnsaUDP.cc.

Referenced by processUDPPacket().

{
    // send payload with AnsaUDPControlInfo up to the application -- IPv4 version
    AnsaUDPControlInfo *udpCtrl = new AnsaUDPControlInfo();
    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 AnsaUDP::sendUp ( cPacket *  payload,
UDPPacket udpHeader,
IPv6ControlInfo ctrl,
SockDesc sd 
) [protected, virtual]

Definition at line 283 of file AnsaUDP.cc.

{
    // send payload with AnsaUDPControlInfo up to the application -- IPv6 version
    AnsaUDPControlInfo *udpCtrl = new AnsaUDPControlInfo();
    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 AnsaUDP::sendUpErrorNotification ( SockDesc sd,
int  msgkind,
const IPvXAddress localAddr,
const IPvXAddress remoteAddr,
short  remotePort 
) [protected, virtual]

Definition at line 397 of file AnsaUDP.cc.

Referenced by processICMPError().

{
    cPacket *notifyMsg = new cPacket("ERROR", msgkind);
    AnsaUDPControlInfo *udpCtrl = new AnsaUDPControlInfo();
    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 AnsaUDP::unbind ( int  sockId) [protected, virtual]

Definition at line 156 of file AnsaUDP.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 AnsaUDP::updateDisplayString ( ) [protected, virtual]

Definition at line 219 of file AnsaUDP.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* AnsaUDP::icmp [protected]

Definition at line 74 of file AnsaUDP.h.

ICMPv6* AnsaUDP::icmpv6 [protected]

Definition at line 75 of file AnsaUDP.h.

Referenced by initialize(), and processUndeliverablePacket().

short AnsaUDP::lastEphemeralPort [protected]

Definition at line 73 of file AnsaUDP.h.

Referenced by getEphemeralPort(), and initialize().

Definition at line 81 of file AnsaUDP.h.

Referenced by initialize(), and processUDPPacket().

Definition at line 80 of file AnsaUDP.h.

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

int AnsaUDP::numPassedUp [protected]

Definition at line 79 of file AnsaUDP.h.

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

int AnsaUDP::numSent [protected]

Definition at line 78 of file AnsaUDP.h.

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

Definition at line 69 of file AnsaUDP.h.

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


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