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 handleNiceClusterMergeRequest (NiceClusterMerge *mergeMsg)
void handleNiceForceMerge (NiceMessage *msg)
void handleNiceHeartbeat (NiceMessage *msg)
void handleNiceJoinCluster (NiceMessage *joinMsg)
void handleNiceJoineval (NiceMessage *msg)
void handleNiceJoinevalResponse (NiceMessage *msg)
void handleNiceLeaderHeartbeatOrTransfer (NiceMessage *msg)
void handleNiceMulticast (NiceMulticastMessage *multicastMsg)
void handleNicePeerTemporary (NiceMessage *msg)
void handleNicePeerTemporaryRelease (NiceMessage *msg)
void handleNicePingProbe (NiceMessage *msg)
void handleNicePingProbeResponse (NiceMessage *msg)
void handleNicePollRp (NiceMessage *msg)
void handleNicePollRpResponse (NiceMessage *msg)
void handleNiceQuery (NiceMessage *queryMsg)
void handleNiceQueryResponse (NiceMemberMessage *queryRspMsg)
void handleNiceRemove (NiceMessage *msg)
void JoinCluster (const TransportAddress &leader, short layer)
void sendHeartbeats ()
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 (NiceMulticastMessage *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
int numInconsistencies
int numQueryTimeouts
int numPeerTimeouts
int numTempPeerTimeouts
int numStructurePartitions
int numOwnMessagesReceived
double totalSCMinCompare
int numJoins
int numForward
int totalForwardBytes
int numReceived
int totalReceivedBytes
int numHeartbeat
int totalHeartbeatBytes

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 60 of file Nice.cc.

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

Definition at line 83 of file Nice.cc.

00093 {
00094 
00095     // destroy self timer messages
00096     cancelAndDelete(heartbeatTimer);
00097     cancelAndDelete(maintenanceTimer);
00098     cancelAndDelete(structureConnectionTimer);
00099     cancelAndDelete(rpPollTimer);
00100     cancelAndDelete(queryTimer);
00101     cancelAndDelete(visualizationTimer);
00102 


Member Function Documentation

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

Definition at line 550 of file Nice.cc.

00560 {
00561 
00562     // Cancel timers involved in structure refinement
00563     cancelEvent(maintenanceTimer);
00564     cancelEvent(heartbeatTimer);
00565 
00566     Query(RendevouzPoint, layer);
00567 
00568     if (layer > -1)
00569         targetLayer = layer;
00570     else
00571         targetLayer = 0;
00572 
00573     // Temporary peer with RP for faster data reception
00574     NiceMessage* msg = new NiceMessage("NICE_PEER_TEMPORARY");
00575     msg->setSrcNode(thisNode);

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

Definition at line 525 of file Nice.cc.

00525                                      : Send Heartbeat Bytes/s", (double)totalHeartbeatBytes / time);
00526     if( debug_join ) recordScalar("Nice: Total joins", (double)numJoins);
00527 
00528 } // finishOverlay
00529 
00530 
00531 /******************************************************************************
00532  * becomeRendevouzPoint
00533  */
00534 void Nice::becomeRendevouzPoint()
00535 {
00536 
00537     RendevouzPoint = thisNode;
00538     EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << thisNode.getAddress() << endl;
00539 
00540     /* Mark node as new RP (star symbol) */
00541     getParentModule()->getParentModule()->getDisplayString().
00542     setTagArg("i2", 0, "block/star_vs");

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

changes node state

Parameters:
toState state to change to

Definition at line 225 of file Nice.cc.

00235 {
00236     switch (toState) {
00237 
00238     case INIT:
00239 
00240         state = INIT;
00241 
00242         getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, "red");
00243 
00244         scheduleAt(simTime() + 1, visualizationTimer);
00245 
00246         break;
00247 
00248     case BOOTSTRAP:
00249 
00250         state = BOOTSTRAP;
00251 
00252         /* check wether there exists a Rendevouz Point */
00253         if (RendevouzPoint.isUnspecified()) {
00254 
00255             /* become Rendevouz Point */
00256             becomeRendevouzPoint();
00257 
00258             /* join cluster layer 0 as first node */
00259             clusters[0].add(thisNode);
00260             clusters[0].setLeader(thisNode);
00261 
00262             changeState(READY);
00263 
00264             return;
00265 
00266         }
00267         else {
00268 
00269             /* initiate NICE structure joining */
00270             BasicJoinLayer(-1);
00271 
00272             double offset = structureConnectionInterval.dbl() * heartbeatInterval.dbl();
00273             scheduleAt(simTime() + offset, structureConnectionTimer);
00274 
00275         }
00276 
00277         break;
00278 
00279     case READY:
00280 
00281         state = READY;
00282 
00283         cancelEvent(heartbeatTimer);
00284         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
00285         cancelEvent(maintenanceTimer);
00286         scheduleAt(simTime() + maintenanceInterval, maintenanceTimer);
00287 

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

Definition at line 3047 of file Nice.cc.

03057 {
03058 
03059     simtime_t min_delay = 999;
03060 
03061     TransportAddress min_node = TransportAddress::UNSPECIFIED_NODE;
03062 
03063     for (int i=0; i<clusters[layer+1].getSize(); i++) {
03064 
03065         TransportAddress node = clusters[layer+1].get(i);
03066 
03067         if (node != thisNode) {
03068 
03069             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(node);
03070 
03071             if (it != peerInfos.end()) {
03072                 simtime_t delay = it->second->get_distance();
03073 
03074                 if ((delay > 0) && (delay < min_delay)) {
03075 
03076                     min_delay = delay;
03077                     min_node = node;
03078 
03079                 }
03080             }
03081         }
03082 
03083     }
03084 
03085     if (!min_node.isUnspecified()) {
03086 
03087         // leave
03088         for (int i=maxLayers-1; i>layer; i--) {
03089 
03090             if (clusters[i].getSize() > 0) {
03091 
03092                 if (clusters[i].contains(thisNode)) {
03093 
03094                     EV << "REPAIR: " << i << endl;
03095 
03096                     if (clusters[i].getLeader() == thisNode) {
03097 
03098                         EV << "1 remove from: " << i << endl;
03099                         Remove(i);
03100 
03101                         TaSet cl;
03102                         for (int j=0; j<clusters[i].getSize(); j++) {
03103 
03104                             cl.insert(clusters[i].get(j));
03105 
03106                             deleteOverlayNeighborArrow(clusters[i].get(j));
03107 
03108                         }
03109 
03110                         TransportAddress new_sc_center = findCenter(cl).first;
03111 
03112                         EV << "NEW LEADER (CM): " << i << " --> " << new_sc_center.getAddress() << endl;
03113 
03114                         clusters[i].setLeader(new_sc_center);
03115 
03116                         LeaderTransfer(i, new_sc_center, cl, new_sc_center);
03117 
03118                         // repair RP
03119                         if (i == maxLayers-1) {
03120 
03121                             RendevouzPoint = new_sc_center;
03122                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
03123 
03124                         }
03125                         else if (clusters[i+1].getSize() == 0) {
03126 
03127                             RendevouzPoint = new_sc_center;
03128                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
03129 
03130                         }
03131 
03132                     }
03133                     else {
03134 
03135                         // simply leave cluster
03136                         EV << "2 remove from: " << i << endl;
03137                         Remove(i);
03138                         clusters[i].remove(thisNode);
03139 
03140                     }
03141 
03142                 }
03143 
03144             }
03145 
03146         }
03147 
03148         clusters[layer+1].remove(thisNode);
03149 
03150         for (int j=0; j<clusters[layer+1].getSize(); j++) {
03151 
03152             deleteOverlayNeighborArrow(clusters[layer+1].get(j));
03153 
03154         }
03155 
03156         for (short i=0; i<maxLayers; i++) {
03157 
03158             if (clusters[i].getSize() > 0) {
03159 
03160                 if (clusters[i].contains(thisNode)) {
03161 
03162                     getParentModule()->getParentModule()->getDisplayString().setTagArg
03163                     ("i2", 1, clustercolors[i]);
03164 
03165                 }
03166 
03167             }
03168 
03169         }
03170 
03171         // send merge request
03172         ClusterMergeRequest(min_node, layer);

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

Definition at line 3178 of file Nice.cc.

03188 {
03189 
03190     NiceClusterMerge* msg = new NiceClusterMerge("NICE_CLUSTER_MERGE_REQUEST");
03191     msg->setSrcNode(thisNode);
03192     msg->setCommand(NICE_CLUSTER_MERGE_REQUEST);
03193     msg->setLayer(layer);
03194 
03195     msg->setMembersArraySize(clusters[layer].getSize());
03196 
03197     /* Fill in members */
03198     for (int j = 0; j < clusters[layer].getSize(); j++) {
03199 
03200         msg->setMembers(j, clusters[layer].get(j));
03201 
03202         deleteOverlayNeighborArrow(clusters[layer].get(j));
03203 
03204     }
03205 
03206     msg->setNewClusterLeader(clusters[layer+1].getLeader());
03207 
03208     msg->setBitLength(NICECLUSTERMERGE_L(msg));

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

Definition at line 2764 of file Nice.cc.

02774 {
02775 
02776     EV << simTime() << " : " << thisNode.getAddress() << " : ClusterSplit in Layer " << layer << endl;
02777 
02778     /* Get cluster to be splitted */
02779     NiceCluster cluster = clusters[layer];
02780 
02781     /* Introduce some helper structures */
02782     std::vector<TransportAddress> vec1;
02783     std::vector<TransportAddress> vec2;
02784     std::vector<TransportAddress> cl1;
02785     std::vector<TransportAddress> cl2;
02786     TransportAddress cl1_center = TransportAddress::UNSPECIFIED_NODE;
02787     TransportAddress cl2_center = TransportAddress::UNSPECIFIED_NODE;
02788     simtime_t min_delay = 999;
02789 
02790     for (int i=0; i<cluster.getSize(); i++) {
02791 
02792         /* Delete all arrows in visualization */
02793         deleteOverlayNeighborArrow(cluster.get(i));
02794 
02795         /* Put all members to first vector */
02796         vec1.push_back(cluster.get(i));
02797         //EV << "vec1.push_back(cluster.get(i)): " << cluster.get(i).getAddress() << endl;
02798 
02799         /* Put first half of members to second vector */
02800         if (i < cluster.getSize()/2) {
02801             vec2.push_back(cluster.get(i));
02802             //EV << "vec2.push_back(cluster.get(i)): " << cluster.get(i).getAddress() << endl;
02803         }
02804 
02805     }
02806 
02807     int combinations = 0;
02808 
02809     TaSet cl1set, cl2set, newClSet;
02810     TaSet::iterator sit;
02811 
02812     if (cluster.getSize() < /*(6*k-1)*/18) {
02813 
02814         /* Go through all combinations of clusters */
02815         do {
02816 
02817             combinations++;
02818 
02819             //EV << "combinations: " << combinations << endl;
02820 
02821             /* Introduce some helper structures */
02822             TransportAddress q1_center;
02823             TransportAddress q2_center;
02824             std::vector<TransportAddress> vec3;
02825 
02826             /* Determine elements that are in first set but not in second */
02827             std::set_difference(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), inserter(vec3, vec3.begin()));
02828 
02829             simtime_t min_q1_delay = 999;
02830             simtime_t min_q2_delay = 999;
02831             simtime_t max_delay = 0;
02832 
02833             q1_center = findCenter(vec2).first;
02834 
02835             //EV << "q1_center: " << q1_center.getAddress() << endl;
02836 
02837             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(q1_center);
02838 
02839             if (it != peerInfos.end()) {
02840 
02841                 min_q1_delay = it->second->get_distance();
02842 
02843             }
02844             else {
02845 
02846                 min_q1_delay = 0;
02847 
02848             }
02849 
02850             q2_center = findCenter(vec3).first;
02851 
02852             //EV << "q2_center: " << q2_center.getAddress() << endl;
02853 
02854             it = peerInfos.find(q2_center);
02855 
02856             if (it != peerInfos.end()) {
02857 
02858                 min_q2_delay = it->second->get_distance();
02859 
02860             }
02861             else {
02862 
02863                 min_q2_delay = 0;
02864 
02865             }
02866 
02867             max_delay = std::max(min_q1_delay, min_q2_delay);
02868 
02869             if (min_delay == 0) min_delay = max_delay;
02870 
02871             if ((max_delay < min_delay) && !q1_center.isUnspecified() && !q2_center.isUnspecified()) {
02872 
02873                 min_delay = max_delay;
02874                 cl1 = vec2;
02875                 cl2 = vec3;
02876                 cl1_center = q1_center;
02877                 cl2_center = q2_center;
02878             }
02879 
02880             //isplay(q1.begin(),q1.end());
02881 
02882         } while (next_combination(vec1.begin(), vec1.end(), vec2.begin(), vec2.end()));
02883 
02884         //EV << "COMBINATIONS: " << combinations << endl;
02885 
02886         //build sets
02887         std::vector<TransportAddress>::iterator vit;
02888 
02889         //EV << "cl1_center: " << cl1_center << endl;
02890         //EV << "cl2_center: " << cl2_center << endl;
02891 
02892         vit = cl1.begin();
02893         while (vit != cl1.end()) {
02894             cl1set.insert(*vit);
02895             vit++;
02896         }
02897 
02898         vit = cl2.begin();
02899         while (vit != cl2.end()) {
02900             cl2set.insert(*vit);
02901             vit++;
02902         }
02903 
02904     }
02905     else {
02906 
02907     }
02908 
02909     //if no valid split possible, split randomly
02910     if (cl1_center.isUnspecified() || cl2_center.isUnspecified()) {
02911         EV << thisNode.getAddress() << " RANDOM SPLIT" << endl;
02912         cl1set.clear();
02913         cl2set.clear();
02914         for (int i=0; i<cluster.getSize(); i++) {
02915             if (i < cluster.getSize()/2) {
02916                 cl1set.insert(cluster.get(i));
02917             }
02918             else {
02919                 cl2set.insert(cluster.get(i));
02920             }
02921         }
02922         cl1_center = findCenter(cl1set,true).first;
02923         cl2_center = findCenter(cl2set,true).first;
02924     }
02925 
02926     //find new neighbors
02927     TransportAddress newLeader, otherLeader;
02928     TaSet newCl;
02929     TaSet::iterator it = cl1set.begin();
02930     while (it != cl1set.end()) {
02931         if (*it == thisNode) {
02932             newCl = cl1set;
02933             newLeader = cl1_center;
02934             otherLeader = cl2_center;
02935         }
02936         it++;
02937     }
02938 
02939     it = cl2set.begin();
02940     while (it != cl2set.end()) {
02941         if (*it == thisNode) {
02942             newCl = cl2set;
02943             newLeader = cl2_center;
02944             otherLeader = cl1_center;
02945         }
02946         it++;
02947 
02948     }
02949 
02950     //####################################################################
02951 
02952     // Cluster split accomplished, now handling consequences
02953 
02954     // CASE 1: We lost all cluster leaderships
02955     // repair all cluster layer, top down
02956     if ((cl1_center != thisNode) && (cl2_center != thisNode)) {
02957 
02958         gracefulLeave(layer);
02959 
02960         if (clusters[layer+1].getSize() == 0) {
02961 
02962             clusters[layer+1].add(cl1_center);
02963             clusters[layer+1].add(cl2_center);
02964             clusters[layer+1].setLeader(cl1_center);
02965             RendevouzPoint = cl1_center;
02966             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << cl1_center.getAddress() << endl;
02967 
02968 
02969         }
02970 
02971         LeaderTransfer(layer, cl1_center, cl1set, cl1_center);
02972         LeaderTransfer(layer, cl2_center, cl2set, cl1_center);
02973 
02974         getParentModule()->getParentModule()
02975         ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02976 
02977     } // CASE 1
02978 
02979 
02980     // CASE 2: We stay leader in one of the new clusters
02981     if ((cl1_center == thisNode) || (cl2_center == thisNode)) {
02982 
02983         if (clusters[layer+1].getSize() == 0) {
02984 
02985             clusters[layer+1].add(cl1_center);
02986             clusters[layer+1].add(cl2_center);
02987 
02988             clusters[layer+1].setLeader(thisNode);
02989 
02990 
02991         }
02992 
02993         if (cl1_center == thisNode) {
02994 
02995             clusters[layer+1].add(cl2_center);
02996             LeaderTransfer(layer, cl2_center, cl2set, cl1_center);
02997 
02998         }
02999         else {
03000 
03001             clusters[layer+1].add(cl1_center);
03002             LeaderTransfer(layer, cl1_center, cl1set, cl1_center);
03003 
03004         }
03005 
03006 
03007     } // CASE 2
03008 
03009     // update local cluster information for focussed layer
03010     TaSet::const_iterator cit = cl1set.begin();
03011     bool found = false;
03012     while (cit != cl1set.end()) {
03013 
03014         if (*cit == thisNode)
03015             found = true;
03016         cit++;
03017     }
03018 
03019     clusters[layer].clear();
03020 
03021     if (found) {
03022 
03023         clusters[layer].setLeader(cl1_center);
03024 
03025         cit = cl1set.begin();
03026         while (cit != cl1set.end()) {
03027             clusters[layer].add(*cit);
03028             cit++;
03029         }
03030 
03031     }
03032     else {
03033 
03034         clusters[layer].setLeader(cl2_center);
03035 
03036         cit = cl2set.begin();
03037         while (cit != cl2set.end()) {
03038             clusters[layer].add(*cit);
03039             cit++;
03040         }
03041 

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

Definition at line 3282 of file Nice.cc.

03282                    : " << center << endl;
03283     return std::make_pair(center, min_delay);
03284 
03285 } // findCenter
03286 
03287 
03288 /******************************************************************************
03289  * findCenter
03290  */
03291 std::pair<TransportAddress, simtime_t> Nice::findCenter(std::vector<TransportAddress> cluster, bool allowRandom)
03292 {
03293     TaSet clusterset;
03294     std::vector<TransportAddress>::const_iterator it = cluster.begin();
03295 

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

Definition at line 3245 of file Nice.cc.

03245                            : " << thisNode.getAddress() << " : myMaxDistance: " << myDistance << endl;
03246 
03247 
03248 } // findClusterLeader
03249 
03250 
03251 /******************************************************************************
03252  * findCenter
03253  */
03254 std::pair<TransportAddress,simtime_t> Nice::findCenter(TaSet cluster, bool allowRandom)
03255 {
03256 
03257     TaSet::const_iterator it = cluster.begin();
03258     TransportAddress center = TransportAddress::UNSPECIFIED_NODE;
03259     simtime_t min_delay = 1000;
03260 
03261     if (cluster.size() > 1) {
03262 
03263         while (it != cluster.end()) {
03264 
03265             simtime_t delay = getMaxDistance(*it, cluster);
03266 
03267             if ((delay > 0) && (delay < min_delay)) {
03268 
03269                 min_delay = delay;
03270                 center = *it;
03271 
03272             }
03273 
03274             it++;
03275         }
03276 

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

Definition at line 3214 of file Nice.cc.

03224 {
03225     // Function not implemented. Do not call.
03226     fprintf(stderr, "Called unimplemented Nice.findClusterLeader\n");
03227     fflush(stderr);
03228     throw 0;
03229 
03230     // Determine if there is a more fitting cluster leader than me
03231 
03232     // First, get own maxDistance for this Cluster
03233     std::set<TransportAddress> clusterset;
03234 
03235     for (int i=0; i<cluster.getSize(); i++) {
03236 
03237         clusterset.insert(cluster.get(i));
03238         EV << simTime() << " : " << thisNode.getAddress() << " : MaxDistance: "
03239         << cluster.get(i).getAddress() << " : " << getMaxDistance(cluster.get(i), clusterset) << endl;

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

collects statistical data in derived class

Reimplemented from BaseOverlay.

Definition at line 497 of file Nice.cc.

00507 {
00508 
00509     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00510     if (time < GlobalStatistics::MIN_MEASURED) return;
00511 
00512     globalStatistics->addStdDev("Nice: Inconsistencies/s", (double)numInconsistencies / time);
00513     globalStatistics->addStdDev("Nice: Query Timeouts/s", (double)numQueryTimeouts / time);
00514     globalStatistics->addStdDev("Nice: Peer Timeouts/s", (double)numPeerTimeouts / time);
00515     globalStatistics->addStdDev("Nice: Temporary Peer Timeouts/s", (double)numTempPeerTimeouts / time);
00516     globalStatistics->addStdDev("Nice: Structure Partitions/s", (double)numStructurePartitions / time);
00517     globalStatistics->addStdDev("Nice: Own Messages Received/s", (double)numOwnMessagesReceived / time);
00518     globalStatistics->addStdDev("Nice: SC Minimum Compare/s", (double)totalSCMinCompare / time);
00519     globalStatistics->addStdDev("Nice: Received JOIN Messages/s", (double)numJoins / time);

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

Definition at line 1754 of file Nice.cc.

01764 {
01765 
01766     short highest = -1;
01767 
01768     for (short i=0; i<maxLayers; i++) {
01769 

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

Definition at line 1736 of file Nice.cc.

01746 {
01747 
01748     short highest = -1;
01749 
01750     for (short i=0; i<maxLayers; i++) {
01751 
01752         if (!clusters[i].getLeader().isUnspecified())

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

Definition at line 3301 of file Nice.cc.

03311 {
03312     simtime_t maxDelay = 0;
03313     simtime_t delay = 0;
03314 
03315     if (member == thisNode) {
03316 
03317         std::set<TransportAddress>::iterator it = neighbors.begin();
03318 
03319         while (it != neighbors.end()) {
03320 
03321             std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(*it);
03322 
03323             if (it2 != peerInfos.end()) {
03324 
03325                 delay = it2->second->get_distance();
03326                 maxDelay = std::max(delay, maxDelay);
03327 
03328             }
03329 
03330             it++;
03331 
03332         }
03333 
03334     }
03335     else {
03336 
03337         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(member);
03338 
03339         if (it != peerInfos.end()) {
03340 
03341             std::set<TransportAddress>::iterator it2 = neighbors.begin();
03342 
03343             while (it2 != neighbors.end()) {
03344 
03345                 //EV << "getDistanceTo " << *it2 << endl;
03346                 delay = it->second->getDistanceTo(*it2);
03347                 //EV << thisNode.getAddress() << " : Distance to " << it2->getAddress() << " : " << delay << endl;
03348                 maxDelay = std::max(delay, maxDelay);
03349 
03350                 it2++;
03351 

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

Definition at line 3356 of file Nice.cc.

03366 {
03367     simtime_t meanDelay = 0;
03368     simtime_t delay = 0;
03369     unsigned int number = 0;
03370 
03371     std::set<TransportAddress>::iterator it = neighbors.begin();
03372 
03373     while (it != neighbors.end()) {
03374 
03375         if (*it != thisNode) {
03376 
03377             std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(*it);
03378 
03379             if (it2 != peerInfos.end()) {
03380 
03381                 delay = it2->second->get_distance();
03382                 //EV << "delay to " << *it << " : " << delay << endl;
03383 
03384                 if  (delay > 0.0) {
03385 
03386                     meanDelay += delay;
03387                     number++;
03388 
03389                 }
03390 
03391             }
03392 
03393         }
03394 
03395         it++;
03396 
03397     }
03398 
03399     if (number > 0) {
03400 
03401         return meanDelay/number;

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

Definition at line 3496 of file Nice.cc.

03496                              : " << thisNode.getAddress() << " : Remove() finished." << endl;
03497 
03498 
03499 } // Remove
03500 
03501 
03502 /******************************************************************************
03503  * gracefulLeave
03504  */
03505 void Nice::gracefulLeave(short bottomLayer)
03506 {
03507     EV << simTime() << " : " << thisNode.getAddress() << " : gracefulLeave()" << endl;
03508 
03509     for (int i=maxLayers-1; i>bottomLayer; i--) {
03510 
03511         if (clusters[i].getSize() > 0) {
03512 
03513             if (clusters[i].contains(thisNode)) {
03514 
03515                 EV << "REPAIR: " << i << endl;
03516 
03517                 if (clusters[i].getLeader() == thisNode) {
03518 
03519                     EV << "remove from: " << i << endl;
03520                     Remove(i);
03521 
03522                     if (clusters[i].getSize() > 0) {
03523 
03524                         TaSet cl;
03525                         for (int j=0; j<clusters[i].getSize(); j++) {
03526 
03527                             cl.insert(clusters[i].get(j));
03528 
03529                             EV << "rest: " << clusters[i].get(j).getAddress() << endl;
03530 
03531                             deleteOverlayNeighborArrow(clusters[i].get(j));
03532 
03533                         }
03534 
03535                         TransportAddress new_sc_center = findCenter(cl).first;
03536 
03537                         EV << "NEW LEADER (GL): " << i << " --> " << new_sc_center.getAddress() << endl;
03538 
03539                         if (new_sc_center.isUnspecified()) {
03540 
03541                             new_sc_center = clusters[i].get(0);
03542 
03543                             EV << "UNSPECIFIED! instead choose: " << new_sc_center.getAddress() << endl;
03544 
03545                         }
03546 
03547                         clusters[i].setLeader(new_sc_center);
03548 
03549                         LeaderTransfer(i, new_sc_center, cl, new_sc_center);
03550 
03551                         // repair RP
03552                         if (i == maxLayers-1) {
03553 
03554                             RendevouzPoint = new_sc_center;
03555                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
03556 
03557                         }
03558                         else if (clusters[i+1].getSize() == 0) {
03559 
03560                             RendevouzPoint = new_sc_center;
03561                             EV << simTime() << " : " << thisNode.getAddress() << " : Set RP to " << new_sc_center.getAddress() << endl;
03562 
03563                         }
03564 
03565                     }
03566 
03567                 }
03568                 else {
03569 
03570                     // simply leave cluster
03571                     EV << "removing " << thisNode.getAddress() << " from " << i << endl;
03572                     Remove(i);
03573                     clusters[i].remove(thisNode);
03574 
03575                 }
03576 
03577             }

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 3583 of file Nice.cc.

03583                          : " << thisNode.getAddress() << " : gracefulLeave() finished." << endl;
03584 
03585 
03586 } // gracefulLeave
03587 
03588 
03589 /******************************************************************************
03590  * handleAppMessage
03591  */
03592 void Nice::handleAppMessage(cMessage* msg)
03593 {
03594     if ( ALMAnycastMessage* anycastMsg = dynamic_cast<ALMAnycastMessage*>(msg) ) {
03595         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getAddress()
03596            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03597            << "    Anycast message for group " << anycastMsg->getGroupId() << "\n"
03598            << "    ignored: Not implemented yet!"
03599            << endl;
03600     }
03601     else if ( ALMCreateMessage* createMsg = dynamic_cast<ALMCreateMessage*>(msg) ) {
03602         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getAddress()
03603            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03604            << "    Create message for group " << createMsg->getGroupId() << "\n"
03605            << "    ignored: Not implemented yet!"
03606            << endl;
03607     }
03608     else if ( ALMDeleteMessage* deleteMsg = dynamic_cast<ALMDeleteMessage*>(msg) ) {
03609         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getAddress()
03610            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03611            << "    Delete message for group " << deleteMsg->getGroupId() << "\n"
03612            << "    ignored: Not implemented yet!"
03613            << endl;
03614     }
03615     else if ( ALMLeaveMessage* leaveMsg = dynamic_cast<ALMLeaveMessage*>(msg) ) {
03616         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getAddress()
03617            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03618            << "    Leave message for group " << leaveMsg->getGroupId() << "\n"
03619            << "    ignored: Not implemented yet!"
03620            << endl;
03621     }
03622     else if ( ALMMulticastMessage* multicastMsg = dynamic_cast<ALMMulticastMessage*>(msg) ) {
03623         NiceMulticastMessage *niceMsg = new NiceMulticastMessage("NICE_MULTICAST");
03624         niceMsg->setCommand(NICE_MULTICAST);
03625         niceMsg->setLayer(-1);
03626         niceMsg->setSrcNode(thisNode);
03627         niceMsg->setLastHop(thisNode);
03628         niceMsg->setHopCount(0);
03629 
03630         niceMsg->setBitLength(NICEMULTICAST_L(niceMsg));
03631 
03632         niceMsg->encapsulate(multicastMsg);
03633         sendDataToOverlay(niceMsg);
03634 
03635         // otherwise msg gets deleted later
03636         msg = NULL;
03637     }
03638     else if ( ALMSubscribeMessage* subscribeMsg = dynamic_cast<ALMSubscribeMessage*>(msg) ) {
03639         EV << "[Nice::handleAppMessage() @ " << overlay->getThisNode().getAddress()
03640            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
03641            << "    Subscribe message for group " << subscribeMsg->getGroupId() << "\n"
03642            << "    ignored: Not implemented yet!"

void oversim::Nice::handleNiceClusterMergeRequest ( NiceClusterMerge *  mergeMsg  )  [private]

Definition at line 731 of file Nice.cc.

00732                                 : " << queryMsg->getSrcNode() << endl;
00733 
00734     if (debug_queries)
00735         EV << simTime() << " : " << thisNode.getAddress() << " : handleNiceQuery() finished." << endl;
00736 
00737     delete queryMsg;
00738 } // handleNiceQuery
00739 
00740 void Nice::handleNiceClusterMergeRequest(NiceClusterMerge* mergeMsg)
00741 {
00742     EV << simTime() << " : " << thisNode.getAddress() << " : NICE_CLUSTER_MERGE_REQUEST" << endl;
00743 
00744     short layer = mergeMsg->getLayer();
00745 
00746     // Only react if I am a leader of this cluster layer
00747 
00748     if (clusters[layer].getLeader().isUnspecified()) {
00749 
00750         EV << simTime() << " : " << thisNode.getAddress() << " : NO LEADER! BREAK. NICE_CLUSTER_MERGE_REQUEST finished" << endl;
00751 
00752         delete mergeMsg;
00753 
00754         return;
00755 
00756     }
00757 
00758     if (clusters[layer].getLeader() == thisNode) {
00759 
00760         clusters[layer+1].remove(mergeMsg->getSrcNode());
00761         deleteOverlayNeighborArrow(mergeMsg->getSrcNode());
00762 
00763         if (clusters[layer+1].getLeader() != thisNode)
00764             clusters[layer+1].setLeader(mergeMsg->getNewClusterLeader());
00765 
00766         // if I am alone now, become leader
00767         if (clusters[layer+1].getSize() == 1) {
00768 
00769             becomeRendevouzPoint();
00770 
00771             // cancel layer
00772             clusters[layer+1].clear();
00773 
00774             for (short i=0; i<maxLayers; i++) {
00775 
00776                 if (clusters[i].getSize() > 0) {
00777 
00778                     if (clusters[i].contains(thisNode)) {
00779 
00780                         getParentModule()->getParentModule()->getDisplayString().setTagArg
00781                             ("i2", 1, clustercolors[i]);
00782 
00783                     }
00784 
00785                 }
00786 
00787             }
00788 
00789         }
00790 
00791         for (unsigned int i=0; i<mergeMsg->getMembersArraySize(); i++) {
00792 
00793             /* Add new node to cluster */
00794             clusters[layer].add(mergeMsg->getMembers(i));
00795 
00796             /* Create peer context to joining node */
00797             /* Check if peer info already exists */
00798             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(mergeMsg->getMembers(i));
00799 
00800             if (it != peerInfos.end()) { /* We already know this node */
00801 
00802             }
00803             else { /* Create PeerInfo object */
00804 
00805                 NicePeerInfo* pi = new NicePeerInfo(this);
00806 
00807                 pi->set_last_HB_arrival(simTime().dbl());
00808 
00809                 peerInfos.insert(std::make_pair(mergeMsg->getMembers(i), pi));
00810 
00811             }
00812 
00813             /* Draw arrow to new member */
00814             showOverlayNeighborArrow(mergeMsg->getMembers(i), false, clusterarrows[layer]);
00815 
00816             EV << "getHighestLeaderLayer()].getSize(): " << clusters[getHighestLeaderLayer()].getSize() << endl;
00817 
00818             if (clusters[getHighestLeaderLayer()].getSize() < 2) {
00819 
00820                 // cancel layer
00821                 clusters[getHighestLeaderLayer()].clear();
00822 
00823                 for (short i=0; i<maxLayers; i++) {
00824 
00825                     if (clusters[i].getSize() > 0) {
00826 
00827                         if (clusters[i].contains(thisNode)) {
00828 
00829                             getParentModule()->getParentModule()->getDisplayString().setTagArg
00830                                 ("i2", 1, clustercolors[i]);
00831 
00832                         }
00833 
00834                     }
00835 
00836                 }
00837 
00838             }
00839 
00840         }
00841 
00842     }
00843     else { // Forward to new cluster leader
00844 
00845         if (pimp) {
00846 
00847             NiceMemberMessage* dup = static_cast<NiceMemberMessage*>(mergeMsg->dup());
00848             sendMessageToUDP(clusters[layer].getLeader(), dup);
00849             delete mergeMsg;
00850             return;
00851 
00852         }
00853 

void oversim::Nice::handleNiceForceMerge ( NiceMessage *  msg  )  [private]

Definition at line 855 of file Nice.cc.

00861                          : " << thisNode.getAddress() << " : NICE_CLUSTER_MERGE_REQUEST finished" << endl;

void oversim::Nice::handleNiceHeartbeat ( NiceMessage *  msg  )  [private]

Definition at line 862 of file Nice.cc.

Referenced by handleNiceMulticast().

00865 {
00866     ClusterMergeRequest(msg->getSrcNode(), msg->getLayer());
00867 
00868     delete msg;
00869 }
00870 
00871 void Nice::handleNiceHeartbeat(NiceMessage* msg)
00872 {
00873     if (debug_heartbeats)
00874         EV << simTime() << " : " << thisNode.getAddress() << " : handleHeartbeat()...  " << endl;
00875 
00876 
00877     // First, check if heartbeat is LeaderTransfer
00878     if (msg->getCommand() == NICE_LEADERTRANSFER) {
00879 
00880         if (debug_heartbeats)
00881             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_LEADERTRANSFER from " << msg->getSrcNode() << " for " << msg->getLayer() << endl;
00882 
00883         if (!clusters[msg->getLayer()].getLeader().isUnspecified()) {
00884 
00885             /* React only if I am not already leader */
00886             if (clusters[msg->getLayer()].getLeader() != thisNode /*&& clusters[msg->getLayer()].getLeader() == msg->getSrcNode()*/) {
00887 
00888                 if (debug_heartbeats)
00889                     EV << "I am not already leader of this cluster layer." << endl;
00890 
00891                 NiceLeaderHeartbeat* hbMsg = check_and_cast<NiceLeaderHeartbeat*>(msg);
00892 
00893                 clusters[hbMsg->getLayer()].clear();
00894                 clusters[hbMsg->getLayer()].setLeader(thisNode);
00895 
00896                 for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
00897 
00898                     if (debug_heartbeats)
00899                         EV << "Adding: " << hbMsg->getMembers(i) << endl;
00900 
00901                     clusters[hbMsg->getLayer()].add(hbMsg->getMembers(i));
00902                     showOverlayNeighborArrow(hbMsg->getMembers(i), false, clusterarrows[hbMsg->getLayer()]);
00903 
00904                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getMembers(i));
00905 
00906                     if (it != peerInfos.end()) {
00907 
00908                         /* We already know this node */
00909                         it->second->touch();
00910 
00911                     }
00912                     else {
00913 
00914                         //We don't know him yet
00915 
00916                     }
00917 
00918                 }
00919 
00920                 if (hbMsg->getSupercluster_membersArraySize() > 0) {
00921 
00922                     clusters[hbMsg->getLayer()+1].clear();
00923 
00924                     for (unsigned int i=0; i<hbMsg->getSupercluster_membersArraySize(); i++) {
00925 
00926                         clusters[hbMsg->getLayer()+1].add(hbMsg->getSupercluster_members(i));
00927 
00928                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSupercluster_members(i));
00929 
00930                         if (it != peerInfos.end()) {
00931 
00932                             /* We already know this node */
00933                             it->second->touch();
00934 
00935                         }
00936                         else {
00937 
00938                             //We don't know him yet
00939 
00940                         }
00941 
00942                     }
00943 
00944                     // experimental
00945                     clusters[hbMsg->getLayer()+1].add(thisNode);
00946 
00947                     clusters[hbMsg->getLayer()+1].setLeader(hbMsg->getSupercluster_leader());
00948 
00949                     if ((clusters[hbMsg->getLayer()+1].getLeader() == thisNode) && (clusters[hbMsg->getLayer()+2].getSize() == 0)) {
00950 
00951                         for (unsigned int i=0; i<hbMsg->getSupercluster_membersArraySize(); i++) {
00952 
00953                             showOverlayNeighborArrow(hbMsg->getSupercluster_members(i), false, clusterarrows[hbMsg->getLayer()+1]);
00954 
00955                         }
00956 
00957                         becomeRendevouzPoint();
00958 
00959                     }
00960                     else {
00961 
00962                         JoinCluster(hbMsg->getSupercluster_leader(), hbMsg->getLayer()+1);
00963 
00964                     }
00965 
00966                 }
00967                 else {
00968 
00969                     becomeRendevouzPoint();
00970 
00971                 }
00972 
00973                 for (int i=0; i<maxLayers; i++) {
00974 
00975                     if (clusters[i].contains(thisNode))
00976                         getParentModule()->getParentModule()->getDisplayString().setTagArg("i2", 1, clustercolors[i]);
00977 
00978                 }
00979 
00980                 clusters[hbMsg->getLayer()].set_Last_LT();
00981 
00982                 delete hbMsg;
00983 
00984             }
00985             else {
00986 
00987                 //Do nothing
00988 
00989             }
00990 
00991         }
00992         else {
00993 
00994 
00995 
00996         }
00997 
00998         if (pimp)
00999             sendHeartbeats();
01000 
01001         return;
01002 
01003     }
01004     else if (msg->getCommand() == NICE_HEARTBEAT) {
01005 
01006         NiceHeartbeat* hbMsg = check_and_cast<NiceHeartbeat*>(msg);
01007 
01008         if (debug_heartbeats)
01009             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_HEARTBEAT from  " << hbMsg->getSrcNode() << endl;
01010 
01011         /* Update sequence number information and evaluate distance */
01012         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSrcNode());
01013 
01014         if (it != peerInfos.end()) {
01015 
01016             /* We already know this node */
01017             // Collect subcluster infos
01018             it->second->setSubClusterMembers(hbMsg->getSublayermembers());
01019 
01020             it->second->set_last_HB_arrival(simTime().dbl());
01021 
01022             if (it->second->get_backHB(hbMsg->getSeqRspNo()) > 0) {
01023 
01024                 /* Valid distance measurement, get value */
01025                 double oldDistance = it->second->get_distance();
01026 
01027                 /* Use Exponential Moving Average with factor 0.1 */
01028                 double newDistance = (simTime().dbl() - it->second->get_backHB(hbMsg->getSeqRspNo()) - hbMsg->getHb_delay())/2.0;
01029 
01030                 if (oldDistance > 0) {
01031 
01032                     it->second->set_distance((0.1 * newDistance) + (0.9 * oldDistance));
01033 
01034                 }
01035                 else {
01036 
01037                     it->second->set_distance(newDistance);
01038 
01039                 }
01040 
01041             }
01042 
01043             it->second->set_last_recv_HB(hbMsg->getSeqNo());
01044 
01045         }
01046 
01047         it = peerInfos.find(hbMsg->getSrcNode());
01048 
01049         if (it != peerInfos.end()) {
01050 
01051             for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01052 
01053                 it->second->updateDistance(hbMsg->getMembers(i), hbMsg->getDistances(i));
01054 
01055             }
01056 
01057         }
01058 
01059         delete hbMsg;
01060 
01061     }
01062     else if (msg->getCommand() == NICE_LEADERHEARTBEAT) {
01063 
01064         NiceLeaderHeartbeat* hbMsg = check_and_cast<NiceLeaderHeartbeat*>(msg);
01065 
01066         if (debug_heartbeats)
01067             EV << simTime() << " : " << thisNode.getAddress() << " : NICE_LEADERHEARTBEAT from  " << hbMsg->getSrcNode() << endl;
01068 
01069         //Alternative Detection
01070         leaderHeartbeats.push_back(std::make_pair(hbMsg->getSrcNode(), simTime()));
01071 
01072         if (leaderHeartbeats.size() > 3) {
01073 
01074             if (debug_heartbeats)
01075                 EV << simTime() << "leaderHeartbeats.size() > 3 :  " << leaderHeartbeats.size() << endl;
01076 
01077             simtime_t predecessor =  leaderHeartbeats.at(leaderHeartbeats.size()-2).second;
01078 
01079             if (debug_heartbeats)
01080                 EV << simTime() << "predecessor :  " << predecessor << endl;
01081 
01082 
01083             if (simTime() < (predecessor + heartbeatInterval)) {
01084 
01085                 if (debug_heartbeats)
01086                     EV << simTime() << "simTime() < (predecessor + heartbeatInterval)" << endl;
01087 
01088                 if (leaderHeartbeats.at(leaderHeartbeats.size()-2).first != hbMsg->getSrcNode()) {
01089 
01090                     if (debug_heartbeats) {
01091                         EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-2).first != hbMsg->getSrcNode())" << endl;
01092                         EV << "leaderHeartbeats.at(leaderHeartbeats.size()-2).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-2).first << endl;
01093                     }
01094 
01095                     if (leaderHeartbeats.at(leaderHeartbeats.size()-3).first == hbMsg->getSrcNode()) {
01096 
01097                         if (debug_heartbeats) {
01098                             EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-3).first == hbMsg->getSrcNode())" << endl;
01099                             EV << "leaderHeartbeats.at(leaderHeartbeats.size()-3).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-3).first << endl;
01100                             EV << "timestamp: " << leaderHeartbeats.at(leaderHeartbeats.size()-3).second << endl;
01101                         }
01102 
01103                         if (leaderHeartbeats.at(leaderHeartbeats.size()-4).first == leaderHeartbeats.at(leaderHeartbeats.size()-2).first) {
01104 
01105                             if (debug_heartbeats) {
01106                                 EV << simTime() << "(leaderHeartbeats.at(leaderHeartbeats.size()-4).first == leaderHeartbeats.at(leaderHeartbeats.size()-2).first" << endl;
01107                                 EV << "leaderHeartbeats.at(leaderHeartbeats.size()-4).first: " << leaderHeartbeats.at(leaderHeartbeats.size()-4).first << endl;
01108                                 EV << "timestamp: " << leaderHeartbeats.at(leaderHeartbeats.size()-4).second << endl;
01109 
01110                             }
01111 
01112                             if (debug_heartbeats)
01113                                 EV << simTime() << " : " << thisNode.getAddress() << " : CONFLICTING LEADERS!" << endl;
01114 
01115                             NiceMessage* removeMsg = new NiceMessage("NICE_REMOVE");
01116                             removeMsg->setSrcNode(thisNode);
01117                             removeMsg->setCommand(NICE_REMOVE);
01118                             removeMsg->setLayer(hbMsg->getLayer());
01119 
01120                             removeMsg->setBitLength(NICEMESSAGE_L(removeMsg));
01121 
01122                             sendMessageToUDP(leaderHeartbeats.at(leaderHeartbeats.size()-2).first, removeMsg);
01123 
01124                         }
01125 
01126                     }
01127 
01128                 }
01129             }
01130 
01131         }
01132 
01133 
01134         /* Tidy up leaderheartbeats */
01135         if (leaderHeartbeats.size() > 4) {
01136 
01137             for (unsigned int i=0; i<(leaderHeartbeats.size()-4); i++) {
01138 
01139                 leaderHeartbeats.erase(leaderHeartbeats.begin());
01140 
01141             }
01142 
01143         }
01144 
01145         /* Update sequence number information and evaluate distance */
01146         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSrcNode());
01147 
01148         if (it != peerInfos.end()) { /* We already know this node */
01149 
01150             it->second->set_last_HB_arrival(simTime().dbl());
01151 
01152             if (it->second->get_backHB(hbMsg->getSeqRspNo()) > 0) {
01153 
01154                 /* Valid distance measurement, get value */
01155                 it->second->set_distance((simTime().dbl() - it->second->get_backHB(hbMsg->getSeqRspNo()) - hbMsg->getHb_delay())/2);
01156 
01157             }
01158 
01159             it->second->set_last_recv_HB(hbMsg->getSeqNo());
01160 
01161         }
01162 
01163         it = peerInfos.find(hbMsg->getSrcNode());
01164 
01165         if (it != peerInfos.end()) {
01166 
01167             for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01168 
01169                 it->second->updateDistance(hbMsg->getMembers(i), hbMsg->getDistances(i));
01170 
01171             }
01172 
01173         }
01174 
01175         // Maintain cluster memberships
01176 
01177         if (!clusters[hbMsg->getLayer()].contains(thisNode)) {
01178 
01179             /* Node is not part of this cluster, remove it */
01180             NiceMessage* removeMsg = new NiceMessage("NICE_REMOVE");
01181             removeMsg->setSrcNode(thisNode);
01182             removeMsg->setCommand(NICE_REMOVE);
01183             removeMsg->setLayer(hbMsg->getLayer());
01184 
01185             removeMsg->setBitLength(NICEMESSAGE_L(removeMsg));
01186 
01187             if (debug_heartbeats)
01188                 EV << "Node is not part of this cluster (" << hbMsg->getLayer() << "), removing it..." << endl;
01189 
01190             sendMessageToUDP(hbMsg->getSrcNode(), removeMsg);
01191 
01192             return;
01193 
01194         }
01195 
01196         if (clusters[hbMsg->getLayer()].getLeader() == thisNode) {
01197 
01198             if (simTime() < clusters[hbMsg->getLayer()].get_Last_LT() + 1.0) {
01199 
01200                 if (debug_heartbeats)
01201                     EV << "Potential deprecated LeaderHeartbeat. Ignoring..." << endl;
01202 
01203                 return;
01204 
01205             }
01206 
01207             if (debug_heartbeats)
01208                 EV << "I am also Leader in this cluster. Conflicting!..." << endl;
01209 
01210             /* Winner: The one with minimum max distance*/
01211             bool allIn = true;
01212 
01213             //Check if we're talking about same cluster
01214 
01215             for (unsigned int u=0; u<hbMsg->getMembersArraySize(); u++) {
01216 
01217                 if (!clusters[hbMsg->getLayer()].contains(hbMsg->getMembers(u))) {
01218                     allIn = false;
01219 
01220                     if (debug_heartbeats)
01221                         EV << hbMsg->getMembers(u) << " : Not in my cluster." << endl;
01222 
01223                 }
01224                 else {
01225 
01226                     if (debug_heartbeats)
01227                         EV << hbMsg->getMembers(u) << " : Check." << endl;
01228 
01229                 }
01230 
01231             }
01232 
01233             if (allIn) {
01234 
01235                 // Perform check for better cluster leader
01236                 TaSet cl;
01237                 for (int l=0; l<clusters[hbMsg->getLayer()].getSize(); l++) {
01238 
01239                     cl.insert(clusters[hbMsg->getLayer()].get(l));
01240 
01241                 }
01242 
01243                 simtime_t myDistance = getMaxDistance(thisNode, cl);
01244                 simtime_t hisDistance = getMaxDistance(hbMsg->getSrcNode(), cl);
01245 
01246 
01247                 if (myDistance > hisDistance) {
01248 
01249                     TaSet cl;
01250                     for (int i=0; i<clusters[hbMsg->getLayer()].getSize(); i++) {
01251 
01252                         cl.insert(clusters[hbMsg->getLayer()].get(i));
01253 
01254                         deleteOverlayNeighborArrow(clusters[hbMsg->getLayer()].get(i));
01255 
01256                     }
01257                     LeaderTransfer(hbMsg->getLayer(), hbMsg->getSrcNode(), cl, clusters[hbMsg->getLayer()+1].getLeader());
01258 
01259                     clusters[hbMsg->getLayer()].setLeader(hbMsg->getSrcNode());
01260 
01261                     gracefulLeave(hbMsg->getLayer());
01262 
01263                     /* Anyways, update cluster info */
01264 
01265                 }
01266                 else {
01267 
01268                     sendHeartbeatTo(hbMsg->getSrcNode(), hbMsg->getLayer());
01269 
01270                     return;
01271 
01272                 }
01273 
01274             }
01275             else { // We have different children, simply leave other
01276 
01277                 /* Remove it */
01278                 NiceMessage* removeMsg = new NiceMessage("NICE_REMOVE");
01279                 removeMsg->setSrcNode(thisNode);
01280                 removeMsg->setCommand(NICE_REMOVE);
01281                 removeMsg->setLayer(hbMsg->getLayer());
01282 
01283                 removeMsg->setBitLength(NICEMESSAGE_L(removeMsg));
01284 
01285                 sendMessageToUDP(hbMsg->getSrcNode(), removeMsg);
01286 
01287                 return;
01288 
01289             }
01290         }
01291 
01292         /* Everything is in order. Process HB */
01293 
01294         for (int m=hbMsg->getLayer(); m<maxLayers; m++) {
01295             clusters[m].clear();
01296         }
01297 
01298         for (unsigned int i=0; i<hbMsg->getMembersArraySize(); i++) {
01299 
01300             //Check if member is already part of cluster
01301 
01302             /* Check if peer info already exists */
01303             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getMembers(i));
01304 
01305             if (it != peerInfos.end()) { /* We already know this node */
01306 
01307             }
01308             else { /* Create PeerInfo object */
01309 
01310                 NicePeerInfo* pi = new NicePeerInfo(this);
01311 
01312                 pi->set_last_HB_arrival(simTime().dbl());
01313 
01314                 peerInfos.insert(std::make_pair(hbMsg->getMembers(i), pi));
01315 
01316             }
01317 
01318             clusters[hbMsg->getLayer()].add(hbMsg->getMembers(i));
01319 
01320         }
01321 
01322         // set cluster leadership
01323         clusters[hbMsg->getLayer()].setLeader(hbMsg->getSrcNode());
01324 
01325         if (hbMsg->getSupercluster_membersArraySize() > 0) {
01326 
01327             clusters[hbMsg->getLayer()+1].clear();
01328 
01329             for (unsigned int i=0; i<hbMsg->getSupercluster_membersArraySize(); i++) {
01330 
01331                 /* Check if peer info already exists */
01332                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(hbMsg->getSupercluster_members(i));
01333 
01334                 if (it != peerInfos.end()) { /* We already know this node */
01335 
01336                 }
01337                 else { /* Create PeerInfo object */
01338 
01339                     NicePeerInfo* pi = new NicePeerInfo(this);
01340 
01341                     pi->set_last_HB_arrival(simTime().dbl());
01342 
01343                     peerInfos.insert(std::make_pair(hbMsg->getSupercluster_members(i), pi));
01344 
01345                 }
01346 
01347                 clusters[hbMsg->getLayer()+1].add(hbMsg->getSupercluster_members(i));
01348 
01349             }
01350 
01351             clusters[hbMsg->getLayer()+1].setLeader(hbMsg->getSupercluster_leader());
01352 
01353             it = peerInfos.find(hbMsg->getSrcNode());
01354 
01355             if (it != peerInfos.end()) {
01356 
01357                 for (unsigned int k=0; k<hbMsg->getMembersArraySize(); k++) {
01358 
01359                     it->second->updateDistance(hbMsg->getMembers(k), hbMsg->getDistances(k));
01360 
01361                 }
01362 
01363             }
01364             else {
01365 
01366                 NicePeerInfo* pi = new NicePeerInfo(this);
01367 
01368                 pi->set_last_HB_arrival(simTime().dbl());
01369 
01370                 peerInfos.insert(std::make_pair(hbMsg->getSrcNode(), pi));
01371 
01372             }

void oversim::Nice::handleNiceJoinCluster ( NiceMessage *  joinMsg  )  [private]

Definition at line 1374 of file Nice.cc.

01380                              : " << thisNode.getAddress() << " : handleHeartbeat() finished.  " << endl;
01381 }
01382 
01383 void Nice::handleNiceJoinCluster(NiceMessage* joinMsg)
01384 {
01385 
01386     if (debug_join)
01387         EV << simTime() << " : " << thisNode.getAddress() << " : handleNiceJoinCluster()" << endl;
01388 
01389     short layer = joinMsg->getLayer();
01390 
01391     if (debug_join)
01392         std::cout << " From : " << joinMsg->getSrcNode() << ", Layer:  " << layer << endl;
01393 
01394     if (!clusters[layer].getLeader().isUnspecified()) {
01395 
01396         if (clusters[layer].getLeader() != thisNode) {
01397 
01398             if (pimp) {
01399 
01400                 NiceMessage* dup = static_cast<NiceMessage*>(joinMsg->dup());
01401                 sendMessageToUDP(clusters[layer].getLeader(), dup);
01402 
01403             }
01404 
01405         }
01406         else {
01407 
01408             RECORD_STATS(++numJoins);
01409 
01410             /* Add new node to cluster */
01411             clusters[layer].add(joinMsg->getSrcNode());
01412 
01413             /* Create peer context to joining node */
01414             /* Check if peer info already exists */
01415             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(joinMsg->getSrcNode());
01416 
01417             if (it != peerInfos.end()) { /* We already know this node */
01418 
01419 
01420             }
01421             else { /* Create PeerInfo object */
01422 
01423                 NicePeerInfo* pi = new NicePeerInfo(this);
01424 
01425                 peerInfos.insert(std::make_pair(joinMsg->getSrcNode(), pi));
01426 
01427             }
01428 
01429             /* Draw arrow to new member */
01430             showOverlayNeighborArrow(joinMsg->getSrcNode(), false, clusterarrows[layer]);
01431 
01432             if (pimp)
01433                 sendHeartbeatTo(joinMsg->getSrcNode(), layer);
01434         }
01435 
01436     }
01437     else {
01438 
01439         if (debug_join)

void oversim::Nice::handleNiceJoineval ( NiceMessage *  msg  )  [private]

Definition at line 1441 of file Nice.cc.

01445                              : " << thisNode.getAddress() << " : handleNiceJoinCluster() finished." << endl;
01446 
01447     delete joinMsg;
01448 } // handleNiceJoinCluster
01449 
01450 void Nice::handleNiceJoineval(NiceMessage* msg)
01451 {
01452     NiceMessage* responseMsg = new NiceMessage("NICE_JOINEVAL_RESPONSE");
01453     responseMsg->setSrcNode(thisNode);

void oversim::Nice::handleNiceJoinevalResponse ( NiceMessage *  msg  )  [private]

Definition at line 1455 of file Nice.cc.

01465 {
01466     if (evalLayer > 0 && evalLayer == msg->getLayer()) {
01467 
01468         query_compare = simTime() - query_compare;
01469 
01470         if (query_compare < query_start) {
01471 
01472             Query(msg->getSrcNode(), msg->getLayer()-1);
01473 
01474         }
01475         else {
01476 

void oversim::Nice::handleNiceLeaderHeartbeatOrTransfer ( NiceMessage *  msg  )  [private]

Definition at line 1478 of file Nice.cc.

void oversim::Nice::handleNiceMulticast ( NiceMulticastMessage *  multicastMsg  )  [private]

Definition at line 1487 of file Nice.cc.

01488 {
01489             cancelEvent(structureConnectionTimer);
01490             double offset = structureConnectionInterval.dbl() * heartbeatInterval.dbl();
01491             scheduleAt(simTime() + offset, structureConnectionTimer);
01492 
01493             handleNiceHeartbeat(msg);
01494 }
01495 
01496 void Nice::handleNiceMulticast(NiceMulticastMessage* multicastMsg)
01497 {
01498     RECORD_STATS(++numReceived; totalReceivedBytes += multicastMsg->getByteLength());
01499 
01500     /* If it is mine, count */
01501     if (multicastMsg->getSrcNode() == thisNode) {
01502 
01503         RECORD_STATS(++numOwnMessagesReceived);
01504 
01505     }
01506     else {
01507 
01508         unsigned int hopCount = multicastMsg->getHopCount();
01509         hopCount++;
01510 
01511         if (hopCount < 8) {
01512 
01513             RECORD_STATS(++numForward; totalForwardBytes += multicastMsg->getByteLength());
01514 
01515             NiceMulticastMessage* forOverlay = static_cast<NiceMulticastMessage*>(multicastMsg->dup());
01516             forOverlay->setHopCount(hopCount);

void oversim::Nice::handleNicePeerTemporary ( NiceMessage *  msg  )  [private]

Definition at line 1518 of file Nice.cc.

void oversim::Nice::handleNicePeerTemporaryRelease ( NiceMessage *  msg  )  [private]

Definition at line 1526 of file Nice.cc.

01528 {
01529     // Add node to tempPeers
01530     tempPeers.insert(std::make_pair(msg->getSrcNode(), simTime()));
01531 
01532     delete msg;

void oversim::Nice::handleNicePingProbe ( NiceMessage *  msg  )  [private]

Definition at line 1534 of file Nice.cc.

01536 {
01537     // Remove node from tempPeers
01538     tempPeers.erase(msg->getSrcNode());
01539 
01540     delete msg;
01541 }
01542 
01543 void Nice::handleNicePingProbe(NiceMessage* msg)
01544 {
01545     // Only answer if I am part of requested layer
01546     if (clusters[msg->getLayer()].contains(thisNode)) {
01547 
01548         NiceMessage* probe = new NiceMessage("NICE_PING_PROBE");
01549         probe->setSrcNode(thisNode);
01550         probe->setCommand(NICE_PING_PROBE_RESPONSE);
01551         probe->setLayer(msg->getLayer());
01552 
01553         probe->setBitLength(NICEMESSAGE_L(probe));
01554 
01555         sendMessageToUDP(msg->getSrcNode(), probe);
01556 

void oversim::Nice::handleNicePingProbeResponse ( NiceMessage *  msg  )  [private]

Definition at line 1558 of file Nice.cc.

01558          {
01559 
01560         //Do nothing
01561 
01562     }
01563 
01564     delete msg;
01565 }
01566 
01567 void Nice::handleNicePingProbeResponse(NiceMessage* msg)
01568 {
01569     //Only react if still in same cluster as when asked
01570     if (msg->getLayer() == getHighestLayer()+1) {
01571 
01572         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(msg->getSrcNode());
01573 
01574         if (it != peerInfos.end()) {
01575 
01576             double distance = simTime().dbl() - it->second->getDES();
01577 

void oversim::Nice::handleNicePollRp ( NiceMessage *  msg  )  [private]

Definition at line 1579 of file Nice.cc.

01589 {
01590     if (RendevouzPoint == thisNode) {
01591 
01592         NiceMessage* response = new NiceMessage("NICE_POLL_RP_RESPONSE");
01593         response->setSrcNode(thisNode);

void oversim::Nice::handleNicePollRpResponse ( NiceMessage *  msg  )  [private]

Definition at line 1595 of file Nice.cc.

01605 {
01606     if (isPollingRP) {
01607 
01608         if (msg->getLayer() < getHighestLayer()) {
01609 
01610             becomeRendevouzPoint();
01611 
01612         }
01613         else {

void oversim::Nice::handleNiceQuery ( NiceMessage *  queryMsg  )  [private]

Definition at line 614 of file Nice.cc.

00617                              : " << thisNode.getAddress() << " : Query() finished." << endl;
00618 
00619 } // Query
00620 
00621 /* Functions handling NICE messages */
00622 
00623 void Nice::handleNiceQuery(NiceMessage* queryMsg)
00624 {
00625 
00626     if (debug_queries)
00627         EV << simTime() << " : " << thisNode.getAddress() << " : handleNiceQuery()" << endl;
00628 
00629     short layer = queryMsg->getLayer();
00630 
00631     if (debug_queries)
00632         EV << " layer before: " << layer << endl;
00633 
00634     if (layer > getHighestLeaderLayer()) {
00635 
00636         if (debug_queries)
00637             EV << " getHighestLeaderLayer(): " << getHighestLeaderLayer() << " ! Returning." << endl;
00638 
00639         delete queryMsg;
00640         return;
00641 
00642     }
00643 
00644     if (layer < 0) {
00645 
00646         if (RendevouzPoint == thisNode) {
00647 
00648             /* If layer is < 0, response with highest layer I am leader of */
00649             if (debug_queries)
00650                 EV << " I am RP." << endl;
00651             layer = getHighestLeaderLayer();
00652 
00653         }
00654         else {
00655 
00656             if (debug_queries)
00657                 EV << " I am not RP. Return." << endl;
00658 
00659             if (pimp) {
00660 
00661                 /* forward to Rendevouz Point */
00662                 NiceMessage* dup = static_cast<NiceMessage*>(queryMsg->dup());
00663                 sendMessageToUDP(RendevouzPoint, dup);
00664 
00665             }
00666 
00667             delete queryMsg;
00668             return;
00669 
00670         }
00671 
00672     }
00673 
00674     if (debug_queries)
00675         EV << " layer after: " << layer << endl;
00676 
00677     if (!clusters[layer].getLeader().isUnspecified()) {
00678 
00679         if (clusters[layer].getLeader() != thisNode) {
00680 
00681             if (pimp) {
00682 
00683                 NiceMessage* dup = static_cast<NiceMessage*>(queryMsg->dup());
00684                 sendMessageToUDP(clusters[layer].getLeader(), dup);
00685 
00686             }
00687 
00688             if (debug_queries)
00689                 EV << " I am not leader of this cluster. return." << endl;
00690 
00691             delete queryMsg;
00692             return;
00693 
00694         }
00695 
00696     }
00697     else {
00698 
00699         delete queryMsg;
00700         return;
00701 
00702     }
00703 
00704     NiceMemberMessage* response = new NiceMemberMessage("NICE_QUERY_RESPONSE");
00705     response->setSrcNode(thisNode);
00706     response->setCommand(NICE_QUERY_RESPONSE);
00707     response->setLayer(layer);
00708 
00709     /* Fill in current cluster members except me */
00710     response->setMembersArraySize(clusters[layer].getSize()-1);
00711 
00712     int j=0;
00713 
00714     for (int i = 0; i < clusters[layer].getSize(); i++) {
00715 
00716         if (clusters[layer].get(i) != thisNode) {
00717 
00718             response->setMembers(j, clusters[layer].get(i));
00719             if (debug_queries)
00720                 EV << " Response: " << i << " : " << clusters[layer].get(i) << endl;
00721             j++;
00722 
00723         }
00724 
00725     }
00726 
00727     response->setBitLength(NICEMEMBERMESSAGE_L(response));
00728 
00729     sendMessageToUDP(queryMsg->getSrcNode(), response);

void oversim::Nice::handleNiceQueryResponse ( NiceMemberMessage *  queryRspMsg  )  [private]

Definition at line 1615 of file Nice.cc.

01625 {
01626 
01627     cancelEvent(queryTimer);
01628 
01629     short layer = queryRspMsg->getLayer();
01630 
01631     /* Check layer response */
01632     if (layer == targetLayer) {
01633 
01634         /* Use member information for own cluster update */
01635         for (unsigned int i = 0; i < queryRspMsg->getMembersArraySize(); i++) {
01636 
01637             clusters[layer].add(queryRspMsg->getMembers(i));
01638 
01639         }
01640 
01641         clusters[layer].add(queryRspMsg->getSrcNode());
01642 
01643         /* Initiate joining of lowest layer */
01644         JoinCluster(queryRspMsg->getSrcNode(), layer);
01645 
01646         changeState(READY);
01647 
01648     }
01649     else {
01650 
01651         /* Evaluate RTT to queried node */
01652         query_start = simTime() - query_start;
01653 
01654         /* Find out who is nearest cluster member in response, if nodes are given */
01655         if (queryRspMsg->getMembersArraySize() > 0) {
01656 
01657             NiceMessage* joineval = new NiceMessage("NICE_JOINEVAL");
01658             joineval->setSrcNode(thisNode);
01659             joineval->setCommand(NICE_JOINEVAL);
01660             joineval->setLayer(layer);
01661 
01662             joineval->setBitLength(NICEMESSAGE_L(joineval));
01663 
01664             /* Initiate evaluation with all cluster members */
01665             for (unsigned int i = 0; i < queryRspMsg->getMembersArraySize(); i++) {
01666 
01667                 NiceMessage* dup = static_cast<NiceMessage*>(joineval->dup());
01668 
01669                 sendMessageToUDP(queryRspMsg->getMembers(i), dup);
01670 
01671             }
01672 
01673             delete joineval;
01674 
01675         }
01676         else { // Directly query same node again for lower layer
01677 
01678             Query(queryRspMsg->getSrcNode(), queryRspMsg->getLayer()-1);
01679 

void oversim::Nice::handleNiceRemove ( NiceMessage *  msg  )  [private]

Definition at line 1681 of file Nice.cc.

01691 {
01692     if (debug_removes)
01693         EV << simTime() << " : " << thisNode.getAddress() << " : NICE_REMOVE" << endl;
01694 
01695     short layer = msg->getLayer();
01696 
01697     if (pimp) {
01698         if (!clusters[layer].getLeader().isUnspecified()) {
01699             if (clusters[layer].getLeader() != thisNode && (clusters[layer].getLeader() != msg->getSrcNode())) {
01700 
01701                 NiceMessage* dup = static_cast<NiceMessage*>(msg->dup());
01702                 sendMessageToUDP(clusters[layer].getLeader(), dup);
01703                 delete msg;
01704                 return;
01705             }
01706         }
01707     }
01708 
01709     if (debug_removes)
01710         EV << simTime() << " : " << thisNode.getAddress() << " : removing " << msg->getSrcNode() << " from layer " << layer << endl;
01711 
01712     if (!clusters[msg->getLayer()].getLeader().isUnspecified()) {
01713 
01714         if (clusters[msg->getLayer()].getLeader() == thisNode) {
01715 
01716             // check prevents visualization arrows to be deleted by error
01717             if (clusters[msg->getLayer()].contains(msg->getSrcNode())) {
01718 
01719                 deleteOverlayNeighborArrow(msg->getSrcNode());
01720                 clusters[msg->getLayer()].remove(msg->getSrcNode());
01721                 updateVisualization();
01722 
01723             }
01724 
01725         }
01726 
01727         if (clusters[msg->getLayer()].getLeader() == msg->getSrcNode()) {
01728 
01729 

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

Reimplemented from BaseRpc.

Definition at line 294 of file Nice.cc.

00304 {
00305 
00306     if (msg->isName("visualizationTimer")) {
00307 
00308         updateVisualization();
00309         scheduleAt(simTime() + 1, visualizationTimer);
00310 
00311     }
00312     else if (msg->isName("heartbeatTimer")) {
00313 
00314         sendHeartbeats();
00315         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
00316 
00317     }
00318     else if (msg->isName("maintenanceTimer")) {
00319 
00320         maintenance();
00321         cancelEvent(maintenanceTimer);
00322         scheduleAt(simTime() + maintenanceInterval, maintenanceTimer);
00323 
00324     }
00325     else if (msg->isName("queryTimer")) {
00326 
00327         RECORD_STATS(++numInconsistencies; ++numQueryTimeouts);
00328         BasicJoinLayer(-1);
00329 
00330     }
00331     else if (msg->isName("structureConnectionTimer")) {
00332 
00333         if (RendevouzPoint == thisNode)
00334             return;
00335 
00336         RECORD_STATS(++numStructurePartitions; ++numInconsistencies);
00337         BasicJoinLayer(getHighestLayer());
00338 
00339     }
00340     else if (msg->isName("rpPollTimer")) {
00341 
00342         isPollingRP = false;

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

Processes messages from underlay.

Parameters:
msg Message from UDP

Reimplemented from BaseOverlay.

Definition at line 349 of file Nice.cc.

00359 {
00360 
00361     // try message cast to NICE base message
00362     if (dynamic_cast<NiceMessage*>(msg) != NULL) {
00363 
00364         NiceMessage* niceMsg = check_and_cast<NiceMessage*>(msg);
00365 
00366         // First of all, update activity information for sourcenode
00367         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(niceMsg->getSrcNode());
00368 
00369         if (it != peerInfos.end()) {
00370 
00371             it->second->touch();
00372 
00373         }
00374 
00375         /* Dispatch message, possibly downcasting to a more concrete type */
00376         switch (niceMsg->getCommand()) {
00377 
00378             /* More concrete types, to which the message is cast if needed */
00379             NiceMemberMessage* queryRspMsg;
00380             NiceClusterMerge* mergeMsg;
00381             NiceMulticastMessage* multicastMsg;
00382 
00383             case NICE_QUERY:
00384 
00385                 handleNiceQuery(niceMsg);
00386 
00387                 break;
00388 
00389             case NICE_QUERY_RESPONSE:
00390 
00391                 queryRspMsg = check_and_cast<NiceMemberMessage*>(niceMsg);
00392                 handleNiceQueryResponse(queryRspMsg);
00393 
00394                 break;
00395 
00396             case NICE_JOIN_CLUSTER:
00397 
00398                 handleNiceJoinCluster(niceMsg);
00399 
00400                 break;
00401 
00402             case NICE_POLL_RP:
00403 
00404                 handleNicePollRp(niceMsg);
00405 
00406                 break;
00407 
00408             case NICE_POLL_RP_RESPONSE:
00409 
00410                 handleNicePollRpResponse(niceMsg);
00411 
00412                 break;
00413 
00414             case NICE_HEARTBEAT:
00415 
00416                 handleNiceHeartbeat(niceMsg);
00417 
00418                 break;
00419 
00420             case NICE_LEADERHEARTBEAT:
00421             case NICE_LEADERTRANSFER:
00422 
00423                 handleNiceLeaderHeartbeatOrTransfer(niceMsg);
00424 
00425                 break;
00426 
00427             case NICE_JOINEVAL:
00428 
00429                 handleNiceJoineval(niceMsg);
00430 
00431                 break;
00432 
00433             case NICE_JOINEVAL_RESPONSE:
00434 
00435                 handleNiceJoinevalResponse(niceMsg);
00436 
00437                 break;
00438 
00439             case NICE_REMOVE:
00440 
00441                 handleNiceRemove(niceMsg);
00442 
00443                 break;
00444 
00445             case NICE_PEER_TEMPORARY:
00446 
00447                 handleNicePeerTemporary(niceMsg);
00448 
00449                 break;
00450 
00451             case NICE_PEER_TEMPORARY_RELEASE:
00452 
00453                 handleNicePeerTemporaryRelease(niceMsg);
00454 
00455                 break;
00456 
00457             case NICE_PING_PROBE:
00458 
00459                 handleNicePingProbe(niceMsg);
00460 
00461                 break;
00462 
00463             case NICE_PING_PROBE_RESPONSE:
00464 
00465                 handleNicePingProbeResponse(niceMsg);
00466 
00467                 break;
00468 
00469             case NICE_FORCE_MERGE:
00470 
00471                 handleNiceForceMerge(niceMsg);
00472 
00473                 break;
00474 
00475             case NICE_CLUSTER_MERGE_REQUEST:
00476 
00477                 mergeMsg = check_and_cast<NiceClusterMerge*>(niceMsg);
00478 
00479                 handleNiceClusterMergeRequest(mergeMsg);
00480 
00481                 break;
00482 
00483             case NICE_MULTICAST:
00484 
00485                 multicastMsg = check_and_cast<NiceMulticastMessage*>(msg);
00486 
00487                 handleNiceMulticast(multicastMsg);
00488 
00489                 break;
00490 

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 109 of file Nice.cc.

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

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

Definition at line 1771 of file Nice.cc.

01781 {
01782 
01783     if (debug_join)
01784         EV << simTime() << " : " << thisNode.getAddress() << " : JoinCluster()" << endl;
01785 
01786     NiceMessage* msg = new NiceMessage("NICE_JOIN_CLUSTER");
01787     msg->setSrcNode(thisNode);
01788     msg->setCommand(NICE_JOIN_CLUSTER);
01789     msg->setLayer(layer);
01790     msg->setBitLength(NICEMESSAGE_L(msg));
01791 
01792     sendMessageToUDP(leader, msg);
01793 
01794     /* Create peer context to leader */
01795     /* Check if peer info already exists */
01796     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(leader);
01797 
01798     if (it != peerInfos.end()) { /* We already know this node */
01799 
01800     }
01801     else { /* Create PeerInfo object */
01802 
01803         NicePeerInfo* pi = new NicePeerInfo(this);
01804 
01805         peerInfos.insert(std::make_pair(leader, pi));
01806 
01807     }
01808 
01809     /* Locally add thisNode, too */
01810     clusters[layer].add(thisNode);
01811 
01812     /* Set leader for cluster */
01813     clusters[layer].setLeader(leader);
01814 
01815     for (short i=0; i<maxLayers; i++) {
01816 
01817         if (clusters[i].getSize() > 0) {
01818 
01819             if (clusters[i].contains(thisNode)) {
01820 
01821                 getParentModule()->getParentModule()->getDisplayString().setTagArg
01822                 ("i2", 1, clustercolors[i]);
01823 
01824             }
01825 
01826         }
01827 
01828     }
01829 
01830     // If not already running, schedule some timers
01831     if (!heartbeatTimer->isScheduled()) {
01832 
01833         scheduleAt(simTime() + heartbeatInterval, heartbeatTimer);
01834 
01835     }
01836     if (!maintenanceTimer->isScheduled()) {
01837 
01838         scheduleAt(simTime() + heartbeatInterval, maintenanceTimer);
01839 
01840     }
01841 
01842     if (isTempPeered) {
01843 
01844         // Release temporary peering
01845         NiceMessage* msg = new NiceMessage("NICE_PEER_TEMPORARY_RELEASE");
01846         msg->setSrcNode(thisNode);
01847         msg->setCommand(NICE_PEER_TEMPORARY_RELEASE);
01848         msg->setLayer(-1);
01849         msg->setBitLength(NICEMESSAGE_L(msg));
01850 
01851         sendMessageToUDP(RendevouzPoint, msg);

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 214 of file Nice.cc.

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

Definition at line 3407 of file Nice.cc.

03417 {
03418 
03419     NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERTRANSFER");
03420     msg->setSrcNode(thisNode);
03421     msg->setCommand(NICE_LEADERTRANSFER);
03422     msg->setLayer(layer);
03423 
03424     msg->setMembersArraySize(cluster.size());
03425 
03426     // fill in members
03427     TaSet::iterator it = cluster.begin();
03428     int i = 0;
03429     while (it != cluster.end()) {
03430         msg->setMembers(i++, *it);
03431         it++;
03432     }
03433 
03434     // fill in supercluster members, if existent
03435     if (clusters[layer+1].getSize() > 0) {
03436 
03437         msg->setSupercluster_leader(clusters[layer+1].getLeader());
03438 
03439         msg->setSupercluster_membersArraySize(clusters[layer+1].getSize());
03440 
03441         for (int j = 0; j < clusters[layer+1].getSize(); j++) {
03442 
03443             msg->setSupercluster_members(j, clusters[layer+1].get(j));
03444 
03445         }
03446 
03447     }
03448     else {
03449 

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

Definition at line 2235 of file Nice.cc.

02245 {
02246 
02247     // care for structure connection timer
02248     if (!RendevouzPoint.isUnspecified()) {
02249 
02250         if (RendevouzPoint == thisNode) {
02251 
02252             cancelEvent(structureConnectionTimer);
02253 
02254         }
02255         else {
02256 
02257             if (!structureConnectionTimer->isScheduled()) {
02258 
02259                 double offset = structureConnectionInterval.dbl() * heartbeatInterval.dbl();
02260                 scheduleAt(simTime() + offset, structureConnectionTimer);
02261 
02262             }
02263 
02264         }
02265 
02266     }
02267     else {
02268 
02269         EV << "No RendevouzPoint! " << endl;
02270         becomeRendevouzPoint();
02271 
02272     }
02273 
02274     /* Delete deprecated tempPeers from map */
02275 
02276     bool deleted;
02277 
02278     do {
02279 
02280         deleted = false;
02281 
02282         std::map<TransportAddress, simtime_t>::iterator it = tempPeers.begin();
02283 
02284         while (it != tempPeers.end()) {
02285 
02286             if (simTime() > (it->second + 3*heartbeatInterval)) {
02287 
02288                 RECORD_STATS(++numTempPeerTimeouts);
02289 
02290                 tempPeers.erase(it->first);
02291                 deleted = true;
02292                 break;
02293 
02294             }
02295 
02296             it++;
02297 
02298         }
02299 
02300     } while (deleted);
02301 
02302     /* Delete nodes that haven't been active for too long autonomously */
02303 
02304     std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.begin();
02305 
02306     while (it2 != peerInfos.end()) {
02307 
02308         if (it2->first != thisNode) {
02309 
02310             double offset = peerTimeoutInterval.dbl()*heartbeatInterval.dbl();
02311             if (simTime() > (it2->second->getActivity() + offset)) {
02312 
02313                 if (debug_peertimeouts) {
02314                     EV << simTime() << " : " << thisNode.getAddress() << " : PEER TIMED OUT! : " << it2->first << endl;
02315                     EV << "Activity : " << it2->second->getActivity() << endl;
02316                 }
02317 
02318                 RECORD_STATS(++numPeerTimeouts);
02319 
02320                 // Delete node from all layer clusters
02321                 for (int i=0; i<maxLayers; i++) {
02322 
02323                     if (clusters[i].contains(it2->first)) {
02324 
02325                         clusters[i].remove(it2->first);
02326 
02327                         /* If node was leader, elect new! */
02328                         if (!(clusters[i].getLeader().isUnspecified())) {
02329 
02330                             if (clusters[i].getLeader() == it2->first) {
02331 
02332                                 if (debug_peertimeouts)
02333                                     EV << simTime() << " : " << thisNode.getAddress() << " : Need new Cluster Leader for Cluster : " << i << endl;
02334 
02335                                 // Perform check for new cluster leader
02336                                 TaSet cl;
02337                                 for (int l=0; l<clusters[i].getSize(); l++) {
02338 
02339                                     cl.insert(clusters[i].get(l));
02340 
02341                                 }
02342 
02343                                 TransportAddress new_leader = findCenter(cl).first;
02344 
02345                                 /* Remove old leader from supercluster */
02346                                 clusters[i+1].remove(clusters[i].getLeader());
02347 
02348                                 clusters[i].setLeader(new_leader);
02349 
02350                                 if (new_leader == thisNode) {
02351 
02352                                     // I am new leader
02353                                     if (clusters[i+1].getSize() > 0) {
02354 
02355                                         /* TODO Experimental Hack: If old leader is also leader of sc -> basicJoinLayer*/
02356                                         if (clusters[i+1].getLeader() == clusters[i].getLeader()) {
02357 
02358                                             /* Locally add thisNode, too */
02359                                             clusters[i+1].add(thisNode);
02360 
02361                                             for (short j=0; j<maxLayers; j++) {
02362 
02363                                                 if (clusters[j].getSize() > 0) {
02364 
02365                                                     if (clusters[j].contains(thisNode)) {
02366 
02367                                                         getParentModule()->getParentModule()->getDisplayString().setTagArg
02368                                                         ("i2", 1, clustercolors[j]);
02369 
02370                                                     }
02371 
02372                                                 }
02373 
02374                                             }
02375 
02376                                             BasicJoinLayer(i+1);
02377 
02378                                         }
02379                                         else {
02380 
02381                                             JoinCluster(clusters[i+1].getLeader(), i+1);
02382 
02383                                         }
02384 
02385                                     }
02386                                     else {
02387 
02388                                         //TODO Experimental
02389                                         //Poll RP if existent
02390                                         //pollRP(getHighestLayer());
02391                                         //becomeRendevouzPoint();
02392 
02393                                     }
02394 
02395                                     for (int n=0; n<clusters[i].getSize(); n++) {
02396 
02397                                         if (clusters[i].get(n) != thisNode)
02398                                             showOverlayNeighborArrow(clusters[i].get(n), false, clusterarrows[i]);
02399 
02400                                     }
02401 
02402                                 }
02403 
02404                             }
02405 
02406                         }
02407 
02408                     }
02409 
02410                 }
02411 
02412                 TransportAddress cand = it2->first;
02413                 ++it2;
02414                 peerInfos.erase(cand);
02415                 continue;
02416 
02417             }
02418         }
02419 
02420         it2++;
02421 
02422     }
02423 
02424     // if node is cluster leader, check size bounds for every cluster
02425     for (int i=getHighestLayer(); i >= 0; i--) {
02426 
02427         //TODO Experimental Check for inconsistency: If I am node in cluster but not leader in subcluster, remove
02428         if (clusters[i].contains(thisNode) && (i > 0)) {
02429 
02430             if (clusters[i-1].getLeader() != thisNode) {
02431 
02432                 Remove(i);
02433                 return;
02434 
02435             }
02436 
02437         }
02438 
02439         if (!clusters[i].getLeader().isUnspecified()) {
02440 
02441             if (clusters[i].getLeader() == thisNode) {
02442 
02443                 if (clusters[i].getSize() > (3*k-1)) {
02444 
02445                     ClusterSplit(i);
02446 
02447                     return;
02448 
02449                 }
02450 
02451 
02452                 if ((clusters[i].getSize() < k) && (clusters[i+1].getSize() > 1)) {
02453 
02454                     EV << simTime() << " : " << thisNode.getAddress()
02455                     << ": CLUSTER MERGE!: " << i << endl;
02456 
02457                     ClusterMerge(i);
02458 
02459                     return;
02460 
02461                 }
02462                 else if ((clusters[i].getSize() < k)) {
02463 
02464 
02465                 }
02466 
02467             }
02468 
02469         }
02470 
02471     } // All Layers
02472 
02473     // if highest super cluster has more than one member
02474     if (clusters[getHighestLayer()+1].getSize() > 1) {
02475 
02476         if (clusterrefinement)
02477             EV << simTime() << " : " << thisNode.getAddress() << " : Look for better parent node in cluster : " << getHighestLayer()+1 << " ..."<< endl;
02478 
02479         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[getHighestLayer()].getLeader());
02480 
02481         if (it != peerInfos.end()) {
02482 
02483             if (it->second->get_distance() > 0) {
02484 
02485                 double distance = it->second->get_distance() - ((it->second->get_distance()/100.0) * SC_PROC_DISTANCE);
02486 
02487                 double smallest = 10000.0;
02488                 TransportAddress candidate = TransportAddress::UNSPECIFIED_NODE;
02489 
02490                 for (int i=0; i < clusters[getHighestLayer()+1].getSize(); i++) {
02491 
02492                     if (clusters[getHighestLayer()+1].get(i) != clusters[getHighestLayer()].getLeader()) {
02493 
02494                         std::map<TransportAddress, NicePeerInfo*>::iterator it2 = peerInfos.find(clusters[getHighestLayer()+1].get(i));
02495 
02496                         if (it2 != peerInfos.end()) {
02497 
02498                             if ((it2->second->get_distance() < smallest) && (it2->second->get_distance() > 0)) {
02499                                 smallest = it2->second->get_distance();
02500                                 candidate = it2->first;
02501                             }
02502 
02503                         }
02504 
02505                     }
02506 
02507                 }
02508 
02509                 std::set<TransportAddress> clusterset;
02510 
02511                 for (int m=0; m<clusters[getHighestLayer()+1].getSize(); m++) {
02512 
02513                     clusterset.insert(clusters[getHighestLayer()+1].get(m));
02514 
02515                 }
02516 
02517                 simtime_t meanDistance = getMeanDistance(clusterset);
02518 
02519                 simtime_t minCompare = (meanDistance/100.0)*SC_MIN_OFFSET;
02520 
02521                 RECORD_STATS(totalSCMinCompare += minCompare.dbl());
02522 
02523                 if (minCompare < 0.005)
02524                     minCompare = 0.005;
02525 
02526                 if ((smallest < distance) && ((distance - smallest) > minCompare.dbl())) { // change supercluster
02527 
02528 
02529                     if (clusterrefinement) {
02530                         EV << simTime() <<" : " << thisNode.getAddress() << ": Change SuperCluster! to " << candidate.getAddress() << endl;
02531                         EV << "Old distance ():  " << it->second->get_distance() << endl;
02532                         EV << "SC_PROC_DISTANCE:  " << SC_PROC_DISTANCE << endl;
02533                         EV << "Compare distance:  " << distance << endl;
02534                         EV << "New distance:  " << smallest << endl;
02535                         EV << "New SC_MIN_OFFSET:  " << SC_MIN_OFFSET << endl;
02536                     }
02537 
02538                     short highestLayer = getHighestLayer();
02539 
02540                     // leave old
02541                     Remove(highestLayer);
02542 
02543                     // join new
02544                     JoinCluster(candidate, highestLayer);
02545 
02546                     return;
02547 
02548                 }
02549             }
02550 
02551         }
02552         else {
02553 
02554             //Do nothing
02555 
02556         }
02557 
02558     }
02559 
02560     //return;
02561     for (int i=getHighestLayer(); i >= 0; i--) {
02562 
02563         if (clusters[i].getSize() > 1 && clusters[i].getLeader() == thisNode) {
02564 
02565             bool allDistancesKnown = true;
02566 
02567             if (clusterrefinement)
02568                 EV << simTime() << " : " << thisNode.getAddress() << " : Find better cluster leader in ..." << i << endl;
02569 
02570             /* Only make decisions if node has total distance knowledge in this cluster */
02571             for (int j=0; j<clusters[i].getSize(); j++) {
02572 
02573                 /* Check if peer info already exists */
02574                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
02575 
02576                 if (it != peerInfos.end()) { /* We already know this node */
02577 
02578                     simtime_t distance = it->second->get_distance();
02579 
02580                     //EV << "My distance to " << it->first << " : " << distance << endl;
02581 
02582                     if (distance < 0) {
02583                         allDistancesKnown = false;
02584                         continue;
02585                     }
02586 
02587                     for (int k=0; k<clusters[i].getSize(); k++) {
02588 
02589                         if ((it->first != thisNode) && (clusters[i].get(k) != it->first)) {
02590 
02591                             if (it->second->getDistanceTo(clusters[i].get(k)) < 0) {
02592                                 allDistancesKnown = false;
02593                                 break;
02594                             }
02595                         }
02596 
02597                     }
02598 
02599                 }
02600                 else { /* Create PeerInfo object */
02601 
02602                     allDistancesKnown = false;
02603 
02604                 }
02605 
02606             }
02607 
02608             if (allDistancesKnown) {
02609 
02610                 if (clusterrefinement)
02611                     EV << "Complete distance knowledge available." << endl;
02612 
02613                 // Perform check for better cluster leader
02614                 TaSet cl;
02615                 for (int l=0; l<clusters[i].getSize(); l++) {
02616 
02617                     cl.insert(clusters[i].get(l));
02618 
02619                 }
02620 
02621                 TransportAddress new_leader = findCenter(cl).first;
02622 
02623                 if (clusterrefinement)
02624                     EV << "NEW LEADER laut " << thisNode.getAddress() << " --> " << new_leader.getAddress() << endl;
02625 
02626                 std::set<TransportAddress> clusterset;
02627 
02628                 for (int m=0; m<clusters[i].getSize(); m++) {
02629 
02630                     clusterset.insert(clusters[i].get(m));
02631 
02632                 }
02633 
02634 
02635                 simtime_t meanDistance = getMeanDistance(clusterset);
02636                 simtime_t oldDistance = getMaxDistance(clusters[i].getLeader(), clusterset);
02637                 simtime_t newDistance = getMaxDistance(new_leader, clusterset);
02638                 simtime_t compareDistance = (oldDistance - ((oldDistance/100.0)*CLUSTERLEADERCOMPAREDIST));
02639 
02640                 simtime_t minCompare = (meanDistance/100.0)*CLUSTERLEADERBOUND;
02641 
02642                 if (minCompare < 0.005)
02643                     minCompare = 0.005;
02644 
02645                 if ((newDistance.dbl() < compareDistance.dbl()) && ((compareDistance.dbl() - newDistance.dbl()) > minCompare.dbl())) {
02646 
02647                     if (clusterrefinement)
02648                         EV << "CHANGE " << CLUSTERLEADERCOMPAREDIST << endl;
02649 
02650                     if (new_leader != thisNode) {
02651 
02652                         /* Check if I was leader*/
02653                         if (clusters[i].getLeader() == thisNode) {
02654 
02655                             for (int j=0; j<clusters[i].getSize(); j++) {
02656 
02657                                 deleteOverlayNeighborArrow(clusters[i].get(j));
02658 
02659                             }
02660 
02661                             gracefulLeave(i);
02662 
02663                             LeaderTransfer(i, new_leader, cl, new_leader);
02664 
02665                             getParentModule()->getParentModule()
02666                             ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
02667 
02668 
02669                         }
02670                         else {
02671 
02672                             // Do nothing
02673 
02674                         }
02675 
02676                     }
02677                     else {
02678 
02679                         /* I am the new leader of this cluster */
02680                         /* Check if I already was*/
02681                         if (clusters[i].getLeader() == thisNode) {
02682 
02683                             // Do nothing
02684 
02685                         }
02686                         else {
02687 
02688                             /* Remove old leader from supercluster */
02689                             clusters[i+1].remove(clusters[i].getLeader());
02690 
02691                             // I am new leader
02692                             if (clusters[i+1].getSize() > 0) {
02693 
02694                                 /* If old leader is also leader of sc -> basicJoinLayer*/
02695                                 if (clusters[i+1].getLeader() == clusters[i].getLeader()) {
02696 
02697                                     /* Locally add thisNode, too */
02698                                     clusters[i+1].add(thisNode);
02699 
02700                                     for (short j=0; j<maxLayers; j++) {
02701 
02702                                         if (clusters[j].getSize() > 0) {
02703 
02704                                             if (clusters[j].contains(thisNode)) {
02705 
02706                                                 getParentModule()->getParentModule()->getDisplayString().setTagArg
02707                                                 ("i2", 1, clustercolors[j]);
02708 
02709                                             }
02710 
02711                                         }
02712 
02713                                     }
02714 
02715                                     BasicJoinLayer(i+1);
02716 
02717                                 }
02718                                 else {
02719 
02720                                     JoinCluster(clusters[i+1].getLeader(), i+1);
02721 
02722                                 }
02723 
02724                             }
02725                             else {
02726 
02727                                 becomeRendevouzPoint();
02728 
02729                             }
02730 
02731                             for (int n=0; n<clusters[i].getSize(); n++) {
02732 
02733                                 if (clusters[i].get(n) != thisNode)
02734                                     showOverlayNeighborArrow(clusters[i].get(n), false, clusterarrows[i]);
02735 
02736                             }
02737 
02738 
02739                         }
02740 
02741 
02742                     }
02743 
02744                     // Set new leader for this cluster
02745                     clusters[i].setLeader(new_leader);
02746 
02747                 }
02748 
02749                 if (clusterrefinement) {
02750                     EV << "MaxDistance " << new_leader.getAddress() << " : " << getMaxDistance(new_leader, clusterset) << endl;
02751                     EV << "MaxDistance " << clusters[i].getLeader() << " : " << getMaxDistance(clusters[i].getLeader(), clusterset) << endl;
02752                     EV << "MaxDistance " << thisNode.getAddress() << " : " << getMaxDistance(thisNode, clusterset) << endl;
02753                 }
02754 
02755 
02756             }
02757             else {
02758 

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

Definition at line 3755 of file Nice.cc.

03765 {
03766 
03767     if (debug_queries)
03768         EV << simTime() << " : " << thisNode.getAddress() << " : pollRP()" << endl;
03769 
03770     NiceMessage* msg = new NiceMessage("NICE_POLL_RP");
03771     msg->setSrcNode(thisNode);
03772     msg->setCommand(NICE_POLL_RP);
03773     msg->setLayer(layer);
03774     msg->setBitLength(NICEMESSAGE_L(msg));
03775 
03776     cancelEvent(rpPollTimer);
03777     scheduleAt(simTime() + rpPollTimerInterval, rpPollTimer);

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

Definition at line 585 of file Nice.cc.

00595 {
00596     if (debug_queries)
00597         EV << simTime() << " : " << thisNode.getAddress() << " : Query()" << endl;
00598 
00599 
00600     NiceMessage* msg = new NiceMessage("NICE_QUERY");
00601     msg->setSrcNode(thisNode);
00602     msg->setCommand(NICE_QUERY);
00603     msg->setLayer(layer);
00604     msg->setBitLength(NICEMESSAGE_L(msg));
00605 
00606     query_start = simTime();
00607     tempResolver = destination;
00608 
00609     cancelEvent(queryTimer);
00610     scheduleAt(simTime() + queryInterval, queryTimer);

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

Definition at line 3455 of file Nice.cc.

03465 {
03466     if (debug_removes)
03467         EV << simTime() << " : " << thisNode.getAddress() << " : Remove()" << endl;
03468 
03469     NiceMessage* msg = new NiceMessage("NICE_REMOVE");
03470     msg->setSrcNode(thisNode);
03471     msg->setCommand(NICE_REMOVE);
03472     msg->setLayer(layer);
03473 
03474     msg->setBitLength(NICEMESSAGE_L(msg));
03475 
03476     sendMessageToUDP(clusters[layer].getLeader(), msg);
03477 
03478     clusters[layer].remove(thisNode);
03479 
03480     for (short i=0; i<maxLayers; i++) {
03481 
03482         if (clusters[i].getSize() > 0) {
03483 
03484             if (clusters[i].contains(thisNode)) {
03485 
03486                 getParentModule()->getParentModule()->getDisplayString().setTagArg
03487                 ("i2", 1, clustercolors[i]);
03488 
03489             }
03490 

void oversim::Nice::sendDataToOverlay ( NiceMulticastMessage *  appMsg  )  [private]

Definition at line 3648 of file Nice.cc.

03658 {
03659 
03660     for (int layer=0; clusters[layer].contains(thisNode); layer++) {
03661 
03662         if ( appMsg->getLayer() != layer ) {
03663 
03664             for (int j=0; j<clusters[layer].getSize(); j++) {
03665 
03666                 if (!(clusters[layer].contains(appMsg->getLastHop())) || appMsg->getSrcNode() == thisNode) {
03667 
03668                     const TransportAddress& member = clusters[layer].get(j);
03669 
03670                     if (!(member == thisNode)) {
03671 
03672                         NiceMulticastMessage* dup = static_cast<NiceMulticastMessage*>(appMsg->dup());
03673 
03674                         dup->setLayer( layer );
03675                         dup->setLastHop(thisNode);
03676 
03677                         sendMessageToUDP(member, dup);
03678 
03679                     }
03680 
03681                 }
03682 
03683             } // for
03684 
03685         }
03686 
03687     }
03688 
03689     // Also forward data to temporary peers
03690     std::map<TransportAddress, simtime_t>::iterator it = tempPeers.begin();
03691 
03692     while (it != tempPeers.end()) {
03693 
03694         NiceMulticastMessage* dup = static_cast<NiceMulticastMessage*>(appMsg->dup());
03695 
03696         dup->setSrcNode(thisNode);
03697 

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

Definition at line 1857 of file Nice.cc.

01858                              : " << thisNode.getAddress() << " : JoinCluster() finished." << endl;
01859 
01860 } // JoinCluster
01861 
01862 
01863 /******************************************************************************
01864  * sendHeartbeats
01865  */
01866 void Nice::sendHeartbeats()
01867 {
01868 
01869     /* Go through all cluster layers from top to bottom */
01870 
01871     for (int i=getHighestLayer(); i >= 0; i--) {
01872 
01873         /* Determine if node is cluster leader in this layer */
01874         if (!clusters[i].getLeader().isUnspecified()) {
01875 
01876             if (clusters[i].getLeader() == thisNode) {
01877 
01878                 /* Build heartbeat message with info on all current members */
01879                 NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERHEARTBEAT");
01880                 msg->setSrcNode(thisNode);
01881                 msg->setCommand(NICE_LEADERHEARTBEAT);
01882                 msg->setLayer(i);
01883                 msg->setOne_hop_distance(simTime().dbl());
01884                 msg->setK(k);
01885                 msg->setSc_tolerance(SC_PROC_DISTANCE);
01886 
01887                 msg->setMembersArraySize(clusters[i].getSize());
01888 
01889                 /* Fill in members */
01890                 for (int j = 0; j < clusters[i].getSize(); j++) {
01891 
01892                     msg->setMembers(j, clusters[i].get(j));
01893 
01894                 }
01895 
01896                 /* Fill in distances to members */
01897                 msg->setDistancesArraySize(clusters[i].getSize());
01898 
01899                 for (int j = 0; j < clusters[i].getSize(); j++) {
01900 
01901                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01902 
01903                     if (it != peerInfos.end()) {
01904 
01905                         msg->setDistances(j, it->second->get_distance());
01906 
01907                     }
01908                     else {
01909 
01910                         msg->setDistances(j, -1);
01911 
01912                     }
01913 
01914                 }
01915 
01916                 /* Fill in Supercluster members, if existent */
01917                 if (clusters[i+1].getSize() > 0) {
01918 
01919                     msg->setSupercluster_leader(clusters[i+1].getLeader());
01920 
01921                     msg->setSupercluster_membersArraySize(clusters[i+1].getSize());
01922 
01923                     for (int j = 0; j < clusters[i+1].getSize(); j++) {
01924 
01925                         msg->setSupercluster_members(j, clusters[i+1].get(j));
01926 
01927                     }
01928 
01929                 }
01930 
01931                 /* Send Heartbeat to all members in cluster, except me */
01932                 for (int j = 0; j < clusters[i].getSize(); j++) {
01933 
01934                     if (clusters[i].get(j) != thisNode) {
01935 
01936                         NiceLeaderHeartbeat *copy = static_cast<NiceLeaderHeartbeat*>(msg->dup());
01937 
01938                         /* Get corresponding sequence numbers out of peerInfo */
01939                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
01940 
01941                         if (it != peerInfos.end()) {
01942 
01943                             unsigned int seqNo = it->second->get_last_sent_HB();
01944 
01945                             copy->setSeqNo(++seqNo);
01946 
01947                             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
01948                             it->second->set_last_sent_HB(seqNo);
01949                             it->second->set_backHBPointer(!it->second->get_backHBPointer());
01950 
01951                             copy->setSeqRspNo(it->second->get_last_recv_HB());
01952 
01953                             if (it->second->get_last_HB_arrival() > 0) {
01954 
01955                                 copy->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
01956 
01957                             }
01958                             else {
01959 
01960                                 copy->setHb_delay(0.0);
01961 
01962                             }
01963 
01964                         }
01965 
01966                         copy->setBitLength(NICELEADERHEARTBEAT_L(msg));
01967 
01968                         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += copy->getByteLength());
01969 
01970                         sendMessageToUDP(clusters[i].get(j), copy);
01971 
01972                     }
01973 
01974                 }
01975 
01976                 delete msg;
01977 
01978             }
01979             else { // I am normal cluster member
01980 
01981                 /* Build heartbeat message with info on all current members */
01982                 NiceHeartbeat* msg = new NiceHeartbeat("NICE_HEARTBEAT");
01983                 msg->setSrcNode(thisNode);
01984                 msg->setCommand(NICE_HEARTBEAT);
01985                 msg->setLayer(i);
01986                 msg->setOne_hop_distance(simTime().dbl());
01987 
01988                 msg->setSublayermembers(0);
01989                 if (i>0) {
01990                     if (clusters[i-1].getLeader() == thisNode)
01991                         msg->setSublayermembers(clusters[i-1].getSize());
01992 
01993                 }
01994 
01995                 msg->setMembersArraySize(clusters[i].getSize());
01996 
01997                 /* Fill in members */
01998                 for (int j = 0; j < clusters[i].getSize(); j++) {
01999 
02000                     msg->setMembers(j, clusters[i].get(j));
02001 
02002                 }
02003 
02004                 /* Fill in distances to members */
02005                 msg->setDistancesArraySize(clusters[i].getSize());
02006 
02007                 for (int j = 0; j < clusters[i].getSize(); j++) {
02008 
02009                     std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
02010 
02011                     if (it != peerInfos.end()) {
02012 
02013                         msg->setDistances(j, it->second->get_distance());
02014 
02015                     }
02016                     else {
02017 
02018                         msg->setDistances(j, -1);
02019 
02020                     }
02021 
02022                 }
02023 
02024                 /* Send Heartbeat to all members in cluster, except me */
02025                 for (int j = 0; j < clusters[i].getSize(); j++) {
02026 
02027                     if (clusters[i].get(j) != thisNode) {
02028 
02029                         NiceHeartbeat *copy = static_cast<NiceHeartbeat*>(msg->dup());
02030 
02031                         /* Get corresponding sequence number out of peerInfo */
02032                         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[i].get(j));
02033 
02034                         if (it != peerInfos.end()) {
02035 
02036                             unsigned int seqNo = it->second->get_last_sent_HB();
02037 
02038                             copy->setSeqNo(++seqNo);
02039 
02040                             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
02041                             it->second->set_backHBPointer(!it->second->get_backHBPointer());
02042                             it->second->set_last_sent_HB(seqNo);
02043 
02044                             copy->setSeqRspNo(it->second->get_last_recv_HB());
02045 
02046                             copy->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
02047 
02048                         }
02049 
02050                         copy->setBitLength(NICEHEARTBEAT_L(msg));
02051 
02052                         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += copy->getByteLength());
02053 
02054                         sendMessageToUDP(clusters[i].get(j), copy);
02055 
02056                     }
02057 
02058                 }
02059 
02060                 delete msg;
02061 
02062             }
02063         }
02064 
02065     }
02066 
02067     // Additionally, ping all supercluster members, if existent
02068     if (clusters[getHighestLayer()+1].getSize() > 0) {
02069 
02070         NiceMessage* msg = new NiceMessage("NICE_PING_PROBE");
02071         msg->setSrcNode(thisNode);
02072         msg->setCommand(NICE_PING_PROBE);
02073         msg->setLayer(getHighestLayer()+1);
02074 
02075         msg->setBitLength(NICEMESSAGE_L(msg));
02076 
02077         for (int i=0; i<clusters[getHighestLayer()+1].getSize(); i++) {
02078 
02079             if (clusters[getHighestLayer()+1].get(i) != clusters[getHighestLayer()].getLeader()) {
02080 
02081                 NiceMessage* dup = static_cast<NiceMessage*>(msg->dup());
02082 
02083                 sendMessageToUDP(clusters[getHighestLayer()+1].get(i), dup);
02084 
02085                 std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[getHighestLayer()+1].get(i));
02086 
02087                 if (it != peerInfos.end()) {
02088 
02089                     it->second->set_distance_estimation_start(simTime().dbl());
02090 
02091                 }
02092 

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

Definition at line 2098 of file Nice.cc.

02108 {
02109 
02110     if (clusters[layer].getLeader() == thisNode) {
02111 
02112         /* Build heartbeat message with info on all current members */
02113         NiceLeaderHeartbeat* msg = new NiceLeaderHeartbeat("NICE_LEADERHEARTBEAT");
02114         msg->setSrcNode(thisNode);
02115         msg->setCommand(NICE_LEADERHEARTBEAT);
02116         msg->setLayer(layer);
02117 
02118         msg->setMembersArraySize(clusters[layer].getSize());
02119 
02120         /* Fill in members */
02121         for (int j = 0; j < clusters[layer].getSize(); j++) {
02122 
02123             msg->setMembers(j, clusters[layer].get(j));
02124 
02125         }
02126 
02127         /* Fill in distances to members */
02128         msg->setDistancesArraySize(clusters[layer].getSize());
02129 
02130         for (int j = 0; j < clusters[layer].getSize(); j++) {
02131 
02132             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[layer].get(j));
02133 
02134             if (it != peerInfos.end()) {
02135 
02136                 msg->setDistances(j, it->second->get_distance());
02137 
02138             }
02139             else {
02140 
02141                 msg->setDistances(j, -1);
02142 
02143             }
02144 
02145         }
02146 
02147         /* Fill in Supercluster members, if existent */
02148         if (clusters[layer+1].getSize() > 0) {
02149 
02150             msg->setSupercluster_leader(clusters[layer+1].getLeader());
02151 
02152             msg->setSupercluster_membersArraySize(clusters[layer+1].getSize());
02153 
02154             for (int j = 0; j < clusters[layer+1].getSize(); j++) {
02155 
02156                 msg->setSupercluster_members(j, clusters[layer+1].get(j));
02157 
02158             }
02159 
02160         }
02161 
02162         /* Get corresponding sequence numbers out of peerInfo */
02163         std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(node);
02164 
02165         if (it != peerInfos.end()) {
02166 
02167             unsigned int seqNo = it->second->get_last_sent_HB();
02168 
02169             msg->setSeqNo(++seqNo);
02170 
02171             it->second->set_backHB(it->second->get_backHBPointer(), seqNo, simTime().dbl());
02172             it->second->set_last_sent_HB(seqNo);
02173             it->second->set_backHBPointer(!it->second->get_backHBPointer());
02174 
02175             msg->setSeqRspNo(it->second->get_last_recv_HB());
02176 
02177             msg->setHb_delay(simTime().dbl() - it->second->get_last_HB_arrival());
02178 
02179         }
02180 
02181         msg->setBitLength(NICELEADERHEARTBEAT_L(msg));
02182 
02183         RECORD_STATS(++numHeartbeat; totalHeartbeatBytes += msg->getByteLength());
02184 
02185         sendMessageToUDP(node, msg);
02186 
02187     }
02188     else {
02189 
02190         // build heartbeat message with info on all current members
02191         NiceHeartbeat* msg = new NiceHeartbeat("NICE_HEARTBEAT");
02192         msg->setSrcNode(thisNode);
02193         msg->setCommand(NICE_HEARTBEAT);
02194         msg->setLayer(layer);
02195 
02196         msg->setMembersArraySize(clusters[layer].getSize());
02197 
02198         // fill in members
02199         for (int j = 0; j < clusters[layer].getSize(); j++) {
02200 
02201             msg->setMembers(j, clusters[layer].get(j));
02202 
02203         }
02204 
02205         // fill in distances to members
02206         msg->setDistancesArraySize(clusters[layer].getSize());
02207 
02208         for (int j = 0; j < clusters[layer].getSize(); j++) {
02209 
02210             std::map<TransportAddress, NicePeerInfo*>::iterator it = peerInfos.find(clusters[layer].get(j));
02211 
02212             if (it != peerInfos.end()) {
02213 
02214                 msg->setDistances(j, it->second->get_distance());
02215 
02216             }
02217             else if (clusters[layer].get(j) == thisNode) {
02218 
02219                 msg->setDistances(j, 0);
02220 
02221             }
02222             else {
02223 
02224                 msg->setDistances(j, -1);
02225 
02226             }
02227 
02228         }
02229 

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

Definition at line 3703 of file Nice.cc.

03713 {
03714 
03715     if (debug_visualization)
03716         EV << simTime() << " : " << thisNode.getAddress() << " : updateVisualization" << endl;
03717 
03718     /* Update node symbol */
03719     getParentModule()->getParentModule()
03720     ->getDisplayString().setTagArg("i2", 0, "block/circle_vs");
03721 
03722     if (!RendevouzPoint.isUnspecified()) {
03723 
03724         if (RendevouzPoint == thisNode) {
03725 
03726             getParentModule()->getParentModule()
03727             ->getDisplayString().setTagArg("i2", 0, "block/star_vs");
03728 
03729         }
03730 
03731     }
03732 
03733     /* Update node color */
03734     if (debug_visualization)
03735         EV << "getHighestLayer(): " << getHighestLayer() << endl;
03736 
03737     getParentModule()->getParentModule()
03738     ->getDisplayString().setTagArg("i2", 1, clustercolors[getHighestLayer()]);
03739 
03740     //redraw
03741     for (int i=0; clusters[i].contains(thisNode); i++) {
03742 
03743         if (!(clusters[i].getLeader().isUnspecified())) {
03744 
03745             if (clusters[i].getLeader() == thisNode) {
03746 
03747                 for (int j=0; j<clusters[i].getSize();j++) {
03748 
03749                     if (debug_visualization)
03750                         EV << "draw to: " << clusters[i].get(j) << endl;
03751 
03752                     showOverlayNeighborArrow(clusters[i].get(j), false, clusterarrows[i]);
03753 


Friends And Related Function Documentation

friend class NicePeerInfo [friend]

Definition at line 75 of file Nice.h.


Member Data Documentation

Definition at line 189 of file Nice.h.

Definition at line 190 of file Nice.h.

Definition at line 150 of file Nice.h.

Definition at line 162 of file Nice.h.

Definition at line 151 of file Nice.h.

Definition at line 153 of file Nice.h.

Definition at line 154 of file Nice.h.

Definition at line 156 of file Nice.h.

Referenced by Query().

Definition at line 155 of file Nice.h.

Definition at line 152 of file Nice.h.

int oversim::Nice::evalLayer [private]

Definition at line 165 of file Nice.h.

simtime_t oversim::Nice::first_HB [private]

Definition at line 142 of file Nice.h.

Definition at line 143 of file Nice.h.

simtime_t oversim::Nice::heartbeatInterval [private]

Definition at line 116 of file Nice.h.

Referenced by handleNiceMulticast().

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

Definition at line 115 of file Nice.h.

Definition at line 168 of file Nice.h.

Definition at line 187 of file Nice.h.

int oversim::Nice::joinLayer [private]

Definition at line 166 of file Nice.h.

Referenced by Query().

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

Definition at line 159 of file Nice.h.

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

Definition at line 147 of file Nice.h.

Definition at line 120 of file Nice.h.

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

Definition at line 119 of file Nice.h.

Definition at line 211 of file Nice.h.

Definition at line 219 of file Nice.h.

Definition at line 195 of file Nice.h.

int oversim::Nice::numJoins [private]

Definition at line 209 of file Nice.h.

Definition at line 205 of file Nice.h.

Definition at line 199 of file Nice.h.

Definition at line 197 of file Nice.h.

Definition at line 215 of file Nice.h.

Definition at line 203 of file Nice.h.

Definition at line 201 of file Nice.h.

Definition at line 183 of file Nice.h.

Definition at line 134 of file Nice.h.

int oversim::Nice::pimp [private]

Definition at line 110 of file Nice.h.

simtime_t oversim::Nice::query_compare [private]

Definition at line 177 of file Nice.h.

simtime_t oversim::Nice::query_start [private]

Definition at line 171 of file Nice.h.

Referenced by Query().

simtime_t oversim::Nice::queryInterval [private]

Definition at line 124 of file Nice.h.

Referenced by Query().

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

Definition at line 123 of file Nice.h.

Referenced by Query().

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

Definition at line 131 of file Nice.h.

Definition at line 132 of file Nice.h.

double oversim::Nice::SC_MIN_OFFSET [private]

Definition at line 192 of file Nice.h.

Definition at line 191 of file Nice.h.

simtime_t oversim::Nice::second_HB [private]

Definition at line 144 of file Nice.h.

Definition at line 145 of file Nice.h.

Definition at line 128 of file Nice.h.

Referenced by handleNiceMulticast().

Definition at line 127 of file Nice.h.

Referenced by handleNiceMulticast().

short oversim::Nice::targetLayer [private]

Definition at line 180 of file Nice.h.

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

Definition at line 186 of file Nice.h.

Referenced by handleNicePeerTemporaryRelease(), and handleNicePingProbe().

Definition at line 174 of file Nice.h.

Referenced by Query().

Definition at line 213 of file Nice.h.

Definition at line 221 of file Nice.h.

Definition at line 217 of file Nice.h.

Definition at line 207 of file Nice.h.

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

Definition at line 137 of file Nice.h.


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:20 2010 for OverSim by  doxygen 1.6.3