Permalink
Browse files

Adding managed connection count management. Nodes per bucket is now h…

…andled via a configuration option. Currently the oldest node is always chosen, which still needs fixed.
  • Loading branch information...
1 parent 0d08622 commit a5698163a8625f80079cc1c4193c2446491c5b4e @reines committed Mar 29, 2012
View
@@ -188,6 +188,7 @@ simtime-scale=-9
**.overlay*.kademlia.enableDownlistsForwarding = true
**.overlay*.kademlia.routingTableStatsDelay = 10s
**.overlay*.kademlia.enableManagedConnections = false
+**.overlay*.kademlia.managedConnectionBucketLimit = 1
# R/Kademlia
**.overlay*.kademlia.activePing = false
View
@@ -15,19 +15,22 @@ description = Kademlia (SimpleUnderlayNetwork)
# Kademlia
**.overlayType = "oversim.overlay.kademlia.KademliaModules"
-**.overlay*.kademlia.lookupRedundantNodes = 2 # k?
-**.overlay*.kademlia.lookupParallelRpcs = 2 # k?
+**.overlay*.kademlia.lookupRedundantNodes = 8 # k?
+**.overlay*.kademlia.lookupParallelRpcs = 8 # k?
**.overlay*.kademlia.secureMaintenance = false
**.overlay*.kademlia.minBucketRefreshInterval = 36000s
**.overlay*.kademlia.maxStaleCount = 0
-**.overlay*.kademlia.k = 2
+**.overlay*.kademlia.k = 8
**.overlay*.kademlia.enableDownlists = false
-**.overlay*.kademlia.enableManagedConnections = ${true, false}
+
+# Managed connections
+**.overlay*.kademlia.enableManagedConnections = true
+**.overlay*.kademlia.managedConnectionBucketLimit = 1
# S/Kademlia
**.overlay*.kademlia.minSiblingTableRefreshInterval = 36000s
**.overlay*.kademlia.siblingPingInterval = 0s
-**.overlay*.kademlia.s = 2
+**.overlay*.kademlia.s = 8
**.overlay*.kademlia.pingNewSiblings = false
**.overlay*.kademlia.siblingRefreshNodes = 0
@@ -176,12 +176,13 @@ void Kademlia::initializeOverlay(int stage)
}
enableManagedConnections = par("enableManagedConnections");
+ managedConnectionBucketLimit = par("managedConnectionBucketLimit");
// calculate number of buckets: ( (2^b)-1 ) * ( keylength / b )
numBuckets = ((1L << b) - 1L) * (OverlayKey::getLength() / b);
// init routing and sibling table
- siblingTable = new KademliaBucket(s * 5, NULL);
+ siblingTable = new KademliaBucket(this, s * 5, NULL);
// initialize pointers
routingTable.assign(numBuckets, (KademliaBucket*)NULL);
@@ -446,7 +447,7 @@ KademliaBucket* Kademlia::routingBucket(const OverlayKey& key, bool ensure)
if (bucket == NULL && ensure)
{
int bucketSize = routingBucketSize(num);
- bucket = routingTable[ num ] = new KademliaBucket( bucketSize, comparator );
+ bucket = routingTable[ num ] = new KademliaBucket( this, bucketSize, comparator );
}
// return bucket
@@ -682,7 +683,7 @@ bool Kademlia::routingAdd(const NodeHandle& handle, bool isAlive,
currentRoutingTableSize++;
if (enableManagedConnections)
- openManagedConnection(kadHandle);
+ bucket->updateManagedConnections();
result = true;
}
@@ -720,7 +721,7 @@ bool Kademlia::routingAdd(const NodeHandle& handle, bool isAlive,
currentRoutingTableSize++;
if (enableManagedConnections)
- openManagedConnection(kadHandle);
+ bucket->updateManagedConnections();
result = true;
} else if (isAlive) {
@@ -743,7 +744,7 @@ bool Kademlia::routingAdd(const NodeHandle& handle, bool isAlive,
if (enableManagedConnections) {
closeManagedConnection(*kickHim);
- openManagedConnection(kadHandle);
+ bucket->updateManagedConnections();
}
kadHandle = temp;
@@ -870,7 +871,7 @@ void Kademlia::refillSiblingTable()
if (index < (int)OverlayKey::getLength() &&
routingTable[index] != NULL && routingTable[index]->size()) {
- KademliaBucket sortedBucket(k, comparator);
+ KademliaBucket sortedBucket(this, k, comparator);
for (uint32_t i = 0; i < routingTable[index]->size(); ++i) {
sortedBucket.add(routingTable[index]->at(i));
}
@@ -1487,9 +1488,6 @@ void Kademlia::handleRpcTimeout(BaseCallMessage* msg,
void Kademlia::openManagedConnection(NodeHandle handle)
{
KademliaBucket* bucket = routingBucket(handle.getKey(), false);
-// if (bucket->hasManagedConnections())
-// return;
-
TransportAddress address = TransportAddress(handle.getIp(), localPort);
managedConnections.insert(std::make_pair(address, handle));
@@ -1524,14 +1522,7 @@ void Kademlia::handleConnectionEvent(EvCode code, TransportAddress address)
bucket->decManagedConnections();
managedConnections.erase(it);
-// if (!bucket->hasManagedConnections()) {
-// // We now have no managed connection in this bucket, replace it
-//
-// KademliaBucket::iterator it = bucket->begin();
-// if (it != bucket->end()) {
-// openManagedConnection(*it);
-// }
-// }
+ bucket->updateManagedConnections();
if (code == PEER_TIMEDOUT || code == PEER_REFUSED || code == CONNECTION_RESET)
routingTimeout(handle.getKey(), true);
@@ -106,6 +106,7 @@ class Kademlia : public BaseOverlay, public ProxListener
bool enableDownlistsForwarding;
bool enableManagedConnections;
+ uint32_t managedConnectionBucketLimit; /*< maximum number of managed connections in each bucket */
std::map<TransportAddress, NodeHandle> managedConnections;
simtime_t minSiblingTableRefreshInterval;
@@ -184,6 +185,7 @@ class Kademlia : public BaseOverlay, public ProxListener
virtual void handleNodeGracefulLeaveNotification();
friend class KademliaLookupListener;
+ friend class KademliaBucket;
// Managed connection support
@@ -64,6 +64,7 @@ simple Kademlia extends BaseOverlay
int extraNodesFinalBucket; // number of extra nodes in bucket 0 for NR128
bool enableDownlists; // toggle downlists on/off
bool enableManagedConnections; // toggle managed connections on/off
+ int managedConnectionBucketLimit; // maximum number of managed connections in each bucket
bool enableDownlistsForwarding; // toggle downlists being forwarded to siblings
}
@@ -22,11 +22,13 @@
#include "KademliaBucket.h"
+#include "Kademlia.h"
-KademliaBucket::KademliaBucket(uint16_t maxSize,
- const Comparator<OverlayKey>* comparator)
- : BaseKeySortedVector< KademliaBucketEntry >(maxSize, comparator)
+KademliaBucket::KademliaBucket(Kademlia* overlay, uint16_t maxSize, const Comparator<OverlayKey>* comparator)
+ : BaseKeySortedVector< KademliaBucketEntry >(maxSize, comparator)
{
+ this->overlay = overlay;
+
lastUsage = -1;
managedConnections = 0;
}
@@ -35,6 +37,24 @@ KademliaBucket::~KademliaBucket()
{
}
+void KademliaBucket::updateManagedConnections()
+{
+ std::cout << overlay->getThisNode().getKey() << ": " << this->countManagedConnections() << std::endl;
+
+ // If all nodes in this bucket (if any) have managed connections, stop
+ if (this->size() <= this->countManagedConnections())
+ return;
+
+ // If we have enough managed connections in this bucket, stop
+ if (this->countManagedConnections() >= overlay->managedConnectionBucketLimit)
+ return;
+
+ // Choose which node to upgrade to a managed connection, and do so
+ KademliaBucketEntry* handle = this->getOldestNode(); // TODO
+
+ overlay->openManagedConnection(*handle);
+}
+
KademliaBucketEntry* KademliaBucket::getOldestNode()
{
if (this->isEmpty())
@@ -48,3 +68,4 @@ KademliaBucketEntry* KademliaBucket::getOldestNode()
return &this->at(oldest);
}
+
@@ -20,14 +20,16 @@
#include "KademliaNodeHandle.h"
+class Kademlia;
+
/**
* @file KademliaBucket.h
* @author Sebastian Mies, Ingmar Baumgart, Bernhard Heep
*/
class KademliaBucket : public BaseKeySortedVector< KademliaBucketEntry > {
public:
- KademliaBucket(uint16_t maxSize=0,
+ KademliaBucket(Kademlia* overlay, uint16_t maxSize=0,
const Comparator<OverlayKey>* comparator = NULL);
~KademliaBucket();
@@ -48,21 +50,20 @@ class KademliaBucket : public BaseKeySortedVector< KademliaBucketEntry > {
this->managedConnections--;
}
- inline bool hasManagedConnections() {
- return this->managedConnections > 0;
- }
-
inline int countManagedConnections() {
return this->managedConnections;
}
+
+ void updateManagedConnections();
KademliaBucketEntry* getOldestNode();
std::list<KademliaBucketEntry> replacementCache;
-private:
+protected:
simtime_t lastUsage;
int managedConnections;
+ Kademlia* overlay;
};
#endif

0 comments on commit a569816

Please sign in to comment.