BasePastry Class Reference

#include <BasePastry.h>

Inheritance diagram for BasePastry:
BaseOverlay ProxListener BaseRpc TopologyVis RpcListener Bamboo Pastry

List of all members.

Classes

struct  PingContext

Public Member Functions

virtual ~BasePastry ()
virtual void pingResponse (PingResponse *pingResponse, cPolymorphic *context, int rpcId, simtime_t rtt)
void pingTimeout (PingCall *call, const TransportAddress &dest, cPolymorphic *context, int rpcId)
int getMaxNumSiblings ()
 Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
int getMaxNumRedundantNodes ()
 Query the maximum number of redundant next hop nodes that are returned by findNode().
virtual void handleAppMessage (BaseOverlayMessage *msg)
 processes messages from application
virtual void updateTooltip ()
 updates information shown in tk-environment
virtual NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg)
 Implements the find node call.
virtual void handleStateMessage (PastryStateMessage *msg)=0
 processes state messages, merging with own state tables
virtual void finishOverlay ()
 collects statistical data in derived class
void sendStateTables (const TransportAddress &destination, int type=PASTRY_STATE_STD,...)
 send a PastryStateMessage directly to a node
void sendStateDelayed (const TransportAddress &destination)
 send a standard state message with a small delay
virtual bool isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err)
 Query if a node is among the siblings for a given key.
virtual AbstractLookupcreateLookup (RoutingType routingType=DEFAULT_ROUTING, const BaseOverlayMessage *msg=NULL, const cObject *dummy=NULL, bool appLookup=false)
uint8_t getBitsPerDigit ()
void proxCallback (const TransportAddress &node, int rpcId, cPolymorphic *contextPointer, Prox prox)

Public Attributes

int joins
int joinTries
int joinPartial
int joinSeen
int joinBytesSeen
int joinReceived
int joinBytesReceived
int joinSent
int joinBytesSent
int stateSent
int stateBytesSent
int stateReceived
int stateBytesReceived
int repairReqSent
int repairReqBytesSent
int repairReqReceived
int repairReqBytesReceived
int stateReqSent
int stateReqBytesSent
int stateReqReceived
int stateReqBytesReceived
int totalLookups
int responsibleLookups
int routingTableLookups
int closerNodeLookups
int closerNodeLookupsFromNeighborhood
int leafsetReqSent
int leafsetReqBytesSent
int leafsetReqReceived
int leafsetReqBytesReceived
int leafsetSent
int leafsetBytesSent
int leafsetReceived
int leafsetBytesReceived
int routingTableReqSent
int routingTableReqBytesSent
int routingTableReqReceived
int routingTableReqBytesReceived
int routingTableSent
int routingTableBytesSent
int routingTableReceived
int routingTableBytesReceived
uint32_t rowToAsk

Protected Types

enum  StateObject { ROUTINGTABLE, LEAFSET, NEIGHBORHOODSET }
enum  { PING_RECEIVED_STATE = 1, PING_NEXT_HOP = 2, PING_SINGLE_NODE = 3, PING_DISCOVERY }

Protected Member Functions

virtual void changeState (int toState)
 changes node state
virtual void checkProxCache (void)=0
 checks whether proxCache is complete, takes appropriate actions depending on the protocol state
virtual void purgeVectors (void)
 delete all information/messages caching vectors, used for restarting overlay or finish()
void baseInit (void)
 initializes parameters and variables used in both Bamboo and Pastry
void baseChangeState (int)
 changes node state, but leaves specific behavour, scheduling tasks in particular, to the inheriting protocols
OverlayKey distance (const OverlayKey &x, const OverlayKey &y, bool useAlternative=false) const
 This method should implement the distance between two keys.
virtual void iterativeJoinHook (BaseOverlayMessage *msg, bool incrHopCount)
void prePing (const PastryStateMessage *stateMsg)
 ping all nodes in a given state message.
void pingNodes (void)
 ping all nodes in the pastry state message pointed to by private member stateCache
void determineAliveTable (const PastryStateMessage *stateMsg)
 change the aliveTable to match the given stateMsg.
void sendRequest (const TransportAddress &ask, int type)
 send a request to a given node
void sendLeafset (const TransportAddress &tell, bool pull=false)
 send the leafset to a node
void sendRoutingRow (const TransportAddress &tell, int row)
 send a row of the routing table to a node
void handleRequestMessage (PastryRequestMessage *msg)
 processes state messages, merging with own state tables
void handleLeafsetMessage (PastryLeafsetMessage *msg, bool mergeSender=false)
 processes leafset messages, merging with own state tables
void newLeafs (void)
 Pastry API: send newLeafs() to application if enabled.

Protected Attributes

uint32_t bitsPerDigit
uint32_t numberOfLeaves
uint32_t numberOfNeighbors
double readyWaitAmount
double joinTimeoutAmount
double repairTimeout
bool enableNewLeafs
bool useRegularNextHop
bool alwaysSendUpdate
bool optimizeLookup
bool proximityNeighborSelection
simtime_t nearNodeRtt
uint32_t pingedNodes
bool nearNodeImproved
bool periodicMaintenance
TransportAddressleaf2ask
TransportAddress bootstrapNode
NodeHandle nearNode
simtime_t lastStateChange
PastryStateMsgHandle stateCache
 Handle for processing a single state message.
std::queue< PastryStateMsgHandlestateCacheQueue
 Queue of state messages waiting to be processed in READY state.
PastryStateMsgProximity aliveTable
 Early update of leaf set: helper structure for marking known-dead nodes.
uint32_t joinHopCount
cMessage * joinTimeout
cMessage * readyWait
cMessage * joinUpdateWait
std::vector< PastrySendState * > sendStateWait
PastryRoutingTableroutingTable
PastryLeafSetleafSet
PastryNeighborhoodSetneighborhoodSet

Friends

class PastryLeafSet

Detailed Description

Definition at line 50 of file BasePastry.h.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
PING_RECEIVED_STATE 
PING_NEXT_HOP 
PING_SINGLE_NODE 
PING_DISCOVERY 

Definition at line 295 of file BasePastry.h.

00296     {
00297         PING_RECEIVED_STATE = 1,
00298         PING_NEXT_HOP = 2,
00299         PING_SINGLE_NODE = 3,
00300         PING_DISCOVERY
00301     };

enum BasePastry::StateObject [protected]
Enumerator:
ROUTINGTABLE 
LEAFSET 
NEIGHBORHOODSET 

Definition at line 277 of file BasePastry.h.

00278     {
00279         ROUTINGTABLE,
00280         LEAFSET,
00281         NEIGHBORHOODSET
00282     };


Constructor & Destructor Documentation

BasePastry::~BasePastry (  )  [virtual]

Definition at line 997 of file BasePastry.cc.

00998 {
00999     cancelAndDelete(joinTimeout);
01000 
01001     purgeVectors();
01002 }


Member Function Documentation

void BasePastry::baseChangeState ( int  toState  )  [protected]

changes node state, but leaves specific behavour, scheduling tasks in particular, to the inheriting protocols

Definition at line 196 of file BasePastry.cc.

Referenced by Pastry::changeState(), and Bamboo::changeState().

00197 {
00198     switch (toState) {
00199     case INIT:
00200         state = INIT;
00201 
00202         if (!thisNode.getKey().isUnspecified())
00203             bootstrapList->removeBootstrapNode(thisNode);
00204 
00205         if (joinTimeout->isScheduled()) cancelEvent(joinTimeout);
00206 
00207         purgeVectors();
00208 
00209         bootstrapNode = bootstrapList->getBootstrapNode();
00210 
00211         routingTable->initializeTable(bitsPerDigit, repairTimeout, thisNode);
00212         leafSet->initializeSet(numberOfLeaves, bitsPerDigit,
00213                                repairTimeout, thisNode, this);
00214         neighborhoodSet->initializeSet(numberOfNeighbors, bitsPerDigit,
00215                                        thisNode);
00216 
00217         updateTooltip();
00218         lastStateChange = simTime();
00219 
00220         getParentModule()->getParentModule()->bubble("entering INIT state");
00221 
00222         break;
00223 
00224     case JOINING_2:
00225         state = JOINING_2;
00226 
00227         // bootstrapNode must be obtained before calling this method,
00228         // for example by calling changeState(INIT)
00229 
00230         if (bootstrapNode.isUnspecified()) {
00231             // no existing pastry network -> first node of a new one
00232             changeState(READY);
00233             return;
00234         }
00235 
00236         cancelEvent(joinTimeout);
00237         scheduleAt(simTime() + joinTimeoutAmount, joinTimeout);
00238 
00239         updateTooltip();
00240         getParentModule()->getParentModule()->bubble("entering JOIN state");
00241 
00242         RECORD_STATS(joinTries++);
00243 
00244         break;
00245 
00246     case READY:
00247         assert(state != READY);
00248         state = READY;
00249 
00250          //bootstrapList->registerBootstrapNode(thisNode);
00251 
00252         // if we are the first node in the network, there's nothing else
00253         // to do
00254         if (bootstrapNode.isUnspecified()) {
00255             RECORD_STATS(joinTries++);
00256             RECORD_STATS(joins++);
00257             setOverlayReady(true);
00258             return;
00259         }
00260 
00261         getParentModule()->getParentModule()->bubble("entering READY state");
00262         updateTooltip();
00263         RECORD_STATS(joins++);
00264 
00265         break;
00266 
00267     default: // discovery
00268         break;
00269     }
00270     setOverlayReady(state == READY);
00271 }

void BasePastry::baseInit ( void   )  [protected]

initializes parameters and variables used in both Bamboo and Pastry

Definition at line 66 of file BasePastry.cc.

Referenced by Pastry::initializeOverlay(), and Bamboo::initializeOverlay().

00067 {
00068     bitsPerDigit = par("bitsPerDigit");
00069     numberOfLeaves = par("numberOfLeaves");
00070     numberOfNeighbors = par("numberOfNeighbors");
00071     joinTimeoutAmount = par("joinTimeout");
00072     repairTimeout = par("repairTimeout");
00073     enableNewLeafs = par("enableNewLeafs");
00074     optimizeLookup = par("optimizeLookup");
00075     useRegularNextHop = par("useRegularNextHop");
00076     alwaysSendUpdate = par("alwaysSendUpdate");
00077     proximityNeighborSelection = par("proximityNeighborSelection");
00078 
00079     if (!neighborCache->isEnabled()) {
00080         throw cRuntimeError("NeighborCache is disabled, which is mandatory "
00081                                 "for Pastry/Bamboo. Activate it by setting "
00082                                 "\"**.neighborCache.enableNeighborCache "
00083                                 "= true\" in your omnetpp.ini!");
00084     }
00085 
00086     if (numberOfLeaves % 2) {
00087         EV << "[BasePastry::baseInit() @ " << thisNode.getAddress()
00088            << " (" << thisNode.getKey().toString(16) << ")]\n"
00089            << "    Warning: numberOfLeaves must be even - adding 1."
00090            << endl;
00091         numberOfLeaves++;
00092     }
00093 
00094     routingTable = check_and_cast<PastryRoutingTable*>
00095         (getParentModule()->getSubmodule("pastryRoutingTable"));
00096     leafSet = check_and_cast<PastryLeafSet*>
00097         (getParentModule()->getSubmodule("pastryLeafSet"));
00098     neighborhoodSet = check_and_cast<PastryNeighborhoodSet*>
00099         (getParentModule()->getSubmodule("pastryNeighborhoodSet"));
00100 
00101     stateCache.msg = NULL;
00102     stateCache.prox = NULL;
00103 
00104     rowToAsk = 0;
00105 
00106     // initialize statistics
00107     joins = 0;
00108     joinTries = 0;
00109     joinPartial = 0;
00110     joinSeen = 0;
00111     joinReceived = 0;
00112     joinSent = 0;
00113     stateSent = 0;
00114     stateReceived = 0;
00115     repairReqSent = 0;
00116     repairReqReceived = 0;
00117     stateReqSent = 0;
00118     stateReqReceived = 0;
00119 
00120     joinBytesSeen = 0;
00121     joinBytesReceived = 0;
00122     joinBytesSent = 0;
00123     stateBytesSent = 0;
00124     stateBytesReceived = 0;
00125     repairReqBytesSent = 0;
00126     repairReqBytesReceived = 0;
00127     stateReqBytesSent = 0;
00128     stateReqBytesReceived = 0;
00129 
00130     totalLookups = 0;
00131     responsibleLookups = 0;
00132     routingTableLookups = 0;
00133     closerNodeLookups = 0;
00134     closerNodeLookupsFromNeighborhood = 0;
00135 
00136     leafsetReqSent = 0;
00137     leafsetReqBytesSent = 0;
00138     leafsetReqReceived = 0;
00139     leafsetReqBytesReceived = 0;
00140     leafsetSent = 0;
00141     leafsetBytesSent = 0;
00142     leafsetReceived = 0;
00143     leafsetBytesReceived = 0;
00144 
00145     routingTableReqSent = 0;
00146     routingTableReqBytesSent = 0;
00147     routingTableReqReceived = 0;
00148     routingTableReqBytesReceived = 0;
00149     routingTableSent = 0;
00150     routingTableBytesSent = 0;
00151     routingTableReceived = 0;
00152     routingTableBytesReceived = 0;
00153 
00154     WATCH(joins);
00155     WATCH(joinTries);
00156     WATCH(joinSeen);
00157     WATCH(joinBytesSeen);
00158     WATCH(joinReceived);
00159     WATCH(joinBytesReceived);
00160     WATCH(joinSent);
00161     WATCH(joinBytesSent);
00162     WATCH(stateSent);
00163     WATCH(stateBytesSent);
00164     WATCH(stateReceived);
00165     WATCH(stateBytesReceived);
00166     WATCH(repairReqSent);
00167     WATCH(repairReqBytesSent);
00168     WATCH(repairReqReceived);
00169     WATCH(repairReqBytesReceived);
00170     WATCH(stateReqSent);
00171     WATCH(stateReqBytesSent);
00172     WATCH(stateReqReceived);
00173     WATCH(stateReqBytesReceived);
00174     WATCH(lastStateChange);
00175 
00176     WATCH(leafsetReqSent);
00177     WATCH(leafsetReqBytesSent);
00178     WATCH(leafsetReqReceived);
00179     WATCH(leafsetReqBytesReceived);
00180     WATCH(leafsetSent);
00181     WATCH(leafsetBytesSent);
00182     WATCH(leafsetReceived);
00183     WATCH(leafsetBytesReceived);
00184 
00185     WATCH(routingTableReqSent);
00186     WATCH(routingTableReqBytesSent);
00187     WATCH(routingTableReqReceived);
00188     WATCH(routingTableReqBytesReceived);
00189     WATCH(routingTableSent);
00190     WATCH(routingTableBytesSent);
00191     WATCH(routingTableReceived);
00192     WATCH(routingTableBytesReceived);
00193 }

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

changes node state

Parameters:
toState state to change to

Reimplemented in Bamboo, and Pastry.

Definition at line 289 of file BasePastry.cc.

Referenced by baseChangeState().

00290 {
00291 
00292 }

virtual void BasePastry::checkProxCache ( void   )  [protected, pure virtual]

checks whether proxCache is complete, takes appropriate actions depending on the protocol state

Implemented in Bamboo, and Pastry.

Referenced by pingNodes(), pingResponse(), pingTimeout(), and proxCallback().

AbstractLookup * BasePastry::createLookup ( RoutingType  routingType = DEFAULT_ROUTING,
const BaseOverlayMessage *  msg = NULL,
const cObject *  dummy = NULL,
bool  appLookup = false 
) [virtual]

Definition at line 1212 of file BasePastry.cc.

Referenced by Bamboo::doGlobalTuning().

01216 {
01217     assert(dummy == NULL);
01218     PastryFindNodeExtData* findNodeExt =
01219         new PastryFindNodeExtData("findNodeExt");
01220 
01221     if (msg) {
01222         const PastryMessage* pmsg =
01223             dynamic_cast<const PastryMessage*>(msg->getEncapsulatedPacket());
01224         if ((pmsg) && (pmsg->getPastryMsgType() == PASTRY_MSG_JOIN)) {
01225             const PastryJoinMessage* jmsg =
01226                 check_and_cast<const PastryJoinMessage*>(pmsg);
01227             findNodeExt->setSendStateTo(jmsg->getSendStateTo());
01228             findNodeExt->setJoinHopCount(1);
01229         }
01230     }
01231     findNodeExt->setBitLength(PASTRYFINDNODEEXTDATA_L);
01232 
01233     AbstractLookup* newLookup = BaseOverlay::createLookup(routingType,
01234                                                           msg, findNodeExt,
01235                                                           appLookup);
01236 
01237     delete findNodeExt;
01238     return newLookup;
01239 }

void BasePastry::determineAliveTable ( const PastryStateMessage *  stateMsg  )  [protected]

change the aliveTable to match the given stateMsg.

each node that's knowm to be dead from our neighborCache gets a value of PASTRY_PROX_INFINITE, all other nodes just get a value of 1

Definition at line 537 of file BasePastry.cc.

Referenced by Pastry::handleStateMessage(), and Bamboo::handleStateMessage().

00538 {
00539     uint32_t rt_size = stateMsg->getRoutingTableArraySize();
00540     aliveTable.pr_rt.clear();
00541     aliveTable.pr_rt.resize(rt_size, 1);
00542 
00543     uint32_t ls_size = stateMsg->getLeafSetArraySize();
00544     aliveTable.pr_ls.clear();
00545     aliveTable.pr_ls.resize(ls_size, 1);
00546 
00547     uint32_t ns_size = stateMsg->getNeighborhoodSetArraySize();
00548     aliveTable.pr_ns.clear();
00549     aliveTable.pr_ns.resize(ns_size, 1);
00550 
00551     for (uint32_t i = 0; i < rt_size + ls_size + ns_size; i++) {
00552         const TransportAddress* node;
00553         std::vector<simtime_t>::iterator tblPos;
00554         if (i < rt_size) {
00555             node = &(stateMsg->getRoutingTable(i));
00556             tblPos = aliveTable.pr_rt.begin() + i;
00557         } else if ( i < (rt_size + ls_size) ) {
00558             node = &(stateMsg->getLeafSet(i - rt_size));
00559             tblPos = aliveTable.pr_ls.begin() + (i - rt_size);
00560         } else {
00561             node = &(stateMsg->getNeighborhoodSet(i - rt_size - ls_size));
00562             tblPos = aliveTable.pr_ns.begin() + (i - rt_size - ls_size);
00563         }
00564         if (neighborCache->getProx(*node, NEIGHBORCACHE_DEFAULT_IMMEDIATELY) ==
00565                 Prox::PROX_TIMEOUT) {
00566             *tblPos = PASTRY_PROX_INFINITE;
00567         }
00568     }
00569 }

OverlayKey BasePastry::distance ( const OverlayKey x,
const OverlayKey y,
bool  useAlternative = false 
) const [protected, virtual]

This method should implement the distance between two keys.

It may be overloaded to implement a new metric. The default implementation uses the standard-metric d = abs(x-y).

Parameters:
x Left-hand-side Key
y Right-hand-side key
useAlternative use an alternative distance metric
Returns:
OverlayKey Distance between x and y

Reimplemented from BaseOverlay.

Definition at line 1275 of file BasePastry.cc.

01278 {
01279     if (!useAlternative) return KeyRingMetric().distance(x, y);
01280     return KeyPrefixMetric().distance(x, y);
01281 }

NodeVector * BasePastry::findNode ( const OverlayKey key,
int  numRedundantNodes,
int  numSiblings,
BaseOverlayMessage *  msg 
) [virtual]

Implements the find node call.

This method simply returns the closest nodes known in the corresponding routing topology. If the node is a sibling for this key (isSiblingFor(key) = true), this method returns all numSiblings siblings, with the closest neighbor to the key first.

Parameters:
key The lookup key.
numRedundantNodes Maximum number of next hop nodes to return.
numSiblings number of siblings to return
msg A pointer to the BaseRouteMessage or FindNodeCall message of this lookup.
Returns:
NodeVector with closest nodes.

Reimplemented from BaseOverlay.

Definition at line 1100 of file BasePastry.cc.

01104 {
01105     if ((numRedundantNodes > getMaxNumRedundantNodes()) ||
01106         (numSiblings > getMaxNumSiblings())) {
01107 
01108         opp_error("(Pastry::findNode()) numRedundantNodes or numSiblings "
01109                   "too big!");
01110     }
01111     RECORD_STATS(totalLookups++);
01112 
01113     NodeVector* nextHops = new NodeVector(numRedundantNodes);
01114 
01115     if (state != READY) {
01116         return nextHops;
01117     } else if (key.isUnspecified() || leafSet->isClosestNode(key)) {
01118         RECORD_STATS(responsibleLookups++);
01119         nextHops->add(thisNode);
01120     } else {
01121         const NodeHandle* next = &(leafSet->getDestinationNode(key));
01122 
01123         if (next->isUnspecified()) {
01124             next = &(routingTable->lookupNextHop(key));
01125             if (!next->isUnspecified()) {
01126                 RECORD_STATS(routingTableLookups++);
01127             }
01128         } else {
01129             RECORD_STATS(responsibleLookups++);
01130         }
01131 
01132         if (next->isUnspecified()) {
01133             RECORD_STATS(closerNodeLookups++);
01134             // call findCloserNode() on all state objects
01135             if (optimizeLookup) {
01136                 const NodeHandle* tmp;
01137                 next = &(routingTable->findCloserNode(key, true));
01138                 tmp = &(neighborhoodSet->findCloserNode(key, true));
01139 
01140                 if ((! tmp->isUnspecified()) &&
01141                     (leafSet->isCloser(*tmp, key, *next))) {
01142                     RECORD_STATS(closerNodeLookupsFromNeighborhood++);
01143                     next = tmp;
01144                 }
01145 
01146                 tmp = &(leafSet->findCloserNode(key, true));
01147                 if ((! tmp->isUnspecified()) &&
01148                     (leafSet->isCloser(*tmp, key, *next))) {
01149                     RECORD_STATS(closerNodeLookupsFromNeighborhood--);
01150                     next = tmp;
01151                 }
01152             } else {
01153                 next = &(routingTable->findCloserNode(key));
01154 
01155                 if (next->isUnspecified()) {
01156                     RECORD_STATS(closerNodeLookupsFromNeighborhood++);
01157                     next = &(neighborhoodSet->findCloserNode(key));
01158                 }
01159 
01160                 if (next->isUnspecified()) {
01161                     RECORD_STATS(closerNodeLookupsFromNeighborhood--);
01162                     next = &(leafSet->findCloserNode(key));
01163                 }
01164             }
01165         }
01166 
01167         iterativeJoinHook(msg, !next->isUnspecified());
01168 
01169         if (!next->isUnspecified()) {
01170             nextHops->add(*next);
01171         }
01172     }
01173 
01174     bool err;
01175 
01176     // if we're a sibling, return all numSiblings
01177     if ((numSiblings >= 0) && isSiblingFor(thisNode, key, numSiblings, &err)) {
01178         if (err == false) {
01179             delete nextHops;
01180             return  leafSet->createSiblingVector(key, numSiblings);
01181         }
01182     }
01183 
01184     if (/*(nextHops->size() > 0) &&*/ (numRedundantNodes > 1)) {
01185 
01186         //memleak... comp should be a ptr and deleted in NodeVector::~NodeVector()...
01187         //KeyDistanceComparator<KeyRingMetric>* comp =
01188         //    new KeyDistanceComparator<KeyRingMetric>( key );
01189 
01190         KeyDistanceComparator<KeyRingMetric> comp(key);
01191         //KeyDistanceComparator<KeyPrefixMetric> comp(key);
01192         NodeVector* additionalHops = new NodeVector( numRedundantNodes, &comp );
01193 
01194         routingTable->findCloserNodes(key, additionalHops);
01195         leafSet->findCloserNodes(key, additionalHops);
01196         neighborhoodSet->findCloserNodes(key, additionalHops);
01197 
01198         if (useRegularNextHop && (nextHops->size() > 0) &&
01199             (*additionalHops)[0] != (*nextHops)[0]) {
01200             for (uint32_t i = 0; i < additionalHops->size(); i++) {
01201                 if ((*additionalHops)[i] != (*nextHops)[0])
01202                     nextHops->push_back((*additionalHops)[i]);
01203             }
01204             delete additionalHops;
01205         } else {
01206             delete nextHops;
01207             return additionalHops;
01208         }
01209     }
01210     return nextHops;
01211 }

void BasePastry::finishOverlay (  )  [virtual]

collects statistical data in derived class

Reimplemented from BaseOverlay.

Definition at line 1004 of file BasePastry.cc.

01005 {
01006     // remove this node from the bootstrap list
01007     if (!thisNode.getKey().isUnspecified()) bootstrapList->removeBootstrapNode(thisNode);
01008 
01009     // collect statistics
01010     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
01011     if (time < GlobalStatistics::MIN_MEASURED) return;
01012 
01013     // join statistics
01014     //if (joinTries > joins)
01015         //std::cout << thisNode << " jt:" << joinTries << " j:" << joins << " jts:"
01016         //          << joinTimeout->isScheduled() << " rws:" << readyWait->isScheduled()
01017         //          << " state:" << state << " time:" << time << std::endl;
01018     // join is on the way...
01019     if (joinTries > 0 && joinTimeout->isScheduled()) joinTries--;
01020     if (joinTries > 0) {
01021         globalStatistics->addStdDev("Pastry: join success ratio", (double)joins / (double)joinTries);
01022         globalStatistics->addStdDev("Pastry: join tries", joinTries);
01023     } else if (state == READY) {
01024         // nodes has joined in init-/transition-phase
01025         globalStatistics->addStdDev("Pastry: join success ratio", 1);
01026         globalStatistics->addStdDev("Pastry: join tries", 1);
01027     } else {
01028         globalStatistics->addStdDev("Pastry: join success ratio", 0);
01029         globalStatistics->addStdDev("Pastry: join tries", 1);
01030     }
01031 
01032     globalStatistics->addStdDev("Pastry: joins with missing replies from routing path/s",
01033                                 joinPartial / time);
01034     globalStatistics->addStdDev("Pastry: JOIN Messages seen/s", joinSeen / time);
01035     globalStatistics->addStdDev("Pastry: bytes of JOIN Messages seen/s", joinBytesSeen / time);
01036     globalStatistics->addStdDev("Pastry: JOIN Messages received/s", joinReceived / time);
01037     globalStatistics->addStdDev("Pastry: bytes of JOIN Messages received/s",
01038                                 joinBytesReceived / time);
01039     globalStatistics->addStdDev("Pastry: JOIN Messages sent/s", joinSent / time);
01040     globalStatistics->addStdDev("Pastry: bytes of JOIN Messages sent/s", joinBytesSent / time);
01041     globalStatistics->addStdDev("Pastry: STATE Messages sent/s", stateSent / time);
01042     globalStatistics->addStdDev("Pastry: bytes of STATE Messages sent/s", stateBytesSent / time);
01043     globalStatistics->addStdDev("Pastry: STATE Messages received/s", stateReceived / time);
01044     globalStatistics->addStdDev("Pastry: bytes of STATE Messages received/s",
01045                                 stateBytesReceived / time);
01046     globalStatistics->addStdDev("Pastry: REPAIR Requests sent/s", repairReqSent / time);
01047     globalStatistics->addStdDev("Pastry: bytes of REPAIR Requests sent/s",
01048                                 repairReqBytesSent / time);
01049     globalStatistics->addStdDev("Pastry: REPAIR Requests received/s", repairReqReceived / time);
01050     globalStatistics->addStdDev("Pastry: bytes of REPAIR Requests received/s",
01051                                 repairReqBytesReceived / time);
01052     globalStatistics->addStdDev("Pastry: STATE Requests sent/s", stateReqSent / time);
01053     globalStatistics->addStdDev("Pastry: bytes of STATE Requests sent/s", stateReqBytesSent / time);
01054     globalStatistics->addStdDev("Pastry: STATE Requests received/s", stateReqReceived / time);
01055     globalStatistics->addStdDev("Pastry: bytes of STATE Requests received/s",
01056                                 stateReqBytesReceived / time);
01057 
01058     globalStatistics->addStdDev("Pastry: bytes of STATE Requests received/s",
01059                                 stateReqBytesReceived / time);
01060 
01061     globalStatistics->addStdDev("Pastry: total number of lookups", totalLookups);
01062     globalStatistics->addStdDev("Pastry: responsible lookups", responsibleLookups);
01063     globalStatistics->addStdDev("Pastry: lookups in routing table", routingTableLookups);
01064     globalStatistics->addStdDev("Pastry: lookups using closerNode()", closerNodeLookups);
01065     globalStatistics->addStdDev("Pastry: lookups using closerNode() with result from "
01066                                 "neighborhood set", closerNodeLookupsFromNeighborhood);
01067     globalStatistics->addStdDev("Pastry: LEAFSET Requests sent/s", leafsetReqSent / time);
01068     globalStatistics->addStdDev("Pastry: bytes of LEAFSET Requests sent/s", leafsetReqBytesSent / time);
01069     globalStatistics->addStdDev("Pastry: LEAFSET Requests received/s", leafsetReqReceived / time);
01070     globalStatistics->addStdDev("Pastry: bytes of LEAFSET Requests received/s",
01071                                 leafsetReqBytesReceived / time);
01072     globalStatistics->addStdDev("Pastry: LEAFSET Messages sent/s", leafsetSent / time);
01073     globalStatistics->addStdDev("Pastry: bytes of LEAFSET Messages sent/s", leafsetBytesSent / time);
01074     globalStatistics->addStdDev("Pastry: LEAFSET Messages received/s", leafsetReceived / time);
01075     globalStatistics->addStdDev("Pastry: bytes of LEAFSET Messages received/s",
01076                                 leafsetBytesReceived / time);
01077     globalStatistics->addStdDev("Pastry: ROUTING TABLE Requests sent/s", routingTableReqSent / time);
01078     globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Requests sent/s", routingTableReqBytesSent / time);
01079     globalStatistics->addStdDev("Pastry: ROUTING TABLE Requests received/s", routingTableReqReceived / time);
01080     globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Requests received/s",
01081                                 routingTableReqBytesReceived / time);
01082     globalStatistics->addStdDev("Pastry: ROUTING TABLE Messages sent/s", routingTableSent / time);
01083     globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Messages sent/s", routingTableBytesSent / time);
01084     globalStatistics->addStdDev("Pastry: ROUTING TABLE Messages received/s", routingTableReceived / time);
01085     globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Messages received/s",
01086                                 routingTableBytesReceived / time);
01087 
01088 }

uint8_t BasePastry::getBitsPerDigit (  )  [inline, virtual]

Reimplemented from BaseOverlay.

Definition at line 134 of file BasePastry.h.

00134 { return bitsPerDigit; };

int BasePastry::getMaxNumRedundantNodes (  )  [virtual]

Query the maximum number of redundant next hop nodes that are returned by findNode().

Returns:
int number of redundant nodes returned by findNode().

Reimplemented from BaseOverlay.

Definition at line 1095 of file BasePastry.cc.

Referenced by findNode().

01096 {
01097     return (int)floor(numberOfLeaves);
01098 }

int BasePastry::getMaxNumSiblings (  )  [virtual]

Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.

Returns:
int number of siblings.

Reimplemented from BaseOverlay.

Definition at line 1090 of file BasePastry.cc.

Referenced by findNode().

01091 {
01092     return (int)floor(numberOfLeaves / 2.0);
01093 }

void BasePastry::handleAppMessage ( BaseOverlayMessage *  msg  )  [virtual]

processes messages from application

Parameters:
msg message from application

Definition at line 968 of file BasePastry.cc.

00969 {
00970     delete msg;
00971 }

void BasePastry::handleLeafsetMessage ( PastryLeafsetMessage *  msg,
bool  mergeSender = false 
) [protected]

processes leafset messages, merging with own state tables

Parameters:
msg the pastry state message
mergeSender should the sender also be merged

Definition at line 892 of file BasePastry.cc.

Referenced by Pastry::handleUDPMessage(), and Bamboo::handleUDPMessage().

00893 {
00894     uint32_t lsSize = msg->getLeafSetArraySize();
00895     PastryStateMessage* stateMsg;
00896 
00897     stateMsg = new PastryStateMessage("STATE");
00898     stateMsg->setTimestamp(msg->getTimestamp());
00899     stateMsg->setPastryMsgType(PASTRY_MSG_STATE);
00900     stateMsg->setStatType(MAINTENANCE_STAT);
00901     stateMsg->setSender(msg->getSender());
00902     stateMsg->setLeafSetArraySize(lsSize);
00903     stateMsg->setNeighborhoodSetArraySize(0);
00904     stateMsg->setRoutingTableArraySize(0);
00905 
00906     for (uint32_t i = 0; i < lsSize; i++) {
00907         stateMsg->setLeafSet(i, msg->getLeafSet(i));
00908     }
00909 
00910     if (mergeSender) {
00911         stateMsg->setLeafSetArraySize(lsSize+1);
00912         stateMsg->setLeafSet(lsSize, msg->getSender());
00913     }
00914 
00915     handleStateMessage(stateMsg);
00916     delete msg;
00917 }

void BasePastry::handleRequestMessage ( PastryRequestMessage *  msg  )  [protected]

processes state messages, merging with own state tables

Parameters:
msg the pastry state message

Definition at line 844 of file BasePastry.cc.

Referenced by Pastry::handleUDPMessage(), and Bamboo::handleUDPMessage().

00845 {
00846     assert(msg->getSendStateTo() != thisNode);
00847     uint32_t reqtype = msg->getPastryReqType();
00848     if (reqtype == PASTRY_REQ_REPAIR) {
00849         RECORD_STATS(repairReqReceived++; repairReqBytesReceived +=
00850             msg->getByteLength());
00851         if (state == READY)
00852             sendStateTables(msg->getSendStateTo(),
00853                             PASTRY_STATE_REPAIR);
00854         else
00855             EV << "[BasePastry::handleRequestMessage() @ " << thisNode.getAddress()
00856             << " (" << thisNode.getKey().toString(16) << ")]\n"
00857             << "    received repair request before reaching"
00858             << " READY state, dropping message!"
00859             << endl;
00860         delete msg;
00861     }
00862     else if (reqtype == PASTRY_REQ_STATE) {
00863         RECORD_STATS(stateReqReceived++; stateReqBytesReceived +=
00864             msg->getByteLength());
00865         if (state == READY)
00866             sendStateTables(msg->getSendStateTo());
00867         else
00868             EV << "[BasePastry::handleRequestMessage() @ " << thisNode.getAddress()
00869             << " (" << thisNode.getKey().toString(16) << ")]\n"
00870             << "    received state request before reaching"
00871             << " READY state, dropping message!"
00872             << endl;
00873         delete msg;
00874     }
00875     else if (PASTRY_REQ_LEAFSET) {
00876         RECORD_STATS(leafsetReqReceived++; leafsetReqBytesReceived +=
00877             msg->getByteLength());
00878         if (state == READY) {
00879             sendLeafset(msg->getSendStateTo());
00880         }
00881         else
00882             EV << "[BasePastry::handleRequestMessage() @ " << thisNode.getAddress()
00883             << " (" << thisNode.getKey().toString(16) << ")]\n"
00884             << "    received leafset request before reaching"
00885             << " READY state, dropping message!"
00886             << endl;
00887         delete msg;
00888     }
00889 
00890 }

virtual void BasePastry::handleStateMessage ( PastryStateMessage *  msg  )  [pure virtual]

processes state messages, merging with own state tables

Parameters:
msg the pastry state message

Implemented in Bamboo, and Pastry.

Referenced by handleLeafsetMessage().

bool BasePastry::isSiblingFor ( const NodeHandle node,
const OverlayKey key,
int  numSiblings,
bool *  err 
) [virtual]

Query if a node is among the siblings for a given key.

Query if a node is among the siblings for a given key. This means, that the nodeId of this node is among the closest numSiblings nodes to the key and that by a local findNode() call all other siblings to this key can be retrieved.

Parameters:
node the NodeHandle
key destination key
numSiblings The nodes knows all numSiblings nodes close to this key
err return false if the range could not be determined
Returns:
bool true, if the node is responsible for the key.

Reimplemented from BaseOverlay.

Definition at line 919 of file BasePastry.cc.

Referenced by findNode().

00923 {
00924     if (key.isUnspecified())
00925         error("Pastry::isSiblingFor(): key is unspecified!");
00926 
00927     if ((numSiblings == 1) && (node == thisNode)) {
00928         if (leafSet->isClosestNode(key)) {
00929             *err = false;
00930             return true;
00931         } else {
00932             *err = false;
00933             return false;
00934         }
00935     }
00936 
00937     NodeVector* result =  leafSet->createSiblingVector(key, numSiblings);
00938 
00939     if (result == NULL) {
00940         *err = true;
00941         return false;
00942     }
00943 
00944     if (result->contains(node.getKey())) {
00945         delete result;
00946         *err = false;
00947         return true;
00948     } else {
00949         delete result;
00950         *err = true;
00951         return false;
00952     }
00953 
00954     /*
00955       const NodeHandle& dest = leafSet->getDestinationNode(key);
00956       if (!dest.isUnspecified()) {
00957       *err = false;
00958       return true;
00959       } else {
00960 
00961       *err = true;
00962       return false;
00963       }
00964     */
00965 }

virtual void BasePastry::iterativeJoinHook ( BaseOverlayMessage *  msg,
bool  incrHopCount 
) [inline, protected, virtual]

Reimplemented in Pastry.

Definition at line 274 of file BasePastry.h.

Referenced by findNode().

00275                                                       { };

void BasePastry::newLeafs ( void   )  [protected]

Pastry API: send newLeafs() to application if enabled.

Definition at line 274 of file BasePastry.cc.

Referenced by Pastry::handleFailedNode(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), and Pastry::mergeState().

00275 {
00276     if (! enableNewLeafs) return;
00277 
00278     PastryNewLeafsMessage* msg = leafSet->getNewLeafsMessage();
00279     if (msg) {
00280         send(msg, "appOut");
00281         EV << "[BasePastry::newLeafs() @ " << thisNode.getAddress()
00282            << " (" << thisNode.getKey().toString(16) << ")]\n"
00283            << "    newLeafs() called."
00284            << endl;
00285     }
00286 }

void BasePastry::pingNodes ( void   )  [protected]

ping all nodes in the pastry state message pointed to by private member stateCache

Definition at line 472 of file BasePastry.cc.

Referenced by Bamboo::checkProxCache(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), and Pastry::processState().

00473 {
00474     EV << "[BasePastry::pingNodes() @ " << thisNode.getAddress()
00475        << " (" << thisNode.getKey().toString(16) << ")]" << endl;
00476 
00477     if (stateCache.msg == NULL) throw cRuntimeError("no state msg");
00478 
00479     assert(stateCache.prox == NULL);
00480     stateCache.prox = new PastryStateMsgProximity();
00481 
00482     uint32_t rt_size = stateCache.msg->getRoutingTableArraySize();
00483     stateCache.prox->pr_rt.resize(rt_size, PASTRY_PROX_UNDEF);
00484 
00485     uint32_t ls_size = stateCache.msg->getLeafSetArraySize();
00486     stateCache.prox->pr_ls.resize(ls_size, PASTRY_PROX_UNDEF);
00487 
00488     uint32_t ns_size = stateCache.msg->getNeighborhoodSetArraySize();
00489     stateCache.prox->pr_ns.resize(ns_size, PASTRY_PROX_UNDEF);
00490 
00491     std::vector< std::pair<const NodeHandle*, PingContext*> > nodesToPing;
00492     // set prox state
00493     for (uint32_t i = 0; i < rt_size + ls_size + ns_size; i++) {
00494         const NodeHandle* node;
00495         std::vector<simtime_t>::iterator proxPos;
00496         PingContext* pingContext = NULL;
00497         StateObject stateObject;
00498         uint32_t index;
00499         if (stateCache.msg == NULL) break;
00500         if (i < rt_size) {
00501             node = &(stateCache.msg->getRoutingTable(i));
00502             proxPos = stateCache.prox->pr_rt.begin() + i;
00503             stateObject = ROUTINGTABLE;
00504             index = i;
00505         } else if ( i < (rt_size + ls_size) ) {
00506             node = &(stateCache.msg->getLeafSet(i - rt_size));
00507             proxPos = stateCache.prox->pr_ls.begin() + (i - rt_size);
00508             stateObject = LEAFSET;
00509             index = i - rt_size;
00510         } else {
00511             node = &(stateCache.msg->getNeighborhoodSet(i - rt_size - ls_size));
00512             proxPos = stateCache.prox->pr_ns.begin() + (i - rt_size - ls_size);
00513             stateObject = NEIGHBORHOODSET;
00514             index = i - rt_size - ls_size;
00515         }
00516         // proximity is undefined for unspecified nodes:
00517         if (!node->isUnspecified()) {
00518             pingContext = new PingContext(stateObject, index,
00519                                           stateCache.nonce);
00520 
00521             Prox prox = neighborCache->getProx(*node, NEIGHBORCACHE_DEFAULT, -1,
00522                                                this, pingContext);
00523             if (prox == Prox::PROX_SELF) {
00524                 *proxPos = 0;
00525             } else if (prox == Prox::PROX_TIMEOUT) {
00526                 *proxPos = PASTRY_PROX_INFINITE;
00527             } else if (prox == Prox::PROX_UNKNOWN) {
00528                 *proxPos = PASTRY_PROX_PENDING;
00529             } else {
00530                 *proxPos = prox.proximity;
00531             }
00532         }
00533     }
00534     checkProxCache();
00535 }

void BasePastry::pingResponse ( PingResponse *  pingResponse,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [virtual]

Reimplemented from BaseRpc.

Reimplemented in Pastry.

Definition at line 295 of file BasePastry.cc.

00297 {
00298     EV << "[BasePastry::pingResponse() @ " << thisNode.getAddress()
00299        << " (" << thisNode.getKey().toString(16) << ")]\n"
00300        << "    Pong (or Ping-context from NeighborCache) received (from "
00301        << msg->getSrcNode().getAddress() << ")"
00302        << endl;
00303 
00304     const NodeHandle& src = msg->getSrcNode();
00305     assert(!src.isUnspecified());
00306 
00307     // merge single pinged nodes (bamboo global tuning)
00308     if (rpcId == PING_SINGLE_NODE) {
00309         routingTable->mergeNode(src, proximityNeighborSelection ?
00310                                      rtt : SimTime::getMaxTime());
00311         return;
00312     }
00313 
00314     /*// a node with the an equal ID has responded
00315     if ((src.getKey() == thisNode.getKey()) && (src.getAddress() != thisNode.getAddress())) {
00316         EV << "[BasePastry::pingResponse() @ " << thisNode.getAddress()
00317            << " (" << thisNode.getKey().toString(16) << ")]\n"
00318            << "    a node with the an equal ID has responded, rejoining" << endl;
00319         delete context;
00320         //joinOverlay();
00321         return;
00322     }*/
00323 
00324     if (context != NULL && stateCache.msg && stateCache.prox) {
00325         PingContext* pingContext = check_and_cast<PingContext*>(context);
00326         if (pingContext->nonce != stateCache.nonce) {
00327             delete context;
00328             return;
00329             //throw cRuntimeError("response doesn't fit stateCache");
00330         }
00331         switch (pingContext->stateObject) {
00332             case ROUTINGTABLE: {
00333                 /*node = &(stateCache.msg->getRoutingTable(pingContext->index));
00334                 if((node->isUnspecified()) || (*node != src)) {
00335                     std::cout << simTime() << " " << thisNode.getAddress() << " rt: state from "
00336                               << stateCache.msg->getSender().getAddress() << " *** failed: node "
00337                               << node->ip << " src " << src.getAddress() << std::endl;
00338                     break;
00339                 }*/
00340                 *(stateCache.prox->pr_rt.begin() + pingContext->index) = rtt;
00341                 break;
00342             }
00343             case LEAFSET: {
00344                 /*node = &(stateCache.msg->getLeafSet(pingContext->index));
00345                 if ((node->isUnspecified()) || (*node != src)) {
00346                     std::cout << simTime() << " " << thisNode.getAddress() << " ls: state from "
00347                               << stateCache.msg->getSender().getAddress() << " *** failed: node "
00348                               << node->ip << " src " << src.getAddress() << std::endl;
00349                     break;
00350                 }*/
00351                 *(stateCache.prox->pr_ls.begin() + pingContext->index) = rtt;
00352                 break;
00353             }
00354             case NEIGHBORHOODSET: {
00355                 /*node = &(stateCache.msg->getNeighborhoodSet(pingContext->index));
00356                 if((node->isUnspecified()) || (*node != src)) {
00357                     std::cout << simTime() << " " << thisNode.getAddress() << " ns: state from "
00358                               << stateCache.msg->getSender().getAddress() << " *** failed: node "
00359                               << node->ip << " src " << src.getAddress() << std::endl;
00360                     break;
00361                 }*/
00362                 *(stateCache.prox->pr_ns.begin() + pingContext->index) = rtt;
00363                 break;
00364             }
00365             default: {
00366                 throw cRuntimeError("wrong state object type!");
00367             }
00368         }
00369         checkProxCache();
00370     }
00371     delete context;
00372 }

void BasePastry::pingTimeout ( PingCall *  call,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId 
) [virtual]

Reimplemented from BaseRpc.

Definition at line 661 of file BasePastry.cc.

00665 {
00666     EV << "[BasePastry::sendStateDelayed() @ " << thisNode.getAddress()
00667        << " (" << thisNode.getKey().toString(16) << ")]\n"
00668        << "    Ping timeout occurred (" << dest.getAddress() << ")"
00669        << endl;
00670 
00671     // handle failed node
00672     if (state == READY) {
00673         handleFailedNode(dest); // TODO
00674         updateTooltip();
00675 
00676         // this could initiate a re-join, exit the handler in that
00677         // case because all local data was erased:
00678         if (state != READY) {
00679             delete context;
00680             return;
00681         }
00682     }
00683 
00684     //TODO must be removed
00685     if (context && stateCache.msg && stateCache.prox &&
00686         rpcId == PING_RECEIVED_STATE) {
00687         PingContext* pingContext = check_and_cast<PingContext*>(context);
00688         if (pingContext->nonce != stateCache.nonce) {
00689             delete context;
00690             return;
00691             //std::stringstream temp;
00692             //temp << thisNode << " timeout/call doesn't fit stateCache";
00693             //throw cRuntimeError(temp.str().c_str());
00694         }
00695         //const NodeHandle* node;
00696         switch (pingContext->stateObject) {
00697             case ROUTINGTABLE: {
00698                 /*if (pingContext->index >=
00699                     stateCache.msg->getRoutingTableArraySize()) {
00700                     std::cout << "*** FAILED ***" << std::endl;
00701                     break;
00702                 }
00703                 node = &(stateCache.msg->getRoutingTable(pingContext->index));
00704                 if((node->isUnspecified()) || (dest != *node)) {
00705                     std::cout << msg->getNonce() << " " << simTime() << " " << thisNode.getAddress() << " rt: state from "
00706                     << stateCache.msg->getSender().getAddress() << " *** failed: node "
00707                     << node->ip << " failed dest " << dest.getAddress() << std::endl;
00708                     break;
00709                 }*/
00710                 *(stateCache.prox->pr_rt.begin() + pingContext->index) =
00711                     PASTRY_PROX_INFINITE;
00712                 break;
00713             }
00714             case LEAFSET: {
00715                 /*if (pingContext->index >=
00716                     stateCache.msg->getLeafSetArraySize()) {
00717                     std::cout << "*** FAILED ***" << std::endl;
00718                     break;
00719                 }
00720                 node = &(stateCache.msg->getLeafSet(pingContext->index));
00721                 if((node->isUnspecified()) || (dest != *node)) {
00722                     std::cout << msg->getNonce() << " " << simTime() << " " << thisNode.getAddress() << " ls: state from "
00723                     << stateCache.msg->getSender().getAddress() << " *** failed: node "
00724                     << node->ip << " failed dest " << dest.getAddress() << std::endl;
00725                     break;
00726                 }*/
00727                 *(stateCache.prox->pr_ls.begin() + pingContext->index) =
00728                     PASTRY_PROX_INFINITE;
00729                 break;
00730             }
00731             case NEIGHBORHOODSET: {
00732                 /*if (pingContext->index >=
00733                     stateCache.msg->getNeighborhoodSetArraySize()) {
00734                     std::cout << "*** FAILED ***" << std::endl;
00735                     break;
00736                 }
00737                 node = &(stateCache.msg->getNeighborhoodSet(pingContext->index));
00738                 if((node->isUnspecified()) || (dest != *node)) {
00739                     std::cout << msg->getNonce() << " " << simTime() << " " << thisNode.getAddress() << " ns: state from "
00740                     << stateCache.msg->getSender().getAddress() << " *** failed: node "
00741                     << node->ip << " failed dest " << dest.getAddress() << std::endl;
00742                     break;
00743                 }*/
00744                 *(stateCache.prox->pr_ns.begin() + pingContext->index) =
00745                     PASTRY_PROX_INFINITE;
00746                 break;
00747             }
00748         }
00749         checkProxCache();
00750     }
00751 
00752     delete context;
00753 }

void BasePastry::prePing ( const PastryStateMessage *  stateMsg  )  [protected]

ping all nodes in a given state message.

this is called when a state message arrives while another one is still being processed.

Definition at line 439 of file BasePastry.cc.

Referenced by Pastry::doSecondStage(), Pastry::handleStateMessage(), and Bamboo::handleStateMessage().

00440 {
00441     uint32_t rt_size = stateMsg->getRoutingTableArraySize();
00442     uint32_t ls_size = stateMsg->getLeafSetArraySize();
00443     uint32_t ns_size = stateMsg->getNeighborhoodSetArraySize();
00444 
00445     for (uint32_t i = 0; i < rt_size + ls_size + ns_size; i++) {
00446         const NodeHandle* node;
00447         if (i < rt_size) {
00448             node = &(stateMsg->getRoutingTable(i));
00449         }
00450         else if (i < (rt_size + ls_size) ) {
00451             node = &(stateMsg->getLeafSet(i - rt_size));
00452         }
00453         else {
00454             node = &(stateMsg->getNeighborhoodSet(i - rt_size - ls_size));
00455         }
00456         if ((node->isUnspecified()) || (*node == thisNode)) {
00457             continue;
00458         }
00459         /*if (node->key == thisNode.getKey()) {
00460             cerr << "Pastry Warning: Other node with same key found, "
00461                 "restarting!" << endl;
00462             opp_error("TODO: Other node with same key found...");
00463             joinOverlay(); //segfault
00464             //return;
00465             continue;
00466         }*/
00467 
00468         neighborCache->getProx(*node, NEIGHBORCACHE_DEFAULT, PING_RECEIVED_STATE, this, NULL);
00469     }
00470 }

void BasePastry::proxCallback ( const TransportAddress node,
int  rpcId,
cPolymorphic *  contextPointer,
Prox  prox 
) [virtual]

Implements ProxListener.

Definition at line 375 of file BasePastry.cc.

00377 {
00378     Enter_Method("proxCallback()");
00379 
00380     EV << "[BasePastry::proxCallback() @ " << thisNode.getAddress()
00381            << " (" << thisNode.getKey().toString(16) << ")]\n"
00382            << "    Pong received (from "
00383            << node.getAddress() << ")"
00384            << endl;
00385 
00386     double rtt = ((prox == Prox::PROX_TIMEOUT) ? PASTRY_PROX_INFINITE
00387                                                : prox.proximity);
00388 
00389     // merge single pinged nodes (bamboo global tuning)
00390     if (rpcId == PING_SINGLE_NODE) {
00391         routingTable->mergeNode((const NodeHandle&)node,
00392                                 proximityNeighborSelection ?
00393                                 rtt : SimTime::getMaxTime());
00394         delete contextPointer;
00395         return;
00396     }
00397 
00398     if (contextPointer != NULL && stateCache.msg && stateCache.prox) {
00399         PingContext* pingContext = check_and_cast<PingContext*>(contextPointer);
00400 
00401         if (pingContext->nonce != stateCache.nonce) {
00402             delete contextPointer;
00403             return;
00404         }
00405         // handle failed node
00406         if (rtt == PASTRY_PROX_INFINITE && state== READY) {
00407             handleFailedNode(node); // TODO
00408             updateTooltip();
00409 
00410             // this could initiate a re-join, exit the handler in that
00411             // case because all local data was erased:
00412             if (state != READY) {
00413                 delete contextPointer;
00414                 return;
00415             }
00416         }
00417         switch (pingContext->stateObject) {
00418         case ROUTINGTABLE:
00419             *(stateCache.prox->pr_rt.begin() + pingContext->index) = rtt;
00420             break;
00421 
00422         case LEAFSET:
00423             *(stateCache.prox->pr_ls.begin() + pingContext->index) = rtt;
00424             break;
00425 
00426         case NEIGHBORHOODSET:
00427             *(stateCache.prox->pr_ns.begin() + pingContext->index) = rtt;
00428             break;
00429 
00430         default:
00431             throw cRuntimeError("wrong state object type!");
00432         }
00433         checkProxCache();
00434     }
00435     delete contextPointer;
00436 }

void BasePastry::purgeVectors ( void   )  [protected, virtual]

delete all information/messages caching vectors, used for restarting overlay or finish()

Reimplemented in Pastry.

Definition at line 40 of file BasePastry.cc.

Referenced by baseChangeState(), and ~BasePastry().

00041 {
00042     // purge Queue for processing multiple STATE messages:
00043     while (! stateCacheQueue.empty()) {
00044         delete stateCacheQueue.front().msg;
00045         delete stateCacheQueue.front().prox;
00046         stateCacheQueue.pop();
00047     }
00048 
00049     // delete cached state message:
00050     delete stateCache.msg;
00051     stateCache.msg = NULL;
00052     delete stateCache.prox;
00053     stateCache.prox = NULL;
00054 
00055     // purge vector of waiting sendState messages:
00056     if (! sendStateWait.empty()) {
00057         for (std::vector<PastrySendState*>::iterator it =
00058                  sendStateWait.begin(); it != sendStateWait.end(); it++) {
00059             if ( (*it)->isScheduled() ) cancelEvent(*it);
00060             delete *it;
00061         }
00062         sendStateWait.clear();
00063     }
00064 }

void BasePastry::sendLeafset ( const TransportAddress tell,
bool  pull = false 
) [protected]

send the leafset to a node

Parameters:
tell the node to send to
pull true requests his leafset

Definition at line 805 of file BasePastry.cc.

Referenced by Bamboo::doLeafsetMaintenance(), handleRequestMessage(), and Bamboo::handleUDPMessage().

00806 {
00807     if (tell.isUnspecified())
00808         opp_error("Pastry::sendLeafset(): send leafset to "
00809                   "unspecified node!");
00810 
00811     PastryLeafsetMessage* msg = new PastryLeafsetMessage("Leafset");
00812     if (pull) msg->setPastryMsgType(PASTRY_MSG_LEAFSET_PULL);
00813     else msg->setPastryMsgType(PASTRY_MSG_LEAFSET);
00814     msg->setTimestamp(simTime());
00815     msg->setStatType(MAINTENANCE_STAT);
00816     msg->setSender(thisNode);
00817     msg->setSendStateTo(thisNode);
00818     leafSet->dumpToStateMessage(msg);
00819     msg->setBitLength(PASTRYLEAFSET_L(msg));
00820     RECORD_STATS(leafsetSent++; leafsetBytesSent += msg->getByteLength());
00821     sendMessageToUDP(tell, msg);
00822 
00823 
00824 }

void BasePastry::sendRequest ( const TransportAddress ask,
int  type 
) [protected]

send a request to a given node

Parameters:
ask request from this node
type specifies the data requested

Definition at line 755 of file BasePastry.cc.

Referenced by Pastry::changeState(), Pastry::checkProxCache(), Pastry::doSecondStage(), Pastry::handleFailedNode(), and Pastry::handleStateMessage().

00756 {
00757     assert(ask != thisNode);
00758     std::string msgName("Req: ");
00759     switch (type) {
00760     case PASTRY_REQ_REPAIR:
00761         if (ask.isUnspecified())
00762             throw cRuntimeError("Pastry::sendRequest(): asked for repair from "
00763                                 "unspecified node!");
00764         msgName += "Repair";
00765         break;
00766 
00767     case PASTRY_REQ_STATE:
00768         if (ask.isUnspecified())
00769             throw cRuntimeError("Pastry::sendRequest(): asked for state from "
00770                                 "unspecified node!");
00771         msgName += "State";
00772         break;
00773 
00774     case PASTRY_REQ_LEAFSET:
00775         if (ask.isUnspecified())
00776             throw cRuntimeError("Pastry::sendRequest(): asked for leafset from "
00777                   "unspecified node!");
00778         msgName += "Leafset";
00779         break;
00780     }
00781     PastryRequestMessage* msg = new PastryRequestMessage(msgName.c_str());
00782     msg->setPastryMsgType(PASTRY_MSG_REQ);
00783     msg->setPastryReqType(type);
00784     msg->setStatType(MAINTENANCE_STAT);
00785     msg->setSendStateTo(thisNode);
00786     msg->setBitLength(PASTRYREQ_L(msg));
00787     sendMessageToUDP(ask, msg); //TODO RPCs
00788 
00789     switch (type) {
00790     case PASTRY_REQ_REPAIR:
00791         RECORD_STATS(repairReqSent++; repairReqBytesSent += msg->getByteLength());
00792         break;
00793 
00794     case PASTRY_REQ_STATE:
00795         RECORD_STATS(stateReqSent++; stateReqBytesSent += msg->getByteLength());
00796         break;
00797 
00798     case PASTRY_REQ_LEAFSET:
00799         RECORD_STATS(leafsetReqSent++; leafsetReqBytesSent += msg->getByteLength());
00800         break;
00801     }
00802 }

void BasePastry::sendRoutingRow ( const TransportAddress tell,
int  row 
) [protected]

send a row of the routing table to a node

Parameters:
tell the node to send to
row the number of the row

Definition at line 826 of file BasePastry.cc.

Referenced by Pastry::handleUDPMessage(), and Bamboo::handleUDPMessage().

00827 {
00828     if (tell.isUnspecified())
00829         opp_error("Pastry::sendRoutingTable(): asked for routing Table from "
00830                   "unspecified node!");
00831 
00832     PastryRoutingRowMessage* msg = new PastryRoutingRowMessage("Routing Row");
00833     msg->setPastryMsgType(PASTRY_MSG_RROW);
00834     msg->setStatType(MAINTENANCE_STAT);
00835     //msg->setSendStateTo(thisNode);
00836     msg->setSender(thisNode);
00837     msg->setRow(row);
00838     routingTable->dumpRowToMessage(msg, row);
00839     msg->setBitLength(PASTRYRTABLE_L(msg));
00840     RECORD_STATS(routingTableSent++; routingTableBytesSent += msg->getByteLength());
00841     sendMessageToUDP(tell, msg);
00842 }

void BasePastry::sendStateDelayed ( const TransportAddress destination  ) 

send a standard state message with a small delay

Parameters:
destination destination node

Definition at line 653 of file BasePastry.cc.

Referenced by Pastry::checkProxCache().

00654 {
00655     PastrySendState* selfMsg = new PastrySendState("sendStateWait");
00656     selfMsg->setDest(destination);
00657     sendStateWait.push_back(selfMsg);
00658     scheduleAt(simTime() + 0.0001, selfMsg);
00659 }

void BasePastry::sendStateTables ( const TransportAddress destination,
int  type = PASTRY_STATE_STD,
  ... 
)

send a PastryStateMessage directly to a node

Parameters:
destination destination node
type the type of the state message to be sent
... additional arguments for some types:
PASTRY_STATE_JOIN: int hops number of hops to destination node
PASTRY_STATE_JOIN: bool last mark the state message to originate from closest node found
PASTRY_STATE_UPDATE: simtime_t* timestamp pointer use this timestamp for the uptade message

Definition at line 571 of file BasePastry.cc.

Referenced by Pastry::doJoinUpdate(), Pastry::endProcessingState(), handleRequestMessage(), Pastry::handleTimerEvent(), Pastry::handleUDPMessage(), Pastry::iterativeJoinHook(), and Pastry::recursiveRoutingHook().

00573 {
00574     if (destination.getAddress() == thisNode.getAddress())
00575         opp_error("Pastry: trying to send state to self!");
00576 
00577     int hops = 0;
00578     bool last = false;
00579     simtime_t timestamp = 0;
00580 
00581     if ((type == PASTRY_STATE_JOIN) ||
00582         (type == PASTRY_STATE_MINJOIN) ||
00583         (type == PASTRY_STATE_UPDATE)) {
00584         // additional parameters needed:
00585         va_list ap;
00586         va_start(ap, type);
00587         if (type == PASTRY_STATE_JOIN || type == PASTRY_STATE_MINJOIN) {
00588             hops = va_arg(ap, int);
00589             last = static_cast<bool>(va_arg(ap, int));
00590         } else {
00591             timestamp = *va_arg(ap, simtime_t*);
00592         }
00593         va_end(ap);
00594     }
00595 
00596     // create new state msg and set special fields for some types:
00597     PastryStateMessage* stateMsg;
00598     if (type == PASTRY_STATE_JOIN || type == PASTRY_STATE_MINJOIN) {
00599         stateMsg = new PastryStateMessage("STATE (Join)");
00600         stateMsg->setJoinHopCount(hops);
00601         stateMsg->setLastHop(last);
00602         stateMsg->setTimestamp(simTime());
00603     } else if (type == PASTRY_STATE_UPDATE) {
00604         stateMsg = new PastryStateMessage("STATE (Update)");
00605         EV << "[BasePastry::sendStateTables() @ " << thisNode.getAddress()
00606            << " (" << thisNode.getKey().toString(16) << ")]\n"
00607            << "    sending state (update) to " << destination
00608            << endl;
00609         stateMsg->setTimestamp(timestamp);
00610     } else if (type == PASTRY_STATE_REPAIR) {
00611         stateMsg = new PastryStateMessage("STATE (Repair)");
00612         stateMsg->setTimestamp(timestamp);
00613         EV << "[BasePastry::sendStateTables() @ " << thisNode.getAddress()
00614            << " (" << thisNode.getKey().toString(16) << ")]\n"
00615            << "    sending state (repair) to " << destination
00616            << endl;
00617     } else {
00618         stateMsg = new PastryStateMessage("STATE");
00619         EV << "[BasePastry::sendStateTables() @ " << thisNode.getAddress()
00620            << " (" << thisNode.getKey().toString(16) << ")]\n"
00621            << "    sending state (standard) to " << destination
00622            << endl;
00623     }
00624 
00625     // fill in standard content:
00626     stateMsg->setPastryMsgType(PASTRY_MSG_STATE);
00627     stateMsg->setStatType(MAINTENANCE_STAT);
00628     stateMsg->setPastryStateMsgType(type);
00629     stateMsg->setSender(thisNode);
00630 
00631     // the following part of the new join works on the assumption, that the node
00632     // routing the join message is close to the joining node
00633     // therefore its switched on together with the discovery algorithm
00634     if (type == PASTRY_STATE_MINJOIN) {
00635         //send just the needed row for new join protocol
00636         routingTable->dumpRowToMessage(stateMsg, hops);
00637         if (last) leafSet->dumpToStateMessage(stateMsg);
00638         else stateMsg->setLeafSetArraySize(0);
00639         if (hops == 1) neighborhoodSet->dumpToStateMessage(stateMsg);
00640         else stateMsg->setNeighborhoodSetArraySize(0);
00641     } else {
00642         routingTable->dumpToStateMessage(stateMsg);
00643         leafSet->dumpToStateMessage(stateMsg);
00644         neighborhoodSet->dumpToStateMessage(stateMsg);
00645     }
00646 
00647     // send...
00648     stateMsg->setBitLength(PASTRYSTATE_L(stateMsg));
00649     RECORD_STATS(stateSent++; stateBytesSent += stateMsg->getByteLength());
00650     sendMessageToUDP(destination, stateMsg);
00651 }

void BasePastry::updateTooltip (  )  [virtual]

updates information shown in tk-environment

Definition at line 973 of file BasePastry.cc.

Referenced by baseChangeState(), Pastry::checkProxCache(), Bamboo::checkProxCache(), Pastry::doJoinUpdate(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), pingTimeout(), and proxCallback().

00974 {
00975     if (ev.isGUI()) {
00976         std::stringstream ttString;
00977 
00978         // show our predecessor and successor in tooltip
00979         ttString << leafSet->getPredecessor() << endl << thisNode << endl
00980                  << leafSet->getSuccessor();
00981 
00982         getParentModule()->getParentModule()->getDisplayString().
00983             setTagArg("tt", 0, ttString.str().c_str());
00984         getParentModule()->getDisplayString().
00985             setTagArg("tt", 0, ttString.str().c_str());
00986         getDisplayString().setTagArg("tt", 0, ttString.str().c_str());
00987 
00988         // draw arrows:
00989         showOverlayNeighborArrow(leafSet->getSuccessor(), true,
00990                                  "m=m,50,0,50,0;ls=red,1");
00991         showOverlayNeighborArrow(leafSet->getPredecessor(), false,
00992                                  "m=m,50,100,50,100;ls=green,1");
00993 
00994     }
00995 }


Friends And Related Function Documentation

friend class PastryLeafSet [friend]

Definition at line 366 of file BasePastry.h.


Member Data Documentation

Early update of leaf set: helper structure for marking known-dead nodes.

Definition at line 235 of file BasePastry.h.

Referenced by determineAliveTable(), Pastry::handleStateMessage(), and Bamboo::handleStateMessage().

bool BasePastry::alwaysSendUpdate [protected]

Definition at line 204 of file BasePastry.h.

Referenced by baseInit(), and Pastry::endProcessingState().

uint32_t BasePastry::bitsPerDigit [protected]

Definition at line 196 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), and Bamboo::doGlobalTuning().

Definition at line 161 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 162 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

bool BasePastry::enableNewLeafs [protected]

Definition at line 202 of file BasePastry.h.

Referenced by baseInit(), and newLeafs().

Definition at line 143 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and Pastry::handleUDPMessage().

Definition at line 141 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and Pastry::recursiveRoutingHook().

Definition at line 145 of file BasePastry.h.

Referenced by baseInit(), Pastry::changeState(), and finishOverlay().

uint32_t BasePastry::joinHopCount [protected]

Definition at line 139 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and Pastry::handleTimerEvent().

Definition at line 142 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and Pastry::handleUDPMessage().

Definition at line 134 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), and finishOverlay().

Definition at line 144 of file BasePastry.h.

Referenced by baseInit(), Pastry::changeState(), and finishOverlay().

cMessage* BasePastry::joinTimeout [protected]
double BasePastry::joinTimeoutAmount [protected]

Definition at line 200 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), Pastry::changeState(), and Bamboo::changeState().

Definition at line 138 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), and finishOverlay().

cMessage* BasePastry::joinUpdateWait [protected]
simtime_t BasePastry::lastStateChange [protected]

Definition at line 215 of file BasePastry.h.

Definition at line 169 of file BasePastry.h.

Referenced by baseInit(), Bamboo::changeState(), finishOverlay(), and sendLeafset().

Definition at line 167 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 165 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 166 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 164 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 168 of file BasePastry.h.

Referenced by baseInit(), Bamboo::changeState(), finishOverlay(), and sendLeafset().

bool BasePastry::nearNodeImproved [protected]
simtime_t BasePastry::nearNodeRtt [protected]

Definition at line 208 of file BasePastry.h.

Referenced by Pastry::changeState(), and Pastry::pingResponse().

uint32_t BasePastry::numberOfLeaves [protected]
uint32_t BasePastry::numberOfNeighbors [protected]

Definition at line 198 of file BasePastry.h.

Referenced by baseChangeState(), and baseInit().

bool BasePastry::optimizeLookup [protected]

Definition at line 205 of file BasePastry.h.

Referenced by baseInit(), and findNode().

Definition at line 213 of file BasePastry.h.

uint32_t BasePastry::pingedNodes [protected]

Definition at line 210 of file BasePastry.h.

Referenced by Pastry::handleTimerEvent(), and Pastry::handleUDPMessage().

cMessage* BasePastry::readyWait [protected]
double BasePastry::readyWaitAmount [protected]

Definition at line 199 of file BasePastry.h.

Referenced by Pastry::handleStateMessage(), and Pastry::initializeOverlay().

Definition at line 153 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 151 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 152 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 150 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

double BasePastry::repairTimeout [protected]

Definition at line 201 of file BasePastry.h.

Referenced by baseChangeState(), and baseInit().

Definition at line 159 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 178 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRoutingRow().

Definition at line 160 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 177 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRoutingRow().

Definition at line 181 of file BasePastry.h.

Referenced by baseInit(), and Bamboo::doLocalTuning().

std::vector<PastrySendState*> BasePastry::sendStateWait [protected]

Definition at line 247 of file BasePastry.h.

Referenced by Pastry::handleTimerEvent(), purgeVectors(), and sendStateDelayed().

Definition at line 147 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendStateTables().

Queue of state messages waiting to be processed in READY state.

Definition at line 230 of file BasePastry.h.

Referenced by Bamboo::checkProxCache(), Pastry::doSecondStage(), Pastry::endProcessingState(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), and purgeVectors().

Definition at line 157 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 155 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 156 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 154 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 146 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendStateTables().

Definition at line 158 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 203 of file BasePastry.h.

Referenced by baseInit(), and findNode().


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