NICE overlay module. More...
#include <Nice.h>
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 |
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.
Definition at line 72 of file Nice.h.
oversim::Nice::Nice | ( | ) |
Definition at line 60 of file Nice.cc.
00069 : numInconsistencies(0), 00070 numQueryTimeouts(0), 00071 numPeerTimeouts(0), 00072 numTempPeerTimeouts(0), 00073 numStructurePartitions(0), 00074 numOwnMessagesReceived(0), 00075 totalSCMinCompare(0), 00076 numJoins(0), 00077 totalForwardBytes(0),
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
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
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] |
short oversim::Nice::getHighestLeaderLayer | ( | ) | [private] |
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.
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] |
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] |
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] |
void oversim::Nice::handleNicePeerTemporaryRelease | ( | NiceMessage * | msg | ) | [private] |
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.
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.
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.
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
friend class NicePeerInfo [friend] |
double oversim::Nice::CLUSTERLEADERBOUND [private] |
double oversim::Nice::CLUSTERLEADERCOMPAREDIST [private] |
int oversim::Nice::clusterrefinement [private] |
NiceCluster oversim::Nice::clusters[maxLayers] [private] |
int oversim::Nice::debug_heartbeats [private] |
int oversim::Nice::debug_join [private] |
int oversim::Nice::debug_peertimeouts [private] |
int oversim::Nice::debug_queries [private] |
int oversim::Nice::debug_removes [private] |
int oversim::Nice::debug_visualization [private] |
int oversim::Nice::evalLayer [private] |
simtime_t oversim::Nice::first_HB [private] |
TransportAddress oversim::Nice::first_leader [private] |
simtime_t oversim::Nice::heartbeatInterval [private] |
Definition at line 116 of file Nice.h.
Referenced by handleNiceMulticast().
cMessage* oversim::Nice::heartbeatTimer [private] |
bool oversim::Nice::isPollingRP [private] |
bool oversim::Nice::isTempPeered [private] |
int oversim::Nice::joinLayer [private] |
unsigned short oversim::Nice::k [private] |
std::vector<std::pair<TransportAddress, simtime_t> > oversim::Nice::leaderHeartbeats [private] |
simtime_t oversim::Nice::maintenanceInterval [private] |
cMessage* oversim::Nice::maintenanceTimer [private] |
int oversim::Nice::numForward [private] |
int oversim::Nice::numHeartbeat [private] |
int oversim::Nice::numInconsistencies [private] |
int oversim::Nice::numJoins [private] |
int oversim::Nice::numOwnMessagesReceived [private] |
int oversim::Nice::numPeerTimeouts [private] |
int oversim::Nice::numQueryTimeouts [private] |
int oversim::Nice::numReceived [private] |
int oversim::Nice::numStructurePartitions [private] |
int oversim::Nice::numTempPeerTimeouts [private] |
std::map<TransportAddress, NicePeerInfo*> oversim::Nice::peerInfos [private] |
simtime_t oversim::Nice::peerTimeoutInterval [private] |
int oversim::Nice::pimp [private] |
simtime_t oversim::Nice::query_compare [private] |
simtime_t oversim::Nice::query_start [private] |
simtime_t oversim::Nice::queryInterval [private] |
cMessage* oversim::Nice::queryTimer [private] |
cMessage* oversim::Nice::rpPollTimer [private] |
simtime_t oversim::Nice::rpPollTimerInterval [private] |
double oversim::Nice::SC_MIN_OFFSET [private] |
double oversim::Nice::SC_PROC_DISTANCE [private] |
simtime_t oversim::Nice::second_HB [private] |
TransportAddress oversim::Nice::second_leader [private] |
simtime_t oversim::Nice::structureConnectionInterval [private] |
Definition at line 128 of file Nice.h.
Referenced by handleNiceMulticast().
cMessage* oversim::Nice::structureConnectionTimer [private] |
Definition at line 127 of file Nice.h.
Referenced by handleNiceMulticast().
short oversim::Nice::targetLayer [private] |
std::map<TransportAddress, simtime_t> oversim::Nice::tempPeers [private] |
Definition at line 186 of file Nice.h.
Referenced by handleNicePeerTemporaryRelease(), and handleNicePingProbe().
TransportAddress oversim::Nice::tempResolver [private] |
int oversim::Nice::totalForwardBytes [private] |
int oversim::Nice::totalHeartbeatBytes [private] |
int oversim::Nice::totalReceivedBytes [private] |
double oversim::Nice::totalSCMinCompare [private] |
cMessage* oversim::Nice::visualizationTimer [private] |