00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00027 #include <vector>
00028 #include <string>
00029 #include <cassert>
00030
00031 #include <CommonMessages_m.h>
00032 #include <UnderlayConfiguratorAccess.h>
00033 #include <GlobalStatisticsAccess.h>
00034 #include <NeighborCache.h>
00035 #include <CryptoModule.h>
00036 #include <Vivaldi.h>
00037 #include <OverlayAccess.h>
00038
00039 #include "BaseRpc.h"
00040 #include "RpcMacros.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 BaseRpc::BaseRpc()
00053 {
00054 defaultRpcListener = NULL;
00055 neighborCache = NULL;
00056 cryptoModule = NULL;
00057 }
00058
00059 bool BaseRpc::internalHandleMessage(cMessage* msg)
00060 {
00061
00062 if (msg->isSelfMessage()) {
00063
00064 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00065 if (rpcMessage != NULL) {
00066 internalHandleRpcMessage(rpcMessage);
00067 return true;
00068 }
00069
00070 handleTimerEvent(msg);
00071 return true;
00072 }
00073
00074
00075 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00076 if (rpcMessage != NULL) {
00077 internalHandleRpcMessage(rpcMessage);
00078 return true;
00079 }
00080
00081
00082
00083 return false;
00084 }
00085
00086 void BaseRpc::handleTimerEvent(cMessage* msg)
00087 {
00088
00089 }
00090
00091
00092 void BaseRpc::initRpcs()
00093 {
00094
00095 globalStatistics = GlobalStatisticsAccess().get();
00096
00097 rpcUdpTimeout = par("rpcUdpTimeout");
00098 rpcKeyTimeout = par("rpcKeyTimeout");
00099 rpcExponentialBackoff = par("rpcExponentialBackoff");
00100
00101 rpcsPending = 0;
00102 rpcStates.clear();
00103
00104 defaultRpcListener = new RpcListener();
00105
00106
00107 numPingSent = 0;
00108 bytesPingSent = 0;
00109 numPingResponseSent = 0;
00110 bytesPingResponseSent = 0;
00111
00112 WATCH(numPingSent);
00113 WATCH(bytesPingSent);
00114 WATCH(numPingResponseSent);
00115 WATCH(bytesPingResponseSent);
00116
00117
00118 overlay = OverlayAccess().get(this);
00119
00120
00121 thisCompType = getThisCompType();
00122 overlay->registerComp(thisCompType, this);
00123
00124
00125 cModule *mod = getParentModule();
00126 while (neighborCache == NULL) {
00127 neighborCache = (NeighborCache*)mod->getSubmodule("neighborCache");
00128 mod = mod->getParentModule();
00129 if (!mod)
00130 throw cRuntimeError("BaseRpc::initRpc: "
00131 "Module type contains no ping cache!");
00132 }
00133
00134
00135 mod = getParentModule();
00136 cryptoModule = NULL;
00137 while (cryptoModule == NULL) {
00138 cryptoModule = (CryptoModule*)mod->getSubmodule("cryptoModule");
00139 mod = mod->getParentModule();
00140 if (!mod)
00141 throw cRuntimeError("BaseRpc::initRpc: CryptoModule not found!");
00142 }
00143 }
00144
00145
00146 void BaseRpc::finishRpcs()
00147 {
00148 cancelAllRpcs();
00149
00150
00151 if (defaultRpcListener != NULL) {
00152 delete defaultRpcListener;
00153 defaultRpcListener = NULL;
00154 }
00155 }
00156
00157 void BaseRpc::cancelAllRpcs()
00158 {
00159
00160 for (RpcStates::iterator i = rpcStates.begin();
00161 i != rpcStates.end(); i++) {
00162 cancelAndDelete(i->second.callMsg);
00163 cancelAndDelete(i->second.timeoutMsg);
00164 delete i->second.dest;
00165 i->second.dest = NULL;
00166 delete i->second.context;
00167 i->second.context = NULL;
00168 }
00169 rpcStates.clear();
00170 }
00171
00172 uint32_t BaseRpc::sendRpcCall(TransportType transportType,
00173 CompType destComp,
00174 const TransportAddress& dest,
00175 const OverlayKey& destKey,
00176 BaseCallMessage* msg,
00177 cPolymorphic* context,
00178 RoutingType routingType,
00179 simtime_t timeout,
00180 int retries,
00181 int rpcId,
00182 RpcListener* rpcListener)
00183 {
00184
00185 uint32_t nonce;
00186 do {
00187 nonce = intuniform(1, 2147483647);
00188 } while (rpcStates.count(nonce) > 0);
00189
00190 if (timeout == -1) {
00191 switch (transportType) {
00192 case INTERNAL_TRANSPORT:
00193 timeout = 0;
00194 break;
00195 case UDP_TRANSPORT:
00196 timeout = rpcUdpTimeout;
00197 break;
00198 case ROUTE_TRANSPORT:
00199 timeout = (destKey.isUnspecified() ?
00200 rpcUdpTimeout :
00201 rpcKeyTimeout);
00202 break;
00203 default:
00204 throw cRuntimeError("BaseRpc::sendRpcMessage(): "
00205 "Unknown RpcTransportType!");
00206 }
00207 }
00208
00209 if (rpcListener == NULL)
00210 rpcListener = defaultRpcListener;
00211
00212
00213 RpcState state;
00214 state.id = rpcId;
00215 state.timeSent = simTime();
00216 state.dest = dest.dup();
00217 state.destKey = destKey;
00218 state.srcComp = getThisCompType();
00219 state.destComp = destComp;
00220 state.listener = rpcListener;
00221 state.timeoutMsg = new RpcTimeoutMessage();
00222 state.timeoutMsg->setNonce(nonce);
00223 state.retries = retries;
00224 state.rto = timeout;
00225 state.transportType = transportType;
00226
00227
00228 state.routingType = routingType;
00229 state.context = context;
00230
00231 if (rpcStates.count(nonce) > 0)
00232 throw cRuntimeError("RPC nonce collision");
00233
00234
00235 msg->setNonce(nonce);
00236 if (transportType == ROUTE_TRANSPORT)
00237 msg->setSrcNode(overlay->getThisNode());
00238 else
00239 msg->setSrcNode(thisNode);
00240 msg->setType(RPC);
00241
00242
00243
00244
00245
00246 state.callMsg = dynamic_cast<BaseCallMessage*>(msg->dup());
00247 assert(!msg->getEncapsulatedMsg() || !msg->getEncapsulatedMsg()->getControlInfo());
00248
00249
00250 rpcStates[nonce] = state;
00251
00252
00253 if (state.rto != 0)
00254 scheduleAt(simTime() + state.rto, state.timeoutMsg);
00255
00256
00257 std::vector<TransportAddress> sourceRoute;
00258 sourceRoute.push_back(dest);
00259 if (dest.getSourceRouteSize() > 0) {
00260 state.transportType = transportType = ROUTE_TRANSPORT;
00261 sourceRoute.insert(sourceRoute.begin(), dest.getSourceRoute().rend(),
00262 dest.getSourceRoute().rbegin());
00263
00264 sourceRoute.back().clearSourceRoute();
00265 }
00266 sendRpcMessageWithTransport(transportType, destComp, routingType,
00267 sourceRoute, destKey, msg);
00268
00269 return nonce;
00270 }
00271
00272
00273
00274 void BaseRpc::cancelRpcMessage(uint32_t nonce)
00275 {
00276 if (rpcStates.count(nonce)==0)
00277 return;
00278 RpcState state = rpcStates[nonce];
00279 rpcStates.erase(nonce);
00280 cancelAndDelete(state.callMsg);
00281 cancelAndDelete(state.timeoutMsg);
00282 delete state.dest;
00283 state.dest = NULL;
00284 delete state.context;
00285 state.context = NULL;
00286 }
00287
00288
00289 void BaseRpc::internalHandleRpcMessage(BaseRpcMessage* msg)
00290 {
00291
00292 BaseCallMessage* rpCall = dynamic_cast<BaseCallMessage*>(msg);
00293 if (rpCall != NULL) {
00294
00295
00296
00297 OverlayCtrlInfo* overlayCtrlInfo =
00298 check_and_cast<OverlayCtrlInfo*>(msg->getControlInfo());
00299
00300 if (overlayCtrlInfo->getSrcRoute().isUnspecified() &&
00301 (!overlayCtrlInfo->getLastHop().isUnspecified())) {
00302 overlayCtrlInfo->setSrcRoute(NodeHandle(msg->getSrcNode().getKey(),
00303 overlayCtrlInfo->getLastHop()));
00304 }
00305
00306 bool rpcHandled = true;
00307 if (!handleRpcCall(rpCall)) rpcHandled = internalHandleRpcCall(rpCall);
00308 if (!rpcHandled) {
00309 EV << "[BaseRpc::internalHandleRpcMessage() @ " << thisNode.getAddress()
00310 << " (" << thisNode.getKey().toString(16) << ")]\n"
00311 << " Error: RPC '" << msg->getFullName()<< "' was not handled"
00312 << endl;
00313 delete msg;
00314 }
00315 return;
00316 }
00317
00318
00319 int nonce = msg->getNonce();
00320
00321
00322 if (rpcStates.count(nonce)==0) {
00323 EV << "[BaseRpc::internalHandleRpcMessage() @ " << thisNode.getAddress()
00324 << " " << thisNode.getKey().toString(16) << ")]\n"
00325 << " RPC: Nonce Unknown"
00326 << endl;
00327 delete msg;
00328 return;
00329 }
00330
00331
00332 RpcState state = rpcStates[nonce];
00333 rpcStates.erase(nonce);
00334
00335
00336 if (msg->isSelfMessage() &&
00337 (dynamic_cast<RpcTimeoutMessage*>(msg) != NULL)) {
00338
00339
00340
00341 state.retries--;
00342 if (state.retries>=0) {
00343
00344 std::vector<TransportAddress> sourceRoute;
00345 sourceRoute.push_back(*state.dest);
00346 if (state.dest->getSourceRouteSize() > 0) {
00347 sourceRoute.insert(sourceRoute.begin(),
00348 state.dest->getSourceRoute().rend(),
00349 state.dest->getSourceRoute().rbegin());
00350
00351 sourceRoute.back().clearSourceRoute();
00352 }
00353
00354 sendRpcMessageWithTransport(state.transportType, state.destComp,
00355 state.routingType,
00356 sourceRoute,
00357 state.destKey,
00358 dynamic_cast<BaseCallMessage*>
00359 (state.callMsg->dup()));
00360
00361 if (rpcExponentialBackoff) {
00362 state.rto *= 2;
00363 }
00364
00365 if (state.rto!=0)
00366 scheduleAt(simTime() + state.rto, msg);
00367
00368 state.timeSent = simTime();
00369 rpcStates[nonce] = state;
00370 return;
00371 }
00372
00373 if (state.transportType == UDP_TRANSPORT ||
00374 (!state.dest->isUnspecified() && state.destKey.isUnspecified())) {
00375 neighborCache->setNodeTimeout(*state.dest);
00376 }
00377
00378
00379 if (state.listener != NULL)
00380 state.listener->handleRpcTimeout(state);
00381
00382
00383 internalHandleRpcTimeout(state.callMsg, *state.dest, state.context,
00384 state.id, state.destKey);
00385 handleRpcTimeout(state);
00386
00387 } else {
00388
00389
00390
00391
00392 OverlayCtrlInfo* overlayCtrlInfo =
00393 check_and_cast<OverlayCtrlInfo*>(msg->getControlInfo());
00394
00395 if (overlayCtrlInfo->getSrcRoute().isUnspecified() &&
00396 (!overlayCtrlInfo->getLastHop().isUnspecified())) {
00397 overlayCtrlInfo->setSrcRoute(NodeHandle(msg->getSrcNode().getKey(),
00398 overlayCtrlInfo->getLastHop()));
00399 }
00400
00401
00402 if (state.destKey.isUnspecified()) {
00403 const NodeHandle* stateHandle =
00404 dynamic_cast<const NodeHandle*>(state.dest);
00405 if (stateHandle != NULL &&
00406 stateHandle->getKey() != msg->getSrcNode().getKey()) {
00407
00408 EV << "[BaseRpc::internalHandleRpcMessage() @ "
00409 << thisNode.getAddress()
00410 << " " << thisNode.getKey().toString(16) << ")]\n"
00411 << " Dropping RPC: Invalid source key"
00412 << endl;
00413
00414
00415 rpcStates[nonce] = state;
00416 delete msg;
00417 return;
00418 }
00419 }
00420
00421
00422 simtime_t rtt = simTime() - state.timeSent;
00423 BaseResponseMessage* response
00424 = dynamic_cast<BaseResponseMessage*>(msg);
00425
00426
00427
00428
00429
00430
00431 if (state.transportType == UDP_TRANSPORT ||
00432 (state.transportType != INTERNAL_TRANSPORT &&
00433 response->getCallHopCount() == 1)) {
00434 if (neighborCache->vivaldiEnabled()) {
00435
00436 std::vector<double> nodeCoords;
00437 nodeCoords.resize(response->getCoordsArraySize());
00438 for (uint32_t i = 0; i < response->getCoordsArraySize(); i++)
00439 nodeCoords[i] = response->getCoords(i);
00440 OverlayCtrlInfo* ctrlInfo =
00441 dynamic_cast<OverlayCtrlInfo*>(response->getControlInfo());
00442 neighborCache->updateNode(response->getSrcNode(), rtt,
00443 (ctrlInfo ?
00444 ctrlInfo->getSrcRoute() :
00445 NodeHandle::UNSPECIFIED_NODE),
00446 nodeCoords, response->getError());
00447 } else {
00448 neighborCache->updateNode(response->getSrcNode(), rtt);
00449 }
00450 }
00451
00452
00453 if (state.listener != NULL)
00454 state.listener->handleRpcResponse(response, state, rtt);
00455
00456
00457 internalHandleRpcResponse(response, state.context, state.id, rtt);
00458 handleRpcResponse(response, state, rtt);
00459
00460
00461 delete response->removeControlInfo();
00462 delete response;
00463 }
00464
00465
00466 delete state.callMsg;
00467 cancelAndDelete(state.timeoutMsg);
00468 delete state.dest;
00469
00470
00471 state.dest = NULL;
00472 state.context = NULL;
00473 state.callMsg = NULL;
00474 state.timeoutMsg = NULL;
00475 }
00476
00477
00478 bool BaseRpc::internalHandleRpcCall(BaseCallMessage* msg)
00479 {
00480 RPC_SWITCH_START( msg );
00481 RPC_DELEGATE( Ping, pingRpcCall );
00482 RPC_SWITCH_END( );
00483
00484 return RPC_HANDLED;
00485 }
00486
00487 void BaseRpc::internalHandleRpcResponse(BaseResponseMessage* msg,
00488 cPolymorphic* context,
00489 int rpcId, simtime_t rtt)
00490 {
00491
00492 RPC_SWITCH_START( msg );
00493 RPC_ON_RESPONSE( Ping ) {
00494 pingRpcResponse(_PingResponse, context, rpcId, rtt);
00495 }
00496 RPC_SWITCH_END( );
00497 }
00498
00499 void BaseRpc::internalHandleRpcTimeout(BaseCallMessage* msg,
00500 const TransportAddress& dest,
00501 cPolymorphic* context,
00502 int rpcId, const OverlayKey& destKey)
00503 {
00504 RPC_SWITCH_START( msg ) {
00505 RPC_ON_CALL( Ping ) {
00506 pingRpcTimeout(_PingCall, dest, context, rpcId);
00507 }
00508 }
00509 RPC_SWITCH_END( )
00510 }
00511
00512
00513 bool BaseRpc::handleRpcCall(BaseCallMessage* msg)
00514 {
00515 return false;
00516 }
00517
00518 void BaseRpc::sendRpcResponse(TransportType transportType,
00519 CompType compType,
00520 const TransportAddress& dest,
00521 const OverlayKey& destKey,
00522 BaseCallMessage* call,
00523 BaseResponseMessage* response)
00524 {
00525 if (call == NULL || response == NULL) {
00526 throw cRuntimeError("call or response = NULL!");
00527 }
00528
00529
00530 if (neighborCache->vivaldiEnabled()) {
00531 const std::vector<double>& nodeCoord =
00532 neighborCache->getVivaldiAccess().getOwnCoordinates();
00533 response->setError(neighborCache->getVivaldiAccess().getOwnError());
00534 response->setCoordsArraySize(nodeCoord.size());
00535 for (uint32_t i = 0; i < nodeCoord.size(); i++) {
00536 response->setCoords(i, nodeCoord[i]);
00537 }
00538 }
00539
00540 assert(transportType == INTERNAL_TRANSPORT ||
00541 !dest.isUnspecified() ||
00542 !destKey.isUnspecified());
00543
00544 if (transportType == ROUTE_TRANSPORT)
00545 response->setSrcNode(overlay->getThisNode());
00546 else
00547 response->setSrcNode(thisNode);
00548 response->setType(RPC);
00549 response->setNonce(call->getNonce());
00550 response->setStatType(call->getStatType());
00551
00552 RoutingType routingType = NO_OVERLAY_ROUTING;
00553 OverlayCtrlInfo* overlayCtrlInfo = NULL;
00554 if (dynamic_cast<OverlayCtrlInfo*>(call->getControlInfo())) {
00555 overlayCtrlInfo =
00556 static_cast<OverlayCtrlInfo*>(call->removeControlInfo());
00557 response->setCallHopCount(overlayCtrlInfo->getHopCount());
00558 } else {
00559 delete call->removeControlInfo();
00560 response->setCallHopCount(1);
00561 }
00562
00563
00564 std::vector<TransportAddress> sourceRoute;
00565 if (overlayCtrlInfo && transportType == ROUTE_TRANSPORT) {
00566 routingType =
00567 static_cast<RoutingType>(overlayCtrlInfo->getRoutingType());
00568 for (uint32_t i = overlayCtrlInfo->getVisitedHopsArraySize(); i > 0; --i) {
00569 sourceRoute.push_back(overlayCtrlInfo->getVisitedHops(i - 1));
00570 }
00571 }
00572
00573 if (sourceRoute.size() == 0) {
00574
00575 sourceRoute.push_back(dest);
00576 }
00577
00578 sendRpcMessageWithTransport(transportType, compType,
00579 routingType, sourceRoute,
00580 destKey, response);
00581 delete overlayCtrlInfo;
00582 delete call;
00583 }
00584
00585
00586 void BaseRpc::sendRpcResponse(BaseCallMessage* call,
00587 BaseResponseMessage* response)
00588 {
00589 const TransportAddress* destNode = &(call->getSrcNode());
00590 const OverlayKey* destKey = &(call->getSrcNode().getKey());
00591
00592 OverlayCtrlInfo* overlayCtrlInfo =
00593 dynamic_cast<OverlayCtrlInfo*>(call->getControlInfo());
00594
00595
00596 if (overlayCtrlInfo &&
00597 overlayCtrlInfo->getTransportType() == INTERNAL_TRANSPORT) {
00598 sendRpcResponse(INTERNAL_TRANSPORT,
00599 static_cast<CompType>(overlayCtrlInfo->getSrcComp()),
00600 *destNode, *destKey, call, response);
00601 } else {
00602 internalSendRpcResponse(call, response);
00603 }
00604 }
00605
00606 void BaseRpc::sendRpcMessageWithTransport(TransportType transportType,
00607 CompType destComp,
00608 RoutingType routingType,
00609 const std::vector<TransportAddress>& sourceRoute,
00610 const OverlayKey& destKey,
00611 BaseRpcMessage* message)
00612 {
00613 switch (transportType) {
00614 case UDP_TRANSPORT: {
00615 sendMessageToUDP(sourceRoute[0], message);
00616 break;
00617 }
00618 case ROUTE_TRANSPORT: {
00619 internalSendRouteRpc(message, destKey,
00620 sourceRoute, routingType);
00621 break;
00622 }
00623 case INTERNAL_TRANSPORT: {
00624 cGate *destCompGate = overlay->getCompRpcGate(destComp);
00625 if (destCompGate == NULL) {
00626 throw cRuntimeError("BaseRpc::sendRpcMessageWithTransport():"
00627 " INTERNAL_RPC to unknown RpcCompType!");
00628 }
00629 OverlayCtrlInfo *overlayCtrlInfo = new OverlayCtrlInfo();
00630 overlayCtrlInfo->setSrcComp(getThisCompType());
00631 overlayCtrlInfo->setDestComp(destComp);
00632 overlayCtrlInfo->setTransportType(INTERNAL_TRANSPORT);
00633 message->setControlInfo(overlayCtrlInfo);
00634 sendDirect(message, destCompGate);
00635 break;
00636 }
00637 default:
00638 throw cRuntimeError("BaseRpc::sendRpcMessageWithTransport: "
00639 "invalid transportType!");
00640 break;
00641 }
00642 }
00643
00644
00645 void BaseRpc::pingResponse(PingResponse* response, cPolymorphic* context,
00646 int rpcId, simtime_t rtt)
00647 {
00648 }
00649
00650 void BaseRpc::pingTimeout(PingCall* call, const TransportAddress& dest,
00651 cPolymorphic* context, int rpcId)
00652 {
00653 }
00654
00655 void BaseRpc::pingRpcCall(PingCall* call)
00656 {
00657 std::string pongName(call->getName());
00658 if (pongName == "PING")
00659 pongName = "PONG";
00660 else {
00661 pongName = "PONG: [ ";
00662 pongName += call->getName();
00663 pongName += " ]";
00664 }
00665
00666 PingResponse* response = new PingResponse(pongName.c_str());
00667 response->setBitLength(PINGRESPONSE_L(response));
00668 RECORD_STATS(numPingResponseSent++; bytesPingResponseSent +=
00669 response->getByteLength());
00670
00671 sendRpcResponse(call, response );
00672 }
00673
00674 void BaseRpc::pingRpcResponse(PingResponse* response,
00675 cPolymorphic* context, int rpcId, simtime_t rtt)
00676 {
00677 pingResponse(response, context, rpcId, rtt);
00678 }
00679
00680 void BaseRpc::pingRpcTimeout(PingCall* pingCall,
00681 const TransportAddress& dest,
00682 cPolymorphic* context,
00683 int rpcId)
00684 {
00685 pingTimeout(pingCall, dest, context, rpcId);
00686 }
00687
00688 void BaseRpc::pingNode(const TransportAddress& dest, simtime_t timeout,
00689 int retries, cPolymorphic* context,
00690 const char* caption, RpcListener* rpcListener,
00691 int rpcId, TransportType transportType)
00692 {
00693
00694
00695 PingCall* call = new PingCall(caption);
00696 call->setBitLength(PINGCALL_L(call));
00697 RECORD_STATS(numPingSent++; bytesPingSent += call->getByteLength());
00698
00699 if (transportType == UDP_TRANSPORT ||
00700 (transportType != ROUTE_TRANSPORT &&
00701 getThisCompType() == OVERLAY_COMP)) {
00702 sendUdpRpcCall(dest, call, context, timeout, retries, rpcId,
00703 rpcListener);
00704 } else {
00705 sendRouteRpcCall(getThisCompType(), dest, call, context,
00706 DEFAULT_ROUTING, timeout, retries, rpcId,
00707 rpcListener);
00708 }
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727