Kademlia overlay module. More...
#include <Kademlia.h>
Public Member Functions | |
Kademlia () | |
~Kademlia () | |
void | initializeOverlay (int stage) |
Initializes derived-class-attributes. | |
void | finishOverlay () |
collects statistical data in derived class | |
void | joinOverlay () |
Join the overlay with a given nodeID in thisNode.key. | |
bool | isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err) |
Query if a node is among the siblings for a given key. | |
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(). | |
void | handleTimerEvent (cMessage *msg) |
bool | handleRpcCall (BaseCallMessage *msg) |
Processes Remote-Procedure-Call invocation messages. | |
Protected Member Functions | |
NodeVector * | findNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg) |
Implements the find node call. | |
void | handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
void | handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey) |
This method is called if an RPC timeout has been reached. | |
void | handleBucketRefreshTimerExpired () |
handle a expired bucket refresh timer | |
OverlayKey | distance (const OverlayKey &x, const OverlayKey &y, bool useAlternative=false) const |
This method should implement the distance between two keys. | |
void | updateTooltip () |
updates information shown in GUI | |
virtual void | lookupFinished (bool isValid) |
virtual void | handleNodeGracefulLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed if this node is among the gracefulLeaveProbability nodes. | |
Protected Attributes | |
uint32_t | k |
uint32_t | b |
uint32_t | s |
uint32_t | maxStaleCount |
bool | exhaustiveRefresh |
bool | pingNewSiblings |
bool | secureMaintenance |
if true, ping not authenticated nodes before adding them to a bucket | |
bool | newMaintenance |
bool | enableReplacementCache |
bool | replacementCachePing |
uint | replacementCandidates |
int | siblingRefreshNodes |
int | bucketRefreshNodes |
simtime_t | minSiblingTableRefreshInterval |
simtime_t | minBucketRefreshInterval |
simtime_t | siblingPingInterval |
cMessage * | bucketRefreshTimer |
cMessage * | siblingPingTimer |
Private Member Functions | |
void | routingInit () |
void | routingDeinit () |
int | routingBucketIndex (const OverlayKey &key, bool firstOnLayer=false) |
Returns the index of the bucket the key would reside with respect to Kademlia parameters. | |
KademliaBucket * | routingBucket (const OverlayKey &key, bool ensure) |
Returns a Bucket or NULL if the bucket has not yet allocated. | |
bool | routingAdd (const NodeHandle &handle, bool isAlive, simtime_t rtt=MAXTIME, bool maintenanceLookup=false) |
Adds a node to the routing table. | |
bool | routingTimeout (const OverlayKey &key, bool immediately=false) |
Removes a node after a number of timeouts or immediately if immediately is true (behaves like routingRemove). | |
void | refillSiblingTable () |
void | sendSiblingFindNodeCall (const TransportAddress &dest) |
void | setBucketUsage (const OverlayKey &key) |
bool | handleFailedNode (const TransportAddress &failed) |
Handles a failed node. | |
Private Attributes | |
uint32_t | bucketRefreshCount |
uint32_t | siblingTableRefreshCount |
uint32_t | nodesReplaced |
KeyDistanceComparator < KeyXorMetric > * | comparator |
KademliaBucket * | siblingTable |
std::vector< KademliaBucket * > | routingTable |
int | numBuckets |
Friends | |
class | KademliaLookupListener |
Kademlia overlay module.
Definition at line 44 of file Kademlia.h.
Kademlia::Kademlia | ( | ) |
Definition at line 155 of file Kademlia.cc.
00156 { 00157 siblingTable = NULL; 00158 comparator = NULL; 00159 bucketRefreshTimer = NULL; 00160 siblingPingTimer = NULL; 00161 }
Kademlia::~Kademlia | ( | ) |
Definition at line 163 of file Kademlia.cc.
00164 { 00165 routingDeinit(); 00166 00167 delete siblingTable; 00168 delete comparator; 00169 cancelAndDelete(bucketRefreshTimer); 00170 cancelAndDelete(siblingPingTimer); 00171 }
OverlayKey Kademlia::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).
x | Left-hand-side Key | |
y | Right-hand-side key | |
useAlternative | use an alternative distance metric |
Reimplemented from BaseOverlay.
Definition at line 1119 of file Kademlia.cc.
01122 { 01123 if (!useAlternative) return x^y; // KeyXorMetric().distance(x, y); 01124 return KeyPrefixMetric().distance(x, y); 01125 }
NodeVector * Kademlia::findNode | ( | const OverlayKey & | key, | |
int | numRedundantNodes, | |||
int | numSiblings, | |||
BaseOverlayMessage * | msg | |||
) | [protected, 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.
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. |
Reimplemented from BaseOverlay.
Definition at line 762 of file Kademlia.cc.
00764 { 00765 if (numSiblings > getMaxNumSiblings()) { 00766 opp_error("(Kademlia::findNode()) numRedundantNodes or numSiblings " 00767 "too big!"); 00768 } 00769 00770 #if 0 00771 if (numRedundantNodes < 2) { 00772 throw cRuntimeError("Kademlia::findNode(): For Kademlia " 00773 "redundantNodes must be at least 2 " 00774 "and lookupMerge should be true!"); 00775 } 00776 #endif 00777 00778 // create temporary comparator 00779 KeyDistanceComparator<KeyXorMetric>* comp = 00780 new KeyDistanceComparator<KeyXorMetric>( key ); 00781 00782 // select result set size 00783 bool err; 00784 int resultSize; 00785 00786 if (numSiblings < 0) { 00787 // exhaustive iterative doesn't care about siblings 00788 resultSize = numRedundantNodes; 00789 } else { 00790 resultSize = isSiblingFor(thisNode, key, numSiblings, &err) ? 00791 (numSiblings ? numSiblings : 1) : numRedundantNodes; 00792 } 00793 assert(numSiblings || numRedundantNodes); 00794 00795 NodeVector* result = new NodeVector(resultSize, comp); 00796 00797 if (siblingTable->isEmpty()) { 00798 result->add(thisNode); 00799 delete comp; 00800 return result; 00801 } 00802 00803 // add items from buckets 00804 int index; 00805 int mainIndex = routingBucketIndex(key); 00806 int startIndex = routingBucketIndex(key, true); 00807 int endIndex = routingBucketIndex(siblingTable->back().getKey()); 00808 00809 // add nodes from best fitting bucket 00810 if (mainIndex != -1) { 00811 KademliaBucket* bucket = routingTable[mainIndex]; 00812 if (bucket != NULL && bucket->size()) { 00813 for (KademliaBucket::iterator i=bucket->begin(); i!=bucket->end(); i++) { 00814 result->add(*i); 00815 //EV << "Kademlia::findNode(): Adding " 00816 // << *i << " from bucket " << mainIndex << endl; 00817 } 00818 } 00819 } 00820 00821 // add most fitting buckets 00822 if (startIndex >= endIndex || !result->isFull()) { 00823 for (index = startIndex; index >= endIndex; --index) { 00824 // add bucket to result vector 00825 if (index == mainIndex) continue; 00826 KademliaBucket* bucket = routingTable[index]; 00827 if (bucket != NULL && bucket->size()) { 00828 for (KademliaBucket::iterator i=bucket->begin(); i!=bucket->end(); i++) { 00829 result->add(*i); 00830 //EV << "Kademlia::routingGetClosestNodes(): Adding " 00831 // << *i << " from bucket " << index << endl; 00832 } 00833 } 00834 } 00835 00836 // add nodes from sibling table 00837 for (KademliaBucket::iterator i = siblingTable->begin(); 00838 i != siblingTable->end(); i++) { 00839 result->add(*i); 00840 } 00841 // add local node 00842 result->add(thisNode); 00843 } 00844 00845 // add more distant buckets 00846 for (index = mainIndex + 1; !result->isFull() && index < numBuckets; 00847 ++index) { 00848 // add bucket to result vector 00849 KademliaBucket* bucket = routingTable[index]; 00850 if (bucket != NULL && bucket->size()) { 00851 for (KademliaBucket::iterator i=bucket->begin(); i!=bucket->end(); i++) { 00852 result->add(*i); 00853 //EV << "[Kademlia::routingGetClosestNodes()]\n" 00854 // << " Adding " << *i << " from bucket " << index 00855 // << endl; 00856 } 00857 } 00858 } 00859 00860 delete comp; 00861 00862 return result; 00863 }
void Kademlia::finishOverlay | ( | ) | [virtual] |
collects statistical data in derived class
Reimplemented from BaseOverlay.
Definition at line 173 of file Kademlia.cc.
00174 { 00175 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00176 if (time < GlobalStatistics::MIN_MEASURED) return; 00177 00178 globalStatistics->addStdDev("Kademlia: Nodes replaced in buckets/s", 00179 nodesReplaced / time); 00180 globalStatistics->addStdDev("Kademlia: Bucket Refreshes/s", 00181 bucketRefreshCount / time); 00182 globalStatistics->addStdDev("Kademlia: Sibling Table Refreshes/s", 00183 siblingTableRefreshCount / time); 00184 }
int Kademlia::getMaxNumRedundantNodes | ( | ) | [virtual] |
Query the maximum number of redundant next hop nodes that are returned by findNode().
Reimplemented from BaseOverlay.
Definition at line 273 of file Kademlia.cc.
00274 { 00275 return k; 00276 }
int Kademlia::getMaxNumSiblings | ( | ) | [virtual] |
Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
Reimplemented from BaseOverlay.
Definition at line 268 of file Kademlia.cc.
Referenced by findNode(), isSiblingFor(), sendSiblingFindNodeCall(), and setBucketUsage().
00269 { 00270 return s; 00271 }
void Kademlia::handleBucketRefreshTimerExpired | ( | ) | [protected] |
handle a expired bucket refresh timer
Definition at line 1037 of file Kademlia.cc.
Referenced by handleTimerEvent().
01038 { 01039 // refresh buckets 01040 if (state != READY || (((simTime() - siblingTable->getLastUsage()) > 01041 minSiblingTableRefreshInterval))) { 01042 if (exhaustiveRefresh) { 01043 //TODO config shit 01044 int baseRedundantNodes = iterativeLookupConfig.redundantNodes; 01045 iterativeLookupConfig.redundantNodes = siblingRefreshNodes; 01046 createLookup(EXHAUSTIVE_ITERATIVE_ROUTING)->lookup( 01047 getThisNode().getKey(), siblingRefreshNodes, 01048 hopCountMax, 0, new KademliaLookupListener(this)); 01049 iterativeLookupConfig.redundantNodes = baseRedundantNodes; 01050 } else if (newMaintenance) { 01051 //for (KademliaBucket::iterator i = siblingTable->begin(); 01052 // i != siblingTable->end(); i++) { 01053 01054 // sendSiblingFindNodeCall(*i); 01055 //} 01056 if (siblingTable->size()) { 01057 sendSiblingFindNodeCall(siblingTable->at(intuniform(0,siblingTable->size()-1))); 01058 } 01059 state = READY; 01060 setOverlayReady(true); 01061 } else { 01062 createLookup()->lookup(getThisNode().getKey(), s, hopCountMax, 0, 01063 new KademliaLookupListener(this)); 01064 } 01065 siblingTable->setLastUsage(simTime()); 01066 ++siblingTableRefreshCount; 01067 } 01068 01069 if (state == READY) { 01070 if (siblingTable->size()) { 01071 // get bit index of most significant digit that differs 01072 // from our next sibling's key to prevent us from refreshing 01073 // buckets, which can't contain any nodes 01074 int32_t diff = OverlayKey::getLength() - b*(getThisNode().getKey(). 01075 sharedPrefixLength(siblingTable->front().getKey(), b) + 1); 01076 int bucketsRefreshedPerTask = 0; 01077 for (int32_t i = OverlayKey::getLength() - b; i >= diff; i -=b ) { 01078 for (int32_t d=0; d < ((1 << b) - 1); d++) { 01079 int32_t index = (i / b) * ((1 << b) - 1) + d; 01080 if (index < 0) continue; 01081 if ((routingTable[index] == NULL) || 01082 ((simTime() - routingTable[index]->getLastUsage()) > 01083 minBucketRefreshInterval)) { 01084 01085 OverlayKey refreshKey = 01086 getThisNode().getKey() ^ (OverlayKey(d+1) << i); 01087 01088 if (exhaustiveRefresh) { 01089 //TODO config stuff 01090 int baseRedundantNodes = iterativeLookupConfig.redundantNodes; 01091 iterativeLookupConfig.redundantNodes = bucketRefreshNodes; 01092 createLookup(EXHAUSTIVE_ITERATIVE_ROUTING)->lookup( 01093 refreshKey, bucketRefreshNodes, hopCountMax, 01094 0, new KademliaLookupListener(this)); 01095 iterativeLookupConfig.redundantNodes = baseRedundantNodes; 01096 } else { 01097 createLookup()->lookup(refreshKey, s, hopCountMax, 0, 01098 new KademliaLookupListener(this)); 01099 } 01100 01101 ++bucketsRefreshedPerTask; 01102 ++bucketRefreshCount; 01103 setBucketUsage(refreshKey); 01104 } 01105 } 01106 } 01107 RECORD_STATS(globalStatistics->recordOutVector( 01108 "Kademlia: Buckets Refreshed Per Task", 01109 bucketsRefreshedPerTask)); 01110 } 01111 // schedule next bucket refresh process 01112 cancelEvent(bucketRefreshTimer); 01113 scheduleAt(simTime() + (std::min(minSiblingTableRefreshInterval, 01114 minBucketRefreshInterval) / 10.0), bucketRefreshTimer); 01115 } 01116 }
bool Kademlia::handleFailedNode | ( | const TransportAddress & | failed | ) | [private, virtual] |
Handles a failed node.
This method is called whenever a node given by findNode() was unreachable. The default implementation does nothing at all.
failed | the failed node |
Reimplemented from BaseOverlay.
Definition at line 720 of file Kademlia.cc.
00721 { 00722 assert(!failed.isUnspecified()); 00723 00724 KademliaBucket::iterator i; 00725 // check sibling table 00726 for (i = siblingTable->begin(); i != siblingTable->end(); ++i) { 00727 if (failed == *i) break; 00728 } 00729 00730 if (i != siblingTable->end()) { 00731 // remove from sibling table 00732 NodeHandle oldSibling = *i; 00733 siblingTable->erase(i); 00734 00735 // call update() for removed sibling 00736 deleteOverlayNeighborArrow(oldSibling); 00737 callUpdate(oldSibling, false); 00738 00739 updateTooltip(); 00740 00741 // try to refill with new closest contact 00742 refillSiblingTable(); 00743 } else { 00744 // check buckets 00745 uint32_t m; 00746 for (m = 0; m < routingTable.size(); ++m) { 00747 if (routingTable[m] != NULL) { 00748 for (i = routingTable[m]->begin(); i != routingTable[m]->end(); 00749 ++i) { 00750 if (failed == *i) { 00751 // remove from routing table 00752 routingTable[m]->erase(i); 00753 return (siblingTable->size() != 0); 00754 } 00755 } 00756 } 00757 } 00758 } 00759 return (siblingTable->size() != 0); 00760 }
void Kademlia::handleNodeGracefulLeaveNotification | ( | ) | [protected, virtual] |
This method gets call **.gracefulLeaveDelay seconds before it is killed if this node is among the gracefulLeaveProbability nodes.
Reimplemented from BaseOverlay.
Definition at line 705 of file Kademlia.cc.
00706 { 00707 // send failed node call to all siblings 00708 FailedNodeCall* call = new FailedNodeCall(); 00709 call->setFailedNode(getThisNode()); 00710 call->setBitLength(FAILEDNODECALL_L(call)); 00711 for (KademliaBucket::iterator i = siblingTable->begin(); 00712 i != siblingTable->end(); i++) { 00713 countFailedNodeCall(call); 00714 sendUdpRpcCall(*i, call->dup()); 00715 } 00716 00717 delete call; 00718 }
bool Kademlia::handleRpcCall | ( | BaseCallMessage * | msg | ) | [virtual] |
Processes Remote-Procedure-Call invocation messages.
This method should be overloaded when the overlay provides RPC functionality.
Reimplemented from BaseRpc.
Definition at line 886 of file Kademlia.cc.
00887 { 00888 bool maintenanceLookup = (msg->getStatType() == MAINTENANCE_STAT); 00889 RPC_SWITCH_START(msg) 00890 RPC_ON_CALL(Ping) { 00891 // add active node 00892 OverlayCtrlInfo* ctrlInfo = 00893 check_and_cast<OverlayCtrlInfo*>(msg->getControlInfo()); 00894 routingAdd(ctrlInfo->getSrcRoute(), true, MAXTIME, maintenanceLookup); 00895 break; 00896 } 00897 RPC_ON_CALL(FindNode) 00898 { 00899 // add active node 00900 OverlayCtrlInfo* ctrlInfo = 00901 check_and_cast<OverlayCtrlInfo*>(msg->getControlInfo()); 00902 routingAdd(ctrlInfo->getSrcRoute(), true, MAXTIME, maintenanceLookup); 00903 break; 00904 } 00905 RPC_SWITCH_END() 00906 return false; 00907 }
void Kademlia::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [protected, virtual] |
This method is called if an RPC response has been received.
msg | The response message. | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
rtt | The Round-Trip-Time of this RPC |
Reimplemented from RpcListener.
Definition at line 910 of file Kademlia.cc.
00913 { 00914 bool maintenanceLookup = (msg->getStatType() == MAINTENANCE_STAT); 00915 OverlayCtrlInfo* ctrlInfo = 00916 dynamic_cast<OverlayCtrlInfo*>(msg->getControlInfo()); 00917 NodeHandle srcRoute = (ctrlInfo ? ctrlInfo->getSrcRoute() 00918 : msg->getSrcNode()); 00919 00920 RPC_SWITCH_START(msg) 00921 RPC_ON_RESPONSE(Ping) { 00922 if (state == INIT) { 00923 // schedule bucket refresh timer 00924 cancelEvent(bucketRefreshTimer); 00925 scheduleAt(simTime(), bucketRefreshTimer); 00926 cancelEvent(siblingPingTimer); 00927 scheduleAt(simTime() + siblingPingInterval, siblingPingTimer); 00928 state = JOIN; 00929 } 00930 } 00931 RPC_ON_RESPONSE(FindNode) 00932 { 00933 if (state == INIT) { 00934 state = JOIN; 00935 00936 // bootstrap node is trustworthy: add all nodes immediately 00937 routingAdd(srcRoute, true, rtt, maintenanceLookup); 00938 for (uint32_t i=0; i<_FindNodeResponse->getClosestNodesArraySize(); i++) 00939 routingAdd(_FindNodeResponse->getClosestNodes(i), true, 00940 MAXTIME-1, maintenanceLookup); 00941 00942 if (newMaintenance) { 00943 createLookup()->lookup(getThisNode().getKey(), s, hopCountMax, 0, 00944 new KademliaLookupListener(this)); 00945 } else { 00946 // schedule bucket refresh timer 00947 cancelEvent(bucketRefreshTimer); 00948 scheduleAt(simTime(), bucketRefreshTimer); 00949 cancelEvent(siblingPingTimer); 00950 scheduleAt(simTime() + siblingPingInterval, siblingPingTimer); 00951 } 00952 00953 break; 00954 } 00955 00956 // add active node 00957 if (defaultRoutingType == SEMI_RECURSIVE_ROUTING || 00958 defaultRoutingType == FULL_RECURSIVE_ROUTING || 00959 defaultRoutingType == RECURSIVE_SOURCE_ROUTING) { 00960 rtt = MAXTIME; 00961 } 00962 setBucketUsage(srcRoute.getKey()); 00963 00964 // add inactive nodes 00965 for (uint32_t i=0; i<_FindNodeResponse->getClosestNodesArraySize(); i++) 00966 routingAdd(_FindNodeResponse->getClosestNodes(i), false, 00967 MAXTIME, maintenanceLookup); 00968 break; 00969 } 00970 RPC_SWITCH_END() 00971 00972 // add node that responded 00973 routingAdd(srcRoute, true, rtt, maintenanceLookup); 00974 }
void Kademlia::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
cPolymorphic * | context, | |||
int | rpcId, | |||
const OverlayKey & | destKey | |||
) | [protected, virtual] |
This method is called if an RPC timeout has been reached.
msg | The original RPC message. | |
dest | The destination node | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
destKey | the destination OverlayKey |
Reimplemented from RpcListener.
Definition at line 977 of file Kademlia.cc.
00981 { 00982 if (dest.isUnspecified()) return; 00983 try { 00984 RPC_SWITCH_START(msg) 00985 RPC_ON_CALL(Ping) { 00986 if (state == INIT) { 00987 joinOverlay(); 00988 return; 00989 } 00990 00991 const NodeHandle& handle = dynamic_cast<const NodeHandle&>(dest); 00992 routingTimeout(handle.getKey()); 00993 break; 00994 } 00995 RPC_ON_CALL(FindNode) { 00996 if (state == INIT) { 00997 joinOverlay(); 00998 return; 00999 } 01000 01001 const NodeHandle& handle = dynamic_cast<const NodeHandle&>(dest); 01002 routingTimeout(handle.getKey()); 01003 setBucketUsage(handle.getKey()); 01004 break; 01005 } 01006 RPC_SWITCH_END() 01007 } catch (...) { 01008 EV << "[Kademlia:handleRpcTimout() @ " << thisNode.getAddress() 01009 << " (" << thisNode.getKey().toString(16) << ")]\n" 01010 << " ERROR: RPC timeout without key (" 01011 << msg << " -> " << dest << ")" << endl; 01012 return; 01013 } 01014 }
void Kademlia::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Reimplemented from BaseRpc.
Definition at line 868 of file Kademlia.cc.
00869 { 00870 if (msg == bucketRefreshTimer) { 00871 handleBucketRefreshTimerExpired(); 00872 } else if (msg == siblingPingTimer) { 00873 if (siblingPingInterval == 0) { 00874 return; 00875 } 00876 00877 for (KademliaBucket::iterator i = siblingTable->begin(); 00878 i != siblingTable->end(); i++) { 00879 pingNode(*i); 00880 } 00881 scheduleAt(simTime() + siblingPingInterval, msg); 00882 } 00883 }
void Kademlia::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 94 of file Kademlia.cc.
00095 { 00096 if (stage != MIN_STAGE_OVERLAY) 00097 return; 00098 00099 // Kademlia provides KBR services 00100 kbr = true; 00101 00102 // setup kademlia parameters 00103 minSiblingTableRefreshInterval = par("minSiblingTableRefreshInterval"); 00104 minBucketRefreshInterval = par("minBucketRefreshInterval"); 00105 siblingPingInterval = par("siblingPingInterval"); 00106 exhaustiveRefresh = par("exhaustiveRefresh"); 00107 maxStaleCount = par("maxStaleCount"); 00108 pingNewSiblings = par("pingNewSiblings"); 00109 enableReplacementCache = par("enableReplacementCache"); 00110 replacementCachePing = par("replacementCachePing"); 00111 replacementCandidates = par("replacementCandidates"); 00112 secureMaintenance = par("secureMaintenance"); 00113 newMaintenance = par("newMaintenance"); 00114 00115 k = par("k"); 00116 b = par("b"); 00117 s = par("s"); 00118 00119 siblingRefreshNodes = par("siblingRefreshNodes"); 00120 00121 if (siblingRefreshNodes <= 0) { 00122 siblingRefreshNodes = 5 * s; 00123 } 00124 00125 bucketRefreshNodes = par("bucketRefreshNodes"); 00126 00127 if (bucketRefreshNodes <= 0) { 00128 bucketRefreshNodes = iterativeLookupConfig.redundantNodes; 00129 } 00130 00131 // calculate number of buckets: ( (2^b)-1 ) * ( keylength / b ) 00132 numBuckets = ((1L << b) - 1L) * (OverlayKey::getLength() / b); 00133 00134 // init routing and sibling table 00135 siblingTable = new KademliaBucket(s * 5, NULL); 00136 00137 // initialize pointers 00138 routingTable.assign(numBuckets, (KademliaBucket*)NULL); 00139 00140 WATCH_VECTOR(*siblingTable); 00141 WATCH_VECTOR(routingTable); 00142 00143 // self-message 00144 bucketRefreshTimer = new cMessage("bucketRefreshTimer"); 00145 siblingPingTimer = new cMessage("siblingPingTimer"); 00146 00147 // statistics 00148 bucketRefreshCount = 0; 00149 siblingTableRefreshCount = 0; 00150 nodesReplaced = 0; 00151 00152 comparator = NULL; 00153 }
bool Kademlia::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.
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 |
Reimplemented from BaseOverlay.
Definition at line 629 of file Kademlia.cc.
Referenced by findNode().
00631 { 00632 if (key.isUnspecified()) 00633 error("Kademlia::isSiblingFor(): key is unspecified!"); 00634 00635 if (state != READY) { 00636 EV << "[Kademlia::isSiblingFor()] @ " 00637 << thisNode.getAddress() 00638 << " (" << thisNode.getKey().toString(16) << ")]\n" 00639 << " state != READY" 00640 << endl; 00641 *err = true; 00642 return false; 00643 } 00644 00645 if (numSiblings > getMaxNumSiblings()) { 00646 opp_error("Kademlia::isSiblingFor(): numSiblings too big!"); 00647 } 00648 00649 // set default number of siblings to consider 00650 if (numSiblings == -1) { 00651 numSiblings = getMaxNumSiblings(); 00652 } 00653 00654 if (numSiblings == 0) { 00655 *err = false; 00656 return (node.getKey() == key); 00657 } 00658 00659 if (siblingTable->size() < (uint)numSiblings) { 00660 *err = false; 00661 return true; 00662 } 00663 00664 if (siblingTable->isFull() && 00665 ((thisNode.getKey() ^ key) > 00666 (thisNode.getKey() ^ siblingTable->back().getKey()))) { 00667 EV << "[Kademlia::isSiblingFor()] @ " 00668 << thisNode.getAddress() 00669 << " (" << thisNode.getKey().toString(16) << ")]\n" 00670 << " Not sure if I am sibling for " << key << " !\n" 00671 << " (" << key << " is not closer to me than " 00672 << siblingTable->back().getKey() << ")" 00673 << endl; 00674 *err = true; 00675 return false; 00676 } 00677 00678 KeyDistanceComparator<KeyXorMetric>* comp = 00679 new KeyDistanceComparator<KeyXorMetric>(key); 00680 00681 // create result vector 00682 NodeVector* result = new NodeVector(numSiblings, comp); 00683 00684 for (KademliaBucket::iterator i=siblingTable->begin(); 00685 i != siblingTable->end(); i++) { 00686 result->add( *i); 00687 } 00688 00689 // add local node 00690 result->add(thisNode); 00691 00692 *err = false; 00693 delete comp; 00694 00695 if (result->contains(node.getKey())) { 00696 delete result; 00697 return true; 00698 } else { 00699 delete result; 00700 assert(!(numSiblings == 1 && key == node.getKey())); 00701 return false; 00702 } 00703 }
void Kademlia::joinOverlay | ( | ) | [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 197 of file Kademlia.cc.
Referenced by handleRpcTimeout(), and lookupFinished().
00198 { 00199 // remove current node handle from the bootstrap list 00200 if (!thisNode.getKey().isUnspecified()) { 00201 bootstrapList->removeBootstrapNode(thisNode); 00202 } 00203 00204 // initialize routing 00205 routingDeinit(); 00206 routingInit(); 00207 00208 TransportAddress handle = bootstrapList->getBootstrapNode(); 00209 00210 if (!handle.isUnspecified()) { 00211 if (secureMaintenance) { 00212 sendSiblingFindNodeCall(handle); 00213 } else { 00214 // ping the bootstrap node to start bootstrapping 00215 pingNode(handle); 00216 } 00217 } else { 00218 // we're the only node in the network 00219 state = READY; 00220 setOverlayReady(true); 00221 00222 // schedule bucket refresh timer 00223 cancelEvent(bucketRefreshTimer); 00224 scheduleAt(simTime(), bucketRefreshTimer); 00225 cancelEvent(siblingPingTimer); 00226 scheduleAt(simTime() + siblingPingInterval, siblingPingTimer); 00227 } 00228 }
void Kademlia::lookupFinished | ( | bool | isValid | ) | [protected, virtual] |
Definition at line 1016 of file Kademlia.cc.
Referenced by KademliaLookupListener::lookupFinished().
01017 { 01018 if (state == JOIN) { 01019 cancelEvent(bucketRefreshTimer); 01020 01021 if (siblingTable->size() == 0) { 01022 // initial lookup failed - get new bootstrap node 01023 joinOverlay(); 01024 return; 01025 } 01026 01027 scheduleAt(simTime(), bucketRefreshTimer); 01028 01029 if (!newMaintenance) { 01030 state = READY; 01031 setOverlayReady(true); 01032 } 01033 } 01034 }
void Kademlia::refillSiblingTable | ( | ) | [private] |
Definition at line 574 of file Kademlia.cc.
Referenced by handleFailedNode(), and routingTimeout().
00575 { 00576 if (siblingTable->size() == 0 || 00577 siblingTable->isFull()) 00578 return; 00579 00580 int index = routingBucketIndex(siblingTable->back().getKey()) - 1; 00581 assert(index > 0); 00582 00583 while ((routingTable[index] == NULL || 00584 routingTable[index]->empty()) && 00585 index < (int)(OverlayKey::getLength() - 1)) { 00586 index++; 00587 } 00588 if (index < (int)OverlayKey::getLength() && 00589 routingTable[index] != NULL && routingTable[index]->size()) { 00590 00591 KademliaBucket sortedBucket(k, comparator); 00592 for (uint32_t i = 0; i < routingTable[index]->size(); ++i) { 00593 sortedBucket.add(routingTable[index]->at(i)); 00594 } 00595 00596 siblingTable->add(sortedBucket.front()); 00597 00598 // call update() for new sibling 00599 if (!secureMaintenance) { 00600 showOverlayNeighborArrow(sortedBucket.front(), false, 00601 "m=m,50,100,50,100;ls=green,1"); 00602 callUpdate(sortedBucket.front(), true); 00603 } 00604 00605 // remove node from bucket 00606 routingTable[index]->erase(routingTable[index]-> 00607 findIterator(sortedBucket.front().getKey())); 00608 assert(siblingTable->isFull()); 00609 BUCKET_CONSISTENCY(routingTimeout: end refillSiblingTable()); 00610 } 00611 }
bool Kademlia::routingAdd | ( | const NodeHandle & | handle, | |
bool | isAlive, | |||
simtime_t | rtt = MAXTIME , |
|||
bool | maintenanceLookup = false | |||
) | [private] |
Adds a node to the routing table.
handle | handle to add | |
isAlive | true, if it is known that the node is alive | |
rtt | measured round-trip-time to node | |
maintenanceLookup | true, if this node was learned from a maintenance lookup |
maintenanceLookup ||
Definition at line 313 of file Kademlia.cc.
Referenced by handleRpcCall(), handleRpcResponse(), and routingTimeout().
00315 { 00316 BUCKET_CONSISTENCY(routingAdd: start); 00317 // never add unspecified node handles 00318 if (handle.isUnspecified() || handle.getKey() == getThisNode().getKey() ) 00319 return false; 00320 00321 // bucket index 00322 KademliaBucket::iterator i; 00323 bool result = false; 00324 bool authenticated = (isAlive && (rtt != MAXTIME)); 00325 00326 // convert node handle 00327 KademliaBucketEntry kadHandle = handle; 00328 kadHandle.setRtt(rtt); 00329 kadHandle.setLastSeen(simTime()); 00330 00331 /* check if node is already a sibling -----------------------------------*/ 00332 if ((i = siblingTable->findIterator(handle.getKey())) 00333 != siblingTable->end()) { 00334 // not alive? -> do not change routing information 00335 if (isAlive) { 00336 if (!secureMaintenance || authenticated) { 00337 if (kadHandle.getRtt() == MAXTIME) { 00338 kadHandle.setRtt(i->getRtt()); 00339 } 00340 // refresh sibling 00341 (*i) = kadHandle; 00342 } else { 00343 if (maintenanceLookup) { 00344 return false; 00345 } 00346 00347 if ((i->getAddress() != handle.getAddress()) || 00348 (i->getPort() != handle.getPort())) { 00349 // sibling could have changed transport address 00350 // ping new address for authentication 00351 pingNode(handle); 00352 return false; 00353 } 00354 } 00355 } 00356 BUCKET_CONSISTENCY(routingAdd: node is sibling); 00357 return true; 00358 } 00359 00360 /* check if node is already in a bucket ---------------------------------*/ 00361 KademliaBucket* bucket = routingBucket(handle.getKey(), false); 00362 if (bucket != NULL && (i = bucket->findIterator(handle.getKey() ) ) 00363 != bucket->end() ) { 00364 // not alive? -> do not change routing information 00365 if (isAlive) { 00366 if (!secureMaintenance || authenticated) { 00367 if (kadHandle.getRtt() == MAXTIME) { 00368 kadHandle.setRtt(i->getRtt()); 00369 } 00370 00371 // remove old handle 00372 bucket->erase(i); 00373 // re-add to tail 00374 bucket->push_back(kadHandle); 00375 } else { 00376 if (maintenanceLookup) { 00377 return false; 00378 } 00379 00380 if ((i->getAddress() != handle.getAddress()) || 00381 (i->getPort() != handle.getPort())) { 00382 // sibling could have changed transport address 00383 // ping new address for authentication 00384 pingNode(handle); 00385 return false; 00386 } 00387 } 00388 } 00389 00390 BUCKET_CONSISTENCY(routingAdd: node is in bucket); 00391 return true; 00392 } 00393 00394 /* check if node can be added to the sibling list -----------------------*/ 00395 if (siblingTable->isAddable(handle) ) { 00396 if (secureMaintenance && !authenticated) { 00397 if (!maintenanceLookup || (isAlive && (rtt == MAXTIME))) { 00398 // received a FindNodeCall or PingCall from a potential sibling 00399 // or new nodes from a FindNodeResponse app lookup 00400 pingNode(handle); 00401 } else if (newMaintenance) { 00402 // new node from sibling table refresh 00403 //sendSiblingFindNodeCall(handle); 00404 pingNode(handle); 00405 } 00406 return false; 00407 } 00408 00409 bool finished = false; 00410 int siblingPos = -1; 00411 00412 // check if sibling list is full so a handle is preemted from the list 00413 if (siblingTable->isFull()) { 00414 // get handle thats about to be preempted 00415 KademliaBucketEntry oldHandle = siblingTable->back(); 00416 assert(oldHandle.getKey() != kadHandle.getKey()); 00417 00418 // add handle to the sibling list 00419 siblingPos = siblingTable->add(kadHandle); 00420 00421 // change, so that the preempted handle is added to a bucket 00422 kadHandle = oldHandle; 00423 00424 // call update() for removed sibling 00425 if (!secureMaintenance) { 00426 deleteOverlayNeighborArrow(oldHandle); 00427 callUpdate(oldHandle, false); 00428 } 00429 00430 // return always true, since the handle has been added 00431 result = true; 00432 } else { 00433 // simply add the handle and stop 00434 siblingPos = siblingTable->add(kadHandle); 00435 00436 // don't need to add kadHandle also to regular buckets 00437 finished = true; 00438 } 00439 assert(siblingPos > -1); 00440 00441 // ping new siblings 00442 if ((pingNewSiblings && !isAlive)) { 00443 pingNode(handle); 00444 } 00445 00446 updateTooltip(); 00447 00448 // call update() for new sibling 00449 showOverlayNeighborArrow(handle, false, 00450 "m=m,50,100,50,100;ls=green,1"); 00451 callUpdate(handle, true); 00452 00453 if (finished) { 00454 BUCKET_CONSISTENCY(routingAdd: node is now sibling); 00455 return true; 00456 } 00457 } 00458 00459 /* add node to the appropriate bucket, if not full ---------------------*/ 00460 bucket = routingBucket(kadHandle.getKey(), true); 00461 if (!bucket->isFull()) { 00462 00463 if (secureMaintenance && !authenticated) { 00464 if ((isAlive && (rtt == MAXTIME))) { 00465 // received a FindNodeCall or PingCall from a potential new bucket entry 00466 // or new nodes from a FindNodeReponse app lookup 00467 // optimization: don't send a ping for nodes from FindNodeResponse for app lookups 00468 pingNode(kadHandle); 00469 } 00470 return false; 00471 } 00472 00473 EV << "[Kademlia::routingAdd()]\n" 00474 << " Adding new node " << kadHandle 00475 << " to bucket " << routingBucketIndex(kadHandle.getKey()) 00476 << endl; 00477 00478 bucket->push_back(kadHandle); 00479 result = true; 00480 } else if (isAlive) { 00481 if (enableReplacementCache && (!secureMaintenance || authenticated)) { 00482 bucket->replacementCache.push_front(kadHandle); 00483 if (bucket->replacementCache.size() > replacementCandidates) { 00484 bucket->replacementCache.pop_back(); 00485 } 00486 00487 if (replacementCachePing) { 00488 KademliaBucket::iterator it = bucket->begin(); 00489 while (it != bucket->end() && (it->getPingSent() == true)) { 00490 it++; 00491 } 00492 if (it != bucket->end()) { 00493 pingNode(*it); 00494 it->setPingSent(true); 00495 } 00496 } 00497 } 00498 } 00499 00500 BUCKET_CONSISTENCY(routingAdd: end); 00501 return result; 00502 }
KademliaBucket * Kademlia::routingBucket | ( | const OverlayKey & | key, | |
bool | ensure | |||
) | [private] |
Returns a Bucket or NULL
if the bucket has not yet allocated.
If ensure is true, the bucket allocation is ensured.
key | The key of the node | |
ensure | If true, the bucket allocation is ensured |
Definition at line 297 of file Kademlia.cc.
Referenced by routingAdd(), routingTimeout(), and setBucketUsage().
00298 { 00299 // get bucket index 00300 int num = routingBucketIndex(key); 00301 if (num < 0) 00302 return NULL; 00303 00304 // get bucket and allocate if necessary 00305 KademliaBucket* bucket = routingTable[ num ]; 00306 if (bucket == NULL && ensure) 00307 bucket = routingTable[ num ] = new KademliaBucket( k, comparator ); 00308 00309 // return bucket 00310 return bucket; 00311 }
int Kademlia::routingBucketIndex | ( | const OverlayKey & | key, | |
bool | firstOnLayer = false | |||
) | [private] |
Returns the index of the bucket the key would reside with respect to Kademlia parameters.
key | The key of the node | |
firstOnLayer | If true bucket with smallest index on same layer is returned |
Definition at line 278 of file Kademlia.cc.
Referenced by findNode(), refillSiblingTable(), routingAdd(), and routingBucket().
00279 { 00280 // calculate XOR distance 00281 OverlayKey delta = key ^ getThisNode().getKey(); 00282 00283 // find first subinteger that is not zero... 00284 int i; 00285 for (i = key.getLength() - b; i >= 0 && delta.getBitRange(i, b) == 0; 00286 i -= b); 00287 00288 if (i < 0) 00289 return -1; 00290 00291 if (!firstOnLayer) 00292 return (i / b) * ((1 << b) - 1) + (delta.getBitRange(i, b) - 1); 00293 else 00294 return (i / b) * ((1 << b) - 1) + (pow(2, b) - 2); 00295 }
void Kademlia::routingDeinit | ( | ) | [private] |
Definition at line 248 of file Kademlia.cc.
Referenced by joinOverlay(), and ~Kademlia().
00249 { 00250 // delete buckets 00251 for (uint32_t i = 0; i < routingTable.size(); i++) { 00252 if (routingTable[i] != NULL) { 00253 delete routingTable[i]; 00254 routingTable[i] = NULL; 00255 } 00256 } 00257 00258 if (siblingTable != NULL) { 00259 siblingTable->clear(); 00260 } 00261 00262 if (comparator != NULL) { 00263 delete comparator; 00264 comparator = NULL; 00265 } 00266 }
void Kademlia::routingInit | ( | ) | [private] |
Definition at line 232 of file Kademlia.cc.
Referenced by joinOverlay().
00233 { 00234 // set join state 00235 state = INIT; 00236 00237 setOverlayReady(false); 00238 00239 // setup comparator 00240 comparator = new KeyDistanceComparator<KeyXorMetric>(thisNode.getKey()); 00241 00242 siblingTable->setComparator(comparator); 00243 00244 updateTooltip(); 00245 BUCKET_CONSISTENCY(routingInit: end); 00246 }
bool Kademlia::routingTimeout | ( | const OverlayKey & | key, | |
bool | immediately = false | |||
) | [private] |
Removes a node after a number of timeouts or immediately if immediately is true (behaves like routingRemove).
key | Node's key to remove | |
immediately | If true, the node is removed immediately |
Definition at line 504 of file Kademlia.cc.
Referenced by handleRpcTimeout(), and refillSiblingTable().
00505 { 00506 BUCKET_CONSISTENCY(routingTimeout: start); 00507 // key unspecified? yes -> ignore 00508 if (key.isUnspecified()) 00509 return false; 00510 00511 // bucket index 00512 KademliaBucket::iterator i; 00513 00514 /* check if the node is one of the siblings -----------------------------*/ 00515 if ((i = siblingTable->findIterator(key)) != siblingTable->end()) { 00516 00517 i->incStaleCount(); 00518 i->setPingSent(false); 00519 00520 if (i->getStaleCount() > maxStaleCount || immediately) { 00521 // remove from sibling table 00522 NodeHandle oldSibling = *i; 00523 siblingTable->erase(i); 00524 00525 // lost last sibling? 00526 if (siblingTable->size() == 0) { 00527 join(); 00528 return true; 00529 } 00530 00531 BUCKET_CONSISTENCY(routingTimeout: is sibling); 00532 00533 // try to refill with new closest contact 00534 refillSiblingTable(); 00535 00536 // call update() for removed sibling 00537 deleteOverlayNeighborArrow(oldSibling); 00538 callUpdate(oldSibling, false); 00539 00540 updateTooltip(); 00541 00542 return true; 00543 } 00544 } 00545 00546 /* check if node is already in a bucket ---------------------------------*/ 00547 KademliaBucket* bucket = routingBucket(key, false); 00548 if (bucket != NULL && (i = bucket->findIterator(key) ) != bucket->end() ) { 00549 00550 i->incStaleCount(); 00551 i->setPingSent(false); 00552 00553 if (i->getStaleCount() > maxStaleCount || immediately) { 00554 // remove from routing table 00555 bucket->erase(i); 00556 00557 if (enableReplacementCache) { 00558 if (bucket->replacementCache.size()) { 00559 routingAdd(bucket->replacementCache.front(), true, 00560 bucket->replacementCache.front().getRtt()); 00561 bucket->replacementCache.pop_front(); 00562 nodesReplaced++; 00563 } 00564 } 00565 } 00566 00567 BUCKET_CONSISTENCY(routingTimeout: is in bucket); 00568 return true; 00569 } 00570 BUCKET_CONSISTENCY(routingTimeout: end); 00571 return false; 00572 }
void Kademlia::sendSiblingFindNodeCall | ( | const TransportAddress & | dest | ) | [private] |
Definition at line 186 of file Kademlia.cc.
Referenced by handleBucketRefreshTimerExpired(), and joinOverlay().
00187 { 00188 FindNodeCall* call = new FindNodeCall("FindNodeCall"); 00189 call->setExhaustiveIterative(true); 00190 call->setLookupKey(thisNode.getKey()); 00191 call->setNumRedundantNodes(siblingRefreshNodes); 00192 call->setNumSiblings(getMaxNumSiblings()); 00193 call->setBitLength(FINDNODECALL_L(call)); 00194 sendUdpRpcCall(dest, call); 00195 }
void Kademlia::setBucketUsage | ( | const OverlayKey & | key | ) | [private] |
Definition at line 613 of file Kademlia.cc.
Referenced by handleBucketRefreshTimerExpired(), handleRpcResponse(), and handleRpcTimeout().
00614 { 00615 KademliaBucket* bucket = routingBucket(key, true); 00616 00617 if (bucket) { 00618 bucket->setLastUsage(simTime()); 00619 } 00620 00621 if (((siblingTable->size() + 1) < (uint32_t)getMaxNumSiblings()) 00622 || ((siblingTable->at(getMaxNumSiblings() - 2).getKey() ^ thisNode.getKey()) 00623 >= (key ^ thisNode.getKey()))) { 00624 siblingTable->setLastUsage(simTime()); 00625 } 00626 00627 }
void Kademlia::updateTooltip | ( | ) | [protected] |
updates information shown in GUI
Definition at line 1127 of file Kademlia.cc.
Referenced by handleFailedNode(), routingAdd(), routingInit(), and routingTimeout().
01128 { 01129 if (ev.isGUI()) { 01130 std::stringstream ttString; 01131 01132 // show our nodeId in a tooltip 01133 ttString << "This: " << thisNode << endl << "Siblings: " 01134 << siblingTable->size(); 01135 01136 getParentModule()->getParentModule()->getDisplayString(). 01137 setTagArg("tt", 0, ttString.str().c_str()); 01138 getParentModule()->getDisplayString(). 01139 setTagArg("tt", 0, ttString.str().c_str()); 01140 getDisplayString().setTagArg("tt", 0, ttString.str().c_str()); 01141 } 01142 }
friend class KademliaLookupListener [friend] |
Definition at line 127 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), and handleRpcResponse().
uint32_t Kademlia::b [protected] |
Definition at line 49 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), initializeOverlay(), and routingBucketIndex().
uint32_t Kademlia::bucketRefreshCount [private] |
Definition at line 131 of file Kademlia.h.
Referenced by finishOverlay(), handleBucketRefreshTimerExpired(), and initializeOverlay().
int Kademlia::bucketRefreshNodes [protected] |
Definition at line 64 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), and initializeOverlay().
cMessage* Kademlia::bucketRefreshTimer [protected] |
Definition at line 70 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), handleRpcResponse(), handleTimerEvent(), initializeOverlay(), joinOverlay(), Kademlia(), lookupFinished(), and ~Kademlia().
KeyDistanceComparator<KeyXorMetric>* Kademlia::comparator [private] |
Definition at line 135 of file Kademlia.h.
Referenced by initializeOverlay(), Kademlia(), refillSiblingTable(), routingBucket(), routingDeinit(), routingInit(), and ~Kademlia().
bool Kademlia::enableReplacementCache [protected] |
Definition at line 60 of file Kademlia.h.
Referenced by initializeOverlay(), routingAdd(), and routingTimeout().
bool Kademlia::exhaustiveRefresh [protected] |
Definition at line 55 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), and initializeOverlay().
uint32_t Kademlia::k [protected] |
Definition at line 48 of file Kademlia.h.
Referenced by getMaxNumRedundantNodes(), initializeOverlay(), refillSiblingTable(), and routingBucket().
uint32_t Kademlia::maxStaleCount [protected] |
Definition at line 52 of file Kademlia.h.
Referenced by initializeOverlay(), and routingTimeout().
simtime_t Kademlia::minBucketRefreshInterval [protected] |
Definition at line 67 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), and initializeOverlay().
simtime_t Kademlia::minSiblingTableRefreshInterval [protected] |
Definition at line 66 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), and initializeOverlay().
bool Kademlia::newMaintenance [protected] |
Definition at line 58 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), handleRpcResponse(), initializeOverlay(), lookupFinished(), and routingAdd().
uint32_t Kademlia::nodesReplaced [private] |
Definition at line 133 of file Kademlia.h.
Referenced by finishOverlay(), initializeOverlay(), and routingTimeout().
int Kademlia::numBuckets [private] |
Definition at line 139 of file Kademlia.h.
Referenced by findNode(), and initializeOverlay().
bool Kademlia::pingNewSiblings [protected] |
Definition at line 56 of file Kademlia.h.
Referenced by initializeOverlay(), and routingAdd().
bool Kademlia::replacementCachePing [protected] |
Definition at line 61 of file Kademlia.h.
Referenced by initializeOverlay(), and routingAdd().
uint Kademlia::replacementCandidates [protected] |
Definition at line 62 of file Kademlia.h.
Referenced by initializeOverlay(), and routingAdd().
std::vector<KademliaBucket*> Kademlia::routingTable [private] |
Definition at line 138 of file Kademlia.h.
Referenced by findNode(), handleBucketRefreshTimerExpired(), handleFailedNode(), initializeOverlay(), refillSiblingTable(), routingBucket(), and routingDeinit().
uint32_t Kademlia::s [protected] |
Definition at line 50 of file Kademlia.h.
Referenced by getMaxNumSiblings(), handleBucketRefreshTimerExpired(), handleRpcResponse(), and initializeOverlay().
bool Kademlia::secureMaintenance [protected] |
if true, ping not authenticated nodes before adding them to a bucket
Definition at line 57 of file Kademlia.h.
Referenced by initializeOverlay(), joinOverlay(), refillSiblingTable(), and routingAdd().
simtime_t Kademlia::siblingPingInterval [protected] |
Definition at line 68 of file Kademlia.h.
Referenced by handleRpcResponse(), handleTimerEvent(), initializeOverlay(), and joinOverlay().
cMessage* Kademlia::siblingPingTimer [protected] |
Definition at line 71 of file Kademlia.h.
Referenced by handleRpcResponse(), handleTimerEvent(), initializeOverlay(), joinOverlay(), Kademlia(), and ~Kademlia().
int Kademlia::siblingRefreshNodes [protected] |
Definition at line 63 of file Kademlia.h.
Referenced by handleBucketRefreshTimerExpired(), initializeOverlay(), and sendSiblingFindNodeCall().
KademliaBucket* Kademlia::siblingTable [private] |
Definition at line 137 of file Kademlia.h.
Referenced by findNode(), handleBucketRefreshTimerExpired(), handleFailedNode(), handleNodeGracefulLeaveNotification(), handleTimerEvent(), initializeOverlay(), isSiblingFor(), Kademlia(), lookupFinished(), refillSiblingTable(), routingAdd(), routingDeinit(), routingInit(), routingTimeout(), setBucketUsage(), updateTooltip(), and ~Kademlia().
uint32_t Kademlia::siblingTableRefreshCount [private] |
Definition at line 132 of file Kademlia.h.
Referenced by finishOverlay(), handleBucketRefreshTimerExpired(), and initializeOverlay().