00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <IPAddressResolver.h>
00025
00026 #include "DHT.h"
00027
00028 #include <RpcMacros.h>
00029 #include <BaseRpc.h>
00030 #include <GlobalStatistics.h>
00031
00032 Define_Module(DHT);
00033
00034 using namespace std;
00035
00036 DHT::DHT()
00037 {
00038 dataStorage = NULL;
00039 }
00040
00041 DHT::~DHT()
00042 {
00043 PendingRpcs::iterator it;
00044
00045 for (it = pendingRpcs.begin(); it != pendingRpcs.end(); it++) {
00046 delete(it->second.putCallMsg);
00047 delete(it->second.getCallMsg);
00048 }
00049
00050 pendingRpcs.clear();
00051
00052 if (dataStorage != NULL) {
00053 dataStorage->clear();
00054 }
00055 }
00056
00057 void DHT::initializeApp(int stage)
00058 {
00059 if (stage != MIN_STAGE_APP)
00060 return;
00061
00062 dataStorage = check_and_cast<DHTDataStorage*>
00063 (getParentModule()->getSubmodule("dhtDataStorage"));
00064
00065 numReplica = par("numReplica");
00066 numGetRequests = par("numGetRequests");
00067 ratioIdentical = par("ratioIdentical");
00068 secureMaintenance = par("secureMaintenance");
00069 invalidDataAttack = par("invalidDataAttack");
00070 maintenanceAttack = par("maintenanceAttack");
00071
00072 if ((int)numReplica > overlay->getMaxNumSiblings()) {
00073 opp_error("DHT::initialize(): numReplica bigger than what this "
00074 "overlay can handle (%d)", overlay->getMaxNumSiblings());
00075 }
00076
00077 maintenanceMessages = 0;
00078 normalMessages = 0;
00079 numBytesMaintenance = 0;
00080 numBytesNormal = 0;
00081 WATCH(maintenanceMessages);
00082 WATCH(normalMessages);
00083 WATCH(numBytesNormal);
00084 WATCH(numBytesMaintenance);
00085 WATCH_MAP(pendingRpcs);
00086 }
00087
00088 void DHT::handleTimerEvent(cMessage* msg)
00089 {
00090 DHTTtlTimer* msg_timer = dynamic_cast<DHTTtlTimer*> (msg);
00091
00092 if (msg_timer) {
00093 EV << "[DHT::handleTimerEvent()]\n"
00094 << " received timer ttl, key: "
00095 << msg_timer->getKey().toString(16)
00096 << "\n (overlay->getThisNode().getKey() = "
00097 << overlay->getThisNode().getKey().toString(16) << ")"
00098 << endl;
00099
00100 dataStorage->removeData(msg_timer->getKey(), msg_timer->getKind(),
00101 msg_timer->getId());
00102 }
00103 }
00104
00105 bool DHT::handleRpcCall(BaseCallMessage* msg)
00106 {
00107 RPC_SWITCH_START(msg)
00108
00109 RPC_DELEGATE(DHTPut, handlePutRequest);
00110 RPC_DELEGATE(DHTGet, handleGetRequest);
00111
00112 RPC_DELEGATE(DHTputCAPI, handlePutCAPIRequest);
00113 RPC_DELEGATE(DHTgetCAPI, handleGetCAPIRequest);
00114 RPC_DELEGATE(DHTdump, handleDumpDhtRequest);
00115 RPC_SWITCH_END( )
00116
00117 return RPC_HANDLED;
00118 }
00119
00120 void DHT::handleRpcResponse(BaseResponseMessage* msg, cPolymorphic* context,
00121 int rpcId, simtime_t rtt)
00122 {
00123 RPC_SWITCH_START(msg)
00124 RPC_ON_RESPONSE(DHTPut){
00125 handlePutResponse(_DHTPutResponse, rpcId);
00126 EV << "[DHT::handleRpcResponse()]\n"
00127 << " DHT Put RPC Response received: id=" << rpcId
00128 << " msg=" << *_DHTPutResponse << " rtt=" << rtt
00129 << endl;
00130 break;
00131 }
00132 RPC_ON_RESPONSE(DHTGet) {
00133 handleGetResponse(_DHTGetResponse, rpcId);
00134 EV << "[DHT::handleRpcResponse()]\n"
00135 << " DHT Get RPC Response received: id=" << rpcId
00136 << " msg=" << *_DHTGetResponse << " rtt=" << rtt
00137 << endl;
00138 break;
00139 }
00140 RPC_ON_RESPONSE(Lookup) {
00141 handleLookupResponse(_LookupResponse, rpcId);
00142 EV << "[DHT::handleRpcResponse()]\n"
00143 << " Lookup RPC Response received: id=" << rpcId
00144 << " msg=" << *_LookupResponse << " rtt=" << rtt
00145 << endl;
00146 break;
00147 }
00148 RPC_SWITCH_END()
00149 }
00150
00151 void DHT::handleRpcTimeout(BaseCallMessage* msg, const TransportAddress& dest,
00152 cPolymorphic* context, int rpcId,
00153 const OverlayKey& destKey)
00154 {
00155 RPC_SWITCH_START(msg)
00156 RPC_ON_CALL(DHTPut){
00157 EV << "[DHT::handleRpcResponse()]\n"
00158 << " DHTPut Timeout"
00159 << endl;
00160
00161 PendingRpcs::iterator it = pendingRpcs.find(rpcId);
00162
00163 if (it == pendingRpcs.end())
00164 return;
00165
00166 it->second.numFailed++;
00167
00168 if (it->second.numFailed / (double)it->second.numSent >= 0.5) {
00169 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00170 capiPutRespMsg->setIsSuccess(false);
00171 sendRpcResponse(it->second.putCallMsg, capiPutRespMsg);
00172
00173 pendingRpcs.erase(rpcId);
00174 }
00175
00176 break;
00177 }
00178 RPC_ON_CALL(DHTGet) {
00179 EV << "[DHT::handleRpcResponse()]\n"
00180 << " DHTGet Timeout"
00181 << endl;
00182
00183 PendingRpcs::iterator it = pendingRpcs.find(rpcId);
00184
00185 if (it == pendingRpcs.end()) {
00186 return;
00187 }
00188
00189 if (it->second.state == GET_VALUE_SENT) {
00190
00191
00192 if ((it->second.hashVector != NULL)
00193 && (it->second.hashVector->size() > 0)) {
00194
00195 DHTGetCall* getCall = new DHTGetCall();
00196 getCall->setKey(_DHTGetCall->getKey());
00197 getCall->setKind(_DHTGetCall->getKind());
00198 getCall->setId(_DHTGetCall->getId());
00199 getCall->setIsHash(false);
00200 getCall->setBitLength(GETCALL_L(getCall));
00201 RECORD_STATS(normalMessages++;
00202 numBytesNormal += getCall->getByteLength());
00203
00204 sendRouteRpcCall(TIER1_COMP, it->second.hashVector->back(),
00205 getCall, NULL, DEFAULT_ROUTING, -1, 0, rpcId);
00206 it->second.hashVector->pop_back();
00207 } else {
00208
00209 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00210 capiGetRespMsg->setIsSuccess(false);
00211 sendRpcResponse(it->second.getCallMsg,
00212 capiGetRespMsg);
00213
00214 pendingRpcs.erase(rpcId);
00215 return;
00216 }
00217 } else {
00218
00219
00220 if (it->second.replica.size() > 0) {
00221 DHTGetCall* getCall = new DHTGetCall();
00222 getCall->setKey(_DHTGetCall->getKey());
00223 getCall->setKind(_DHTGetCall->getKind());
00224 getCall->setId(_DHTGetCall->getId());
00225 getCall->setIsHash(true);
00226 getCall->setBitLength(GETCALL_L(getCall));
00227
00228 RECORD_STATS(normalMessages++;
00229 numBytesNormal += getCall->getByteLength());
00230
00231 sendRouteRpcCall(TIER1_COMP, it->second.replica.back(),
00232 getCall, NULL, DEFAULT_ROUTING, -1, 0,
00233 rpcId);
00234 it->second.replica.pop_back();
00235 } else {
00236
00237 if (it->second.numResponses > 0) {
00238 unsigned int maxCount = 0;
00239 NodeVector* hashVector = NULL;
00240 std::map<BinaryValue, NodeVector>::iterator itHashes;
00241 for (itHashes = it->second.hashes.begin();
00242 itHashes != it->second.hashes.end(); itHashes++) {
00243
00244 if (itHashes->second.size() > maxCount) {
00245 maxCount = itHashes->second.size();
00246 hashVector = &(itHashes->second);
00247 }
00248 }
00249
00250
00251
00252
00253 it->second.hashVector = hashVector;
00254 #if 0
00255 if ((double)maxCount/(double)it->second.numResponses >=
00256 ratioIdentical) {
00257 it->second.hashVector = hashVector;
00258 }
00259 #endif
00260 }
00261
00262 if ((it->second.hashVector != NULL)
00263 && (it->second.hashVector->size() > 0)) {
00264
00265 DHTGetCall* getCall = new DHTGetCall();
00266 getCall->setKey(_DHTGetCall->getKey());
00267 getCall->setKind(_DHTGetCall->getKind());
00268 getCall->setId(_DHTGetCall->getId());
00269 getCall->setIsHash(false);
00270 getCall->setBitLength(GETCALL_L(getCall));
00271 RECORD_STATS(normalMessages++;
00272 numBytesNormal += getCall->getByteLength());
00273 sendRouteRpcCall(TIER1_COMP, it->second.hashVector->back(),
00274 getCall, NULL, DEFAULT_ROUTING, -1,
00275 0, rpcId);
00276 it->second.hashVector->pop_back();
00277 } else {
00278
00279 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00280 capiGetRespMsg->setIsSuccess(false);
00281 sendRpcResponse(it->second.getCallMsg, capiGetRespMsg);
00282
00283 pendingRpcs.erase(rpcId);
00284 }
00285 }
00286 }
00287 break;
00288 }
00289 RPC_SWITCH_END( )
00290 }
00291
00292 void DHT::handlePutRequest(DHTPutCall* dhtMsg)
00293 {
00294 std::string tempString = "PUT_REQUEST received: "
00295 + std::string(dhtMsg->getKey().toString(16));
00296 getParentModule()->getParentModule()->bubble(tempString.c_str());
00297
00298 bool err;
00299 bool isSibling = overlay->isSiblingFor(overlay->getThisNode(),
00300 dhtMsg->getKey(), secureMaintenance ? numReplica : 1, &err);
00301 if (err) {
00302 isSibling = true;
00303 }
00304
00305 if (secureMaintenance && dhtMsg->getMaintenance()) {
00306 DhtDataEntry* entry = dataStorage->getDataEntry(dhtMsg->getKey(),
00307 dhtMsg->getKind(),
00308 dhtMsg->getId());
00309 if (entry == NULL) {
00310
00311 DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00312 timerMsg->setKey(dhtMsg->getKey());
00313 timerMsg->setKind(dhtMsg->getKind());
00314 timerMsg->setId(dhtMsg->getId());
00315 scheduleAt(simTime() + dhtMsg->getTtl(), timerMsg);
00316
00317 entry = dataStorage->addData(dhtMsg->getKey(), dhtMsg->getKind(),
00318 dhtMsg->getId(), dhtMsg->getValue(), timerMsg,
00319 dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(),
00320 isSibling);
00321 } else if ((entry->siblingVote.size() == 0) && isSibling) {
00322
00323
00324 delete dhtMsg;
00325 return;
00326 }
00327
00328 SiblingVoteMap::iterator it = entry->siblingVote.find(dhtMsg->getValue());
00329 if (it == entry->siblingVote.end()) {
00330
00331 NodeVector vect;
00332 vect.add(dhtMsg->getSrcNode());
00333 entry->siblingVote.insert(make_pair(dhtMsg->getValue(),
00334 vect));
00335 } else {
00336 it->second.add(dhtMsg->getSrcNode());
00337 }
00338
00339 size_t maxCount = 0;
00340 SiblingVoteMap::iterator majorityIt;
00341
00342 for (it = entry->siblingVote.begin(); it != entry->siblingVote.end(); it++) {
00343 if (it->second.size() > maxCount) {
00344 maxCount = it->second.size();
00345 majorityIt = it;
00346 }
00347 }
00348
00349 entry->value = majorityIt->first;
00350 entry->responsible = true;
00351
00352 if (maxCount > numReplica) {
00353 entry->siblingVote.clear();
00354 }
00355
00356
00357 DHTPutResponse* responseMsg = new DHTPutResponse();
00358 responseMsg->setSuccess(true);
00359 responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00360 RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->getByteLength());
00361
00362 sendRpcResponse(dhtMsg, responseMsg);
00363
00364 return;
00365 }
00366
00367 #if 0
00368 if (!(dataStorage->isModifiable(dhtMsg->getKey(), dhtMsg->getKind(),
00369 dhtMsg->getId()))) {
00370
00371 NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey(),
00372 dhtMsg->getKind(), dhtMsg->getId());
00373 if (((!sourceNode.isUnspecified())
00374 && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode
00375 != dhtMsg->getSrcNode())) || ((dhtMsg->getMaintenance())
00376 && (dhtMsg->getOwnerNode() == sourceNode))) {
00377
00378 DHTPutResponse* responseMsg = new DHTPutResponse();
00379 responseMsg->setSuccess(false);
00380 responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00381 RECORD_STATS(normalMessages++;
00382 numBytesNormal += responseMsg->getByteLength());
00383 sendRpcResponse(dhtMsg, responseMsg);
00384 return;
00385 }
00386
00387 }
00388 #endif
00389
00390
00391 dataStorage->removeData(dhtMsg->getKey(), dhtMsg->getKind(),
00392 dhtMsg->getId());
00393
00394 if (dhtMsg->getValue().size() > 0) {
00395
00396 DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00397 timerMsg->setKey(dhtMsg->getKey());
00398 timerMsg->setKind(dhtMsg->getKind());
00399 timerMsg->setId(dhtMsg->getId());
00400 scheduleAt(simTime() + dhtMsg->getTtl(), timerMsg);
00401
00402 dataStorage->addData(dhtMsg->getKey(), dhtMsg->getKind(),
00403 dhtMsg->getId(), dhtMsg->getValue(), timerMsg,
00404 dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(),
00405 isSibling);
00406 }
00407
00408
00409 DHTPutResponse* responseMsg = new DHTPutResponse();
00410 responseMsg->setSuccess(true);
00411 responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00412 RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->getByteLength());
00413
00414 sendRpcResponse(dhtMsg, responseMsg);
00415 }
00416
00417 void DHT::handleGetRequest(DHTGetCall* dhtMsg)
00418 {
00419 std::string tempString = "GET_REQUEST received: "
00420 + std::string(dhtMsg->getKey().toString(16));
00421
00422 getParentModule()->getParentModule()->bubble(tempString.c_str());
00423
00424 if (dhtMsg->getKey().isUnspecified()) {
00425 throw cRuntimeError("DHT::handleGetRequest: Unspecified key!");
00426 }
00427
00428 DhtDumpVector* dataVect = dataStorage->dumpDht(dhtMsg->getKey(),
00429 dhtMsg->getKind(),
00430 dhtMsg->getId());
00431
00432 if (overlay->isMalicious() && invalidDataAttack) {
00433 dataVect->resize(1);
00434 dataVect->at(0).setKey(dhtMsg->getKey());
00435 dataVect->at(0).setKind(dhtMsg->getKind());
00436 dataVect->at(0).setId(dhtMsg->getId());
00437 dataVect->at(0).setValue("Modified Data");
00438 dataVect->at(0).setTtl(3600*24*365);
00439 dataVect->at(0).setOwnerNode(overlay->getThisNode());
00440 dataVect->at(0).setIs_modifiable(false);
00441 dataVect->at(0).setResponsible(true);
00442 }
00443
00444
00445 DHTGetResponse* responseMsg = new DHTGetResponse();
00446 responseMsg->setKey(dhtMsg->getKey());
00447 responseMsg->setIsHash(dhtMsg->getIsHash());
00448
00449 if (dataVect->size() == 0) {
00450 responseMsg->setHashValue(BinaryValue::UNSPECIFIED_VALUE);
00451 responseMsg->setResultArraySize(0);
00452 } else {
00453 if (dhtMsg->getIsHash()) {
00454
00455 BinaryValue resultValues;
00456 for (uint32_t i = 0; i < dataVect->size(); i++) {
00457 resultValues += (*dataVect)[i].getValue();
00458 }
00459
00460 CSHA1 sha1;
00461 BinaryValue hashValue(20);
00462 sha1.Reset();
00463 sha1.Update((uint8_t*) (&(*resultValues.begin())),
00464 resultValues.size());
00465 sha1.Final();
00466 sha1.GetHash((unsigned char*)&hashValue[0]);
00467
00468 responseMsg->setHashValue(hashValue);
00469 } else {
00470 responseMsg->setResultArraySize(dataVect->size());
00471
00472 for (uint32_t i = 0; i < dataVect->size(); i++) {
00473 responseMsg->setResult(i, (*dataVect)[i]);
00474 }
00475
00476 }
00477 }
00478 delete dataVect;
00479
00480 responseMsg->setBitLength(GETRESPONSE_L(responseMsg));
00481 RECORD_STATS(normalMessages++;
00482 numBytesNormal += responseMsg->getByteLength());
00483 sendRpcResponse(dhtMsg, responseMsg);
00484 }
00485
00486 void DHT::handlePutCAPIRequest(DHTputCAPICall* capiPutMsg)
00487 {
00488
00489 LookupCall* lookupCall = new LookupCall();
00490 lookupCall->setKey(capiPutMsg->getKey());
00491 lookupCall->setNumSiblings(numReplica);
00492 sendInternalRpcCall(OVERLAY_COMP, lookupCall, NULL, -1, 0,
00493 capiPutMsg->getNonce());
00494
00495 PendingRpcsEntry entry;
00496 entry.putCallMsg = capiPutMsg;
00497 entry.state = LOOKUP_STARTED;
00498 pendingRpcs.insert(make_pair(capiPutMsg->getNonce(), entry));
00499 }
00500
00501 void DHT::handleGetCAPIRequest(DHTgetCAPICall* capiGetMsg)
00502 {
00503 LookupCall* lookupCall = new LookupCall();
00504 lookupCall->setKey(capiGetMsg->getKey());
00505 lookupCall->setNumSiblings(numReplica);
00506 sendInternalRpcCall(OVERLAY_COMP, lookupCall, NULL, -1, 0,
00507 capiGetMsg->getNonce());
00508
00509 PendingRpcsEntry entry;
00510 entry.getCallMsg = capiGetMsg;
00511 entry.state = LOOKUP_STARTED;
00512 pendingRpcs.insert(make_pair(capiGetMsg->getNonce(), entry));
00513 }
00514
00515 void DHT::handleDumpDhtRequest(DHTdumpCall* call)
00516 {
00517 DHTdumpResponse* response = new DHTdumpResponse();
00518 DhtDumpVector* dumpVector = dataStorage->dumpDht();
00519
00520 response->setRecordArraySize(dumpVector->size());
00521
00522 for (uint32_t i = 0; i < dumpVector->size(); i++) {
00523 response->setRecord(i, (*dumpVector)[i]);
00524 }
00525
00526 delete dumpVector;
00527
00528 sendRpcResponse(call, response);
00529 }
00530
00531 void DHT::handlePutResponse(DHTPutResponse* dhtMsg, int rpcId)
00532 {
00533 PendingRpcs::iterator it = pendingRpcs.find(rpcId);
00534
00535 if (it == pendingRpcs.end())
00536 return;
00537
00538 if (dhtMsg->getSuccess()) {
00539 it->second.numResponses++;
00540 } else {
00541 it->second.numFailed++;
00542 }
00543
00544
00545
00546 if (it->second.numResponses / (double)it->second.numSent > 0.5) {
00547
00548 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00549 capiPutRespMsg->setIsSuccess(true);
00550 sendRpcResponse(it->second.putCallMsg, capiPutRespMsg);
00551 pendingRpcs.erase(rpcId);
00552 }
00553 }
00554
00555 void DHT::handleGetResponse(DHTGetResponse* dhtMsg, int rpcId)
00556 {
00557 NodeVector* hashVector = NULL;
00558 PendingRpcs::iterator it = pendingRpcs.find(rpcId);
00559
00560 if (it == pendingRpcs.end())
00561 return;
00562
00563 if (it->second.state == GET_VALUE_SENT) {
00564
00565 if (!dhtMsg->getIsHash()) {
00566
00567 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00568 capiGetRespMsg->setResultArraySize(dhtMsg->getResultArraySize());
00569 for (uint i = 0; i < dhtMsg->getResultArraySize(); i++) {
00570 capiGetRespMsg->setResult(i, dhtMsg->getResult(i));
00571 }
00572 capiGetRespMsg->setIsSuccess(true);
00573 sendRpcResponse(it->second.getCallMsg, capiGetRespMsg);
00574 pendingRpcs.erase(rpcId);
00575 return;
00576 }
00577 }
00578
00579 if (dhtMsg->getIsHash()) {
00580 std::map<BinaryValue, NodeVector>::iterator itHashes =
00581 it->second.hashes.find(dhtMsg->getHashValue());
00582
00583 if (itHashes == it->second.hashes.end()) {
00584
00585 NodeVector vect;
00586 vect.push_back(dhtMsg->getSrcNode());
00587 it->second.hashes.insert(make_pair(dhtMsg->getHashValue(),
00588 vect));
00589 } else {
00590 itHashes->second.push_back(dhtMsg->getSrcNode());
00591 }
00592
00593 it->second.numResponses++;
00594
00595 if (it->second.state == GET_VALUE_SENT) {
00596
00597 return;
00598 }
00599
00600
00601 unsigned int maxCount = 0;
00602
00603
00604 for (itHashes = it->second.hashes.begin();
00605 itHashes != it->second.hashes.end(); itHashes++) {
00606
00607 if (itHashes->second.size() > maxCount) {
00608 maxCount = itHashes->second.size();
00609 hashVector = &(itHashes->second);
00610 }
00611 }
00612
00613 if ((double) maxCount / (double) it->second.numAvailableReplica
00614 >= ratioIdentical) {
00615 it->second.hashVector = hashVector;
00616 } else if (it->second.numResponses >= numGetRequests) {
00617
00618 if (it->second.replica.size() > 0) {
00619 DHTGetCall* getCall = new DHTGetCall();
00620 getCall->setKey(dhtMsg->getKey());
00621 getCall->setKind(dhtMsg->getKind());
00622 getCall->setId(dhtMsg->getId());
00623 getCall->setIsHash(true);
00624 getCall->setBitLength(GETCALL_L(getCall));
00625 RECORD_STATS(normalMessages++;
00626 numBytesNormal += getCall->getByteLength());
00627 sendRouteRpcCall(TIER1_COMP,
00628 it->second.replica.back(), getCall,
00629 NULL, DEFAULT_ROUTING, -1, 0, rpcId);
00630 it->second.replica.pop_back();
00631 it->second.state = GET_HASH_SENT;
00632 } else if (hashVector == NULL) {
00633
00634 DHTgetCAPIResponse* capiGetRespMsg =
00635 new DHTgetCAPIResponse();
00636 DhtDumpEntry result;
00637 result.setKey(dhtMsg->getKey());
00638 result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00639 capiGetRespMsg->setResultArraySize(1);
00640 capiGetRespMsg->setResult(0, result);
00641 capiGetRespMsg->setIsSuccess(false);
00642 sendRpcResponse(it->second.getCallMsg, capiGetRespMsg);
00643 #if 0
00644 cout << "DHT: GET failed: hash (no one else)" << endl;
00645 cout << "numResponses: " << it->second.numResponses
00646 << " numAvailableReplica: " << it->second.numAvailableReplica << endl;
00647
00648 for (itHashes = it->second.hashes.begin();
00649 itHashes != it->second.hashes.end(); itHashes++) {
00650 cout << " - " << itHashes->first << " ("
00651 << itHashes->second.size() << ")" << endl;
00652 }
00653 #endif
00654
00655 pendingRpcs.erase(rpcId);
00656 return;
00657 } else {
00658
00659 it->second.hashVector = hashVector;
00660 }
00661 }
00662 }
00663
00664 if ((it->second.state != GET_VALUE_SENT) &&
00665 (it->second.hashVector != NULL)) {
00666
00667 if (it->second.hashVector->size() > 0) {
00668 DHTGetCall* getCall = new DHTGetCall();
00669 getCall->setKey(it->second.getCallMsg->getKey());
00670 getCall->setKind(it->second.getCallMsg->getKind());
00671 getCall->setId(it->second.getCallMsg->getId());
00672 getCall->setIsHash(false);
00673 getCall->setBitLength(GETCALL_L(getCall));
00674 RECORD_STATS(normalMessages++;
00675 numBytesNormal += getCall->getByteLength());
00676 sendRouteRpcCall(TIER1_COMP, it->second.hashVector->back(),
00677 getCall, NULL, DEFAULT_ROUTING, -1, 0, rpcId);
00678 it->second.hashVector->pop_back();
00679 it->second.state = GET_VALUE_SENT;
00680 } else {
00681 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00682 DhtDumpEntry result;
00683 result.setKey(dhtMsg->getKey());
00684 result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00685 capiGetRespMsg->setResultArraySize(1);
00686 capiGetRespMsg->setResult(0, result);
00687 capiGetRespMsg->setIsSuccess(false);
00688 sendRpcResponse(it->second.getCallMsg, capiGetRespMsg);
00689
00690 pendingRpcs.erase(rpcId);
00691 }
00692 }
00693 }
00694
00695 void DHT::update(const NodeHandle& node, bool joined)
00696 {
00697 OverlayKey key;
00698 bool err = false;
00699 DhtDataEntry entry;
00700 std::map<OverlayKey, DhtDataEntry>::iterator it;
00701
00702 EV << "[DHT::update() @ " << overlay->getThisNode().getAddress()
00703 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00704 << " Update called()"
00705 << endl;
00706
00707 if (secureMaintenance) {
00708 for (it = dataStorage->begin(); it != dataStorage->end(); it++) {
00709 if (it->second.responsible) {
00710 NodeVector* siblings = overlay->local_lookup(it->first,
00711 numReplica,
00712 false);
00713 if (siblings->size() == 0) {
00714 delete siblings;
00715 continue;
00716 }
00717
00718 if (joined) {
00719 EV << "[DHT::update() @ " << overlay->getThisNode().getAddress()
00720 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00721 << " Potential new sibling for record " << it->first
00722 << endl;
00723
00724 if (overlay->distance(node.getKey(), it->first) <=
00725 overlay->distance(siblings->back().getKey(), it->first)) {
00726
00727 sendMaintenancePutCall(node, it->first, it->second);
00728 }
00729
00730 if (overlay->distance(overlay->getThisNode().getKey(), it->first) >
00731 overlay->distance(siblings->back().getKey(), it->first)) {
00732
00733 it->second.responsible = false;
00734 }
00735 } else {
00736 if (overlay->distance(node.getKey(), it->first) <
00737 overlay->distance(siblings->back().getKey(), it->first)) {
00738
00739 sendMaintenancePutCall(siblings->back(), it->first,
00740 it->second);
00741 }
00742 }
00743
00744 delete siblings;
00745 }
00746 }
00747
00748 return;
00749 }
00750
00751 for (it = dataStorage->begin(); it != dataStorage->end(); it++) {
00752 key = it->first;
00753 entry = it->second;
00754 if (joined) {
00755 if (entry.responsible && (overlay->isSiblingFor(node, key,
00756 numReplica, &err)
00757 || err)) {
00758
00759 if (err) {
00760 EV << "[DHT::update()]\n"
00761 << " Unable to know if key: " << key
00762 << " is in range of node: " << node
00763 << endl;
00764
00765
00766
00767
00768
00769
00770
00771
00772 }
00773
00774 sendMaintenancePutCall(node, key, entry);
00775 }
00776 }
00777
00778 entry.responsible = overlay->isSiblingFor(overlay->getThisNode(),
00779 key, 1, &err);
00780 }
00781 }
00782
00783 void DHT::sendMaintenancePutCall(const TransportAddress& node,
00784 const OverlayKey& key,
00785 const DhtDataEntry& entry) {
00786
00787 DHTPutCall* dhtMsg = new DHTPutCall();
00788
00789 dhtMsg->setKey(key);
00790 dhtMsg->setKind(entry.kind);
00791 dhtMsg->setId(entry.id);
00792
00793 if (overlay->isMalicious() && maintenanceAttack) {
00794 dhtMsg->setValue("Modified Data");
00795 } else {
00796 dhtMsg->setValue(entry.value);
00797 }
00798
00799 dhtMsg->setTtl((int)SIMTIME_DBL(entry.ttlMessage->getArrivalTime()
00800 - simTime()));
00801 dhtMsg->setIsModifiable(entry.is_modifiable);
00802 dhtMsg->setMaintenance(true);
00803 dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00804 RECORD_STATS(maintenanceMessages++;
00805 numBytesMaintenance += dhtMsg->getByteLength());
00806
00807 sendRouteRpcCall(TIER1_COMP, node, dhtMsg);
00808 }
00809
00810 void DHT::handleLookupResponse(LookupResponse* lookupMsg, int rpcId)
00811 {
00812 PendingRpcs::iterator it = pendingRpcs.find(rpcId);
00813
00814 if (it == pendingRpcs.end()) {
00815 return;
00816 }
00817
00818 if (it->second.putCallMsg != NULL) {
00819
00820 #if 0
00821 cout << "DHT::handleLookupResponse(): PUT "
00822 << lookupMsg->getKey() << " ("
00823 << overlay->getThisNode().getKey() << ")" << endl;
00824
00825 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00826 cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00827 }
00828 #endif
00829
00830 if ((lookupMsg->getIsValid() == false)
00831 || (lookupMsg->getSiblingsArraySize() == 0)) {
00832
00833 EV << "[DHT::handleLookupResponse()]\n"
00834 << " Unable to get replica list : invalid lookup"
00835 << endl;
00836 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00837 capiPutRespMsg->setIsSuccess(false);
00838
00839 sendRpcResponse(it->second.putCallMsg, capiPutRespMsg);
00840 pendingRpcs.erase(rpcId);
00841 return;
00842 }
00843
00844 if ((it->second.putCallMsg->getId() == 0) &&
00845 (it->second.putCallMsg->getValue().size() > 0)) {
00846
00847
00848 it->second.putCallMsg->setId(intuniform(1, 2147483647));
00849 }
00850
00851 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00852 DHTPutCall* dhtMsg = new DHTPutCall();
00853 dhtMsg->setKey(it->second.putCallMsg->getKey());
00854 dhtMsg->setKind(it->second.putCallMsg->getKind());
00855 dhtMsg->setId(it->second.putCallMsg->getId());
00856 dhtMsg->setValue(it->second.putCallMsg->getValue());
00857 dhtMsg->setTtl(it->second.putCallMsg->getTtl());
00858 dhtMsg->setIsModifiable(it->second.putCallMsg->getIsModifiable());
00859 dhtMsg->setMaintenance(false);
00860 dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00861 RECORD_STATS(normalMessages++;
00862 numBytesNormal += dhtMsg->getByteLength());
00863 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00864 dhtMsg, NULL, DEFAULT_ROUTING, -1,
00865 0, rpcId);
00866 }
00867
00868 it->second.state = PUT_SENT;
00869 it->second.numResponses = 0;
00870 it->second.numFailed = 0;
00871 it->second.numSent = lookupMsg->getSiblingsArraySize();
00872 }
00873 else if (it->second.getCallMsg != NULL) {
00874
00875 #if 0
00876 cout << "DHT::handleLookupResponse(): GET "
00877 << lookupMsg->getKey() << " ("
00878 << overlay->getThisNode().getKey() << ")" << endl;
00879
00880 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00881 cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00882 }
00883 #endif
00884
00885 if ((lookupMsg->getIsValid() == false)
00886 || (lookupMsg->getSiblingsArraySize() == 0)) {
00887
00888 EV << "[DHT::handleLookupResponse()]\n"
00889 << " Unable to get replica list : invalid lookup"
00890 << endl;
00891 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00892 DhtDumpEntry result;
00893 result.setKey(lookupMsg->getKey());
00894 result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00895 capiGetRespMsg->setResultArraySize(1);
00896 capiGetRespMsg->setResult(0, result);
00897 capiGetRespMsg->setIsSuccess(false);
00898
00899 sendRpcResponse(it->second.getCallMsg, capiGetRespMsg);
00900 pendingRpcs.erase(rpcId);
00901 return;
00902 }
00903
00904 it->second.numSent = 0;
00905
00906 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00907 if (i < (unsigned int)numGetRequests) {
00908 DHTGetCall* dhtMsg = new DHTGetCall();
00909 dhtMsg->setKey(it->second.getCallMsg->getKey());
00910 dhtMsg->setKind(it->second.getCallMsg->getKind());
00911 dhtMsg->setId(it->second.getCallMsg->getId());
00912 dhtMsg->setIsHash(true);
00913 dhtMsg->setBitLength(GETCALL_L(dhtMsg));
00914 RECORD_STATS(normalMessages++;
00915 numBytesNormal += dhtMsg->getByteLength());
00916 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i), dhtMsg,
00917 NULL, DEFAULT_ROUTING, -1, 0, rpcId);
00918 it->second.numSent++;
00919 } else {
00920
00921 it->second.replica.push_back(lookupMsg->getSiblings(i));
00922 }
00923 }
00924
00925 it->second.numAvailableReplica = lookupMsg->getSiblingsArraySize();
00926 it->second.numResponses = 0;
00927 it->second.hashVector = NULL;
00928 it->second.state = GET_HASH_SENT;
00929 }
00930 }
00931
00932 void DHT::finishApp()
00933 {
00934 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00935
00936 if (time >= GlobalStatistics::MIN_MEASURED) {
00937 globalStatistics->addStdDev("DHT: Sent Maintenance Messages/s",
00938 maintenanceMessages / time);
00939 globalStatistics->addStdDev("DHT: Sent Normal Messages/s",
00940 normalMessages / time);
00941 globalStatistics->addStdDev("DHT: Sent Maintenance Bytes/s",
00942 numBytesMaintenance / time);
00943 globalStatistics->addStdDev("DHT: Sent Normal Bytes/s",
00944 numBytesNormal / time);
00945 }
00946 }
00947
00948 int DHT::resultValuesBitLength(DHTGetResponse* msg) {
00949 int bitSize = 0;
00950 for (uint i = 0; i < msg->getResultArraySize(); i++) {
00951 bitSize += msg->getResult(i).getValue().size();
00952
00953 }
00954 return bitSize;
00955 }
00956
00957 std::ostream& operator<<(std::ostream& os, const DHT::PendingRpcsEntry& entry)
00958 {
00959 if (entry.getCallMsg) {
00960 os << "GET";
00961 } else if (entry.putCallMsg) {
00962 os << "PUT";
00963 }
00964
00965 os << " state: " << entry.state
00966 << " numSent: " << entry.numSent
00967 << " numResponses: " << entry.numResponses
00968 << " numFailed: " << entry.numFailed
00969 << " numAvailableReplica: " << entry.numAvailableReplica;
00970
00971 if (entry.replica.size() > 0) {
00972 os << " replicaSize: " << entry.replica.size();
00973 }
00974
00975 if (entry.hashVector != NULL) {
00976 os << " hashVectorSize: " << entry.hashVector->size();
00977 }
00978
00979 if (entry.hashes.size() > 0) {
00980 os << " hashes:";
00981 std::map<BinaryValue, NodeVector>::const_iterator it;
00982
00983 int i = 0;
00984 for (it = entry.hashes.begin(); it != entry.hashes.end(); it++, i++) {
00985 os << " hash" << i << ":" << it->second.size();
00986 }
00987 }
00988
00989 return os;
00990 }