#include <Pastry.h>

Public Member Functions | |
| virtual | ~Pastry () |
| virtual void | initializeOverlay (int stage) |
| Initializes derived-class-attributes. | |
| virtual void | handleTimerEvent (cMessage *msg) |
| virtual void | handleUDPMessage (BaseOverlayMessage *msg) |
| Processes messages from underlay. | |
| void | handleStateMessage (PastryStateMessage *msg) |
| processes state messages, merging with own state tables | |
Protected Member Functions | |
| virtual void | changeState (int toState) |
| changes node state | |
Private Member Functions | |
| void | doSecondStage (void) |
| do the second stage of initialization as described in the paper | |
| bool | handleFailedNode (const TransportAddress &failed) |
| notifies leafset and routingtable of a failed node and sends out a repair request if possible | |
| void | checkProxCache (void) |
| checks whether proxCache is complete, takes appropriate actions depending on the protocol state | |
| void | processState (void) |
| bool | mergeState (void) |
| void | endProcessingState (void) |
| void | doJoinUpdate (void) |
| send updated state to all nodes when entering ready state | |
| virtual void | joinOverlay () |
| Join the overlay with a given nodeID in thisNode.key. | |
Private Attributes | |
| simtime_t | secondStageInterval |
| simtime_t | ringCheckInterval |
| simtime_t | discoveryTimeoutAmount |
| bool | partialJoinPath |
| int | depth |
| int | updateCounter |
| bool | useSecondStage |
| bool | sendStateAtLeafsetRepair |
| bool | pingBeforeSecondStage |
| bool | overrideOldPastry |
| bool | overrideNewPastry |
| cMessage * | secondStageWait |
| cMessage * | ringCheck |
| cMessage * | discoveryTimeout |
| cMessage * | repairTaskTimeout |
Definition at line 54 of file Pastry.h.
| Pastry::~Pastry | ( | ) | [virtual] |
Definition at line 41 of file Pastry.cc.
00042 { 00043 // destroy self timer messages 00044 cancelAndDelete(readyWait); 00045 cancelAndDelete(joinUpdateWait); 00046 cancelAndDelete(secondStageWait); 00047 cancelAndDelete(ringCheck); 00048 if (useDiscovery) cancelAndDelete(discoveryTimeout); 00049 if (routingTableMaintenanceInterval > 0) cancelAndDelete(repairTaskTimeout); 00050 }
| void Pastry::changeState | ( | int | toState | ) | [protected, virtual] |
changes node state
| toState | state to change to |
Reimplemented from BasePastry.
Definition at line 121 of file Pastry.cc.
Referenced by checkProxCache(), handleStateMessage(), handleTimerEvent(), and joinOverlay().
00122 { 00123 if (ringCheck->isScheduled()) cancelEvent(ringCheck); 00124 if (readyWait->isScheduled()) cancelEvent(readyWait); 00125 baseChangeState(toState); 00126 00127 switch (toState) { 00128 case INIT: 00129 cancelAllRpcs(); 00130 purgeVectors(); 00131 break; 00132 00133 case DISCOVERY: 00134 state = DISCOVERY; 00135 //nearNode = bootstrapNode; 00136 nearNodeRtt = MAXTIME; 00137 pingNode(bootstrapNode, discoveryTimeoutAmount, 0, 00138 NULL, "PING bootstrapNode in discovery mode", 00139 NULL, -1, UDP_TRANSPORT); //TODO 00140 sendRequest(bootstrapNode, PASTRY_REQ_LEAFSET); 00141 depth = -1; 00142 00143 break; 00144 00145 case JOINING_2: 00146 00147 joinHopCount = 0; 00148 00149 { 00150 PastryJoinMessage* msg = new PastryJoinMessage("JOIN-Request"); 00151 //TODO add timestamp to join msg 00152 msg->setPastryMsgType(PASTRY_MSG_JOIN); 00153 msg->setStatType(MAINTENANCE_STAT); 00154 //msg->setJoinHopCount(1); 00155 msg->setSendStateTo(thisNode); 00156 msg->setBitLength(PASTRYJOIN_L(msg)); 00157 RECORD_STATS(joinSent++; joinBytesSent += msg->getByteLength()); 00158 std::vector<TransportAddress> sourceRoute; 00159 sourceRoute.push_back(nearNode); 00160 sendToKey(thisNode.getKey(), msg, 0/*1*/, sourceRoute); 00161 00162 } 00163 00164 00165 break; 00166 00167 case READY: 00168 if (ringCheckInterval > 0) { 00169 scheduleAt(simTime()+ringCheckInterval, ringCheck); 00170 } 00171 00172 // determine list of all known nodes as notifyList 00173 notifyList.clear(); 00174 leafSet->dumpToVector(notifyList); 00175 routingTable->dumpToVector(notifyList); 00176 sort(notifyList.begin(), notifyList.end()); 00177 notifyList.erase(unique(notifyList.begin(), notifyList.end()), 00178 notifyList.end()); 00179 00180 // schedule update 00181 cancelEvent(joinUpdateWait); 00182 scheduleAt(simTime() + sendStateWaitAmount, joinUpdateWait); 00183 00184 // schedule second stage 00185 if (secondStageInterval > 0) { 00186 cancelEvent(secondStageWait); 00187 scheduleAt(simTime() + secondStageInterval, secondStageWait); 00188 } 00189 00190 // schedule routing table maintenance task 00191 if (routingTableMaintenanceInterval > 0) { 00192 cancelEvent(repairTaskTimeout); 00193 scheduleAt(simTime() + routingTableMaintenanceInterval, repairTaskTimeout); 00194 //leaf2ask = NULL; 00195 } 00196 00197 break; 00198 } 00199 }
| void Pastry::checkProxCache | ( | void | ) | [private, virtual] |
checks whether proxCache is complete, takes appropriate actions depending on the protocol state
Implements BasePastry.
Definition at line 656 of file Pastry.cc.
00657 { 00658 //std::cout << "checkProxCache()" << stateCache.msg << " " << stateCache.prox << std::endl; 00659 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00660 << " (" << thisNode.getKey().toString(16) << ")]" 00661 << endl; 00662 00663 // no cached STATE message? 00664 if (!(stateCache.msg && stateCache.prox)) return; 00665 00666 // no entries in stateCache.prox? 00667 if (stateCache.prox->pr_rt.empty() && 00668 stateCache.prox->pr_ls.empty() && 00669 stateCache.prox->pr_ns.empty()) 00670 throw new cRuntimeError("ERROR in Pastry: stateCache.prox empty!"); 00671 00672 /* 00673 //debug 00674 for (uint i = 0; i < stateCache.prox->pr_rt.size(); ++i) { 00675 if (stateCache.prox->pr_rt[i] == -3) 00676 EV << stateCache.msg->getRoutingTable(i).getAddress() << " "; 00677 } 00678 for (uint i = 0; i < stateCache.prox->pr_ls.size(); ++i) { 00679 if (stateCache.prox->pr_ls[i] == -3) 00680 EV << stateCache.msg->getLeafSet(i).getAddress() << " "; 00681 } 00682 for (uint i = 0; i < stateCache.prox->pr_ns.size(); ++i) { 00683 if (stateCache.prox->pr_ns[i] == -3) 00684 EV << stateCache.msg->getNeighborhoodSet(i).getAddress() << " "; 00685 } 00686 EV << endl; 00687 */ 00688 00689 // some entries not yet determined? 00690 if ((find(stateCache.prox->pr_rt.begin(), stateCache.prox->pr_rt.end(), 00691 PASTRY_PROX_PENDING) != stateCache.prox->pr_rt.end()) || 00692 (find(stateCache.prox->pr_ls.begin(), stateCache.prox->pr_ls.end(), 00693 PASTRY_PROX_PENDING) != stateCache.prox->pr_ls.end()) || 00694 (find(stateCache.prox->pr_ns.begin(), stateCache.prox->pr_ns.end(), 00695 PASTRY_PROX_PENDING) != stateCache.prox->pr_ns.end())) { 00696 //std::cout << "pending" << std::endl; 00697 return; 00698 } 00699 00700 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00701 << " (" << thisNode.getKey().toString(16) << ")]\n" 00702 << " all proximities for current STATE message from " 00703 << stateCache.msg->getSender().getAddress() 00704 << " collected!" 00705 << endl; 00706 /* 00707 //debug 00708 if (stateCache.prox != NULL) { 00709 std::vector<PastryStateMsgHandle>::iterator it; 00710 for (it = stReceived.begin(); it != stReceived.end(); ++it) { 00711 if (it->prox == NULL) { 00712 EV << ". " << endl; 00713 continue; 00714 } 00715 for (uint i = 0; i < it->prox->pr_rt.size(); ++i) { 00716 EV << it->prox->pr_rt[i] << " "; 00717 } 00718 for (uint i = 0; i < it->prox->pr_ls.size(); ++i) { 00719 EV << it->prox->pr_ls[i] << " "; 00720 } 00721 for (uint i = 0; i < it->prox->pr_ns.size(); ++i) { 00722 EV << it->prox->pr_ns[i] << " "; 00723 } 00724 EV << endl; 00725 } 00726 EV << endl; 00727 } else EV << "NULL" << endl; 00728 */ 00729 00730 simtime_t now = simTime(); 00731 00732 if (state == JOINING_2) { 00733 // save pointer to proximity vectors: 00734 stReceivedPos->prox = stateCache.prox; 00735 00736 // collected proximities for all STATE messages? 00737 if (++stReceivedPos == stReceived.end()) { 00738 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00739 << " (" << thisNode.getKey().toString(16) << ")]\n" 00740 << " proximities for all STATE messages collected!" 00741 << endl; 00742 stateCache.msg = NULL; 00743 stateCache.prox = NULL; 00744 if (debugOutput) { 00745 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00746 << " (" << thisNode.getKey().toString(16) << ")]\n" 00747 << " [JOIN] starting to build own state from " 00748 << stReceived.size() << " received state messages..." 00749 << endl; 00750 } 00751 if (mergeState()) { 00752 changeState(READY); 00753 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00754 << " (" << thisNode.getKey().toString(16) << ")]\n" 00755 << " changeState(READY) called" 00756 << endl; 00757 } else { 00758 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00759 << " (" << thisNode.getKey().toString(16) << ")]\n" 00760 << " Error initializing while joining! Restarting ..." 00761 << endl; 00762 join(); 00763 } 00764 00765 } else { 00766 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00767 << " (" << thisNode.getKey().toString(16) << ")]\n" 00768 << " NOT all proximities for all STATE messages collected!" 00769 << endl; 00770 for (uint32_t i = 0; i < stReceived.size(); ++i) { 00771 EV << ((i == 0) ? " " : " | "); 00772 if (stReceived[i].msg == stReceivedPos->msg) EV << "*"; 00773 EV << stReceived[i].msg; 00774 } 00775 EV << endl; 00776 00777 // process next state message in vector: 00778 if (stReceivedPos->msg == NULL) 00779 throw cRuntimeError("stReceivedPos->msg = NULL"); 00780 stateCache = *stReceivedPos; 00781 if (stateCache.msg == NULL) 00782 throw cRuntimeError("msg = NULL"); 00783 processState(); 00784 } 00785 } else { 00786 // state == READY 00787 if (stateCache.msg->getPastryStateMsgType() == PASTRY_STATE_REPAIR) { 00788 // try to repair routingtable based on repair message: 00789 const TransportAddress& askRt = 00790 routingTable->repair(stateCache.msg, stateCache.prox); 00791 if (! askRt.isUnspecified()) { 00792 sendRequest(askRt, PASTRY_REQ_REPAIR); 00793 } 00794 00795 // while not really known, it's safe to assume that a repair 00796 // message changed our state: 00797 lastStateChange = now; 00798 } else { 00799 if (stateCache.outdatedUpdate) { 00800 // send another STATE message on outdated state update: 00801 updateCounter++; 00802 sendStateDelayed(stateCache.msg->getSender()); 00803 } else { 00804 // merge info in own state tables 00805 // except leafset (was already handled in handleStateMessage) 00806 if (neighborhoodSet->mergeState(stateCache.msg, stateCache.prox)) 00807 lastStateChange = now; 00808 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00809 << " (" << thisNode.getKey().toString(16) << ")]\n" 00810 << " Merging nodes into routing table" 00811 << endl; 00812 if (routingTable->mergeState(stateCache.msg, stateCache.prox)) { 00813 lastStateChange = now; 00814 EV << "[Pastry::checkProxCache() @ " << thisNode.getAddress() 00815 << " (" << thisNode.getKey().toString(16) << ")]\n" 00816 << " Merged nodes into routing table" 00817 << endl; 00818 } 00819 } 00820 } 00821 updateTooltip(); 00822 00823 endProcessingState(); 00824 } 00825 }
| void Pastry::doJoinUpdate | ( | void | ) | [private] |
send updated state to all nodes when entering ready state
Definition at line 540 of file Pastry.cc.
Referenced by handleTimerEvent().
00541 { 00542 // send "update" state message to all nodes who sent us their state 00543 // during INIT, remove these from notifyList so they don't get our 00544 // state twice 00545 std::vector<TransportAddress>::iterator nListPos; 00546 if (!stReceived.empty()) { 00547 for (std::vector<PastryStateMsgHandle>::iterator it = 00548 stReceived.begin(); it != stReceived.end(); ++it) { 00549 simtime_t timestamp = it->msg->getTimestamp(); 00550 sendStateTables(it->msg->getSender(), PASTRY_STATE_UPDATE, 00551 ×tamp); 00552 nListPos = find(notifyList.begin(), notifyList.end(), 00553 it->msg->getSender()); 00554 if (nListPos != notifyList.end()) { 00555 notifyList.erase(nListPos); 00556 } 00557 delete it->msg; 00558 delete it->prox; 00559 } 00560 stReceived.clear(); 00561 } 00562 00563 // send a normal STATE message to all remaining known nodes 00564 for (std::vector<TransportAddress>::iterator it = 00565 notifyList.begin(); it != notifyList.end(); it++) { 00566 if (*it != thisNode) sendStateTables(*it, PASTRY_STATE_JOINUPDATE); 00567 } 00568 notifyList.clear(); 00569 00570 updateTooltip(); 00571 }
| void Pastry::doSecondStage | ( | void | ) | [private] |
do the second stage of initialization as described in the paper
Definition at line 573 of file Pastry.cc.
Referenced by handleTimerEvent().
00574 { 00575 getParentModule()->getParentModule()->bubble("entering SECOND STAGE"); 00576 00577 // probe nodes in local state 00578 if (leafSet->isValid()) { 00579 PastryStateMessage* stateMsg = new PastryStateMessage("STATE"); 00580 stateMsg->setPastryMsgType(PASTRY_MSG_STATE); 00581 stateMsg->setStatType(MAINTENANCE_STAT); 00582 stateMsg->setPastryStateMsgType(PASTRY_STATE_STD); 00583 stateMsg->setSender(thisNode); 00584 routingTable->dumpToStateMessage(stateMsg); 00585 leafSet->dumpToStateMessage(stateMsg); 00586 neighborhoodSet->dumpToStateMessage(stateMsg); 00587 //stateMsg->setBitLength(PASTRYSTATE_L(stateMsg)); 00588 PastryStateMsgHandle handle(stateMsg); 00589 00590 if (!stateCache.msg) { 00591 stateCache = handle; 00592 processState(); 00593 } else { 00594 stateCacheQueue.push(handle); 00595 prePing(stateMsg); 00596 } 00597 } 00598 00599 // "second stage" for locality: 00600 notifyList.clear(); 00601 routingTable->dumpToVector(notifyList); 00602 neighborhoodSet->dumpToVector(notifyList); 00603 sort(notifyList.begin(), notifyList.end()); 00604 notifyList.erase(unique(notifyList.begin(), notifyList.end()), 00605 notifyList.end()); 00606 for (std::vector<TransportAddress>::iterator it = notifyList.begin(); 00607 it != notifyList.end(); it++) { 00608 if (*it == thisNode) continue; 00609 EV << "[Pastry::doSecondStage() @ " << thisNode.getAddress() 00610 << " (" << thisNode.getKey().toString(16) << ")]\n" 00611 << " second stage: requesting state from " << *it 00612 << endl; 00613 sendRequest(*it, PASTRY_REQ_STATE); 00614 } 00615 notifyList.clear(); 00616 }
| void Pastry::endProcessingState | ( | void | ) | [private] |
Definition at line 827 of file Pastry.cc.
Referenced by checkProxCache(), and processState().
00828 { 00829 // if state message was not an update, send one back: 00830 if (stateCache.msg && 00831 stateCache.msg->getPastryStateMsgType() != PASTRY_STATE_UPDATE && 00832 (alwaysSendUpdate || lastStateChange == simTime()) && 00833 thisNode != stateCache.msg->getSender()) {//hack 00834 simtime_t timestamp = stateCache.msg->getTimestamp(); 00835 sendStateTables(stateCache.msg->getSender(), PASTRY_STATE_UPDATE, 00836 ×tamp); 00837 } 00838 00839 delete stateCache.msg; 00840 stateCache.msg = NULL; 00841 delete stateCache.prox; 00842 stateCache.prox = NULL; 00843 00844 // process next queued message: 00845 if (! stateCacheQueue.empty()) { 00846 stateCache = stateCacheQueue.front(); 00847 stateCacheQueue.pop(); 00848 processState(); 00849 } //TODO get rid of the delayed update messages... 00850 /*else { 00851 std::cout << thisNode.getAddress() << "\t" << simTime() 00852 << " all states processed (" 00853 << updateCounter << ")" << std::endl; 00854 updateCounter = 0; 00855 }*/ 00856 }
| bool Pastry::handleFailedNode | ( | const TransportAddress & | failed | ) | [private, virtual] |
notifies leafset and routingtable of a failed node and sends out a repair request if possible
| failed | the failed node |
Reimplemented from BaseOverlay.
Definition at line 618 of file Pastry.cc.
Referenced by handleUDPMessage().
00619 { 00620 if (state != READY) { 00621 return false; 00622 } 00623 bool wasValid = leafSet->isValid(); 00624 00625 //std::cout << thisNode.getAddress() << " is handling failed node: " << failed.getAddress() << std::endl; 00626 if (failed.isUnspecified()) 00627 opp_error("Pastry::handleFailedNode(): failed is unspecified!"); 00628 00629 const TransportAddress& lsAsk = leafSet->failedNode(failed); 00630 const TransportAddress& rtAsk = routingTable->failedNode(failed); 00631 neighborhoodSet->failedNode(failed); 00632 00633 if (! lsAsk.isUnspecified()) { 00634 newLeafs(); 00635 if (sendStateAtLeafsetRepair) sendRequest(lsAsk, PASTRY_REQ_REPAIR); 00636 else sendRequest(lsAsk, PASTRY_REQ_LEAFSET); 00637 } 00638 if (! rtAsk.isUnspecified() && 00639 (lsAsk.isUnspecified() || 00640 lsAsk != rtAsk)) sendRequest(rtAsk, PASTRY_REQ_REPAIR); 00641 00642 if (wasValid && lsAsk.isUnspecified() && (! leafSet->isValid())) { 00643 EV << "[Pastry::handleFailedNode() @ " << thisNode.getAddress() 00644 << " (" << thisNode.getKey().toString(16) << ")]\n" 00645 << " lost connection to the network, trying to re-join." 00646 << endl; 00647 //std::cout << thisNode.getAddress() << " Pastry: lost connection to the network, trying to re-join." 00648 // << std::endl; 00649 join(); 00650 return false; 00651 } 00652 00653 return true; 00654 }
| void Pastry::handleStateMessage | ( | PastryStateMessage * | msg | ) | [virtual] |
processes state messages, merging with own state tables
| msg | the pastry state message |
Implements BasePastry.
Definition at line 953 of file Pastry.cc.
Referenced by handleUDPMessage().
00954 { 00955 if (debugOutput) { 00956 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 00957 << " (" << thisNode.getKey().toString(16) << ")]\n" 00958 << " new STATE message to process " 00959 << static_cast<void*>(msg) << " in state " << 00960 ((state == READY)?"READY":((state == JOINING_2)?"JOIN":"INIT")) 00961 << endl; 00962 if (state == JOINING_2) { 00963 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 00964 << " (" << thisNode.getKey().toString(16) << ")]\n" 00965 << " *** own joinHopCount: " << joinHopCount << endl 00966 << " *** already received: " << stReceived.size() << endl 00967 << " *** last-hop flag: " 00968 << (msg->getLastHop() ? "true" : "false") << endl 00969 << " *** msg joinHopCount: " 00970 << msg->getJoinHopCount() << endl; 00971 } 00972 } 00973 if (state == INIT || state == DISCOVERY) { 00974 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 00975 << " (" << thisNode.getKey().toString(16) << ")]\n" 00976 << " can't handle state messages until at least reaching JOIN state." 00977 << endl; 00978 delete msg; 00979 return; 00980 } 00981 00982 PastryStateMsgHandle handle(msg); 00983 00984 // in JOIN state, store all received state Messages, need them later: 00985 if (state == JOINING_2) { 00986 //std::cout << simTime() << " " << thisNode.getAddress() << " " 00987 // << msg->getJoinHopCount() 00988 // << (msg->getLastHop() ? " *" : "") << std::endl; 00989 00990 if (msg->getPastryStateMsgType() != PASTRY_STATE_JOIN) { 00991 delete msg; 00992 return; 00993 } 00994 00995 if (joinHopCount && stReceived.size() == joinHopCount) { 00996 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 00997 << " (" << thisNode.getKey().toString(16) << ")]\n" 00998 << " Warning: dropping state message received after " 00999 << "all needed state messages were collected in JOIN state." 01000 << endl; 01001 delete msg; 01002 return; 01003 } 01004 01005 stReceived.push_back(handle); 01006 if (pingBeforeSecondStage) prePing(msg); 01007 01008 if (msg->getLastHop()) { 01009 if (joinTimeout->isScheduled()) { 01010 //std::cout << simTime() << " " << thisNode.getAddress() 01011 //<< " cancelEvent(joinTimeout), received:" 01012 //<< stReceived.size() << ", hopcount:" << joinHopCount << std::endl; 01013 cancelEvent(joinTimeout); 01014 } 01015 /*if (msg->getSender().getKey() == thisNode.getKey()) { 01016 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01017 << " (" << thisNode.getKey().toString(16) << ")]\n" 01018 << " Error: OverlayKey already in use, restarting!" 01019 << endl; 01020 //std::cout << "Pastry: Error: OverlayKey already in use, restarting!" 01021 // << std::endl; 01022 join(); 01023 return; 01024 }*/ 01025 01026 if (joinHopCount) { 01027 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01028 << " (" << thisNode.getKey().toString(16) << ")]\n" 01029 << " Error: received a second `last' state message! Restarting ..." 01030 << endl; 01031 //std::cout << thisNode.getAddress() << "Pastry: Error: received a second `last' state message! " 01032 // "Restarting ..." << std::endl; 01033 join(); 01034 return; 01035 } 01036 01037 joinHopCount = msg->getJoinHopCount(); 01038 //std::cout << stReceived.size() << " " << joinHopCount << std::endl; 01039 if (stReceived.size() < joinHopCount) { 01040 // some states still missing: 01041 cancelEvent(readyWait); 01042 scheduleAt(simTime() + readyWaitAmount, readyWait); 01043 //std::cout << simTime() << " " << thisNode.getAddress() << " readyWait scheduled!" << std::endl; 01044 } 01045 } 01046 01047 if (joinHopCount) { 01048 if (stReceived.size() > joinHopCount) { 01049 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01050 << " (" << thisNode.getKey().toString(16) << ")]\n" 01051 << " Error: too many state messages received in JOIN state! (" 01052 << stReceived.size() << " > " << joinHopCount << ") Restarting ..." 01053 << endl; 01054 //std::cout << " failed!" << std::endl; 01055 join(); 01056 return; 01057 } 01058 if (stReceived.size() == joinHopCount) { 01059 // all state messages are here, sort by hopcount: 01060 sort(stReceived.begin(), stReceived.end(), 01061 stateMsgIsSmaller); 01062 01063 // start pinging the nodes found in the first state message: 01064 stReceivedPos = stReceived.begin(); 01065 stateCache = *stReceivedPos; 01066 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01067 << " (" << thisNode.getKey().toString(16) << ")]\n" 01068 << " have all STATE messages, now pinging nodes." 01069 << endl; 01070 if (pingBeforeSecondStage) pingNodes(); 01071 else { 01072 mergeState(); // JOINING / stateCache 01073 //endProcessingState(); no way 01074 //stateCache.msg = NULL; //test 01075 changeState(READY); 01076 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01077 << " (" << thisNode.getKey().toString(16) << ")]\n" 01078 << " changeState(READY) called" 01079 << endl; 01080 } 01081 01082 // cancel timeout: 01083 if (readyWait->isScheduled()) cancelEvent(readyWait); 01084 } else { 01085 //TODO occasionally, here we got a wrong hop count in 01086 // iterative mode due to more than one it. lookup during join 01087 // procedure 01088 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01089 << " (" << thisNode.getKey().toString(16) << ")]\n" 01090 << " Still need some STATE messages." 01091 << endl; 01092 } 01093 01094 } 01095 return; 01096 } 01097 01098 if (debugOutput) { 01099 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01100 << " (" << thisNode.getKey().toString(16) << ")]\n" 01101 << " handling STATE message" 01102 << endl; 01103 EV << " type: " << ((msg->getPastryStateMsgType() 01104 == PASTRY_STATE_UPDATE) ? "update" 01105 :"standard") 01106 << endl; 01107 if (msg->getPastryStateMsgType() == PASTRY_STATE_UPDATE) { 01108 EV << " msg timestamp: " << 01109 msg->getTimestamp() << endl; 01110 EV << " last state change: " << 01111 lastStateChange << endl; 01112 } 01113 } 01114 01115 if (((msg->getPastryStateMsgType() == PASTRY_STATE_UPDATE)) 01116 && (msg->getTimestamp() <= lastStateChange)) { 01117 // if we received an update based on our outdated state, 01118 // mark handle for retrying later: 01119 EV << "[Pastry::handleStateMessage() @ " << thisNode.getAddress() 01120 << " (" << thisNode.getKey().toString(16) << ")]\n" 01121 << " outdated state from " << msg->getSender() 01122 << endl; 01123 handle.outdatedUpdate = true; 01124 } 01125 01126 // determine aliveTable to prevent leafSet from merging nodes that are 01127 // known to be dead: 01128 determineAliveTable(msg); 01129 01130 if (msg->getPastryStateMsgType() == PASTRY_STATE_REPAIR) { 01131 // try to repair leafset based on repair message right now 01132 const TransportAddress& askLs = leafSet->repair(msg, &aliveTable); 01133 if (! askLs.isUnspecified()) { 01134 sendRequest(askLs, PASTRY_REQ_REPAIR); 01135 } 01136 01137 // while not really known, it's safe to assume that a repair 01138 // message changed our state: 01139 lastStateChange = simTime(); 01140 newLeafs(); 01141 } else if (leafSet->mergeState(msg, &aliveTable)) { 01142 // merged state into leafset right now 01143 lastStateChange = simTime(); 01144 newLeafs(); 01145 updateTooltip(); 01146 } 01147 // in READY state, only ping nodes to get proximity metric: 01148 if (!stateCache.msg) { 01149 // no state message is processed right now, start immediately: 01150 stateCache = handle; 01151 processState(); 01152 } else { 01153 if (pingBeforeSecondStage || 01154 msg->getPastryStateMsgType() == PASTRY_STATE_STD) { 01155 // enqueue message for later processing: 01156 stateCacheQueue.push(handle); 01157 prePing(msg); 01158 } else { 01159 bool temp = true; 01160 if (!neighborhoodSet->mergeState(msg, NULL)) { 01161 temp = false; 01162 } 01163 if (!leafSet->mergeState(msg, NULL)) { 01164 temp = false; 01165 } else { 01166 newLeafs(); 01167 } 01168 if (!routingTable->mergeState(msg, NULL)) { 01169 temp = false; 01170 } 01171 if (temp) lastStateChange = simTime(); 01172 delete msg; 01173 } 01174 } 01175 }
| void Pastry::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Reimplemented from BaseRpc.
Definition at line 201 of file Pastry.cc.
00202 { 00203 00204 if (msg->isName("joinTimeout")) { 00205 EV << "[Pastry::handleTimerEvent() @ " << thisNode.getAddress() 00206 << " (" << thisNode.getKey().toString(16) << ")]\n" 00207 << " timeout expired, restarting..." 00208 << endl; 00209 //std::cout << simTime() << " " << thisNode.getAddress() << " " << stReceived.size() <<" Pastry: join timeout expired, restarting..." << std::endl; 00210 join(); 00211 } else if (msg->isName("readyWait")) { 00212 if (partialJoinPath) { 00213 RECORD_STATS(joinPartial++); 00214 sort(stReceived.begin(), stReceived.end(), stateMsgIsSmaller); 00215 00216 // start pinging the nodes found in the first state message: 00217 stReceivedPos = stReceived.begin(); 00218 stateCache = *stReceivedPos; 00219 EV << "[Pastry::handleTimerEvent() @ " << thisNode.getAddress() 00220 << " (" << thisNode.getKey().toString(16) << ")]\n" 00221 << " joining despite some missing STATE messages." 00222 << endl; 00223 processState(); 00224 /*if (pingBeforeSecondStage || 00225 stateCache.msg->getPastryStateMsgType() == PASTRY_STATE_STD) { 00226 pingNodes(); 00227 } else { 00228 mergeState(); //JOINING / stateCache 00229 endProcessingState(); 00230 //TODO -> READY 00231 }*/ 00232 } else { 00233 EV << "[Pastry::handleTimerEvent() @ " << thisNode.getAddress() 00234 << " (" << thisNode.getKey().toString(16) << ")]\n" 00235 << " timeout waiting for missing state messages in JOIN state, restarting..." 00236 << endl; 00237 //std::cout << thisNode.getAddress() << "Pastry: timeout waiting for missing state messages in JOIN " 00238 // "state, restarting..." << std::endl; 00239 join(); 00240 } 00241 } else if (msg->isName("joinUpdateWait")) { 00242 EV << "[Pastry::handleTimerEvent() @ " << thisNode.getAddress() 00243 << " (" << thisNode.getKey().toString(16) << ")]\n" 00244 << " sending state updates to all nodes." 00245 << endl; 00246 doJoinUpdate(); 00247 } else if (msg->isName("secondStageWait")) { 00248 EV << "[Pastry::handleTimerEvent() @ " << thisNode.getAddress() 00249 << " (" << thisNode.getKey().toString(16) << ")]\n" 00250 << " sending STATE requests to all nodes in second stage of initialization." 00251 << endl; 00252 doSecondStage(); 00253 } else if (msg->isName("ringCheck")) { 00254 if (state == READY) { 00255 // ping direct neighbors on the ring: 00256 const NodeHandle& pred = leafSet->getPredecessor(); 00257 const NodeHandle& succ = leafSet->getSuccessor(); 00258 if (! pred.isUnspecified()) { 00259 pingNode(pred, timeoutPing, pingRetries, 00260 NULL, "PING ring check"); 00261 } 00262 if (! succ.isUnspecified()) { 00263 pingNode(succ, timeoutPing, pingRetries, 00264 NULL, "PING ring check"); 00265 } 00266 } 00267 scheduleAt(simTime() + ringCheckInterval, ringCheck); 00268 } else if (msg->isName("sendStateWait")) { 00269 PastrySendState* sendStateMsg = check_and_cast<PastrySendState*>(msg); 00270 00271 std::vector<PastrySendState*>::iterator pos = 00272 std::find(sendStateWait.begin(), sendStateWait.end(), 00273 sendStateMsg); 00274 if (pos != sendStateWait.end()) sendStateWait.erase(pos); 00275 00276 sendStateTables(sendStateMsg->getDest()); 00277 delete sendStateMsg; 00278 } else if (msg->isName("discoveryTimeout")) { 00279 if ((depth == 0) && (nearNodeImproved)) { 00280 depth++; //repeat last step if closer node was found 00281 } 00282 if ((depth == 0) || (pingedNodes < 1)) { 00283 changeState(JOINING_2); 00284 } else { 00285 PastryRoutingRowRequestMessage* msg = new PastryRoutingRowRequestMessage("ROWREQ"); 00286 msg->setPastryMsgType(PASTRY_MSG_ROWREQ); 00287 msg->setStatType(MAINTENANCE_STAT); 00288 msg->setSendStateTo(thisNode); 00289 msg->setRow(depth); 00290 msg->setBitLength(PASTRYRTREQ_L(msg)); 00291 RECORD_STATS(routingTableReqSent++; routingTableReqBytesSent += msg->getByteLength()); 00292 sendMessageToUDP(nearNode, msg); 00293 } 00294 } else if (msg->isName("repairTaskTimeout")) { 00295 EV << "[Pastry::handleTimerEvent() @ " << thisNode.getAddress() 00296 << " (" << thisNode.getKey().toString(16) << ")]\n" 00297 << " starting routing table maintenance" 00298 << endl; 00299 doRoutingTableMaintenance(); 00300 scheduleAt(simTime() + routingTableMaintenanceInterval, repairTaskTimeout); 00301 } 00302 }
| void Pastry::handleUDPMessage | ( | BaseOverlayMessage * | msg | ) | [virtual] |
Processes messages from underlay.
| msg | Message from UDP |
Reimplemented from BaseOverlay.
Definition at line 304 of file Pastry.cc.
00305 { 00306 PastryMessage* pastryMsg = check_and_cast<PastryMessage*>(msg); 00307 uint32_t type = pastryMsg->getPastryMsgType(); 00308 00309 if (debugOutput) { 00310 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00311 << " (" << thisNode.getKey().toString(16) << ")]\n" 00312 << " incoming message of type "; 00313 switch(type) { 00314 case PASTRY_MSG_STD: 00315 EV << "PASTRY_MSG_STD"; 00316 break; 00317 case PASTRY_MSG_JOIN: 00318 EV << "PASTRY_MSG_JOIN"; 00319 break; 00320 case PASTRY_MSG_STATE: 00321 EV << "PASTRY_MSG_STATE"; 00322 break; 00323 case PASTRY_MSG_LEAFSET: 00324 EV << "PASTRY_MSG_LEAFSET"; 00325 break; 00326 case PASTRY_MSG_ROWREQ: 00327 EV << "PASTRY_MSG_ROWREQ"; 00328 break; 00329 case PASTRY_MSG_RROW: 00330 EV << "PASTRY_MSG_RROW"; 00331 break; 00332 case PASTRY_MSG_REQ: 00333 EV << "PASTRY_MSG_REQ"; 00334 break; 00335 default: 00336 EV << "UNKNOWN (" << type <<")"; 00337 break; 00338 } 00339 EV << endl; 00340 } 00341 00342 switch (type) { 00343 case PASTRY_MSG_STD: 00344 opp_error("Pastry received PastryMessage of unknown type!"); 00345 break; 00346 00347 case PASTRY_MSG_JOIN: { 00348 PastryJoinMessage* jmsg = 00349 check_and_cast<PastryJoinMessage*>(pastryMsg); 00350 RECORD_STATS(joinReceived++; joinBytesReceived += 00351 jmsg->getByteLength()); 00352 if (state != READY) { 00353 if (jmsg->getSendStateTo() == thisNode) { 00354 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00355 << " (" << thisNode.getKey().toString(16) << ")]\n" 00356 << " PastryJoinMessage received by originator!" 00357 << endl; 00358 } else { 00359 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00360 << " (" << thisNode.getKey().toString(16) << ")]\n" 00361 << " received join message before reaching " 00362 << "READY state, dropping message!" 00363 << endl; 00364 } 00365 } 00366 else if (jmsg->getSendStateTo() == thisNode) { 00367 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00368 << " (" << thisNode.getKey().toString(16) << ")]\n" 00369 << " PastryJoinMessage gets dropped because it is " 00370 << "outdated and has been received by originator!" 00371 << endl; 00372 } else { 00373 OverlayCtrlInfo* overlayCtrlInfo 00374 = check_and_cast<OverlayCtrlInfo*>(jmsg->getControlInfo()); 00375 00376 uint32_t joinHopCount = overlayCtrlInfo->getHopCount(); 00377 if ((joinHopCount > 1) && 00378 ((defaultRoutingType == ITERATIVE_ROUTING) || 00379 (defaultRoutingType == EXHAUSTIVE_ITERATIVE_ROUTING))) 00380 joinHopCount--; 00381 00382 // remove node from state if it is rejoining 00383 handleFailedNode(jmsg->getSendStateTo()); 00384 00385 sendStateTables(jmsg->getSendStateTo(), 00386 PASTRY_STATE_JOIN, joinHopCount, true); 00387 } 00388 00389 delete jmsg; 00390 } 00391 break; 00392 00393 case PASTRY_MSG_LEAFSET: { 00394 PastryLeafsetMessage* lmsg = 00395 check_and_cast<PastryLeafsetMessage*>(pastryMsg); 00396 RECORD_STATS(leafsetReceived++; leafsetBytesReceived += 00397 lmsg->getByteLength()); 00398 00399 if (state == DISCOVERY) { 00400 uint32_t lsSize = lmsg->getLeafSetArraySize(); 00401 const NodeHandle* node; 00402 pingedNodes = 0; 00403 00404 for (uint32_t i = 0; i < lsSize; i++) { 00405 node = &(lmsg->getLeafSet(i)); 00406 // unspecified nodes not considered 00407 if ( !(node->isUnspecified()) ) { 00408 pingNode(*node, discoveryTimeoutAmount, 0, 00409 NULL, "PING received leafs for nearest node", 00410 NULL, -1, UDP_TRANSPORT);//TODO 00411 pingedNodes++; 00412 } 00413 } 00414 00415 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00416 << " (" << thisNode.getKey().toString(16) << ")]\n" 00417 << " received leafset, waiting for pings" 00418 << endl; 00419 if (discoveryTimeout->isScheduled()) cancelEvent(discoveryTimeout); 00420 scheduleAt(simTime() + discoveryTimeoutAmount, discoveryTimeout); 00421 delete lmsg; 00422 } 00423 00424 else if (state == READY) { 00425 handleLeafsetMessage(lmsg, false); 00426 00427 } else { 00428 delete lmsg; 00429 } 00430 } 00431 break; 00432 00433 case PASTRY_MSG_ROWREQ: { 00434 PastryRoutingRowRequestMessage* rtrmsg = 00435 check_and_cast<PastryRoutingRowRequestMessage*>(pastryMsg); 00436 RECORD_STATS(routingTableReqReceived++; routingTableReqBytesReceived += 00437 rtrmsg->getByteLength()); 00438 if (state == READY) 00439 if (rtrmsg->getRow() == -1) 00440 sendRoutingRow(rtrmsg->getSendStateTo(), routingTable->getLastRow()); 00441 else if (rtrmsg->getRow() > routingTable->getLastRow()) 00442 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00443 << " (" << thisNode.getKey().toString(16) << ")]\n" 00444 << " received request for nonexistent routing" 00445 << "table row, dropping message!" 00446 << endl; 00447 else sendRoutingRow(rtrmsg->getSendStateTo(), rtrmsg->getRow()); 00448 else 00449 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00450 << " (" << thisNode.getKey().toString(16) << ")]\n" 00451 << " received routing table request before reaching " 00452 << "READY state, dropping message!" 00453 << endl; 00454 delete rtrmsg; 00455 } 00456 break; 00457 00458 case PASTRY_MSG_RROW: { 00459 PastryRoutingRowMessage* rtmsg = 00460 check_and_cast<PastryRoutingRowMessage*>(pastryMsg); 00461 RECORD_STATS(routingTableReceived++; routingTableBytesReceived += 00462 rtmsg->getByteLength()); 00463 00464 if (state == DISCOVERY) { 00465 uint32_t nodesPerRow = rtmsg->getRoutingTableArraySize(); 00466 const NodeHandle* node; 00467 if (depth == -1) { 00468 depth = rtmsg->getRow(); 00469 } 00470 pingedNodes = 0; 00471 nearNodeImproved = false; 00472 00473 if (depth > 0) { 00474 for (uint32_t i = 0; i < nodesPerRow; i++) { 00475 node = &(rtmsg->getRoutingTable(i)); 00476 // unspecified nodes not considered 00477 if ( !(node->isUnspecified()) ) { 00478 // we look for best connection here, so Timeout is short and there are no retries 00479 pingNode(*node, discoveryTimeoutAmount, 0, NULL, 00480 "PING received routing table for nearest node", 00481 NULL, -1, UDP_TRANSPORT); //TODO 00482 pingedNodes++; 00483 } 00484 } 00485 depth--; 00486 } 00487 EV << "[Pastry::handleUDPMessage() @ " << thisNode.getAddress() 00488 << " (" << thisNode.getKey().toString(16) << ")]\n" 00489 << " received routing table, waiting for pings" 00490 << endl; 00491 if (discoveryTimeout->isScheduled()) { 00492 cancelEvent(discoveryTimeout); 00493 } 00494 scheduleAt(simTime() + discoveryTimeoutAmount, discoveryTimeout); 00495 } 00496 00497 else if (state == READY) { 00498 00499 uint32_t nodesPerRow = rtmsg->getRoutingTableArraySize(); 00500 PastryStateMessage* stateMsg; 00501 00502 stateMsg = new PastryStateMessage("STATE"); 00503 stateMsg->setTimestamp(rtmsg->getTimestamp()); 00504 stateMsg->setPastryMsgType(PASTRY_MSG_STATE); 00505 stateMsg->setStatType(MAINTENANCE_STAT); 00506 stateMsg->setSender(rtmsg->getSender()); 00507 stateMsg->setLeafSetArraySize(0); 00508 stateMsg->setNeighborhoodSetArraySize(0); 00509 stateMsg->setRoutingTableArraySize(nodesPerRow); 00510 00511 for (uint32_t i = 0; i < nodesPerRow; i++) { 00512 stateMsg->setRoutingTable(i, rtmsg->getRoutingTable(i)); 00513 } 00514 00515 handleStateMessage(stateMsg); 00516 } 00517 00518 delete rtmsg; 00519 } 00520 break; 00521 00522 case PASTRY_MSG_REQ: { 00523 PastryRequestMessage* lrmsg = 00524 check_and_cast<PastryRequestMessage*>(pastryMsg); 00525 handleRequestMessage(lrmsg); 00526 } 00527 break; 00528 00529 case PASTRY_MSG_STATE: { 00530 PastryStateMessage* stateMsg = 00531 check_and_cast<PastryStateMessage*>(msg); 00532 RECORD_STATS(stateReceived++; stateBytesReceived += 00533 stateMsg->getByteLength()); 00534 handleStateMessage(stateMsg); 00535 } 00536 break; 00537 } 00538 }
| void Pastry::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 52 of file Pastry.cc.
00053 { 00054 if ( stage != MIN_STAGE_OVERLAY ) 00055 return; 00056 00057 // Pastry provides KBR services 00058 kbr = true; 00059 00060 baseInit(); 00061 00062 useDiscovery = par("useDiscovery"); 00063 pingBeforeSecondStage = par("pingBeforeSecondStage"); 00064 secondStageInterval = par("secondStageWait"); 00065 discoveryTimeoutAmount = par("discoveryTimeoutAmount"); 00066 routingTableMaintenanceInterval = par("repairTaskTimeoutAmount"); // TODO parameter into derived classes 00067 sendStateAtLeafsetRepair = par("sendStateAtLeafsetRepair"); 00068 ringCheckInterval = par("ringCheckInterval"); 00069 partialJoinPath = par("partialJoinPath"); 00070 readyWaitAmount = par("readyWait"); 00071 00072 overrideOldPastry = par("overrideOldPastry"); 00073 overrideNewPastry = par("overrideNewPastry"); 00074 00075 if (overrideOldPastry) { 00076 //useSecondStage = true; 00077 //secondStageInterval = ???; 00078 useDiscovery = false; 00079 sendStateAtLeafsetRepair = true; 00080 routingTableMaintenanceInterval = 0; 00081 } 00082 00083 if (overrideNewPastry) { 00084 //useSecondStage = false; 00085 secondStageInterval = 0; 00086 useDiscovery = true; 00087 discoveryTimeoutAmount = 0.4; 00088 routingTableMaintenanceInterval = 60; 00089 sendStateAtLeafsetRepair = false; 00090 } 00091 00092 joinTimeout = new cMessage("joinTimeout"); 00093 readyWait = new cMessage("readyWait"); 00094 secondStageWait = new cMessage("secondStageWait"); 00095 joinUpdateWait = new cMessage("joinUpdateWait"); 00096 ringCheck = new cMessage("ringCheck"); 00097 00098 if (useDiscovery) discoveryTimeout = new cMessage("discoveryTimeout"); 00099 if (routingTableMaintenanceInterval > 0) repairTaskTimeout = 00100 new cMessage("repairTaskTimeout"); 00101 00102 sendPullFlag = false; 00103 updateCounter = 0; 00104 }
| void Pastry::joinOverlay | ( | ) | [private, virtual] |
Join the overlay with a given nodeID in thisNode.key.
Join the overlay with a given nodeID in thisNode.key. This method may be called by an application to join the overlay with a specific nodeID. It is also called if the node's IP address changes.
Reimplemented from BaseOverlay.
Definition at line 106 of file Pastry.cc.
00107 { 00108 changeState(INIT); 00109 00110 if (bootstrapNode.isUnspecified()) { 00111 // no existing pastry network -> first node of a new one 00112 changeState(READY); 00113 } else { 00114 // join existing pastry network 00115 nearNode = bootstrapNode; 00116 if (useDiscovery) changeState(DISCOVERY); 00117 else changeState(JOINING_2); 00118 } 00119 }
| bool Pastry::mergeState | ( | void | ) | [private] |
Definition at line 858 of file Pastry.cc.
Referenced by checkProxCache(), handleStateMessage(), and processState().
00859 { 00860 bool ret = true; 00861 00862 if (state == JOINING_2) { 00863 // building initial state 00864 if (debugOutput) { 00865 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00866 << " (" << thisNode.getKey().toString(16) << ")]\n" 00867 << " [JOIN] starting to build own state from " 00868 << stReceived.size() << " received state messages..." 00869 << endl; 00870 } 00871 if (stateCache.msg && 00872 stateCache.msg->getNeighborhoodSetArraySize() > 0) { 00873 if (debugOutput) { 00874 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00875 << " (" << thisNode.getKey().toString(16) << ")]\n" 00876 << " [JOIN] initializing NeighborhoodSet from " 00877 << stReceived.front().msg->getJoinHopCount() << ". hop" 00878 << endl; 00879 } 00880 if (!neighborhoodSet->mergeState(stReceived.front().msg, 00881 stReceived.front().prox )) { 00882 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00883 << " (" << thisNode.getKey().toString(16) << ")]\n" 00884 << " Error initializing own neighborhoodSet while joining! Restarting ..." 00885 << endl; 00886 ret = false; 00887 } 00888 } 00889 if (debugOutput) { 00890 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00891 << " (" << thisNode.getKey().toString(16) << ")]\n" 00892 << " [JOIN] initializing LeafSet from " 00893 << stReceived.back().msg->getJoinHopCount() << ". hop" 00894 << endl; 00895 } 00896 00897 assert(!stateCache.msg || stateCache.msg->getLeafSetArraySize() > 0); 00898 00899 if (!leafSet->mergeState(stReceived.back().msg, 00900 stReceived.back().prox )) { 00901 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00902 << " (" << thisNode.getKey().toString(16) << ")]\n" 00903 << " Error initializing own leafSet while joining! Restarting ..." 00904 << endl; 00905 //std::cout << "Pastry: Error initializing own leafSet while " 00906 // "joining! Restarting ..." << std::endl; 00907 ret = false; 00908 } else { 00909 newLeafs(); 00910 } 00911 if (debugOutput) { 00912 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00913 << " (" << thisNode.getKey().toString(16) << ")]\n" 00914 << " [JOIN] initializing RoutingTable from all hops" 00915 << endl; 00916 } 00917 00918 assert(!stateCache.msg || 00919 stateCache.msg->getRoutingTableArraySize() > 0); 00920 00921 if (!routingTable->initStateFromHandleVector(stReceived)) { 00922 EV << "[Pastry::mergeState() @ " << thisNode.getAddress() 00923 << " (" << thisNode.getKey().toString(16) << ")]\n" 00924 << " Error initializing own routingTable while joining! Restarting ..." 00925 << endl; 00926 //std::cout << "Pastry: Error initializing own routingTable " 00927 // "while joining! Restarting ..." << std::endl; 00928 00929 ret = false; 00930 } 00931 stateCache.msg = NULL; 00932 stateCache.prox = NULL; 00933 } else if (state == READY) { 00934 // merging singe state (stateCache.msg) 00935 if ((stateCache.msg->getNeighborhoodSetArraySize() > 0) && 00936 (!neighborhoodSet->mergeState(stateCache.msg, NULL))) { 00937 ret = false; 00938 } 00939 if (!leafSet->mergeState(stateCache.msg, NULL)) { 00940 ret = false; 00941 } else { 00942 newLeafs(); 00943 } 00944 if (!routingTable->mergeState(stateCache.msg, NULL)) { 00945 ret = false; 00946 } 00947 } 00948 00949 if (ret) lastStateChange = simTime(); 00950 return ret; 00951 }
| void Pastry::processState | ( | void | ) | [private] |
Definition at line 1177 of file Pastry.cc.
Referenced by checkProxCache(), doSecondStage(), endProcessingState(), handleStateMessage(), and handleTimerEvent().
01178 { 01179 if (pingBeforeSecondStage || 01180 stateCache.msg->getPastryStateMsgType() == PASTRY_STATE_STD) { 01181 pingNodes(); 01182 } else { 01183 mergeState(); 01184 endProcessingState(); 01185 } 01186 }
int Pastry::depth [private] |
Definition at line 86 of file Pastry.h.
Referenced by changeState(), handleTimerEvent(), and handleUDPMessage().
cMessage* Pastry::discoveryTimeout [private] |
Definition at line 99 of file Pastry.h.
Referenced by handleUDPMessage(), initializeOverlay(), and ~Pastry().
simtime_t Pastry::discoveryTimeoutAmount [private] |
Definition at line 83 of file Pastry.h.
Referenced by changeState(), handleUDPMessage(), and initializeOverlay().
bool Pastry::overrideNewPastry [private] |
bool Pastry::overrideOldPastry [private] |
bool Pastry::partialJoinPath [private] |
bool Pastry::pingBeforeSecondStage [private] |
Definition at line 92 of file Pastry.h.
Referenced by handleStateMessage(), initializeOverlay(), and processState().
cMessage* Pastry::repairTaskTimeout [private] |
Definition at line 100 of file Pastry.h.
Referenced by changeState(), handleTimerEvent(), initializeOverlay(), and ~Pastry().
cMessage* Pastry::ringCheck [private] |
Definition at line 98 of file Pastry.h.
Referenced by changeState(), handleTimerEvent(), initializeOverlay(), and ~Pastry().
simtime_t Pastry::ringCheckInterval [private] |
Definition at line 82 of file Pastry.h.
Referenced by changeState(), handleTimerEvent(), and initializeOverlay().
simtime_t Pastry::secondStageInterval [private] |
cMessage* Pastry::secondStageWait [private] |
Definition at line 97 of file Pastry.h.
Referenced by changeState(), initializeOverlay(), and ~Pastry().
bool Pastry::sendStateAtLeafsetRepair [private] |
int Pastry::updateCounter [private] |
bool Pastry::useSecondStage [private] |
1.5.8