00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <IPAddressResolver.h>
00025 #include <CommonMessages_m.h>
00026 #include <GlobalStatistics.h>
00027 #include <UnderlayConfigurator.h>
00028 #include <GlobalNodeList.h>
00029
00030 #include "KBRTestApp.h"
00031 #include "KBRTestMessage_m.h"
00032
00033 Define_Module(KBRTestApp);
00034
00035 KBRTestApp::KBRTestApp()
00036 {
00037 onewayTimer = NULL;
00038 }
00039
00040 KBRTestApp::~KBRTestApp()
00041 {
00042 cancelAndDelete(onewayTimer);
00043 cancelAndDelete(rpcTimer);
00044 cancelAndDelete(lookupTimer);
00045 }
00046
00047 void KBRTestApp::initializeApp(int stage)
00048 {
00049 if (stage != MIN_STAGE_APP) {
00050 return;
00051 }
00052
00053 kbrOneWayTest = par("kbrOneWayTest");
00054 kbrRpcTest = par("kbrRpcTest");
00055 kbrLookupTest = par("kbrLookupTest");
00056
00057 if (!kbrOneWayTest && !kbrRpcTest && !kbrLookupTest) {
00058 throw cRuntimeError("KBRTestApp::initializeApp(): "
00059 "no tests are configured!");
00060 }
00061
00062 failureLatency = par("failureLatency");
00063
00064 testMsgSize = par("testMsgSize");
00065 lookupNodeIds = par("lookupNodeIds");
00066 mean = par("testMsgInterval");
00067 deviation = mean / 10;
00068 activeNetwInitPhase = par("activeNetwInitPhase");
00069 msgHandleBufSize = par("msgHandleBufSize");
00070 onlyLookupInoffensiveNodes = par("onlyLookupInoffensiveNodes");
00071
00072 numSent = 0;
00073 bytesSent = 0;
00074 numDelivered = 0;
00075 bytesDelivered = 0;
00076 numDropped = 0;
00077 bytesDropped = 0;
00078 WATCH(numSent);
00079 WATCH(bytesSent);
00080 WATCH(numDelivered);
00081 WATCH(bytesDelivered);
00082 WATCH(numDropped);
00083 WATCH(bytesDropped);
00084
00085 numRpcSent = 0;
00086 bytesRpcSent = 0;
00087 numRpcDelivered = 0;
00088 bytesRpcDelivered = 0;
00089 numRpcDropped = 0;
00090 bytesRpcDropped = 0;
00091 rpcSuccLatencyCount = 0;
00092 rpcSuccLatencySum = 0;
00093 rpcTotalLatencyCount = 0;
00094 rpcTotalLatencySum = 0;
00095 WATCH(numRpcSent);
00096 WATCH(bytesRpcSent);
00097 WATCH(numRpcDelivered);
00098 WATCH(bytesRpcDelivered);
00099 WATCH(numRpcDropped);
00100 WATCH(bytesRpcDropped);
00101
00102 numLookupSent = 0;
00103 numLookupSuccess = 0;
00104 numLookupFailed = 0;
00105 WATCH(numLookupSent);
00106 WATCH(numLookupSuccess);
00107 WATCH(numLookupFailed);
00108
00109 sequenceNumber = 0;
00110
00111 nodeIsLeavingSoon = false;
00112
00113
00114 if (msgHandleBufSize > 0) {
00115 mhBuf.resize(msgHandleBufSize);
00116 mhBufBegin = mhBuf.begin();
00117 mhBufEnd = mhBuf.end();
00118 mhBufNext = mhBufBegin;
00119 }
00120
00121 #if 0
00122 bindToPort(1025);
00123 thisNode.setPort(1025);
00124 #endif
00125
00126
00127 onewayTimer = new cMessage("onewayTimer");
00128 rpcTimer = new cMessage("rpcTimer");
00129 lookupTimer = new cMessage("lookupTimer");
00130
00131 if (kbrOneWayTest) {
00132 scheduleAt(simTime() + truncnormal(mean, deviation), onewayTimer);
00133 }
00134 if (kbrRpcTest) {
00135 scheduleAt(simTime() + truncnormal(mean, deviation), rpcTimer);
00136 }
00137 if (kbrLookupTest) {
00138 scheduleAt(simTime() + truncnormal(mean, deviation), lookupTimer);
00139 }
00140 }
00141
00142 void KBRTestApp::handleTimerEvent(cMessage* msg)
00143 {
00144
00145 scheduleAt(simTime() + truncnormal(mean, deviation), msg);
00146
00147
00148 if ((!activeNetwInitPhase && underlayConfigurator->isInInitPhase())
00149 || underlayConfigurator->isSimulationEndingSoon()
00150 || nodeIsLeavingSoon) {
00151 return;
00152 }
00153
00154 std::pair<OverlayKey,TransportAddress> dest = createDestKey();
00155
00156 if (msg == onewayTimer) {
00157
00158
00159 if (!dest.first.isUnspecified()) {
00160
00161 KBRTestMessage* testMsg = new KBRTestMessage("KBRTestMessage");
00162 testMsg->setId(getId());
00163 testMsg->setSeqNum(sequenceNumber++);
00164 testMsg->setByteLength(testMsgSize);
00165 testMsg->setMeasurementPhase(globalStatistics->isMeasuring());
00166
00167 RECORD_STATS(globalStatistics->sentKBRTestAppMessages++;
00168 numSent++; bytesSent += testMsg->getByteLength());
00169
00170 callRoute(dest.first, testMsg);
00171 }
00172 } else if (msg == rpcTimer) {
00173
00174
00175 if (!dest.first.isUnspecified()) {
00176 KbrTestCall* call = new KbrTestCall;
00177 call->setByteLength(testMsgSize);
00178 KbrRpcContext* context = new KbrRpcContext;
00179 context->setDestKey(dest.first);
00180 if (lookupNodeIds) {
00181 context->setDestAddr(dest.second);
00182 }
00183 context->setMeasurementPhase(globalStatistics->isMeasuring());
00184
00185 RECORD_STATS(numRpcSent++;
00186 bytesRpcSent += call->getByteLength());
00187
00188 sendRouteRpcCall(TIER1_COMP, dest.first, call, context);
00189 }
00190 } else {
00191
00192
00193 if (!dest.first.isUnspecified()) {
00194 LookupCall* call = new LookupCall();
00195 call->setKey(dest.first);
00196 call->setNumSiblings(overlay->getMaxNumSiblings());
00197 KbrRpcContext* context = new KbrRpcContext;
00198 context->setDestKey(dest.first);
00199 if (lookupNodeIds) {
00200 context->setDestAddr(dest.second);
00201 }
00202 context->setMeasurementPhase(globalStatistics->isMeasuring());
00203 sendInternalRpcCall(OVERLAY_COMP, call, context);
00204
00205 RECORD_STATS(numLookupSent++);
00206 }
00207 }
00208
00209 #if 0
00210 thisNode.setPort(1025);
00211 NodeHandle handle = globalNodeList->getBootstrapNode();
00212 handle.setPort(1025);
00213 pingNode(handle, -1, -1, NULL, "TestPING", NULL, -1, UDP_TRANSPORT);
00214 #endif
00215
00216 }
00217 void KBRTestApp::pingResponse(PingResponse* response, cPolymorphic* context,
00218 int rpcId, simtime_t rtt)
00219 {
00220
00221 }
00222 bool KBRTestApp::handleRpcCall(BaseCallMessage* msg)
00223 {
00224 RPC_SWITCH_START( msg );
00225 RPC_DELEGATE( KbrTest, kbrTestCall );
00226 RPC_SWITCH_END( );
00227
00228 return RPC_HANDLED;
00229 }
00230 void KBRTestApp::kbrTestCall(KbrTestCall* call)
00231 {
00232 KbrTestResponse* response = new KbrTestResponse;
00233 response->setByteLength(call->getByteLength());
00234 sendRpcResponse(call, response);
00235 }
00236
00237 void KBRTestApp::handleRpcResponse(BaseResponseMessage* msg,
00238 cPolymorphic* context, int rpcId,
00239 simtime_t rtt)
00240 {
00241 RPC_SWITCH_START(msg)
00242 RPC_ON_RESPONSE(Lookup) {
00243 EV << "[KBRTestApp::handleRpcResponse() @ " << overlay->getThisNode().getIp()
00244 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00245 << " Lookup RPC Response received: id=" << rpcId << "\n"
00246 << " msg=" << *_LookupResponse << " rtt=" << rtt
00247 << endl;
00248 handleLookupResponse(_LookupResponse, context, rtt);
00249 break;
00250 }
00251 RPC_ON_RESPONSE(KbrTest) {
00252 KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00253 if (kbrRpcContext->getMeasurementPhase() == true) {
00254 if (!lookupNodeIds ||
00255 (kbrRpcContext->getDestKey() == msg->getSrcNode().getKey() &&
00256 kbrRpcContext->getDestAddr() == msg->getSrcNode())) {
00257
00258 RECORD_STATS(numRpcDelivered++;
00259 bytesRpcDelivered += msg->getByteLength());
00260 RECORD_STATS(globalStatistics->recordOutVector(
00261 "KBRTestApp: RPC Success Latency", SIMTIME_DBL(rtt)));
00262 RECORD_STATS(globalStatistics->recordOutVector(
00263 "KBRTestApp: RPC Total Latency", SIMTIME_DBL(rtt)));
00264 RECORD_STATS(rpcSuccLatencyCount++;
00265 rpcSuccLatencySum += SIMTIME_DBL(rtt));
00266 RECORD_STATS(rpcTotalLatencyCount++;
00267 rpcTotalLatencySum += SIMTIME_DBL(rtt));
00268 OverlayCtrlInfo* overlayCtrlInfo =
00269 dynamic_cast<OverlayCtrlInfo*>(msg->getControlInfo());
00270
00271 uint16_t hopSum = msg->getCallHopCount();
00272 hopSum += (overlayCtrlInfo ? overlayCtrlInfo->getHopCount() : 1);
00273 RECORD_STATS(globalStatistics->recordOutVector(
00274 "KBRTestApp: RPC Hop Count", hopSum));
00275
00276
00277 } else {
00278 RECORD_STATS(numRpcDropped++;
00279 bytesRpcDropped += msg->getByteLength());
00280
00281 RECORD_STATS(globalStatistics->recordOutVector(
00282 "KBRTestApp: RPC Total Latency",
00283 SIMTIME_DBL(failureLatency)));
00284 RECORD_STATS(rpcTotalLatencyCount++;
00285 rpcTotalLatencySum += SIMTIME_DBL(failureLatency));
00286 }
00287 }
00288 delete kbrRpcContext;
00289 break;
00290 }
00291 RPC_SWITCH_END( )
00292 }
00293
00294 void KBRTestApp::handleRpcTimeout(BaseCallMessage* msg,
00295 const TransportAddress& dest,
00296 cPolymorphic* context, int rpcId,
00297 const OverlayKey& destKey)
00298 {
00299 RPC_SWITCH_START(msg)
00300 RPC_ON_CALL(KbrTest) {
00301 KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00302 if (kbrRpcContext->getMeasurementPhase() == true) {
00303 RECORD_STATS(numRpcDropped++;
00304 bytesRpcDropped += msg->getByteLength());
00305
00306 RECORD_STATS(globalStatistics->recordOutVector(
00307 "KBRTestApp: RPC Total Latency",
00308 SIMTIME_DBL(failureLatency)));
00309 RECORD_STATS(rpcTotalLatencyCount++;
00310 rpcTotalLatencySum += SIMTIME_DBL(failureLatency));
00311
00312 }
00313 break;
00314 }
00315 RPC_ON_CALL(Lookup) {
00316 KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00317 if (kbrRpcContext->getMeasurementPhase() == true) {
00318 RECORD_STATS(numLookupFailed++);
00319
00320 RECORD_STATS(globalStatistics->recordOutVector(
00321 "KBRTestApp: Lookup Total Latency",
00322 SIMTIME_DBL(failureLatency)));
00323 }
00324 break;
00325 }
00326 RPC_SWITCH_END()
00327
00328 delete context;
00329 }
00330
00331 void KBRTestApp::handleLookupResponse(LookupResponse* msg,
00332 cObject* context, simtime_t latency)
00333 {
00334 EV << "[KBRTestApp::handleLookupResponse() @ " << overlay->getThisNode().getIp()
00335 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00336 << " Lookup response for key " << msg->getKey()<< " : ";
00337
00338 KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00339
00340 if (kbrRpcContext->getMeasurementPhase() == true) {
00341 if (msg->getIsValid() && (!lookupNodeIds ||
00342 ((msg->getSiblingsArraySize() > 0) &&
00343 (msg->getSiblings(0).getKey() == msg->getKey()) &&
00344 (kbrRpcContext->getDestAddr() == msg->getSiblings(0))))) {
00345 RECORD_STATS(numLookupSuccess++);
00346 RECORD_STATS(globalStatistics->recordOutVector(
00347 "KBRTestApp: Lookup Success Latency", SIMTIME_DBL(latency)));
00348 RECORD_STATS(globalStatistics->recordOutVector(
00349 "KBRTestApp: Lookup Total Latency", SIMTIME_DBL(latency)));
00350 RECORD_STATS(globalStatistics->recordOutVector(
00351 "KBRTestApp: Lookup Hop Count", msg->getHopCount()));
00352 } else {
00353 #if 0
00354 if (!msg->getIsValid()) {
00355 std::cout << "invalid" << std::endl;
00356 } else if (msg->getSiblingsArraySize() == 0) {
00357 std::cout << "empty" << std::endl;
00358 } else {
00359 std::cout << "wrong key" << std::endl;
00360 }
00361 #endif
00362 RECORD_STATS(numLookupFailed++);
00363
00364 RECORD_STATS(globalStatistics->recordOutVector(
00365 "KBRTestApp: Lookup Total Latency",
00366 SIMTIME_DBL(failureLatency)));
00367 RECORD_STATS(globalStatistics->recordOutVector(
00368 "KBRTestApp: Failed Lookup Hop Count", msg->getHopCount()));
00369 }
00370 }
00371
00372 delete kbrRpcContext;
00373 }
00374
00375 void KBRTestApp::handleNodeLeaveNotification()
00376 {
00377 nodeIsLeavingSoon = true;
00378 }
00379
00380 void KBRTestApp::deliver(OverlayKey& key, cMessage* msg)
00381 {
00382 KBRTestMessage* testMsg = check_and_cast<KBRTestMessage*>(msg);
00383 OverlayCtrlInfo* overlayCtrlInfo =
00384 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00385
00386 if (overlay->getThisNode().getKey().isUnspecified())
00387 error("key");
00388
00389
00390 if ((msgHandleBufSize > 0 )
00391 && checkSeen(overlayCtrlInfo->getSrcNode().getKey(), testMsg->getSeqNum())) {
00392 EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().getIp()
00393 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00394 << " Duplicate dropped."
00395 << endl;
00396 delete overlayCtrlInfo;
00397 delete testMsg;
00398 return;
00399 }
00400
00401
00402 if (cModule* mod = simulation.getModule(testMsg->getId())) {
00403 if (KBRTestApp* sender = dynamic_cast<KBRTestApp*>(mod)) {
00404 if ((!lookupNodeIds) || (overlay->getThisNode().getKey() == key)) {
00405 if (testMsg->getMeasurementPhase() == true) {
00406 sender->evaluateData((simTime() - testMsg->getCreationTime()),
00407 overlayCtrlInfo->getHopCount(),
00408 testMsg->getByteLength());
00409 }
00410 } else if(lookupNodeIds) {
00411 if (testMsg->getMeasurementPhase() == true) {
00412 RECORD_STATS(numDropped++;
00413 bytesDropped += testMsg->getByteLength());
00414 }
00415 EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().getIp()
00416 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00417 << " Error: Lookup of NodeIDs and KBRTestMessage"
00418 << " received with different destKey!"
00419 << endl;
00420 }
00421 }
00422 }
00423
00424 EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().getIp()
00425 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00426 << " Received \"" << testMsg->getName() << "(seqNr: "
00427 << testMsg->getSeqNum() << ")\n"
00428 << " with destination key: " << key.toString(16)
00429 << endl;
00430
00431 delete overlayCtrlInfo;
00432 delete testMsg;
00433 }
00434
00435 void KBRTestApp::forward(OverlayKey* key, cPacket** msg,
00436 NodeHandle* nextHopNode)
00437 {
00438 KBRTestMessage* tempMsg = dynamic_cast<KBRTestMessage*>(*msg);
00439
00440 if (tempMsg == NULL) return;
00441
00442 tempMsg->setVisitedNodesArraySize(tempMsg->getVisitedNodesArraySize() + 1);
00443 tempMsg->setVisitedNodes(tempMsg->getVisitedNodesArraySize() - 1,
00444 overlay->getThisNode().getIp());
00445 }
00446
00447 std::pair<OverlayKey, TransportAddress> KBRTestApp::createDestKey()
00448 {
00449 if (lookupNodeIds) {
00450 const NodeHandle& handle = globalNodeList->getRandomNode(0, true,
00451 onlyLookupInoffensiveNodes);
00452 return std::make_pair(handle.getKey(), handle);
00453 }
00454
00455 return std::make_pair(OverlayKey::random(), TransportAddress::UNSPECIFIED_NODE);
00456 }
00457
00458 bool KBRTestApp::checkSeen(const OverlayKey& key, int seqNum)
00459 {
00460 MsgHandle hdl(key, seqNum);
00461
00462 for (MsgHandleBuf::iterator it = mhBufBegin; it != mhBufEnd; ++it) {
00463 if (it->key.isUnspecified()) {
00464 continue;
00465 }
00466 if (*it == hdl) {
00467 return true;
00468 }
00469 }
00470
00471 *(mhBufNext++) = hdl;
00472 if (mhBufNext == mhBufEnd) {
00473 mhBufNext = mhBufBegin;
00474 }
00475
00476 return false;
00477 }
00478
00479 void KBRTestApp::evaluateData(simtime_t latency, int hopCount, long int bytes)
00480 {
00481
00482 RECORD_STATS(numDelivered++; bytesDelivered += bytes;
00483 globalStatistics->deliveredKBRTestAppMessages++);
00484
00485 if (numSent < numDelivered) {
00486 std::ostringstream tempString;
00487 tempString << "KBRTestApp::evaluateData(): numSent ("
00488 << numSent << ") < numDelivered (" << numDelivered << ")!";
00489 throw cRuntimeError(tempString.str().c_str());
00490 }
00491
00492 RECORD_STATS(globalStatistics->recordOutVector("KBRTestApp: One-way Hop "
00493 "Count", hopCount));
00494 RECORD_STATS(globalStatistics->recordOutVector("KBRTestApp: One-way Latency",
00495 SIMTIME_DBL(latency)));
00496 }
00497
00498 void KBRTestApp::finishApp()
00499 {
00500 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00501
00502 if (time >= GlobalStatistics::MIN_MEASURED) {
00503 if (kbrOneWayTest) {
00504 globalStatistics->addStdDev("KBRTestApp: One-way Delivered Messages/s",
00505 numDelivered / time);
00506 globalStatistics->addStdDev("KBRTestApp: One-way Delivered Bytes/s",
00507 bytesDelivered / time);
00508 globalStatistics->addStdDev("KBRTestApp: One-way Dropped Messages/s",
00509 numDropped / time);
00510 globalStatistics->addStdDev("KBRTestApp: One-way Dropped Bytes/s",
00511 bytesDropped / time);
00512 if (numSent > 0) {
00513 globalStatistics->addStdDev("KBRTestApp: One-way Delivery Ratio",
00514 (float)numDelivered /
00515 (float)numSent);
00516 }
00517 }
00518
00519 if (kbrRpcTest) {
00520 globalStatistics->addStdDev("KBRTestApp: RPC Delivered Messages/s",
00521 numRpcDelivered / time);
00522 globalStatistics->addStdDev("KBRTestApp: RPC Delivered Bytes/s",
00523 bytesRpcDelivered / time);
00524 globalStatistics->addStdDev("KBRTestApp: RPC Dropped Messages/s",
00525 numRpcDropped / time);
00526 globalStatistics->addStdDev("KBRTestApp: RPC Dropped Bytes/s",
00527 bytesRpcDropped / time);
00528 #if 0
00529 if (rpcSuccLatencyCount > 0) {
00530 globalStatistics->addStdDev("KBRTestApp: RPC Success Session Latency",
00531 SIMTIME_DBL(rpcSuccLatencySum) / rpcSuccLatencyCount);
00532 }
00533
00534 if (rpcTotalLatencyCount > 0) {
00535 globalStatistics->addStdDev("KBRTestApp: RPC Total Session Latency",
00536 SIMTIME_DBL(rpcTotalLatencySum) / rpcTotalLatencyCount);
00537 }
00538 #endif
00539
00540 if (numRpcSent > 0) {
00541 globalStatistics->addStdDev("KBRTestApp: RPC Delivery Ratio",
00542 (float)numRpcDelivered /
00543 (float)numRpcSent);
00544 }
00545 }
00546
00547 if (kbrLookupTest) {
00548 globalStatistics->addStdDev("KBRTestApp: Successful Lookups/s",
00549 numLookupSuccess / time);
00550 globalStatistics->addStdDev("KBRTestApp: Failed Lookups/s",
00551 numLookupFailed / time);
00552 if (numLookupSent > 0) {
00553 globalStatistics->addStdDev("KBRTestApp: Lookup Success Ratio",
00554 (float)numLookupSuccess /
00555 (float)numLookupSent);
00556 }
00557 }
00558 }
00559 }