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