oversim::Nice Class Reference

NICE overlay module. More...

#include <Nice.h>

Inheritance diagram for oversim::Nice:

BaseOverlay BaseRpc TopologyVis RpcListener

List of all members.

Public Member Functions

 Nice ()
virtual ~Nice ()
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void handleTimerEvent (cMessage *msg)
virtual void handleUDPMessage (BaseOverlayMessage *msg)
 Processes messages from underlay.
virtual void handleAppMessage (cMessage *msg)
 Processes "timer" self-messages.
virtual void finishOverlay ()
 collects statistical data in derived class

Protected Member Functions

virtual void changeState (int toState)
 changes node state
virtual void joinOverlay ()
 Join the overlay with a given nodeID in thisNode.key.

Private Member Functions

void updateVisualization ()
void becomeRendevouzPoint ()
short getHighestLeaderLayer ()
short getHighestLayer ()
void BasicJoinLayer (short layer)
void ClusterSplit (int layer)
void Query (const TransportAddress &node, short layer)
void handleQuery (NiceMessage *queryMsg)
void handleQueryResponse (NiceMemberMessage *queryRspMsg)
void JoinCluster (const TransportAddress &leader, short layer)
void handleJoinCluster (NiceMessage *joinMsg)
void sendHeartbeats ()
void handleHeartbeat (NiceMessage *msg)
void maintenance ()
simtime_t getMaxDistance (TransportAddress member, std::set< TransportAddress > neighbors)
simtime_t getMeanDistance (std::set< TransportAddress > neighbors)
void LeaderTransfer (int layer, TransportAddress leader, TaSet cluster, TransportAddress sc_leader)
void Remove (int layer)
void sendHeartbeatTo (const TransportAddress &node, int layer)
void ClusterMerge (int layer)
void ClusterMergeRequest (const TransportAddress &node, int layer)
void gracefulLeave (short bottomLayer)
TransportAddress findClusterLeader (NiceCluster cluster)
std::pair< TransportAddress,
simtime_t > 
findCenter (TaSet cluster, bool allowRandom=false)
std::pair< TransportAddress,
simtime_t > 
findCenter (std::vector< TransportAddress > cluster, bool allowRandom=false)
void sendDataToOverlay (CbrAppMessage *appMsg)
void pollRP (int layer)

Private Attributes

int pimp
cMessage * heartbeatTimer
simtime_t heartbeatInterval
cMessage * maintenanceTimer
simtime_t maintenanceInterval
cMessage * queryTimer
simtime_t queryInterval
cMessage * structureConnectionTimer
simtime_t structureConnectionInterval
cMessage * rpPollTimer
simtime_t rpPollTimerInterval
simtime_t peerTimeoutInterval
cMessage * visualizationTimer
simtime_t first_HB
TransportAddress first_leader
simtime_t second_HB
TransportAddress second_leader
std::vector< std::pair
< TransportAddress, simtime_t > > 
leaderHeartbeats
int clusterrefinement
int debug_heartbeats
int debug_visualization
int debug_join
int debug_peertimeouts
int debug_removes
int debug_queries
unsigned short k
NiceCluster clusters [maxLayers]
int evalLayer
int joinLayer
bool isPollingRP
simtime_t query_start
TransportAddress tempResolver
simtime_t query_compare
short targetLayer
std::map< TransportAddress,
NicePeerInfo * > 
peerInfos
std::map< TransportAddress,
simtime_t > 
tempPeers
bool isTempPeered
double CLUSTERLEADERBOUND
double CLUSTERLEADERCOMPAREDIST
double SC_PROC_DISTANCE
double SC_MIN_OFFSET

Friends

class NicePeerInfo


Detailed Description

NICE overlay module.

Implementation of the NICE overlay as described in "Scalable Application Layer Multicast" by S. Banerjee and B. Bhattacharjee and C. Kommareddy, published at SIGCOMM'02, 2002.

Author:
Christian Huebsch

Definition at line 72 of file Nice.h.


Constructor & Destructor Documentation

oversim::Nice::Nice (  ) 

Definition at line 68 of file Nice.cc.

00069 {
00070 
00071     /* do nothing at this point of time, OverSim calls initializeOverlay */
00072 
00073 } // Nice

oversim::Nice::~Nice (  )  [virtual]

Definition at line 79 of file Nice.cc.

00080 {
00081 
00082     // destroy self timer messages
00083     cancelAndDelete(heartbeatTimer);
00084     cancelAndDelete(maintenanceTimer);
00085     cancelAndDelete(structureConnectionTimer);
00086     cancelAndDelete(rpPollTimer);
00087     cancelAndDelete(queryTimer);
00088     cancelAndDelete(visualizationTimer);
00089 
00090     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.begin();
00091 
00092     for (; it != peerInfos.end(); it++) {
00093 
00094         delete it->second;
00095 
00096     }
00097 
00098 } // ~NICE


Member Function Documentation

void oversim::Nice::BasicJoinLayer ( short  layer  )  [private]

Definition at line 763 of file Nice.cc.

Referenced by changeState(), handleTimerEvent(), and maintenance().

00764 {
00765 
00766     // Cancel timers involved in structure refinement
00767     cancelEvent(maintenanceTimer);
00768     cancelEvent(heartbeatTimer);
00769 
00770     Query(RendevouzPoint, layer);
00771 
00772     if (layer > -1)
00773         targetLayer = layer;
00774     else
00775         targetLayer = 0;
00776 
00777     // Temporary peer with RP for faster data reception
00778     NiceMessage* msg = new NiceMessage("NICE_PEER_TEMPORARY");
00779     msg->setSrcNode(thisNode);
00780     msg->setCommand(NICE_PEER_TEMPORARY);
00781     msg->setLayer(-1);
00782     msg->setBitLength(NICEMESSAGE_L(msg));
00783 
00784     sendMessageToUDP(RendevouzPoint, msg);
00785 
00786     isTempPeered = true;
00787 
00788 } // BasicJoinLayer

void oversim::Nice::becomeRendevouzPoint (  )  [private]

Definition at line 740 of file Nice.cc.

Referenced by changeState(), handleHeartbeat(), handleTimerEvent(), handleUDPMessage(), and maintenance().

00741 {
00742 
00743     RendevouzPoint = thisNode;
00744     EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << thisNode.getAddress() << endl;
00745 
00746     /* Mark node as new RP (star symbol) */
00747     getParentModule()->getParentModule()->getDisplayString().
00748     setTagArg("i2", 0, "block/star_vs");
00749 
00750     //Become leader of all cluster layers
00751     for (int i=0; i<=getHighestLayer(); i++) {
00752 
00753         clusters[i].setLeader(thisNode);
00754 
00755     }
00756 
00757 } // becomeRendevouzPoint

void oversim::Nice::changeState ( int  toState  )  [protected, virtual]

changes node state

Parameters:
toState state to change to

Definition at line 209 of file Nice.cc.

Referenced by handleQueryResponse(), and joinOverlay().

00210 {
00211     switch (toState) {
00212 
00213     case INIT:
00214 
00215         state = INIT;
00216 
00217         getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, "red");
00218 
00219         scheduleAt(simTime() + 1, visualizationTimer);
00220 
00221         break;
00222 
00223     case BOOTSTRAP:
00224 
00225         state = BOOTSTRAP;
00226 
00227         /* check wether there exists a Rendevouz Point */
00228         if (RendevouzPoint.isUnspecified()) {
00229 
00230             //EV << "[NICE::changeState() @ " << thisNode.ip
00231             //   << "    RP undefined." << endl;
00232 
00233             /* become Rendevouz Point */
00234             becomeRendevouzPoint();
00235 
00236             /* join cluster layer 0 as first node */
00237             clusters[0].add(thisNode);
00238             clusters[0].setLeader(thisNode);
00239 
00240             changeState(READY);
00241 
00242             return;
00243 
00244         } else {
00245 
00246             //EV << "[NICE::changeState() @ " << thisNode.ip
00247             //   << "    RP found: " << RendevouzPoint.getAddress() << endl;
00248 
00249             /* initiate NICE structure joining */
00250             BasicJoinLayer(-1);
00251 
00252             double offset = structureConnectionInterval.dbl() * heartbeatInterval.dbl();
00253             scheduleAt(simTime() + offset, structureConnectionTimer);
00254 
00255         }
00256 
00257         break;
00258 
00259     case READY:
00260 
00261         state = READY;
00262 
00263         cancelEvent(heartbeatTimer);
00264         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
00265         cancelEvent(maintenanceTimer);
00266         scheduleAt(simTime() + maintenanceInterval, maintenanceTimer);
00267 
00268         getParentModule()->getParentModule()->getDisplayString().setTagArg
00269         ("i2", 1, clustercolors[getHighestLayer()]);
00270 
00271         break;
00272 
00273     }
00274 
00275 } // changeState

void oversim::Nice::ClusterMerge ( int  layer  )  [private]

Definition at line 2861 of file Nice.cc.

Referenced by maintenance().

02862 {
02863 
02864     simtime_t min_delay = 999;
02865 
02866     TransportAddress min_node = TransportAddress::UNSPECIFIED_NODE;
02867 
02868     for (int i=0; i<clusters[layer+1].getSize(); i++) {
02869 
02870         TransportAddress node = clusters[layer+1].get(i);
02871 
02872         if (node != thisNode) {
02873 
02874             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(node);
02875 
02876             if (it != peerInfos.end()) {
02877                 simtime_t delay = it->second->get_distance();
02878 
02879                 if ((delay > 0) && (delay < min_delay)) {
02880 
02881                     min_delay = delay;
02882                     min_node = node;
02883 
02884                 }
02885             }
02886         }
02887 
02888     }
02889 
02890     if (!min_node.isUnspecified()) {
02891 
02892         // leave
02893         for (int i=maxLayers-1; i>layer; i--) {
02894 
02895             if (clusters[i].getSize() > 0) {
02896 
02897                 if (clusters[i].contains(thisNode)) {
02898 
02899                     EV << "REPAIR: " << i << endl;
02900 
02901                     if (clusters[i].getLeader() == thisNode) {
02902 
02903                         EV << "1 remove from: " << i << endl;
02904                         Remove(i);
02905 
02906                         TaSet cl;
02907                         for (int j=0; j<clusters[i].getSize(); j++) {
02908 
02909                             cl.insert(clusters[i].get(j));
02910 
02911                             deleteOverlayNeighborArrow(clusters[i].get(j));
02912 
02913                         }
02914 
02915                         TransportAddress new_sc_center = findCenter(cl).first;
02916 
02917                         EV << "NEW LEADER (CM): " << i << " --> " << new_sc_center.getAddress() << endl;
02918 
02919                         clusters[i].setLeader(new_sc_center);
02920 
02921                         LeaderTransfer(i, new_sc_center, cl, new_sc_center);
02922 
02923                         // repair RP
02924                         if (i == maxLayers-1) {
02925 
02926                             RendevouzPoint = new_sc_center;
02927                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
02928 
02929                         } else if (clusters[i+1].getSize() == 0) {
02930 
02931                             RendevouzPoint = new_sc_center;
02932                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
02933 
02934                         }
02935 
02936                     } else {
02937 
02938                         // simply leave cluster
02939                         EV << "2 remove from: " << i << endl;
02940                         Remove(i);
02941                         clusters[i].remove(thisNode);
02942 
02943                     }
02944 
02945                 }
02946 
02947             }
02948 
02949         }
02950 
02951         clusters[layer+1].remove(thisNode);
02952 
02953         for (int j=0; j<clusters[layer+1].getSize(); j++) {
02954 
02955             deleteOverlayNeighborArrow(clusters[layer+1].get(j));
02956 
02957         }
02958 
02959         for (short i=0; i<maxLayers; i++) {
02960 
02961             if (clusters[i].getSize() > 0) {
02962 
02963                 if (clusters[i].contains(thisNode)) {
02964 
02965                     getParentModule()->getParentModule()->getDisplayString().setTagArg
02966                     ("i2", 1, clustercolors[i]);
02967 
02968                 }
02969 
02970             }
02971 
02972         }
02973 
02974         // send merge request
02975         ClusterMergeRequest(min_node, layer);
02976 
02977     } else {
02978 
02979         EV << thisNode.getAddress() << " no suitable cluster found";
02980 
02981     }
02982 
02983 } // ClusterMerge

void oversim::Nice::ClusterMergeRequest ( const TransportAddress node,
int  layer 
) [private]

Definition at line 2989 of file Nice.cc.

Referenced by ClusterMerge(), and handleUDPMessage().

02990 {
02991 
02992     NiceClusterMerge* msg = new NiceClusterMerge("NICE_CLUSTER_MERGE_REQUEST");
02993     msg->setSrcNode(thisNode);
02994     msg->setCommand(NICE_CLUSTER_MERGE_REQUEST);
02995     msg->setLayer(layer);
02996 
02997     msg->setMembersArraySize(clusters[layer].getSize());
02998 
02999     /* Fill in members */
03000     for (int j = 0; j < clusters[layer].getSize(); j++) {
03001 
03002         msg->setMembers(j, clusters[layer].get(j));
03003 
03004         deleteOverlayNeighborArrow(clusters[layer].get(j));
03005 
03006     }
03007 
03008     msg->setNewClusterLeader(clusters[layer+1].getLeader());
03009 
03010     msg->setBitLength(NICECLUSTERMERGE_L(msg));
03011 
03012     clusters[layer].setLeader(node);
03013 
03014     getParentModule()->getParentModule()
03015     ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
03016 
03017     sendMessageToUDP(node, msg);
03018 
03019 } // ClusterMergeRequest

void oversim::Nice::ClusterSplit ( int  layer  )  [private]

Definition at line 2584 of file Nice.cc.

Referenced by maintenance().

02585 {
02586 
02587     EV << simTime() << " : " << thisNode.getAddress() << " : ClusterSplit in Layer " << layer << endl;
02588 
02589     /* Get cluster to be splitted */
02590     NiceCluster cluster = clusters[layer];
02591 
02592     /* Introduce some helper structures */
02593     std::vector<TransportAddress> vec1;
02594     std::vector<TransportAddress> vec2;
02595     std::vector<TransportAddress> cl1;
02596     std::vector<TransportAddress> cl2;
02597     TransportAddress cl1_center = TransportAddress::UNSPECIFIED_NODE;
02598     TransportAddress cl2_center = TransportAddress::UNSPECIFIED_NODE;
02599     simtime_t min_delay = 999;
02600 
02601     for (int i=0; i<cluster.getSize(); i++) {
02602 
02603         /* Delete all arrows in visualization */
02604         deleteOverlayNeighborArrow(cluster.get(i));
02605 
02606         /* Put all members to first vector */
02607         vec1.push_back(cluster.get(i));
02608         //EV << "vec1.push_back(cluster.get(i)): " << cluster.get(i).getAddress() << endl;
02609 
02610         /* Put first half of members to second vector */
02611         if (i < cluster.getSize()/2) {
02612             vec2.push_back(cluster.get(i));
02613             //EV << "vec2.push_back(cluster.get(i)): " << cluster.get(i).getAddress() << endl;
02614         }
02615 
02616     }
02617 
02618     int combinations = 0;
02619 
02620     TaSet cl1set, cl2set, newClSet;
02621     TaSet::iterator sit;
02622 
02623     if (cluster.getSize() < /*(6*k-1)*/18) {
02624 
02625         /* Go through all combinations of clusters */
02626         do {
02627 
02628             combinations++;
02629 
02630             //EV << "combinations: " << combinations << endl;
02631 
02632             /* Introduce some helper structures */
02633             TransportAddress q1_center;
02634             TransportAddress q2_center;
02635             std::vector<TransportAddress> vec3;
02636 
02637             /* Determine elements that are in first set but not in second */
02638             std::set_difference(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), inserter(vec3, vec3.begin()));
02639 
02640             simtime_t min_q1_delay = 999;
02641             simtime_t min_q2_delay = 999;
02642             simtime_t max_delay = 0;
02643 
02644             q1_center = findCenter(vec2).first;
02645 
02646             //EV << "q1_center: " << q1_center.getAddress() << endl;
02647 
02648             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(q1_center);
02649 
02650             if (it != peerInfos.end()) {
02651 
02652                 min_q1_delay = it->second->get_distance();
02653 
02654             } else {
02655 
02656                 min_q1_delay = 0;
02657 
02658             }
02659 
02660             q2_center = findCenter(vec3).first;
02661 
02662             //EV << "q2_center: " << q2_center.getAddress() << endl;
02663 
02664             it = peerInfos.find(q2_center);
02665 
02666             if (it != peerInfos.end()) {
02667 
02668                 min_q2_delay = it->second->get_distance();
02669 
02670             } else {
02671 
02672                 min_q2_delay = 0;
02673 
02674             }
02675 
02676             max_delay = std::max(min_q1_delay, min_q2_delay);
02677 
02678             if (min_delay == 0) min_delay = max_delay;
02679 
02680             if ((max_delay < min_delay) && !q1_center.isUnspecified() && !q2_center.isUnspecified()) {
02681 
02682                 min_delay = max_delay;
02683                 cl1 = vec2;
02684                 cl2 = vec3;
02685                 cl1_center = q1_center;
02686                 cl2_center = q2_center;
02687             }
02688 
02689             //isplay(q1.begin(),q1.end());
02690 
02691         } while (next_combination(vec1.begin(), vec1.end(), vec2.begin(), vec2.end()));
02692 
02693         //EV << "COMBINATIONS: " << combinations << endl;
02694 
02695         //build sets
02696         std::vector<TransportAddress>::iterator vit;
02697 
02698         //EV << "cl1_center: " << cl1_center << endl;
02699         //EV << "cl2_center: " << cl2_center << endl;
02700 
02701         vit = cl1.begin();
02702         while (vit != cl1.end()) {
02703             cl1set.insert(*vit);
02704             vit++;
02705         }
02706 
02707         vit = cl2.begin();
02708         while (vit != cl2.end()) {
02709             cl2set.insert(*vit);
02710             vit++;
02711         }
02712 
02713     } else {
02714 
02715     }
02716 
02717     //if no valid split possible, split randomly
02718     if (cl1_center.isUnspecified() || cl2_center.isUnspecified()) {
02719         EV << thisNode.getAddress() << " RANDOM SPLIT" << endl;
02720         cl1set.clear();
02721         cl2set.clear();
02722         for (int i=0; i<cluster.getSize(); i++) {
02723             if (i < cluster.getSize()/2) {
02724                 cl1set.insert(cluster.get(i));
02725             } else {
02726                 cl2set.insert(cluster.get(i));
02727             }
02728         }
02729         cl1_center = findCenter(cl1set,true).first;
02730         cl2_center = findCenter(cl2set,true).first;
02731     }
02732 
02733     //find new neighbors
02734     TransportAddress newLeader, otherLeader;
02735     TaSet newCl;
02736     TaSet::iterator it = cl1set.begin();
02737     while (it != cl1set.end()) {
02738         if (*it == thisNode) {
02739             newCl = cl1set;
02740             newLeader = cl1_center;
02741             otherLeader = cl2_center;
02742         }
02743         it++;
02744     }
02745 
02746     it = cl2set.begin();
02747     while (it != cl2set.end()) {
02748         if (*it == thisNode) {
02749             newCl = cl2set;
02750             newLeader = cl2_center;
02751             otherLeader = cl1_center;
02752         }
02753         it++;
02754 
02755     }
02756 
02757     //####################################################################
02758 
02759     // Cluster split accomplished, now handling consequences
02760 
02761     // CASE 1: We lost all cluster leaderships
02762     // repair all cluster layer, top down
02763     if ((cl1_center != thisNode) && (cl2_center != thisNode)) {
02764 
02765         gracefulLeave(layer);
02766 
02767         if (clusters[layer+1].getSize() == 0) {
02768 
02769             clusters[layer+1].add(cl1_center);
02770             clusters[layer+1].add(cl2_center);
02771             clusters[layer+1].setLeader(cl1_center);
02772             RendevouzPoint = cl1_center;
02773             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << cl1_center.getAddress() << endl;
02774 
02775 
02776         }
02777 
02778         LeaderTransfer(layer, cl1_center, cl1set, cl1_center);
02779         LeaderTransfer(layer, cl2_center, cl2set, cl1_center);
02780 
02781         getParentModule()->getParentModule()
02782         ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02783 
02784     } // CASE 1
02785 
02786 
02787     // CASE 2: We stay leader in one of the new clusters
02788     if ((cl1_center == thisNode) || (cl2_center == thisNode)) {
02789 
02790         if (clusters[layer+1].getSize() == 0) {
02791 
02792             clusters[layer+1].add(cl1_center);
02793             clusters[layer+1].add(cl2_center);
02794 
02795             clusters[layer+1].setLeader(thisNode);
02796 
02797 
02798         }
02799 
02800         if (cl1_center == thisNode) {
02801 
02802             clusters[layer+1].add(cl2_center);
02803             LeaderTransfer(layer, cl2_center, cl2set, cl1_center);
02804 
02805         } else {
02806 
02807             clusters[layer+1].add(cl1_center);
02808             LeaderTransfer(layer, cl1_center, cl1set, cl1_center);
02809 
02810         }
02811 
02812 
02813     } // CASE 2
02814 
02815     // update local cluster information for focussed layer
02816     TaSet::const_iterator cit = cl1set.begin();
02817     bool found = false;
02818     while (cit != cl1set.end()) {
02819 
02820         if (*cit == thisNode)
02821             found = true;
02822         cit++;
02823     }
02824 
02825     clusters[layer].clear();
02826 
02827     if (found) {
02828 
02829         clusters[layer].setLeader(cl1_center);
02830 
02831         cit = cl1set.begin();
02832         while (cit != cl1set.end()) {
02833             clusters[layer].add(*cit);
02834             cit++;
02835         }
02836 
02837     } else {
02838 
02839         clusters[layer].setLeader(cl2_center);
02840 
02841         cit = cl2set.begin();
02842         while (cit != cl2set.end()) {
02843             clusters[layer].add(*cit);
02844             cit++;
02845         }
02846 
02847     }
02848 
02849     //update arrows
02850     updateVisualization();
02851 
02852     if (pimp)
02853         sendHeartbeats();
02854 
02855 } // ClusterSplit

std::pair< TransportAddress, simtime_t > oversim::Nice::findCenter ( std::vector< TransportAddress cluster,
bool  allowRandom = false 
) [private]

Definition at line 3092 of file Nice.cc.

03093 {
03094     TaSet clusterset;
03095     std::vector<TransportAddress>::const_iterator it = cluster.begin();
03096 
03097     //EV << "cluster.size(): " << cluster.size() << endl;
03098 
03099     while (it != cluster.end()) {
03100         clusterset.insert(*it);
03101         it++;
03102     }
03103     return findCenter(clusterset, allowRandom);
03104 
03105 } // findCenter

std::pair< TransportAddress, simtime_t > oversim::Nice::findCenter ( TaSet  cluster,
bool  allowRandom = false 
) [private]

Definition at line 3052 of file Nice.cc.

Referenced by ClusterMerge(), ClusterSplit(), findCenter(), gracefulLeave(), and maintenance().

03053 {
03054 
03055     TaSet::const_iterator it = cluster.begin();
03056     TransportAddress center = TransportAddress::UNSPECIFIED_NODE;
03057     simtime_t min_delay = 1000;
03058 
03059     if (cluster.size() > 1) {
03060 
03061         while (it != cluster.end()) {
03062 
03063             //if (*it != thisNode) {
03064 
03065             simtime_t delay = getMaxDistance(*it, cluster);
03066 
03067             if ((delay > 0) && (delay < min_delay)) {
03068 
03069                 min_delay = delay;
03070                 center = *it;
03071 
03072             }
03073 
03074             //}
03075             it++;
03076         }
03077 
03078     }
03079 
03080     if (center.isUnspecified()) {
03081         center = *(cluster.begin());
03082     }
03083     //EV << "center: " << center << endl;
03084     return std::make_pair(center, min_delay);
03085 
03086 } // findCenter

TransportAddress oversim::Nice::findClusterLeader ( NiceCluster  cluster  )  [private]

Definition at line 3025 of file Nice.cc.

03026 {
03027 
03028     // Determine if there is a more fitting cluster leader than me
03029 
03030     // First, get own maxDistance for this Cluster
03031     std::set<TransportAddress> clusterset;
03032 
03033     for (int i=0; i<cluster.getSize(); i++) {
03034 
03035         clusterset.insert(cluster.get(i));
03036         EV << simTime() << " : " << thisNode.getAddress() << " : MaxDistance: "
03037         << cluster.get(i).getAddress() << " : " << getMaxDistance(cluster.get(i), clusterset) << endl;
03038 
03039     }
03040 
03041     //simtime_t myDistance = getMaxDistance(thisNode, clusterset);
03042 
03043     //EV << simTime() << " : " << thisNode.getAddress() << " : myMaxDistance: " << myDistance << endl;
03044 
03045 
03046 } // findClusterLeader

void oversim::Nice::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

Definition at line 730 of file Nice.cc.

00731 {
00732 
00733 
00734 } // finishOverlay

short oversim::Nice::getHighestLayer (  )  [private]

Definition at line 961 of file Nice.cc.

Referenced by becomeRendevouzPoint(), changeState(), handleTimerEvent(), handleUDPMessage(), maintenance(), sendHeartbeats(), and updateVisualization().

00962 {
00963 
00964     short highest = -1;
00965 
00966     for (short i=0; i<maxLayers; i++) {
00967 
00968         if (clusters[i].contains(thisNode))
00969 
00970             highest = i;
00971 
00972     }
00973 
00974     return highest;
00975 
00976 } // getHighestLayer

short oversim::Nice::getHighestLeaderLayer (  )  [private]

Definition at line 939 of file Nice.cc.

Referenced by handleQuery(), and handleUDPMessage().

00940 {
00941 
00942     short highest = -1;
00943 
00944     for (short i=0; i<maxLayers; i++) {
00945 
00946         if (!clusters[i].getLeader().isUnspecified())
00947 
00948             if (clusters[i].getLeader() == thisNode)
00949                 highest = i;
00950 
00951     }
00952 
00953     return highest;
00954 
00955 } // getHighestLeaderLayer

simtime_t oversim::Nice::getMaxDistance ( TransportAddress  member,
std::set< TransportAddress neighbors 
) [private]

Definition at line 3111 of file Nice.cc.

Referenced by findCenter(), findClusterLeader(), handleHeartbeat(), and maintenance().

03112 {
03113     simtime_t maxDelay = 0;
03114     simtime_t delay = 0;
03115 
03116     if (member == thisNode) {
03117 
03118         std::set<TransportAddress>::iterator it = neighbors.begin();
03119 
03120         while (it != neighbors.end()) {
03121 
03122             std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(*it);
03123 
03124             if (it2 != peerInfos.end()) {
03125 
03126                 delay = it2->second->get_distance();
03127                 maxDelay = std::max(delay, maxDelay);
03128 
03129             }
03130 
03131             it++;
03132 
03133         }
03134 
03135     } else {
03136 
03137         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(member);
03138 
03139         if (it != peerInfos.end()) {
03140 
03141             std::set<TransportAddress>::iterator it2 = neighbors.begin();
03142 
03143             while (it2 != neighbors.end()) {
03144 
03145                 //EV << "getDistanceTo " << *it2 << endl;
03146                 delay = it->second->getDistanceTo(*it2);
03147                 //EV << thisNode.getAddress() << " : Distance to " << it2->getAddress() << " : " << delay << endl;
03148                 maxDelay = std::max(delay, maxDelay);
03149 
03150                 it2++;
03151 
03152             }
03153 
03154         }
03155 
03156     }
03157 
03158     return maxDelay;
03159 
03160 } // getMaxDistance

simtime_t oversim::Nice::getMeanDistance ( std::set< TransportAddress neighbors  )  [private]

Definition at line 3165 of file Nice.cc.

Referenced by maintenance().

03166 {
03167     simtime_t meanDelay = 0;
03168     simtime_t delay = 0;
03169     unsigned int number = 0;
03170 
03171     std::set<TransportAddress>::iterator it = neighbors.begin();
03172 
03173     while (it != neighbors.end()) {
03174 
03175         if (*it != thisNode) {
03176 
03177             std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(*it);
03178 
03179             if (it2 != peerInfos.end()) {
03180 
03181                 delay = it2->second->get_distance();
03182                 //EV << "delay to " << *it << " : " << delay << endl;
03183 
03184                 if  (delay > 0.0) {
03185 
03186                     meanDelay += delay;
03187                     number++;
03188 
03189                 }
03190 
03191             }
03192 
03193         }
03194 
03195         it++;
03196 
03197     }
03198 
03199     if (number > 0) {
03200 
03201         return meanDelay/number;
03202 
03203     } else {
03204 
03205         return 0;
03206 
03207     }
03208 
03209 } // getMeanDistance

void oversim::Nice::gracefulLeave ( short  bottomLayer  )  [private]

Definition at line 3303 of file Nice.cc.

Referenced by ClusterSplit(), handleHeartbeat(), and maintenance().

03304 {
03305     EV << simTime() << " : " << thisNode.getAddress() << " : gracefulLeave()" << endl;
03306 
03307     for (int i=maxLayers-1; i>bottomLayer; i--) {
03308 
03309         if (clusters[i].getSize() > 0) {
03310 
03311             if (clusters[i].contains(thisNode)) {
03312 
03313                 EV << "REPAIR: " << i << endl;
03314 
03315                 if (clusters[i].getLeader() == thisNode) {
03316 
03317                     EV << "remove from: " << i << endl;
03318                     Remove(i);
03319 
03320                     if (clusters[i].getSize() > 0) {
03321 
03322                         TaSet cl;
03323                         for (int j=0; j<clusters[i].getSize(); j++) {
03324 
03325                             cl.insert(clusters[i].get(j));
03326 
03327                             EV << "rest: " << clusters[i].get(j).getAddress() << endl;
03328 
03329                             deleteOverlayNeighborArrow(clusters[i].get(j));
03330 
03331                         }
03332 
03333                         TransportAddress new_sc_center = findCenter(cl).first;
03334 
03335                         EV << "NEW LEADER (GL): " << i << " --> " << new_sc_center.getAddress() << endl;
03336 
03337                         if (new_sc_center.isUnspecified()) {
03338 
03339                             new_sc_center = clusters[i].get(0);
03340 
03341                             EV << "UNSPECIFIED! instead choose: " << new_sc_center.getAddress() << endl;
03342 
03343                         }
03344 
03345                         clusters[i].setLeader(new_sc_center);
03346 
03347                         LeaderTransfer(i, new_sc_center, cl, new_sc_center);
03348 
03349                         // repair RP
03350                         if (i == maxLayers-1) {
03351 
03352                             RendevouzPoint = new_sc_center;
03353                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
03354 
03355                         } else if (clusters[i+1].getSize() == 0) {
03356 
03357                             RendevouzPoint = new_sc_center;
03358                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
03359 
03360                         }
03361 
03362                     }
03363 
03364                 } else {
03365 
03366                     // simply leave cluster
03367                     EV << "removing " << thisNode.getAddress() << " from " << i << endl;
03368                     Remove(i);
03369                     clusters[i].remove(thisNode);
03370 
03371                 }
03372 
03373             }
03374 
03375         }
03376 
03377     }
03378 
03379     EV << simTime() << " : " << thisNode.getAddress() << " : gracefulLeave() finished." << endl;
03380 
03381 
03382 } // gracefulLeave

void oversim::Nice::handleAppMessage ( cMessage *  msg  )  [virtual]

Processes "timer" self-messages.

Parameters:
msg A self-message Processes non-commonAPI messages
msg non-commonAPIMessage

Reimplemented from BaseOverlay.

Definition at line 3388 of file Nice.cc.

03389 {
03390 
03391     if (dynamic_cast<CbrAppMessage*>(msg)) {
03392 
03393         CbrAppMessage *appMsg = check_and_cast<CbrAppMessage*>(msg);
03394 
03395         switch (appMsg->getCommand()) {
03396 
03397         case CBR_DATA: {
03398 
03399             appMsg->setLayer(-1);
03400             appMsg->setSrcNode(thisNode);
03401             appMsg->setLastHop(thisNode);
03402             appMsg->setHopCount(0);
03403 
03404             appMsg->setBitLength(CBRAPPMSG_L(msg));
03405 
03406             sendDataToOverlay(appMsg);
03407 
03408         }
03409 
03410         break;
03411         }
03412 
03413     } else {
03414 
03415         delete msg;
03416 
03417     }
03418 
03419 } // handleAppMessage

void oversim::Nice::handleHeartbeat ( NiceMessage msg  )  [private]

Definition at line 1567 of file Nice.cc.

Referenced by handleUDPMessage().

01568 {
01569 
01570     if (debug_heartbeats)
01571         EV << simTime() << " : " << thisNode.getAddress() << " : handleHeartbeat()...  " << endl;
01572 
01573 
01574     // First, check if heartbeat is LeaderTransfer
01575     if (msg->getCommand() == NICE_LEADERTRANSFER) {
01576 
01577         if (debug_heartbeats)
01578             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_LEADERTRANSFER from " << msg->getSrcNode() << " for " << msg->getLayer() << endl;
01579 
01580         if (!clusters[msg->getLayer()].getLeader().isUnspecified()) {
01581 
01582             /* React only if I am not already leader */
01583             if (clusters[msg->getLayer()].getLeader() != thisNode /*&& clusters[msg->getLayer()].getLeader() == msg->getSrcNode()*/) {
01584 
01585                 if (debug_heartbeats)
01586                     EV << "I am not already leader of this cluster layer." << endl;
01587 
01588                 NiceLeaderHeartbeat* hbMsg = check_and_cast<NiceLeaderHeartbeat*>(msg);
01589 
01590                 clusters[hbMsg->getLayer()].clear();
01591                 clusters[hbMsg->getLayer()].setLeader(thisNode);
01592 
01593                 for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01594 
01595                     if (debug_heartbeats)
01596                         EV << "Adding: " << hbMsg->getMembers(i) << endl;
01597 
01598                     clusters[hbMsg->getLayer()].add(hbMsg->getMembers(i));
01599                     showOverlayNeighborArrow(hbMsg->getMembers(i), false, clusterarrows[hbMsg->getLayer()]);
01600 
01601                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getMembers(i));
01602 
01603                     if (it != peerInfos.end()) { /* We already know this node */
01604 
01605                         it->second->touch();
01606 
01607                     } else {
01608 
01609                         //We don't know him yet
01610 
01611                     }
01612 
01613                 }
01614 
01615                 if (hbMsg->getSupercluster_membersArraySize() > 0) {
01616 
01617                     clusters[hbMsg->getLayer()+1].clear();
01618 
01619                     for (unsigned int i=0; i<hbMsg->getSupercluster_membersArraySize(); i++) {
01620 
01621                         clusters[hbMsg->getLayer()+1].add(hbMsg->getSupercluster_members(i));
01622 
01623                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSupercluster_members(i));
01624 
01625                         if (it != peerInfos.end()) { /* We already know this node */
01626 
01627                             it->second->touch();
01628 
01629                         } else {
01630 
01631                             //We don't know him yet
01632 
01633                         }
01634 
01635                     }
01636 
01637                     // experimental
01638                     clusters[hbMsg->getLayer()+1].add(thisNode);
01639 
01640                     clusters[hbMsg->getLayer()+1].setLeader(hbMsg->getSupercluster_leader());
01641 
01642                     if ((clusters[hbMsg->getLayer()+1].getLeader() == thisNode) && (clusters[hbMsg->getLayer()+2].getSize() == 0)) {
01643 
01644                         for (unsigned int i=0; i<hbMsg->getSupercluster_membersArraySize(); i++) {
01645 
01646                             showOverlayNeighborArrow(hbMsg->getSupercluster_members(i), false, clusterarrows[hbMsg->getLayer()+1]);
01647 
01648                         }
01649 
01650                         becomeRendevouzPoint();
01651 
01652                     } else {
01653 
01654                         JoinCluster(hbMsg->getSupercluster_leader(), hbMsg->getLayer()+1);
01655 
01656                     }
01657 
01658                 } else {
01659 
01660                     becomeRendevouzPoint();
01661 
01662                 }
01663 
01664                 for (int i=0; i<maxLayers; i++) {
01665 
01666                     if (clusters[i].contains(thisNode))
01667                         getParentModule()->getParentModule()->getDisplayString().setTagArg
01668                         ("i2", 1, clustercolors[i]);
01669 
01670                 }
01671 
01672                 clusters[hbMsg->getLayer()].set_Last_LT();
01673 
01674                 delete hbMsg;
01675 
01676             } else {
01677 
01678                 //Do nothing
01679 
01680             }
01681 
01682         } else {
01683 
01684 
01685 
01686         }
01687 
01688         if (pimp)
01689             sendHeartbeats();
01690 
01691         return;
01692 
01693     } else if (msg->getCommand() == NICE_HEARTBEAT) {
01694 
01695         NiceHeartbeat* hbMsg = check_and_cast<NiceHeartbeat*>(msg);
01696 
01697         if (debug_heartbeats)
01698             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_HEARTBEAT from  " << hbMsg->getSrcNode() << endl;
01699 
01700         /* Update sequence number information and evaluate distance */
01701         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSrcNode());
01702 
01703         if (it != peerInfos.end()) { /* We already know this node */
01704 
01705             // Collect subcluster infos
01706             it->second->setSubClusterMembers(hbMsg->getSublayermembers());
01707 
01708             it->second->set_last_HB_arrival(simTime().dbl());
01709 
01710             if (it->second->get_backHB(hbMsg->getSeqRspNo()) > 0) {
01711 
01712                 /* Valid distance measurement, get value */
01713                 double oldDistance = it->second->get_distance();
01714 
01715                 /* Use Exponential Moving Average with factor 0.1 */
01716                 double newDistance = (simTime().dbl() - it->second->get_backHB(hbMsg->getSeqRspNo()) - hbMsg->getHb_delay())/2.0;
01717 
01718                 if (oldDistance > 0) {
01719 
01720                     it->second->set_distance((0.1 * newDistance) + (0.9 * oldDistance));
01721 
01722                 } else {
01723 
01724                     it->second->set_distance(newDistance);
01725 
01726                 }
01727 
01728             }
01729 
01730             it->second->set_last_recv_HB(hbMsg->getSeqNo());
01731 
01732         }
01733 
01734         it = peerInfos.find(hbMsg->getSrcNode());
01735 
01736         if (it != peerInfos.end()) {
01737 
01738             for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01739 
01740                 it->second->updateDistance(hbMsg->getMembers(i), hbMsg->getDistances(i));
01741 
01742             }
01743 
01744         }
01745 
01746         delete hbMsg;
01747 
01748     } else if (msg->getCommand() == NICE_LEADERHEARTBEAT) {
01749 
01750 
01751         NiceLeaderHeartbeat* hbMsg = check_and_cast<NiceLeaderHeartbeat*>(msg);
01752 
01753         if (debug_heartbeats)
01754             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_LEADERHEARTBEAT from  " << hbMsg->getSrcNode() << endl;
01755 
01756         //Alternative Detection
01757         leaderHeartbeats.push_back(std::make_pair(hbMsg->getSrcNode(), simTime()));
01758 
01759         if (leaderHeartbeats.size() > 3) {
01760 
01761             if (debug_heartbeats)
01762                 EV << simTime() << "leaderHeartbeats.size() > 3 :  " << leaderHeartbeats.size() << endl;
01763 
01764             simtime_t predecessor =  leaderHeartbeats.at(leaderHeartbeats.size()-2).second;
01765 
01766             if (debug_heartbeats)
01767                 EV << simTime() << "predecessor :  " << predecessor << endl;
01768 
01769 
01770             if (simTime() < (predecessor + heartbeatInterval)) {
01771 
01772                 if (debug_heartbeats)
01773                     EV << simTime() << "simTime() < (predecessor + heartbeatInterval)" << endl;
01774 
01775                 if (leaderHeartbeats.at(leaderHeartbeats.size()-2).first != hbMsg->getSrcNode()) {
01776 
01777                     if (debug_heartbeats) {
01778                         EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-2).first != hbMsg->getSrcNode())" << endl;
01779                         EV << "leaderHeartbeats.at(leaderHeartbeats.size()-2).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-2).first << endl;
01780                     }
01781 
01782                     if (leaderHeartbeats.at(leaderHeartbeats.size()-3).first == hbMsg->getSrcNode()) {
01783 
01784                         if (debug_heartbeats) {
01785                             EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-3).first == hbMsg->getSrcNode())" << endl;
01786                             EV << "leaderHeartbeats.at(leaderHeartbeats.size()-3).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-3).first << endl;
01787                             EV << "timestamp: " << leaderHeartbeats.at(leaderHeartbeats.size()-3).second << endl;
01788                         }
01789 
01790                         if (leaderHeartbeats.at(leaderHeartbeats.size()-4).first == leaderHeartbeats.at(leaderHeartbeats.size()-2).first) {
01791 
01792                             if (debug_heartbeats) {
01793                                 EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-4).first == leaderHeartbeats.at(leaderHeartbeats.size()-2).first" << endl;
01794                                 EV << "leaderHeartbeats.at(leaderHeartbeats.size()-4).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-4).first << endl;
01795                                 EV << "timestamp: " << leaderHeartbeats.at(leaderHeartbeats.size()-4).second << endl;
01796 
01797                             }
01798 
01799                             if (debug_heartbeats)
01800                                 EV << simTime() << " : " << thisNode.getAddress() << " : CONFLICTING LEADERS!" << endl;
01801 
01802                             NiceMessage* msg = new NiceMessage("NICE_REMOVE");
01803                             msg->setSrcNode(thisNode);
01804                             msg->setCommand(NICE_REMOVE);
01805                             msg->setLayer(hbMsg->getLayer());
01806 
01807                             msg->setBitLength(NICEMESSAGE_L(msg));
01808 
01809                             sendMessageToUDP(leaderHeartbeats.at(leaderHeartbeats.size()-2).first, msg);
01810 
01811                         }
01812 
01813                     }
01814 
01815                 }
01816             }
01817 
01818         }
01819 
01820 
01821         /* Tidy up leaderheartbeats */
01822         if (leaderHeartbeats.size() > 4) {
01823 
01824             for (unsigned int i=0; i<(leaderHeartbeats.size()-4); i++) {
01825 
01826                 leaderHeartbeats.erase(leaderHeartbeats.begin());
01827 
01828             }
01829 
01830         }
01831 
01832         /* Update sequence number information and evaluate distance */
01833         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSrcNode());
01834 
01835         if (it != peerInfos.end()) { /* We already know this node */
01836 
01837             it->second->set_last_HB_arrival(simTime().dbl());
01838 
01839             if (it->second->get_backHB(hbMsg->getSeqRspNo()) > 0) {
01840 
01841                 /* Valid distance measurement, get value */
01842                 it->second->set_distance((simTime().dbl() - it->second->get_backHB(hbMsg->getSeqRspNo()) - hbMsg->getHb_delay())/2);
01843 
01844             }
01845 
01846             it->second->set_last_recv_HB(hbMsg->getSeqNo());
01847 
01848         }
01849 
01850         it = peerInfos.find(hbMsg->getSrcNode());
01851 
01852         if (it != peerInfos.end()) {
01853 
01854             for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01855 
01856                 it->second->updateDistance(hbMsg->getMembers(i), hbMsg->getDistances(i));
01857 
01858             }
01859 
01860         }
01861 
01862         // Maintain cluster memberships
01863 
01864         if (!clusters[hbMsg->getLayer()].contains(thisNode)) {
01865 
01866             /* Node is not part of this cluster, remove it */
01867             NiceMessage* msg = new NiceMessage("NICE_REMOVE");
01868             msg->setSrcNode(thisNode);
01869             msg->setCommand(NICE_REMOVE);
01870             msg->setLayer(hbMsg->getLayer());
01871 
01872             msg->setBitLength(NICEMESSAGE_L(msg));
01873 
01874             if (debug_heartbeats)
01875                 EV << "Node is not part of this cluster (" << hbMsg->getLayer() << "), removing it..." << endl;
01876 
01877             sendMessageToUDP(hbMsg->getSrcNode(), msg);
01878 
01879             return;
01880 
01881         }
01882 
01883         if (clusters[hbMsg->getLayer()].getLeader() == thisNode) {
01884 
01885             if (simTime() < clusters[hbMsg->getLayer()].get_Last_LT() + 1.0) {
01886 
01887                 if (debug_heartbeats)
01888                     EV << "Potential deprecated LeaderHeartbeat. Ignoring..." << endl;
01889 
01890                 return;
01891 
01892             }
01893 
01894             if (debug_heartbeats)
01895                 EV << "I am also Leader in this cluster. Conflicting!..." << endl;
01896 
01897             /* Winner: The one with minimum max distance*/
01898             bool allIn = true;
01899 
01900             //Check if we're talking about same cluster
01901 
01902             for (unsigned int u=0; u<hbMsg->getMembersArraySize(); u++) {
01903 
01904                 if (!clusters[hbMsg->getLayer()].contains(hbMsg->getMembers(u))) {
01905                     allIn = false;
01906 
01907                     if (debug_heartbeats)
01908                         EV << hbMsg->getMembers(u) << " : Not in my cluster." << endl;
01909 
01910                 } else {
01911 
01912                     if (debug_heartbeats)
01913                         EV << hbMsg->getMembers(u) << " : Check." << endl;
01914 
01915                 }
01916 
01917             }
01918 
01919             if (allIn) {
01920 
01921                 // Perform check for better cluster leader
01922                 TaSet cl;
01923                 for (int l=0; l<clusters[hbMsg->getLayer()].getSize(); l++) {
01924 
01925                     cl.insert(clusters[hbMsg->getLayer()].get(l));
01926 
01927                 }
01928 
01929                 simtime_t myDistance = getMaxDistance(thisNode, cl);
01930                 simtime_t hisDistance = getMaxDistance(hbMsg->getSrcNode(), cl);
01931 
01932 
01933                 if (myDistance > hisDistance) {
01934 
01935                     TaSet cl;
01936                     for (int i=0; i<clusters[hbMsg->getLayer()].getSize(); i++) {
01937 
01938                         cl.insert(clusters[hbMsg->getLayer()].get(i));
01939 
01940                         deleteOverlayNeighborArrow(clusters[hbMsg->getLayer()].get(i));
01941 
01942                     }
01943                     LeaderTransfer(hbMsg->getLayer(), hbMsg->getSrcNode(), cl, clusters[hbMsg->getLayer()+1].getLeader());
01944 
01945                     clusters[hbMsg->getLayer()].setLeader(hbMsg->getSrcNode());
01946 
01947                     gracefulLeave(hbMsg->getLayer());
01948 
01949                     /* Anyways, update cluster info */
01950 
01951                 } else {
01952 
01953                     sendHeartbeatTo(hbMsg->getSrcNode(), hbMsg->getLayer());
01954 
01955                     return;
01956 
01957                 }
01958 
01959             } else { // We have different children, simply leave other
01960 
01961                 /* Remove it */
01962                 NiceMessage* msg = new NiceMessage("NICE_REMOVE");
01963                 msg->setSrcNode(thisNode);
01964                 msg->setCommand(NICE_REMOVE);
01965                 msg->setLayer(hbMsg->getLayer());
01966 
01967                 msg->setBitLength(NICEMESSAGE_L(msg));
01968 
01969                 sendMessageToUDP(hbMsg->getSrcNode(), msg);
01970 
01971                 return;
01972 
01973             }
01974         }
01975 
01976         /* Everything is in order. Process HB */
01977 
01978         for (int m=hbMsg->getLayer(); m<maxLayers; m++) {
01979             clusters[m].clear();
01980         }
01981 
01982         for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01983 
01984             //Check if member is already part of cluster
01985 
01986             /* Check if peer info already exists */
01987             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getMembers(i));
01988 
01989             if (it != peerInfos.end()) { /* We already know this node */
01990 
01991             } else { /* Create PeerInfo object */
01992 
01993                 NicePeerInfo* pi = new NicePeerInfo(this);
01994 
01995                 pi->set_last_HB_arrival(simTime().dbl());
01996 
01997                 peerInfos.insert(std::make_pair(hbMsg->getMembers(i), pi));
01998 
01999             }
02000 
02001             clusters[hbMsg->getLayer()].add(hbMsg->getMembers(i));
02002 
02003         }
02004 
02005         // set cluster leadership
02006         clusters[hbMsg->getLayer()].setLeader(hbMsg->getSrcNode());
02007 
02008         if (hbMsg->getSupercluster_membersArraySize() > 0) {
02009 
02010             clusters[hbMsg->getLayer()+1].clear();
02011 
02012             for (unsigned int i=0; i<hbMsg->getSupercluster_membersArraySize(); i++) {
02013 
02014                 /* Check if peer info already exists */
02015                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSupercluster_members(i));
02016 
02017                 if (it != peerInfos.end()) { /* We already know this node */
02018 
02019                 } else { /* Create PeerInfo object */
02020 
02021                     NicePeerInfo* pi = new NicePeerInfo(this);
02022 
02023                     pi->set_last_HB_arrival(simTime().dbl());
02024 
02025                     peerInfos.insert(std::make_pair(hbMsg->getSupercluster_members(i), pi));
02026 
02027                 }
02028 
02029                 clusters[hbMsg->getLayer()+1].add(hbMsg->getSupercluster_members(i));
02030 
02031             }
02032 
02033             clusters[hbMsg->getLayer()+1].setLeader(hbMsg->getSupercluster_leader());
02034 
02035             it = peerInfos.find(hbMsg->getSrcNode());
02036 
02037             if (it != peerInfos.end()) {
02038 
02039                 for (unsigned int k=0; k<hbMsg->getMembersArraySize(); k++) {
02040 
02041                     it->second->updateDistance(hbMsg->getMembers(k), hbMsg->getDistances(k));
02042 
02043                 }
02044 
02045             } else {
02046 
02047                 NicePeerInfo* pi = new NicePeerInfo(this);
02048 
02049                 pi->set_last_HB_arrival(simTime().dbl());
02050 
02051                 peerInfos.insert(std::make_pair(hbMsg->getSrcNode(), pi));
02052 
02053             }
02054         }
02055 
02056         delete hbMsg;
02057 
02058     }
02059 
02060     if (debug_heartbeats)
02061         EV << simTime() << " : " << thisNode.getAddress() << " : handleHeartbeat() finished.  " << endl;
02062 
02063 
02064 } // handleHeartbeat

void oversim::Nice::handleJoinCluster ( NiceMessage joinMsg  )  [private]

Definition at line 1134 of file Nice.cc.

Referenced by handleUDPMessage().

01135 {
01136 
01137     if (debug_join)
01138         EV << simTime() << " : " << thisNode.getAddress() << " : handleJoinCluster()" << endl;
01139 
01140     short layer = joinMsg->getLayer();
01141 
01142     if (debug_join)
01143         std::cout << " From : " << joinMsg->getSrcNode() << ", Layer:  " << layer << endl;
01144 
01145     if (!clusters[layer].getLeader().isUnspecified()) {
01146 
01147         if (clusters[layer].getLeader() != thisNode) {
01148 
01149             if (pimp) {
01150 
01151                 NiceMessage* dup = static_cast<NiceMessage*>(joinMsg->dup());
01152                 sendMessageToUDP(clusters[layer].getLeader(), dup);
01153 
01154             }
01155 
01156             return;
01157 
01158         }
01159 
01160         /* Add new node to cluster */
01161         clusters[layer].add(joinMsg->getSrcNode());
01162 
01163         /* Create peer context to joining node */
01164         /* Check if peer info already exists */
01165         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(joinMsg->getSrcNode());
01166 
01167         if (it != peerInfos.end()) { /* We already know this node */
01168 
01169 
01170         } else { /* Create PeerInfo object */
01171 
01172             NicePeerInfo* pi = new NicePeerInfo(this);
01173 
01174             peerInfos.insert(std::make_pair(joinMsg->getSrcNode(), pi));
01175 
01176         }
01177 
01178         /* Draw arrow to new member */
01179         showOverlayNeighborArrow(joinMsg->getSrcNode(), false, clusterarrows[layer]);
01180 
01181         if (pimp)
01182             sendHeartbeatTo(joinMsg->getSrcNode(), layer);
01183 
01184     } else {
01185 
01186         if (debug_join)
01187             EV << "Leader unspecified. Ignoring request." << endl;
01188 
01189     }
01190 
01191     if (debug_join)
01192         EV << simTime() << " : " << thisNode.getAddress() << " : handleJoinCluster() finished." << endl;
01193 
01194 
01195 } // handleJoinCluster

void oversim::Nice::handleQuery ( NiceMessage queryMsg  )  [private]

Definition at line 825 of file Nice.cc.

Referenced by handleUDPMessage().

00826 {
00827 
00828     if (debug_queries)
00829         EV << simTime() << " : " << thisNode.getAddress() << " : handleQuery()" << endl;
00830 
00831     short layer = queryMsg->getLayer();
00832 
00833     if (debug_queries)
00834         EV << " layer before: " << layer << endl;
00835 
00836     if (layer > getHighestLeaderLayer()) {
00837 
00838         if (debug_queries)
00839             EV << " getHighestLeaderLayer(): " << getHighestLeaderLayer() << " ! Returning." << endl;
00840 
00841         return;
00842 
00843     }
00844 
00845     if (layer < 0) {
00846 
00847         if (RendevouzPoint == thisNode) {
00848 
00849             /* If layer is < 0, response with highest layer I am leader of */
00850             if (debug_queries)
00851                 EV << " I am RP." << endl;
00852             layer = getHighestLeaderLayer();
00853 
00854         } else {
00855 
00856             if (debug_queries)
00857                 EV << " I am not RP. Return." << endl;
00858 
00859             if (pimp) {
00860 
00861                 /* forward to Rendevouz Point */
00862                 NiceMessage* dup = static_cast<NiceMessage*>(queryMsg->dup());
00863                 sendMessageToUDP(RendevouzPoint, dup);
00864 
00865             }
00866 
00867             return;
00868 
00869         }
00870 
00871     }
00872 
00873     if (debug_queries)
00874         EV << " layer after: " << layer << endl;
00875 
00876     if (!clusters[layer].getLeader().isUnspecified()) {
00877 
00878         if (clusters[layer].getLeader() != thisNode) {
00879 
00880             if (pimp) {
00881 
00882                 NiceMessage* dup = static_cast<NiceMessage*>(queryMsg->dup());
00883                 sendMessageToUDP(clusters[layer].getLeader(), dup);
00884 
00885             }
00886 
00887             if (debug_queries)
00888                 EV << " I am not leader of this cluster. return." << endl;
00889 
00890             return;
00891 
00892         }
00893 
00894     } else {
00895 
00896         return;
00897 
00898     }
00899 
00900     NiceMemberMessage* msg = new NiceMemberMessage("NICE_QUERY_RESPONSE");
00901     msg->setSrcNode(thisNode);
00902     msg->setCommand(NICE_QUERY_RESPONSE);
00903     msg->setLayer(layer);
00904 
00905     /* Fill in current cluster members except me */
00906     msg->setMembersArraySize(clusters[layer].getSize()-1);
00907 
00908     int j=0;
00909 
00910     for (int i = 0; i < clusters[layer].getSize(); i++) {
00911 
00912         if (clusters[layer].get(i) != thisNode) {
00913 
00914             msg->setMembers(j, clusters[layer].get(i));
00915             if (debug_queries)
00916                 EV << " Response: " << i << " : " << clusters[layer].get(i) << endl;
00917             j++;
00918 
00919         }
00920 
00921     }
00922 
00923     msg->setBitLength(NICEMEMBERMESSAGE_L(msg));
00924 
00925     sendMessageToUDP(queryMsg->getSrcNode(), msg);
00926 
00927     if (debug_queries)
00928         EV << " Sent response to: " << queryMsg->getSrcNode() << endl;
00929 
00930     if (debug_queries)
00931         EV << simTime() << " : " << thisNode.getAddress() << " : handleQuery() finished." << endl;
00932 
00933 } // handleQuery

void oversim::Nice::handleQueryResponse ( NiceMemberMessage queryRspMsg  )  [private]

Definition at line 982 of file Nice.cc.

Referenced by handleUDPMessage().

00983 {
00984 
00985     cancelEvent(queryTimer);
00986 
00987     short layer = queryRspMsg->getLayer();
00988 
00989     /* Check layer response */
00990     if (layer == targetLayer) {
00991 
00992         /* Use member information for own cluster update */
00993         for (unsigned int i = 0; i < queryRspMsg->getMembersArraySize(); i++) {
00994 
00995             clusters[layer].add(queryRspMsg->getMembers(i));
00996 
00997         }
00998 
00999         clusters[layer].add(queryRspMsg->getSrcNode());
01000 
01001         /* Initiate joining of lowest layer */
01002         JoinCluster(queryRspMsg->getSrcNode(), layer);
01003 
01004         changeState(READY);
01005 
01006     } else {
01007 
01008         /* Evaluate RTT to queried node */
01009         query_start = simTime() - query_start;
01010 
01011         /* Find out who is nearest cluster member in response, if nodes are given */
01012         if (queryRspMsg->getMembersArraySize() > 0) {
01013 
01014             NiceMessage* msg = new NiceMessage("NICE_JOINEVAL");
01015             msg->setSrcNode(thisNode);
01016             msg->setCommand(NICE_JOINEVAL);
01017             msg->setLayer(layer);
01018 
01019             msg->setBitLength(NICEMESSAGE_L(msg));
01020 
01021             /* Initiate evaluation with all cluster members */
01022             for (unsigned int i = 0; i < queryRspMsg->getMembersArraySize(); i++) {
01023 
01024                 NiceMessage* dup = static_cast<NiceMessage*>(msg->dup());
01025 
01026                 sendMessageToUDP(queryRspMsg->getMembers(i), dup);
01027 
01028             }
01029 
01030             delete msg;
01031 
01032         } else { // Directly query same node again for lower layer
01033 
01034             Query(queryRspMsg->getSrcNode(), queryRspMsg->getLayer()-1);
01035 
01036         }
01037 
01038         evalLayer = layer;
01039         query_compare = simTime();
01040 
01041     }
01042 
01043 } // handleQueryResponse

void oversim::Nice::handleTimerEvent ( cMessage *  msg  )  [virtual]

Reimplemented from BaseRpc.

Definition at line 282 of file Nice.cc.

00283 {
00284 
00285     if (msg->isName("visualizationTimer")) {
00286 
00287         updateVisualization();
00288         scheduleAt(simTime() + 1, visualizationTimer);
00289 
00290     } else if (msg->isName("heartbeatTimer")) {
00291 
00292         sendHeartbeats();
00293         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
00294 
00295     } else if (msg->isName("maintenanceTimer")) {
00296 
00297         maintenance();
00298         cancelEvent(maintenanceTimer);
00299         scheduleAt(simTime() + maintenanceInterval, maintenanceTimer);
00300 
00301     } else if (msg->isName("queryTimer")) {
00302 
00303         globalStatistics->recordOutVector("NICEInconsistencies", 1);
00304         globalStatistics->recordOutVector("NICEQueryTimeouts", 1);
00305         BasicJoinLayer(-1);
00306 
00307     } else if (msg->isName("structureConnectionTimer")) {
00308 
00309         if (RendevouzPoint == thisNode)
00310             return;
00311 
00312         globalStatistics->recordOutVector("NICEStructurePartition", 1);
00313         globalStatistics->recordOutVector("NICEInconsistencies", 1);
00314         BasicJoinLayer(getHighestLayer());
00315 
00316     } else if (msg->isName("rpPollTimer")) {
00317 
00318         isPollingRP = false;
00319 
00320         if (RendevouzPoint == thisNode)
00321             return;
00322 
00323         becomeRendevouzPoint();
00324 
00325     }
00326 
00327 } // handleTimerEvent

void oversim::Nice::handleUDPMessage ( BaseOverlayMessage msg  )  [virtual]

Processes messages from underlay.

Parameters:
msg Message from UDP

Reimplemented from BaseOverlay.

Definition at line 334 of file Nice.cc.

00335 {
00336 
00337     // try message cast to NICE base message
00338     if (dynamic_cast<NiceMessage*>(msg) != NULL) {
00339 
00340         NiceMessage* niceMsg = check_and_cast<NiceMessage*>(msg);
00341 
00342         // First of all, update activity information for sourcenode
00343         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(niceMsg->getSrcNode());
00344         if (it != peerInfos.end()) {
00345 
00346             it->second->touch();
00347 
00348         }
00349 
00350         if (niceMsg->getCommand() == NICE_QUERY) {
00351 
00352             handleQuery(niceMsg);
00353             delete niceMsg;
00354 
00355         } else if (niceMsg->getCommand() == NICE_QUERY_RESPONSE) {
00356 
00357             NiceMemberMessage* queryRspMsg = check_and_cast<NiceMemberMessage*>(niceMsg);
00358             handleQueryResponse(queryRspMsg);
00359             delete queryRspMsg;
00360 
00361         } else if (niceMsg->getCommand() == NICE_JOIN_CLUSTER) {
00362 
00363             handleJoinCluster(niceMsg);
00364             delete niceMsg;
00365 
00366         } else if (niceMsg->getCommand() == NICE_POLL_RP) {
00367 
00368             if (RendevouzPoint == thisNode) {
00369 
00370                 NiceMessage* msg = new NiceMessage("NICE_POLL_RP_RESPONSE");
00371                 msg->setSrcNode(thisNode);
00372                 msg->setCommand(NICE_POLL_RP_RESPONSE);
00373                 msg->setLayer(getHighestLeaderLayer());
00374                 msg->setBitLength(NICEMESSAGE_L(msg));
00375 
00376                 sendMessageToUDP(niceMsg->getSrcNode(), msg);
00377 
00378             }
00379             delete niceMsg;
00380 
00381         } else if (niceMsg->getCommand() == NICE_POLL_RP_RESPONSE) {
00382 
00383             if (isPollingRP) {
00384 
00385                 if (niceMsg->getLayer() < getHighestLayer()) {
00386 
00387                     becomeRendevouzPoint();
00388 
00389                 } else {
00390 
00391                     //BasicJoinLayer(getHighestLayer());
00392 
00393                 }
00394 
00395             }
00396 
00397             delete niceMsg;
00398 
00399         } else if (niceMsg->getCommand() == NICE_HEARTBEAT) {
00400 
00401             handleHeartbeat(niceMsg);
00402 
00403         } else if ((niceMsg->getCommand() == NICE_LEADERHEARTBEAT) ||
00404                    (niceMsg->getCommand() == NICE_LEADERTRANSFER)) {
00405 
00406             cancelEvent(structureConnectionTimer);
00407             double offset = structureConnectionInterval.dbl() * heartbeatInterval.dbl();
00408             scheduleAt(simTime() + offset, structureConnectionTimer);
00409 
00410             handleHeartbeat(niceMsg);
00411 
00412         } else if (niceMsg->getCommand() == NICE_JOINEVAL) {
00413 
00414             NiceMessage* msg = new NiceMessage("NICE_JOINEVAL_RESPONSE");
00415             msg->setSrcNode(thisNode);
00416             msg->setCommand(NICE_JOINEVAL_RESPONSE);
00417             msg->setLayer(niceMsg->getLayer());
00418 
00419             msg->setBitLength(NICEMESSAGE_L(msg));
00420 
00421             sendMessageToUDP(niceMsg->getSrcNode(), msg);
00422 
00423             delete niceMsg;
00424 
00425         } else if (niceMsg->getCommand() == NICE_JOINEVAL_RESPONSE) {
00426 
00427             if (evalLayer > 0 && evalLayer == niceMsg->getLayer()) {
00428 
00429                 query_compare = simTime() - query_compare;
00430 
00431                 if (query_compare < query_start) {
00432 
00433                     Query(niceMsg->getSrcNode(), niceMsg->getLayer()-1);
00434 
00435                 } else {
00436 
00437                     Query(tempResolver, niceMsg->getLayer()-1);
00438 
00439                 }
00440 
00441                 evalLayer = -1;
00442             }
00443 
00444             delete niceMsg;
00445 
00446         } else if (niceMsg->getCommand() == NICE_REMOVE) {
00447 
00448             if (debug_removes)
00449                 EV << simTime() << " : " << thisNode.getAddress() << " : NICE_REMOVE" << endl;
00450 
00451             short layer = niceMsg->getLayer();
00452 
00453             if (pimp) {
00454                 if (!clusters[layer].getLeader().isUnspecified()) {
00455                     if (clusters[layer].getLeader() != thisNode && (clusters[layer].getLeader() != niceMsg->getSrcNode())) {
00456 
00457                         NiceMessage* dup = static_cast<NiceMessage*>(niceMsg->dup());
00458                         sendMessageToUDP(clusters[layer].getLeader(), dup);
00459                         delete niceMsg;
00460                         return;
00461                     }
00462                 }
00463             }
00464 
00465             if (debug_removes)
00466                 EV << simTime() << " : " << thisNode.getAddress() << " : removing " << niceMsg->getSrcNode() << " from layer " << layer << endl;
00467 
00468             if (!clusters[niceMsg->getLayer()].getLeader().isUnspecified()) {
00469 
00470                 if (clusters[niceMsg->getLayer()].getLeader() == thisNode) {
00471 
00472                     // check prevents visualization arrows to be deleted by error
00473                     if (clusters[niceMsg->getLayer()].contains(niceMsg->getSrcNode())) {
00474 
00475                         deleteOverlayNeighborArrow(niceMsg->getSrcNode());
00476                         clusters[niceMsg->getLayer()].remove(niceMsg->getSrcNode());
00477                         updateVisualization();
00478 
00479                     }
00480 
00481                 }
00482 
00483                 if (clusters[niceMsg->getLayer()].getLeader() == niceMsg->getSrcNode()) {
00484 
00485 
00486                 }
00487 
00488             }
00489 
00490             delete niceMsg;
00491 
00492             if (debug_removes)
00493                 EV << simTime() << " : " << thisNode.getAddress() << " : NICE_REMOVE finished." << endl;
00494 
00495         } else if (niceMsg->getCommand() == NICE_PEER_TEMPORARY) {
00496 
00497             // Add node to tempPeers
00498             tempPeers.insert(std::make_pair(niceMsg->getSrcNode(), simTime()));
00499 
00500             delete niceMsg;
00501 
00502         } else if (niceMsg->getCommand() == NICE_PEER_TEMPORARY_RELEASE) {
00503 
00504             // Remove node from tempPeers
00505             tempPeers.erase(niceMsg->getSrcNode());
00506 
00507             delete niceMsg;
00508 
00509         } else if (niceMsg->getCommand() == NICE_PING_PROBE) {
00510 
00511             // Only answer if I am part of requested layer
00512             if (clusters[niceMsg->getLayer()].contains(thisNode)) {
00513 
00514                 NiceMessage* msg = new NiceMessage("NICE_PING_PROBE");
00515                 msg->setSrcNode(thisNode);
00516                 msg->setCommand(NICE_PING_PROBE_RESPONSE);
00517                 msg->setLayer(niceMsg->getLayer());
00518 
00519                 msg->setBitLength(NICEMESSAGE_L(msg));
00520 
00521                 sendMessageToUDP(niceMsg->getSrcNode(), msg);
00522 
00523             } else {
00524 
00525                 //Do nothing
00526 
00527             }
00528 
00529             delete niceMsg;
00530 
00531         } else if (niceMsg->getCommand() == NICE_PING_PROBE_RESPONSE) {
00532 
00533             //Only react if still in same cluster as when asked
00534             if (niceMsg->getLayer() == getHighestLayer()+1) {
00535 
00536                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(niceMsg->getSrcNode());
00537 
00538                 if (it != peerInfos.end()) {
00539 
00540                     double distance = simTime().dbl() - it->second->getDES();
00541 
00542                     it->second->set_distance(distance);
00543                     it->second->touch();
00544 
00545                 }
00546 
00547             }
00548 
00549             delete niceMsg;
00550 
00551         } else if (niceMsg->getCommand() == NICE_FORCE_MERGE) {
00552 
00553             ClusterMergeRequest(niceMsg->getSrcNode(), niceMsg->getLayer());
00554 
00555             delete niceMsg;
00556 
00557         } else if (niceMsg->getCommand() == NICE_CLUSTER_MERGE_REQUEST) {
00558 
00559             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_CLUSTER_MERGE_REQUEST" << endl;
00560 
00561             NiceClusterMerge* mergeMsg = check_and_cast<NiceClusterMerge*>(niceMsg);
00562 
00563             short layer = mergeMsg->getLayer();
00564 
00565             // Only react if I am a leader of this cluster layer
00566 
00567             if (clusters[layer].getLeader().isUnspecified()) {
00568 
00569                 delete mergeMsg;
00570 
00571                 EV << simTime() << " : " << thisNode.getAddress() << " : NO LEADER! BREAK. NICE_CLUSTER_MERGE_REQUEST finished" << endl;
00572 
00573                 return;
00574 
00575             }
00576 
00577             if (clusters[layer].getLeader() == thisNode) {
00578 
00579                 clusters[layer+1].remove(mergeMsg->getSrcNode());
00580                 deleteOverlayNeighborArrow(mergeMsg->getSrcNode());
00581 
00582                 if (clusters[layer+1].getLeader() != thisNode)
00583                     clusters[layer+1].setLeader(mergeMsg->getNewClusterLeader());
00584 
00585                 // if I am alone now, become leader
00586                 if (clusters[layer+1].getSize() == 1) {
00587 
00588                     becomeRendevouzPoint();
00589 
00590                     // cancel layer
00591                     clusters[layer+1].clear();
00592 
00593                     for (short i=0; i<maxLayers; i++) {
00594 
00595                         if (clusters[i].getSize() > 0) {
00596 
00597                             if (clusters[i].contains(thisNode)) {
00598 
00599                                 getParentModule()->getParentModule()->getDisplayString().setTagArg
00600                                 ("i2", 1, clustercolors[i]);
00601 
00602                             }
00603 
00604                         }
00605 
00606                     }
00607 
00608                 }
00609 
00610                 for (unsigned int i=0; i<mergeMsg->getMembersArraySize(); i++) {
00611 
00612                     /* Add new node to cluster */
00613                     clusters[layer].add(mergeMsg->getMembers(i));
00614 
00615                     /* Create peer context to joining node */
00616                     /* Check if peer info already exists */
00617                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(mergeMsg->getMembers(i));
00618 
00619                     if (it != peerInfos.end()) { /* We already know this node */
00620 
00621                     } else { /* Create PeerInfo object */
00622 
00623                         NicePeerInfo* pi = new NicePeerInfo(this);
00624 
00625                         pi->set_last_HB_arrival(simTime().dbl());
00626 
00627                         peerInfos.insert(std::make_pair(mergeMsg->getMembers(i), pi));
00628 
00629                     }
00630 
00631                     /* Draw arrow to new member */
00632                     showOverlayNeighborArrow(mergeMsg->getMembers(i), false, clusterarrows[layer]);
00633 
00634                     EV << "getHighestLeaderLayer()].getSize(): " << clusters[getHighestLeaderLayer()].getSize() << endl;
00635 
00636                     if (clusters[getHighestLeaderLayer()].getSize() < 2) {
00637 
00638                         // cancel layer
00639                         clusters[getHighestLeaderLayer()].clear();
00640 
00641                         for (short i=0; i<maxLayers; i++) {
00642 
00643                             if (clusters[i].getSize() > 0) {
00644 
00645                                 if (clusters[i].contains(thisNode)) {
00646 
00647                                     getParentModule()->getParentModule()->getDisplayString().setTagArg
00648                                     ("i2", 1, clustercolors[i]);
00649 
00650                                 }
00651 
00652                             }
00653 
00654                         }
00655 
00656                     }
00657 
00658                 }
00659 
00660             } else {// Forward to new cluster leader
00661 
00662                 if (pimp) {
00663 
00664                     NiceMemberMessage* dup = static_cast<NiceMemberMessage*>(mergeMsg->dup());
00665                     sendMessageToUDP(clusters[layer].getLeader(), dup);
00666                     delete mergeMsg;
00667                     return;
00668 
00669                 }
00670 
00671             }
00672 
00673             if (pimp)
00674                 sendHeartbeats();
00675 
00676             delete mergeMsg;
00677 
00678             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_CLUSTER_MERGE_REQUEST finished" << endl;
00679 
00680 
00681         }
00682 
00683     } else if (dynamic_cast<CbrAppMessage*>(msg) != NULL) {
00684 
00685         CbrAppMessage* appMsg = check_and_cast<CbrAppMessage*>(msg);
00686 
00687         if (appMsg->getCommand() == CBR_DATA) {
00688 
00689             /* If its mine, count */
00690             if (appMsg->getSrcNode() == thisNode) {
00691 
00692                 //std::cout << simTime() << " : " << thisNode.getAddress() << " : Got my own message back. Not good." << endl;
00693                 globalStatistics->recordOutVector("NiceOwnMessage", 1);
00694 
00695             } else {
00696 
00697                 unsigned int hopCount = appMsg->getHopCount();
00698                 hopCount++;
00699 
00700                 if (hopCount < 8) {
00701 
00702                     CbrAppMessage* dup = static_cast<CbrAppMessage*>(appMsg->dup());
00703                     send(dup, "appOut");
00704 
00705                     CbrAppMessage* dup2 = static_cast<CbrAppMessage*>(appMsg->dup());
00706                     dup2->setHopCount(hopCount);
00707                     sendDataToOverlay(dup2);
00708 
00709                 }
00710 
00711             }
00712 
00713         }
00714 
00715         delete msg;
00716 
00717     } else {
00718 
00719         delete msg;
00720 
00721     }
00722 
00723 } // handleUDPMessage

void oversim::Nice::initializeOverlay ( int  stage  )  [virtual]

Initializes derived-class-attributes.


Initializes derived-class-attributes, called by BaseOverlay::initialize(). By default this method is called once. If more stages are needed one can overload numInitStages() and add more stages.

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

Definition at line 105 of file Nice.cc.

00106 {
00107 
00108     /* Because of IPAddressResolver, we need to wait until interfaces
00109      * are registered, address auto-assignment takes place etc. */
00110     if (stage != MIN_STAGE_OVERLAY)
00111         return;
00112 
00113     /* Set appearance of node in visualization */
00114     getParentModule()->getParentModule()->getDisplayString().setTagArg
00115     ("i", 0, "device/pc_vs");
00116     getParentModule()->getParentModule()
00117     ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
00118 
00119     /* Initially clear all clusters */
00120     for (int i=0; i<maxLayers; i++) {
00121 
00122         clusters[i].clear();
00123 
00124     }
00125 
00126     /* Initialize Self-Messages */
00127 
00128     // Periodic Heartbeat Messages
00129     heartbeatInterval = par("heartbeatInterval");
00130     heartbeatTimer = new cMessage("heartbeatTimer");
00131 
00132     // Periodic Protocol Maintenance
00133     maintenanceInterval = par("maintenanceInterval");
00134     maintenanceTimer = new cMessage("maintenanceTimer");
00135 
00136     queryInterval = par("queryInterval");
00137     queryTimer = new cMessage("queryTimer");
00138 
00139     structureConnectionInterval = par("structureConnectionInterval");
00140     structureConnectionTimer = new cMessage("structureConnectionTimer");
00141 
00142     rpPollTimer = new cMessage("structureConnectionTimer");
00143     rpPollTimerInterval = par("rpPollTimerInterval");
00144 
00145     peerTimeoutInterval = par("peerTimeoutInterval");
00146 
00147     pimp = par("enhancedMode");
00148 
00149     isPollingRP = false;
00150 
00151     /* DEBUG */
00152     clusterrefinement = par("debug_clusterrefinement");
00153     debug_heartbeats = par("debug_heartbeats");
00154     debug_visualization = par("debug_visualization");
00155     debug_join = par("debug_join");
00156     debug_peertimeouts = par("debug_peertimeouts");
00157     debug_removes = par("debug_removes");
00158     debug_queries = par("debug_queries");
00159 
00160     visualizationTimer = new cMessage("visualizationTimer");
00161 
00162     /* Read cluster parameter k */
00163     k = par("k");
00164 
00165     CLUSTERLEADERBOUND = par("clusterLeaderBound");
00166     CLUSTERLEADERCOMPAREDIST = par("clusterLeaderCompareDist");
00167     SC_PROC_DISTANCE = par("scProcDistance");
00168     SC_MIN_OFFSET = par("scMinOffset");
00169 
00170     /* Add own node to peerInfos */
00171     NicePeerInfo* pi = new NicePeerInfo(this);
00172     pi->set_distance(0);
00173     peerInfos.insert(std::make_pair(thisNode, pi));
00174 
00175     /* Set evaluation layer to not specified */
00176     evalLayer = -1;
00177     joinLayer = -1;
00178 
00179     first_leader = TransportAddress::UNSPECIFIED_NODE;
00180     second_leader = TransportAddress::UNSPECIFIED_NODE;
00181 
00182     // add some watches
00183     WATCH(thisNode);
00184     WATCH_POINTER_MAP(peerInfos);
00185     WATCH(evalLayer);
00186     WATCH(query_start);
00187     WATCH(heartbeatTimer);
00188     WATCH_MAP(tempPeers);
00189     WATCH(RendevouzPoint);
00190 
00191 } // initializeOverlay

void oversim::Nice::JoinCluster ( const TransportAddress leader,
short  layer 
) [private]

Definition at line 1049 of file Nice.cc.

Referenced by handleHeartbeat(), handleQueryResponse(), and maintenance().

01050 {
01051 
01052     if (debug_join)
01053         EV << simTime() << " : " << thisNode.getAddress() << " : JoinCluster()" << endl;
01054 
01055     NiceMessage* msg = new NiceMessage("NICE_JOIN_CLUSTER");
01056     msg->setSrcNode(thisNode);
01057     msg->setCommand(NICE_JOIN_CLUSTER);
01058     msg->setLayer(layer);
01059     msg->setBitLength(NICEMESSAGE_L(msg));
01060 
01061     sendMessageToUDP(leader, msg);
01062 
01063     /* Create peer context to leader */
01064     /* Check if peer info already exists */
01065     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(leader);
01066 
01067     if (it != peerInfos.end()) { /* We already know this node */
01068 
01069     } else { /* Create PeerInfo object */
01070 
01071         NicePeerInfo* pi = new NicePeerInfo(this);
01072 
01073         peerInfos.insert(std::make_pair(leader, pi));
01074 
01075     }
01076 
01077     /* Locally add thisNode, too */
01078     clusters[layer].add(thisNode);
01079 
01080     /* Set leader for cluster */
01081     clusters[layer].setLeader(leader);
01082 
01083     for (short i=0; i<maxLayers; i++) {
01084 
01085         if (clusters[i].getSize() > 0) {
01086 
01087             if (clusters[i].contains(thisNode)) {
01088 
01089                 getParentModule()->getParentModule()->getDisplayString().setTagArg
01090                 ("i2", 1, clustercolors[i]);
01091 
01092             }
01093 
01094         }
01095 
01096     }
01097 
01098     // If not already running, schedule some timers
01099     if (!heartbeatTimer->isScheduled()) {
01100 
01101         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
01102 
01103     }
01104     if (!maintenanceTimer->isScheduled()) {
01105 
01106         scheduleAt(simTime() + heartbeatInterval, maintenanceTimer);
01107 
01108     }
01109 
01110     if (isTempPeered) {
01111 
01112         // Release temporary peering
01113         NiceMessage* msg = new NiceMessage("NICE_PEER_TEMPORARY_RELEASE");
01114         msg->setSrcNode(thisNode);
01115         msg->setCommand(NICE_PEER_TEMPORARY_RELEASE);
01116         msg->setLayer(-1);
01117         msg->setBitLength(NICEMESSAGE_L(msg));
01118 
01119         sendMessageToUDP(RendevouzPoint, msg);
01120 
01121         isTempPeered = false;
01122 
01123     }
01124 
01125     if (debug_join)
01126         EV << simTime() << " : " << thisNode.getAddress() << " : JoinCluster() finished." << endl;
01127 
01128 } // JoinCluster

void oversim::Nice::joinOverlay (  )  [protected, virtual]

Join the overlay with a given nodeID in thisNode.key.

Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.

Reimplemented from BaseOverlay.

Definition at line 198 of file Nice.cc.

00199 {
00200     changeState(INIT);
00201     changeState(BOOTSTRAP);
00202 } // joinOverlay

void oversim::Nice::LeaderTransfer ( int  layer,
TransportAddress  leader,
TaSet  cluster,
TransportAddress  sc_leader 
) [private]

Definition at line 3215 of file Nice.cc.

Referenced by ClusterMerge(), ClusterSplit(), gracefulLeave(), handleHeartbeat(), and maintenance().

03216 {
03217 
03218     NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERTRANSFER");
03219     msg->setSrcNode(thisNode);
03220     msg->setCommand(NICE_LEADERTRANSFER);
03221     msg->setLayer(layer);
03222 
03223     msg->setMembersArraySize(cluster.size());
03224 
03225     // fill in members
03226     TaSet::iterator it = cluster.begin();
03227     int i = 0;
03228     while (it != cluster.end()) {
03229         msg->setMembers(i++, *it);
03230         it++;
03231     }
03232 
03233     // fill in supercluster members, if existent
03234     if (clusters[layer+1].getSize() > 0) {
03235 
03236         msg->setSupercluster_leader(clusters[layer+1].getLeader());
03237 
03238         msg->setSupercluster_membersArraySize(clusters[layer+1].getSize());
03239 
03240         for (int j = 0; j < clusters[layer+1].getSize(); j++) {
03241 
03242             msg->setSupercluster_members(j, clusters[layer+1].get(j));
03243 
03244         }
03245 
03246     } else {
03247 
03248         msg->setSupercluster_leader(sc_leader);
03249 
03250     }
03251 
03252     msg->setBitLength(NICELEADERHEARTBEAT_L(msg));
03253 
03254     sendMessageToUDP(leader, msg);
03255 
03256 } // LeaderTransfer

void oversim::Nice::maintenance (  )  [private]

Definition at line 2070 of file Nice.cc.

Referenced by handleTimerEvent().

02071 {
02072 
02073     // care for structure connection timer
02074     if (!RendevouzPoint.isUnspecified()) {
02075 
02076         if (RendevouzPoint == thisNode) {
02077 
02078             cancelEvent(structureConnectionTimer);
02079 
02080         } else {
02081 
02082             if (!structureConnectionTimer->isScheduled()) {
02083 
02084                 double offset = structureConnectionInterval.dbl() * heartbeatInterval.dbl();
02085                 scheduleAt(simTime() + offset, structureConnectionTimer);
02086 
02087             }
02088 
02089         }
02090 
02091     } else {
02092 
02093         EV << "No RendevouzPoint! " << endl;
02094         becomeRendevouzPoint();
02095 
02096     }
02097 
02098     /* Delete deprecated tempPeers from map */
02099 
02100     bool deleted;
02101 
02102     do {
02103 
02104         deleted = false;
02105 
02106         std::map<TransportAddress, simtime_t>::iterator it = tempPeers.begin();
02107 
02108         while (it != tempPeers.end()) {
02109 
02110             if (simTime() > (it->second + 3*heartbeatInterval)) {
02111 
02112                 tempPeers.erase(it->first);
02113                 deleted = true;
02114                 break;
02115 
02116             }
02117 
02118             it++;
02119 
02120         }
02121 
02122     } while (deleted);
02123 
02124     /* Delete nodes that haven't been active for too long autonomously */
02125 
02126     std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.begin();
02127 
02128     while (it2 != peerInfos.end()) {
02129 
02130         if (it2->first != thisNode) {
02131 
02132             double offset = peerTimeoutInterval.dbl()*heartbeatInterval.dbl();
02133             if (simTime() > (it2->second->getActivity() + offset)) {
02134 
02135                 if (debug_peertimeouts) {
02136                     EV << simTime() << " : " << thisNode.getAddress() << " : PEER TIMED OUT! : " << it2->first << endl;
02137                     EV << "Activity : " << it2->second->getActivity() << endl;
02138                 }
02139 
02140                 // Delete node from all layer clusters
02141                 for (int i=0; i<maxLayers; i++) {
02142 
02143                     if (clusters[i].contains(it2->first)) {
02144 
02145                         clusters[i].remove(it2->first);
02146 
02147                         /* If node was leader, elect new! */
02148                         if (!(clusters[i].getLeader().isUnspecified())) {
02149 
02150                             if (clusters[i].getLeader() == it2->first) {
02151 
02152                                 if (debug_peertimeouts)
02153                                     EV << simTime() << " : " << thisNode.getAddress() << " : Need new Cluster Leader for Cluster : " << i << endl;
02154 
02155                                 // Perform check for new cluster leader
02156                                 TaSet cl;
02157                                 for (int l=0; l<clusters[i].getSize(); l++) {
02158 
02159                                     cl.insert(clusters[i].get(l));
02160 
02161                                 }
02162 
02163                                 TransportAddress new_leader = findCenter(cl).first;
02164 
02165                                 /* Remove old leader from supercluster */
02166                                 clusters[i+1].remove(clusters[i].getLeader());
02167 
02168                                 clusters[i].setLeader(new_leader);
02169 
02170                                 if (new_leader == thisNode) {
02171 
02172                                     // I am new leader
02173                                     if (clusters[i+1].getSize() > 0) {
02174 
02175                                         /* TODO Experimental Hack: If old leader is also leader of sc -> basicJoinLayer*/
02176                                         if (clusters[i+1].getLeader() == clusters[i].getLeader()) {
02177 
02178                                             /* Locally add thisNode, too */
02179                                             clusters[i+1].add(thisNode);
02180 
02181                                             for (short j=0; j<maxLayers; j++) {
02182 
02183                                                 if (clusters[j].getSize() > 0) {
02184 
02185                                                     if (clusters[j].contains(thisNode)) {
02186 
02187                                                         getParentModule()->getParentModule()->getDisplayString().setTagArg
02188                                                         ("i2", 1, clustercolors[j]);
02189 
02190                                                     }
02191 
02192                                                 }
02193 
02194                                             }
02195 
02196                                             BasicJoinLayer(i+1);
02197 
02198                                         } else {
02199 
02200                                             JoinCluster(clusters[i+1].getLeader(), i+1);
02201 
02202                                         }
02203 
02204                                     } else {
02205 
02206                                         //TODO Experimental
02207                                         //Poll RP if existent
02208                                         //pollRP(getHighestLayer());
02209                                         //becomeRendevouzPoint();
02210 
02211                                     }
02212 
02213                                     for (int n=0; n<clusters[i].getSize(); n++) {
02214 
02215                                         if (clusters[i].get(n) != thisNode)
02216                                             showOverlayNeighborArrow(clusters[i].get(n), false, clusterarrows[i]);
02217 
02218                                     }
02219 
02220                                 }
02221 
02222                             }
02223 
02224                         }
02225 
02226                     }
02227 
02228                 }
02229 
02230                 TransportAddress cand = it2->first;
02231                 ++it2;
02232                 peerInfos.erase(cand);
02233                 continue;
02234 
02235             }
02236         }
02237 
02238         it2++;
02239 
02240     }
02241 
02242     // if node is cluster leader, check size bounds for every cluster
02243     //for (int i=0; clusters[i].contains(thisNode); i++) {
02244     for (int i=getHighestLayer(); i >= 0; i--) {
02245 
02246         //TODO Experimental Check for inconsistency: If I am node in cluster but not leader in subcluster, remove
02247         if (clusters[i].contains(thisNode) && (i > 0)) {
02248 
02249             if (clusters[i-1].getLeader() != thisNode) {
02250 
02251                 Remove(i);
02252                 return;
02253 
02254             }
02255 
02256         }
02257 
02258         if (!clusters[i].getLeader().isUnspecified()) {
02259 
02260             if (clusters[i].getLeader() == thisNode) {
02261 
02262                 if (clusters[i].getSize() > (3*k-1)) {
02263 
02264                     ClusterSplit(i);
02265 
02266                     return;
02267 
02268                 }
02269 
02270 
02271                 if ((clusters[i].getSize() < k) && (clusters[i+1].getSize() > 1)) {
02272 
02273                     EV  << simTime() << " : " << thisNode.getAddress()
02274                     << ": CLUSTER MERGE!: " << i << endl;
02275 
02276                     ClusterMerge(i);
02277 
02278                     return;
02279 
02280                 } else if ((clusters[i].getSize() < k)) {
02281 
02282 
02283                 }
02284 
02285             }
02286 
02287         }
02288 
02289     } // All Layers
02290 
02291     // if highest super cluster has more than one member
02292     if (clusters[getHighestLayer()+1].getSize() > 1) {
02293 
02294         if (clusterrefinement)
02295             EV << simTime() << " : " << thisNode.getAddress() << " : Look for better parent node in cluster : " << getHighestLayer()+1 << " ..."<< endl;
02296 
02297         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[getHighestLayer()].getLeader());
02298 
02299         if (it != peerInfos.end()) {
02300 
02301             if (it->second->get_distance() > 0) {
02302 
02303                 double distance = it->second->get_distance() - ((it->second->get_distance()/100.0) * SC_PROC_DISTANCE);
02304 
02305                 double smallest = 10000.0;
02306                 TransportAddress candidate = TransportAddress::UNSPECIFIED_NODE;
02307 
02308                 for (int i=0; i < clusters[getHighestLayer()+1].getSize(); i++) {
02309 
02310                     if (clusters[getHighestLayer()+1].get(i) != clusters[getHighestLayer()].getLeader()) {
02311 
02312                         std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(clusters[getHighestLayer()+1].get(i));
02313 
02314                         if (it2 != peerInfos.end()) {
02315 
02316                             if ((it2->second->get_distance() < smallest) && (it2->second->get_distance() > 0)) {
02317                                 smallest = it2->second->get_distance();
02318                                 candidate = it2->first;
02319                             }
02320 
02321                         }
02322 
02323                     }
02324 
02325                 }
02326 
02327                 std::set<TransportAddress> clusterset;
02328 
02329                 for (int m=0; m<clusters[getHighestLayer()+1].getSize(); m++) {
02330 
02331                     clusterset.insert(clusters[getHighestLayer()+1].get(m));
02332 
02333                 }
02334 
02335                 simtime_t meanDistance = getMeanDistance(clusterset);
02336 
02337                 simtime_t minCompare = (meanDistance/100.0)*SC_MIN_OFFSET;
02338 
02339                 globalStatistics->recordOutVector("NICESCminCompare", minCompare.dbl());
02340 
02341                 if (minCompare < 0.005)
02342                     minCompare = 0.005;
02343 
02344                 //if ((smallest < distance) && ((distance - smallest) > (SC_MIN_OFFSET/1000.0))) { // change supercluster
02345                 if ((smallest < distance) && ((distance - smallest) > minCompare.dbl())) { // change supercluster
02346 
02347 
02348                     if (clusterrefinement) {
02349                         EV << simTime() <<" : " << thisNode.getAddress() << ": Change SuperCluster! to " << candidate.getAddress() << endl;
02350                         EV << "Old distance ():  " << it->second->get_distance() << endl;
02351                         EV << "SC_PROC_DISTANCE:  " << SC_PROC_DISTANCE << endl;
02352                         EV << "Compare distance:  " << distance << endl;
02353                         EV << "New distance:  " << smallest << endl;
02354                         EV << "New SC_MIN_OFFSET:  " << SC_MIN_OFFSET << endl;
02355                     }
02356 
02357                     short highestLayer = getHighestLayer();
02358 
02359                     // leave old
02360                     Remove(highestLayer);
02361 
02362                     // join new
02363                     JoinCluster(candidate, highestLayer);
02364 
02365                     return;
02366 
02367                 }
02368             }
02369 
02370         } else {
02371 
02372             //Do nothing
02373 
02374         }
02375 
02376     }
02377 
02378     //return;
02379     for (int i=getHighestLayer(); i >= 0; i--) {
02380 
02381         if (clusters[i].getSize() > 1 && clusters[i].getLeader() == thisNode) {
02382 
02383             bool allDistancesKnown = true;
02384 
02385             if (clusterrefinement)
02386                 EV << simTime() << " : " << thisNode.getAddress() << " : Find better cluster leader in ..." << i << endl;
02387 
02388             /* Only make decisions if node has total distance knowledge in this cluster */
02389             for (int j=0; j<clusters[i].getSize(); j++) {
02390 
02391                 /* Check if peer info already exists */
02392                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
02393 
02394                 if (it != peerInfos.end()) { /* We already know this node */
02395 
02396                     simtime_t distance = it->second->get_distance();
02397 
02398                     //EV << "My distance to " << it->first << " : " << distance << endl;
02399 
02400                     if (distance < 0) {
02401                         allDistancesKnown = false;
02402                         continue;
02403                     }
02404 
02405                     for (int k=0; k<clusters[i].getSize(); k++) {
02406 
02407                         if ((it->first != thisNode) && (clusters[i].get(k) != it->first)) {
02408 
02409                             if (it->second->getDistanceTo(clusters[i].get(k)) < 0) {
02410                                 allDistancesKnown = false;
02411                                 break;
02412                             }
02413                         }
02414 
02415                     }
02416 
02417                 } else { /* Create PeerInfo object */
02418 
02419                     allDistancesKnown = false;
02420 
02421                 }
02422 
02423             }
02424 
02425             if (allDistancesKnown) {
02426 
02427                 if (clusterrefinement)
02428                     EV << "Complete distance knowledge available." << endl;
02429 
02430                 // Perform check for better cluster leader
02431                 TaSet cl;
02432                 for (int l=0; l<clusters[i].getSize(); l++) {
02433 
02434                     cl.insert(clusters[i].get(l));
02435 
02436                 }
02437 
02438                 TransportAddress new_leader = findCenter(cl).first;
02439 
02440                 if (clusterrefinement)
02441                     EV << "NEW LEADER laut " << thisNode.getAddress() << " --> " << new_leader.getAddress() << endl;
02442 
02443                 std::set<TransportAddress> clusterset;
02444 
02445                 for (int m=0; m<clusters[i].getSize(); m++) {
02446 
02447                     clusterset.insert(clusters[i].get(m));
02448 
02449                 }
02450 
02451 
02452                 simtime_t meanDistance = getMeanDistance(clusterset);
02453                 simtime_t oldDistance = getMaxDistance(clusters[i].getLeader(), clusterset);
02454                 simtime_t newDistance = getMaxDistance(new_leader, clusterset);
02455                 simtime_t compareDistance = (oldDistance - ((oldDistance/100.0)*CLUSTERLEADERCOMPAREDIST));
02456 
02457                 simtime_t minCompare = (meanDistance/100.0)*CLUSTERLEADERBOUND;
02458 
02459                 if (minCompare < 0.005)
02460                     minCompare = 0.005;
02461 
02462                 if ((newDistance.dbl() < compareDistance.dbl()) && ((compareDistance.dbl() - newDistance.dbl()) > minCompare.dbl())) {
02463 
02464                     if (clusterrefinement)
02465                         EV << "CHANGE " << CLUSTERLEADERCOMPAREDIST << endl;
02466 
02467                     if (new_leader != thisNode) {
02468 
02469                         /* Check if I was leader*/
02470                         if (clusters[i].getLeader() == thisNode) {
02471 
02472                             for (int j=0; j<clusters[i].getSize(); j++) {
02473 
02474                                 deleteOverlayNeighborArrow(clusters[i].get(j));
02475 
02476                             }
02477 
02478                             gracefulLeave(i);
02479 
02480                             LeaderTransfer(i, new_leader, cl, new_leader);
02481 
02482                             getParentModule()->getParentModule()
02483                             ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02484 
02485 
02486                         } else {
02487 
02488                             // Do nothing
02489 
02490                         }
02491 
02492                     } else {
02493 
02494                         /* I am the new leader of this cluster */
02495                         /* Check if I already was*/
02496                         if (clusters[i].getLeader() == thisNode) {
02497 
02498                             // Do nothing
02499 
02500                         } else {
02501 
02502                             /* Remove old leader from supercluster */
02503                             clusters[i+1].remove(clusters[i].getLeader());
02504 
02505                             // I am new leader
02506                             if (clusters[i+1].getSize() > 0) {
02507 
02508                                 /* If old leader is also leader of sc -> basicJoinLayer*/
02509                                 if (clusters[i+1].getLeader() == clusters[i].getLeader()) {
02510 
02511                                     /* Locally add thisNode, too */
02512                                     clusters[i+1].add(thisNode);
02513 
02514                                     for (short j=0; j<maxLayers; j++) {
02515 
02516                                         if (clusters[j].getSize() > 0) {
02517 
02518                                             if (clusters[j].contains(thisNode)) {
02519 
02520                                                 getParentModule()->getParentModule()->getDisplayString().setTagArg
02521                                                 ("i2", 1, clustercolors[j]);
02522 
02523                                             }
02524 
02525                                         }
02526 
02527                                     }
02528 
02529                                     BasicJoinLayer(i+1);
02530 
02531                                 } else {
02532 
02533                                     JoinCluster(clusters[i+1].getLeader(), i+1);
02534 
02535                                 }
02536 
02537                             } else {
02538 
02539                                 becomeRendevouzPoint();
02540 
02541                             }
02542 
02543                             for (int n=0; n<clusters[i].getSize(); n++) {
02544 
02545                                 if (clusters[i].get(n) != thisNode)
02546                                     showOverlayNeighborArrow(clusters[i].get(n), false, clusterarrows[i]);
02547 
02548                             }
02549 
02550 
02551                         }
02552 
02553 
02554                     }
02555 
02556                     // Set new leader for this cluster
02557                     clusters[i].setLeader(new_leader);
02558 
02559                 }
02560 
02561                 if (clusterrefinement) {
02562                     EV << "MaxDistance " << new_leader.getAddress() << " : " << getMaxDistance(new_leader, clusterset) << endl;
02563                     EV << "MaxDistance " << clusters[i].getLeader() << " : " << getMaxDistance(clusters[i].getLeader(), clusterset) << endl;
02564                     EV << "MaxDistance " << thisNode.getAddress() << " : " << getMaxDistance(thisNode, clusterset) << endl;
02565                 }
02566 
02567 
02568             } else {
02569 
02570                 //return;
02571 
02572             }
02573 
02574         } // getSize() > 1
02575 
02576     }
02577 
02578 } // maintenance

void oversim::Nice::pollRP ( int  layer  )  [private]

Definition at line 3542 of file Nice.cc.

03543 {
03544 
03545     if (debug_queries)
03546         EV << simTime() << " : " << thisNode.getAddress() << " : pollRP()" << endl;
03547 
03548     NiceMessage* msg = new NiceMessage("NICE_POLL_RP");
03549     msg->setSrcNode(thisNode);
03550     msg->setCommand(NICE_POLL_RP);
03551     msg->setLayer(layer);
03552     msg->setBitLength(NICEMESSAGE_L(msg));
03553 
03554     cancelEvent(rpPollTimer);
03555     scheduleAt(simTime() + rpPollTimerInterval, rpPollTimer);
03556 
03557     sendMessageToUDP(RendevouzPoint, msg);
03558 
03559     isPollingRP = true;
03560 
03561     if (debug_queries)
03562         EV << simTime() << " : " << thisNode.getAddress() << " : pollRP() finished." << endl;
03563 
03564 } // pollRP

void oversim::Nice::Query ( const TransportAddress node,
short  layer 
) [private]

Definition at line 794 of file Nice.cc.

Referenced by BasicJoinLayer(), handleQueryResponse(), and handleUDPMessage().

00795 {
00796     if (debug_queries)
00797         EV << simTime() << " : " << thisNode.getAddress() << " : Query()" << endl;
00798 
00799 
00800     NiceMessage* msg = new NiceMessage("NICE_QUERY");
00801     msg->setSrcNode(thisNode);
00802     msg->setCommand(NICE_QUERY);
00803     msg->setLayer(layer);
00804     msg->setBitLength(NICEMESSAGE_L(msg));
00805 
00806     query_start = simTime();
00807     tempResolver = destination;
00808 
00809     cancelEvent(queryTimer);
00810     scheduleAt(simTime() + queryInterval, queryTimer);
00811 
00812     joinLayer = layer;
00813 
00814     sendMessageToUDP(destination, msg);
00815 
00816     if (debug_queries)
00817         EV << simTime() << " : " << thisNode.getAddress() << " : Query() finished." << endl;
00818 
00819 } // Query

void oversim::Nice::Remove ( int  layer  )  [private]

Definition at line 3262 of file Nice.cc.

Referenced by ClusterMerge(), gracefulLeave(), and maintenance().

03263 {
03264     if (debug_removes)
03265         EV << simTime() << " : " << thisNode.getAddress() << " : Remove()" << endl;
03266 
03267     NiceMessage* msg = new NiceMessage("NICE_REMOVE");
03268     msg->setSrcNode(thisNode);
03269     msg->setCommand(NICE_REMOVE);
03270     msg->setLayer(layer);
03271 
03272     msg->setBitLength(NICEMESSAGE_L(msg));
03273 
03274     sendMessageToUDP(clusters[layer].getLeader(), msg);
03275 
03276     clusters[layer].remove(thisNode);
03277 
03278     for (short i=0; i<maxLayers; i++) {
03279 
03280         if (clusters[i].getSize() > 0) {
03281 
03282             if (clusters[i].contains(thisNode)) {
03283 
03284                 getParentModule()->getParentModule()->getDisplayString().setTagArg
03285                 ("i2", 1, clustercolors[i]);
03286 
03287             }
03288 
03289         }
03290 
03291     }
03292 
03293     if (debug_removes)
03294         EV << simTime() << " : " << thisNode.getAddress() << " : Remove() finished." << endl;
03295 
03296 
03297 } // Remove

void oversim::Nice::sendDataToOverlay ( CbrAppMessage appMsg  )  [private]

Definition at line 3425 of file Nice.cc.

Referenced by handleAppMessage(), and handleUDPMessage().

03426 {
03427 
03428     for (int layer=0; clusters[layer].contains(thisNode); layer++) {
03429 
03430         if ( appMsg->getLayer() != layer ) {
03431 
03432             for (int j=0; j<clusters[layer].getSize(); j++) {
03433 
03434                 if (!(clusters[layer].contains(appMsg->getLastHop())) || appMsg->getSrcNode() == thisNode) {
03435 
03436                     const TransportAddress& member = clusters[layer].get(j);
03437 
03438                     if (!(member == thisNode)) {
03439 
03440                         CbrAppMessage* dup = static_cast<CbrAppMessage*>(appMsg->dup());
03441 
03442                         dup->setLayer( layer );
03443                         dup->setLastHop(thisNode);
03444 
03445                         sendMessageToUDP(member, dup);
03446 
03447                     }
03448 
03449                 }
03450 
03451             } // for
03452 
03453         }
03454 
03455     }
03456 
03457     // Also forward data to temporary peers
03458     std::map<TransportAddress, simtime_t>::iterator it = tempPeers.begin();
03459 
03460     while (it != tempPeers.end()) {
03461 
03462         CbrAppMessage* dup = static_cast<CbrAppMessage*>(appMsg->dup());
03463 
03464         dup->setSrcNode(thisNode);
03465 
03466         sendMessageToUDP(it->first, dup);
03467 
03468         it++;
03469 
03470     }
03471 
03472     delete appMsg;
03473 
03474 } // sendDataToOverlay

void oversim::Nice::sendHeartbeats (  )  [private]

Definition at line 1201 of file Nice.cc.

Referenced by ClusterSplit(), handleHeartbeat(), handleTimerEvent(), and handleUDPMessage().

01202 {
01203 
01204     /* Go through all cluster layers from top to bottom */
01205     //for (int i=0; i<=getHighestLayer(); i++) {
01206     for (int i=getHighestLayer(); i >= 0; i--) {
01207 
01208         /* Determine if node is cluster leader in this layer */
01209         if (!clusters[i].getLeader().isUnspecified()) {
01210 
01211             if (clusters[i].getLeader() == thisNode) {
01212 
01213                 /* Build heartbeat message with info on all current members */
01214                 NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERHEARTBEAT");
01215                 msg->setSrcNode(thisNode);
01216                 msg->setCommand(NICE_LEADERHEARTBEAT);
01217                 msg->setLayer(i);
01218                 msg->setOne_hop_distance(simTime().dbl());
01219                 msg->setK(k);
01220                 msg->setSc_tolerance(SC_PROC_DISTANCE);
01221 
01222                 msg->setMembersArraySize(clusters[i].getSize());
01223 
01224                 /* Fill in members */
01225                 for (int j = 0; j < clusters[i].getSize(); j++) {
01226 
01227                     msg->setMembers(j, clusters[i].get(j));
01228 
01229                 }
01230 
01231                 /* Fill in distances to members */
01232                 msg->setDistancesArraySize(clusters[i].getSize());
01233 
01234                 for (int j = 0; j < clusters[i].getSize(); j++) {
01235 
01236                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01237 
01238                     if (it != peerInfos.end()) {
01239 
01240                         msg->setDistances(j, it->second->get_distance());
01241 
01242                     } else {
01243 
01244                         msg->setDistances(j, -1);
01245 
01246                     }
01247 
01248                 }
01249 
01250                 /* Fill in Supercluster members, if existent */
01251                 if (clusters[i+1].getSize() > 0) {
01252 
01253                     msg->setSupercluster_leader(clusters[i+1].getLeader());
01254 
01255                     msg->setSupercluster_membersArraySize(clusters[i+1].getSize());
01256 
01257                     for (int j = 0; j < clusters[i+1].getSize(); j++) {
01258 
01259                         msg->setSupercluster_members(j, clusters[i+1].get(j));
01260 
01261                     }
01262 
01263                 }
01264 
01265                 /* Send Heartbeat to all members in cluster, except me */
01266                 for (int j = 0; j < clusters[i].getSize(); j++) {
01267 
01268                     if (clusters[i].get(j) != thisNode) {
01269 
01270                         NiceLeaderHeartbeat *copy = static_cast<NiceLeaderHeartbeat*>(msg->dup());
01271 
01272                         /* Get corresponding sequence numbers out of peerInfo */
01273                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01274 
01275                         if (it != peerInfos.end()) {
01276 
01277                             unsigned int seqNo = it->second->get_last_sent_HB();
01278 
01279                             copy->setSeqNo(++seqNo);
01280 
01281                             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
01282                             it->second->set_last_sent_HB(seqNo);
01283                             it->second->set_backHBPointer(!it->second->get_backHBPointer());
01284 
01285                             copy->setSeqRspNo(it->second->get_last_recv_HB());
01286 
01287                             if (it->second->get_last_HB_arrival() > 0) {
01288 
01289                                 copy->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
01290 
01291                             } else {
01292 
01293                                 copy->setHb_delay(0.0);
01294 
01295                             }
01296 
01297                         }
01298 
01299                         copy->setBitLength(NICELEADERHEARTBEAT_L(msg));
01300 
01301                         sendMessageToUDP(clusters[i].get(j), copy);
01302 
01303                     }
01304 
01305                 }
01306 
01307                 delete msg;
01308 
01309             } else { // I am normal cluster member
01310 
01311                 /* Build heartbeat message with info on all current members */
01312                 NiceHeartbeat* msg = new NiceHeartbeat("NICE_HEARTBEAT");
01313                 msg->setSrcNode(thisNode);
01314                 msg->setCommand(NICE_HEARTBEAT);
01315                 msg->setLayer(i);
01316                 msg->setOne_hop_distance(simTime().dbl());
01317 
01318                 msg->setSublayermembers(0);
01319                 if (i>0) {
01320                     if (clusters[i-1].getLeader() == thisNode)
01321                         msg->setSublayermembers(clusters[i-1].getSize());
01322 
01323                 }
01324 
01325                 msg->setMembersArraySize(clusters[i].getSize());
01326 
01327                 /* Fill in members */
01328                 for (int j = 0; j < clusters[i].getSize(); j++) {
01329 
01330                     msg->setMembers(j, clusters[i].get(j));
01331 
01332                 }
01333 
01334                 /* Fill in distances to members */
01335                 msg->setDistancesArraySize(clusters[i].getSize());
01336 
01337                 for (int j = 0; j < clusters[i].getSize(); j++) {
01338 
01339                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01340 
01341                     if (it != peerInfos.end()) {
01342 
01343                         msg->setDistances(j, it->second->get_distance());
01344 
01345                     } else {
01346 
01347                         msg->setDistances(j, -1);
01348 
01349                     }
01350 
01351                 }
01352 
01353                 /* Send Heartbeat to all members in cluster, except me */
01354                 for (int j = 0; j < clusters[i].getSize(); j++) {
01355 
01356                     if (clusters[i].get(j) != thisNode) {
01357 
01358                         NiceHeartbeat *copy = static_cast<NiceHeartbeat*>(msg->dup());
01359 
01360                         /* Get corresponding sequence number out of peerInfo */
01361                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01362 
01363                         if (it != peerInfos.end()) {
01364 
01365                             unsigned int seqNo = it->second->get_last_sent_HB();
01366 
01367                             copy->setSeqNo(++seqNo);
01368 
01369                             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
01370                             it->second->set_backHBPointer(!it->second->get_backHBPointer());
01371                             it->second->set_last_sent_HB(seqNo);
01372 
01373                             copy->setSeqRspNo(it->second->get_last_recv_HB());
01374 
01375                             copy->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
01376 
01377                         }
01378 
01379                         copy->setBitLength(NICEHEARTBEAT_L(msg));
01380 
01381                         sendMessageToUDP(clusters[i].get(j), copy);
01382 
01383                     }
01384 
01385                 }
01386 
01387                 delete msg;
01388 
01389             }
01390         }
01391 
01392     }
01393 
01394     // Additionally, ping all supercluster members, if existent
01395     if (clusters[getHighestLayer()+1].getSize() > 0) {
01396 
01397         NiceMessage* msg = new NiceMessage("NICE_PING_PROBE");
01398         msg->setSrcNode(thisNode);
01399         msg->setCommand(NICE_PING_PROBE);
01400         msg->setLayer(getHighestLayer()+1);
01401 
01402         msg->setBitLength(NICEMESSAGE_L(msg));
01403 
01404         for (int i=0; i<clusters[getHighestLayer()+1].getSize(); i++) {
01405 
01406             if (clusters[getHighestLayer()+1].get(i) != clusters[getHighestLayer()].getLeader()) {
01407 
01408                 NiceMessage* dup = static_cast<NiceMessage*>(msg->dup());
01409 
01410                 sendMessageToUDP(clusters[getHighestLayer()+1].get(i), dup);
01411 
01412                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[getHighestLayer()+1].get(i));
01413 
01414                 if (it != peerInfos.end()) {
01415 
01416                     it->second->set_distance_estimation_start(simTime().dbl());
01417 
01418                 }
01419 
01420             }
01421 
01422         }
01423 
01424         delete msg;
01425 
01426     }
01427 
01428 } // sendHeartbeats

void oversim::Nice::sendHeartbeatTo ( const TransportAddress node,
int  layer 
) [private]

Definition at line 1434 of file Nice.cc.

Referenced by handleHeartbeat(), and handleJoinCluster().

01435 {
01436 
01437     if (clusters[layer].getLeader() == thisNode) {
01438 
01439         /* Build heartbeat message with info on all current members */
01440         NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERHEARTBEAT");
01441         msg->setSrcNode(thisNode);
01442         msg->setCommand(NICE_LEADERHEARTBEAT);
01443         msg->setLayer(layer);
01444 
01445         msg->setMembersArraySize(clusters[layer].getSize());
01446 
01447         /* Fill in members */
01448         for (int j = 0; j < clusters[layer].getSize(); j++) {
01449 
01450             msg->setMembers(j, clusters[layer].get(j));
01451 
01452         }
01453 
01454         /* Fill in distances to members */
01455         msg->setDistancesArraySize(clusters[layer].getSize());
01456 
01457         for (int j = 0; j < clusters[layer].getSize(); j++) {
01458 
01459             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[layer].get(j));
01460 
01461             if (it != peerInfos.end()) {
01462 
01463                 msg->setDistances(j, it->second->get_distance());
01464 
01465             } else {
01466 
01467                 msg->setDistances(j, -1);
01468 
01469             }
01470 
01471         }
01472 
01473         /* Fill in Supercluster members, if existent */
01474         if (clusters[layer+1].getSize() > 0) {
01475 
01476             msg->setSupercluster_leader(clusters[layer+1].getLeader());
01477 
01478             msg->setSupercluster_membersArraySize(clusters[layer+1].getSize());
01479 
01480             for (int j = 0; j < clusters[layer+1].getSize(); j++) {
01481 
01482                 msg->setSupercluster_members(j, clusters[layer+1].get(j));
01483 
01484             }
01485 
01486         }
01487 
01488         /* Get corresponding sequence numbers out of peerInfo */
01489         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(node);
01490 
01491         if (it != peerInfos.end()) {
01492 
01493             unsigned int seqNo = it->second->get_last_sent_HB();
01494 
01495             msg->setSeqNo(++seqNo);
01496 
01497             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
01498             it->second->set_last_sent_HB(seqNo);
01499             it->second->set_backHBPointer(!it->second->get_backHBPointer());
01500 
01501             msg->setSeqRspNo(it->second->get_last_recv_HB());
01502 
01503             msg->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
01504 
01505         }
01506 
01507         msg->setBitLength(NICELEADERHEARTBEAT_L(msg));
01508 
01509         sendMessageToUDP(node, msg);
01510 
01511     } else {
01512 
01513         // build heartbeat message with info on all current members
01514         NiceHeartbeat* msg = new NiceHeartbeat("NICE_HEARTBEAT");
01515         msg->setSrcNode(thisNode);
01516         msg->setCommand(NICE_HEARTBEAT);
01517         msg->setLayer(layer);
01518 
01519         msg->setMembersArraySize(clusters[layer].getSize());
01520 
01521         // fill in members
01522         for (int j = 0; j < clusters[layer].getSize(); j++) {
01523 
01524             msg->setMembers(j, clusters[layer].get(j));
01525 
01526         }
01527 
01528         // fill in distances to members
01529         msg->setDistancesArraySize(clusters[layer].getSize());
01530 
01531         for (int j = 0; j < clusters[layer].getSize(); j++) {
01532 
01533             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[layer].get(j));
01534 
01535             if (it != peerInfos.end()) {
01536 
01537                 msg->setDistances(j, it->second->get_distance());
01538 
01539             } else if (clusters[layer].get(j) == thisNode) {
01540 
01541                 msg->setDistances(j, 0);
01542 
01543             } else {
01544 
01545                 msg->setDistances(j, -1);
01546 
01547             }
01548 
01549         }
01550 
01551         msg->setBitLength(NICEHEARTBEAT_L(msg));
01552 
01553         sendMessageToUDP(node, msg);
01554 
01555     }
01556 
01557 } // sendHeartbeatTo

void oversim::Nice::updateVisualization (  )  [private]

Definition at line 3480 of file Nice.cc.

Referenced by ClusterSplit(), handleTimerEvent(), and handleUDPMessage().

03481 {
03482 
03483     if (debug_visualization)
03484         EV << simTime() << " : " << thisNode.getAddress() << " : updateVisualization" << endl;
03485 
03486     /* Update node symbol */
03487     getParentModule()->getParentModule()
03488     ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
03489 
03490     if (!RendevouzPoint.isUnspecified()) {
03491 
03492         if (RendevouzPoint == thisNode) {
03493 
03494             getParentModule()->getParentModule()
03495             ->getDisplayString().setTagArg("i2", 0, "block/star_vs");
03496 
03497         }
03498 
03499     }
03500 
03501     /* Update node color */
03502     if (debug_visualization)
03503         EV << "getHighestLayer(): " << getHighestLayer() << endl;
03504 
03505     getParentModule()->getParentModule()
03506     ->getDisplayString().setTagArg("i2", 1, clustercolors[getHighestLayer()]);
03507 
03508 //      std::set<TransportAddress>::iterator it = AllHosts.begin();
03509 //
03510 //      while (it != AllHosts.end()) {
03511 //
03512 //              deleteOverlayNeighborArrow(*it);
03513 //
03514 //              it++;
03515 //
03516 //      }
03517 
03518     //redraw
03519     for (int i=0; clusters[i].contains(thisNode); i++) {
03520 
03521         if (!(clusters[i].getLeader().isUnspecified())) {
03522 
03523             if (clusters[i].getLeader() == thisNode) {
03524 
03525                 for (int j=0; j<clusters[i].getSize();j++) {
03526 
03527                     if (debug_visualization)
03528                         EV << "draw to: " << clusters[i].get(j) << endl;
03529 
03530                     showOverlayNeighborArrow(clusters[i].get(j), false, clusterarrows[i]);
03531 
03532                 }
03533 
03534             }
03535 
03536         }
03537     }
03538 
03539 
03540 } // updateVisualization


Friends And Related Function Documentation

friend class NicePeerInfo [friend]


Member Data Documentation

Definition at line 189 of file Nice.h.

Referenced by initializeOverlay(), and maintenance().

Definition at line 190 of file Nice.h.

Referenced by initializeOverlay(), and maintenance().

Definition at line 150 of file Nice.h.

Referenced by initializeOverlay(), and maintenance().

Definition at line 151 of file Nice.h.

Referenced by handleHeartbeat(), and initializeOverlay().

Definition at line 153 of file Nice.h.

Referenced by handleJoinCluster(), initializeOverlay(), and JoinCluster().

Definition at line 154 of file Nice.h.

Referenced by initializeOverlay(), and maintenance().

Definition at line 156 of file Nice.h.

Referenced by handleQuery(), initializeOverlay(), pollRP(), and Query().

Definition at line 155 of file Nice.h.

Referenced by handleUDPMessage(), initializeOverlay(), and Remove().

Definition at line 152 of file Nice.h.

Referenced by initializeOverlay(), and updateVisualization().

int oversim::Nice::evalLayer [private]

Definition at line 165 of file Nice.h.

Referenced by handleQueryResponse(), handleUDPMessage(), and initializeOverlay().

simtime_t oversim::Nice::first_HB [private]

Definition at line 142 of file Nice.h.

Definition at line 143 of file Nice.h.

Referenced by initializeOverlay().

simtime_t oversim::Nice::heartbeatInterval [private]

cMessage* oversim::Nice::heartbeatTimer [private]

Definition at line 168 of file Nice.h.

Referenced by handleTimerEvent(), handleUDPMessage(), initializeOverlay(), and pollRP().

Definition at line 187 of file Nice.h.

Referenced by BasicJoinLayer(), and JoinCluster().

int oversim::Nice::joinLayer [private]

Definition at line 166 of file Nice.h.

Referenced by initializeOverlay(), and Query().

unsigned short oversim::Nice::k [private]

Definition at line 159 of file Nice.h.

Referenced by handleHeartbeat(), initializeOverlay(), maintenance(), and sendHeartbeats().

std::vector<std::pair<TransportAddress, simtime_t> > oversim::Nice::leaderHeartbeats [private]

Definition at line 147 of file Nice.h.

Referenced by handleHeartbeat().

Definition at line 120 of file Nice.h.

Referenced by changeState(), handleTimerEvent(), and initializeOverlay().

cMessage* oversim::Nice::maintenanceTimer [private]

Definition at line 134 of file Nice.h.

Referenced by initializeOverlay(), and maintenance().

int oversim::Nice::pimp [private]

simtime_t oversim::Nice::query_compare [private]

Definition at line 177 of file Nice.h.

Referenced by handleQueryResponse(), and handleUDPMessage().

simtime_t oversim::Nice::query_start [private]

Definition at line 171 of file Nice.h.

Referenced by handleQueryResponse(), handleUDPMessage(), initializeOverlay(), and Query().

simtime_t oversim::Nice::queryInterval [private]

Definition at line 124 of file Nice.h.

Referenced by initializeOverlay(), and Query().

cMessage* oversim::Nice::queryTimer [private]

Definition at line 123 of file Nice.h.

Referenced by handleQueryResponse(), initializeOverlay(), Query(), and ~Nice().

cMessage* oversim::Nice::rpPollTimer [private]

Definition at line 131 of file Nice.h.

Referenced by initializeOverlay(), pollRP(), and ~Nice().

Definition at line 132 of file Nice.h.

Referenced by initializeOverlay(), and pollRP().

double oversim::Nice::SC_MIN_OFFSET [private]

Definition at line 192 of file Nice.h.

Referenced by initializeOverlay(), and maintenance().

Definition at line 191 of file Nice.h.

Referenced by initializeOverlay(), maintenance(), and sendHeartbeats().

simtime_t oversim::Nice::second_HB [private]

Definition at line 144 of file Nice.h.

Definition at line 145 of file Nice.h.

Referenced by initializeOverlay().

Definition at line 128 of file Nice.h.

Referenced by changeState(), handleUDPMessage(), initializeOverlay(), and maintenance().

Definition at line 127 of file Nice.h.

Referenced by changeState(), handleUDPMessage(), initializeOverlay(), maintenance(), and ~Nice().

short oversim::Nice::targetLayer [private]

Definition at line 180 of file Nice.h.

Referenced by BasicJoinLayer(), and handleQueryResponse().

std::map<TransportAddress, simtime_t> oversim::Nice::tempPeers [private]

Definition at line 186 of file Nice.h.

Referenced by handleUDPMessage(), initializeOverlay(), maintenance(), and sendDataToOverlay().

Definition at line 174 of file Nice.h.

Referenced by handleUDPMessage(), and Query().

cMessage* oversim::Nice::visualizationTimer [private]

Definition at line 137 of file Nice.h.

Referenced by changeState(), handleTimerEvent(), initializeOverlay(), and ~Nice().


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

Generated on Tue Sep 8 17:27:03 2009 for OverSim by  doxygen 1.5.8