BaseRpc.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 //--- Initialization & finishing -----------------------------------------
00045 //------------------------------------------------------------------------
00046 
00047 
00048 //------------------------------------------------------------------------
00049 //--- RPC Handling -------------------------------------------------------
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     // process self-messages and RPC-timeouts
00062     if (msg->isSelfMessage()) {
00063         // process rpc self-messages
00064         BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00065         if (rpcMessage != NULL) {
00066             internalHandleRpcMessage(rpcMessage);
00067             return true;
00068         }
00069         // process all other self-messages
00070         handleTimerEvent(msg);
00071         return true;
00072     }
00073 
00074     // process RPC messages
00075     BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00076     if (rpcMessage != NULL) {
00077         internalHandleRpcMessage(rpcMessage);
00078         return true;
00079     }
00080 
00081     // other messages are processed by derived classes
00082     // (e.g. BaseOverlay / BaseApp)
00083     return false;
00084 }
00085 
00086 void BaseRpc::handleTimerEvent(cMessage* msg)
00087 {
00088     // ...
00089 }
00090 
00091 //private
00092 void BaseRpc::initRpcs()
00093 {
00094     // set friend modules
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     //set ping cache
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     // set overlay pointer
00119     overlay = OverlayAccess().get(this);
00120 
00121     // register component
00122     thisCompType = getThisCompType();
00123     overlay->registerComp(thisCompType, this);
00124 
00125     // get pointer to the neighborCache
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     // get pointer to the cryptoModule
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 //private
00147 void BaseRpc::finishRpcs()
00148 {
00149     cancelAllRpcs();
00150 
00151     // delete default rpc listener
00152     if (defaultRpcListener != NULL) {
00153         delete defaultRpcListener;
00154         defaultRpcListener = NULL;
00155     }
00156 }
00157 
00158 void BaseRpc::cancelAllRpcs()
00159 {
00160     // stop all rpcs
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     // create nonce, timeout and set default parameters
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     // create state
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     //state.transportType = (destKey.isUnspecified() && (dest.getSourceRouteSize() == 0)
00231     //        ? UDP_TRANSPORT : transportType); //test
00232     state.routingType = routingType;
00233     state.context = context;
00234 
00235     if (rpcStates.count(nonce) > 0)
00236         throw cRuntimeError("RPC nonce collision");
00237 
00238     // set message parameters
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     // sign the message
00247     // if (transportType != INTERNAL_TRANSPORT) cryptoModule->signMessage(msg);
00248 
00249     // save copy of call message in RpcState
00250     state.callMsg = dynamic_cast<BaseCallMessage*>(msg->dup());
00251     assert(!msg->getEncapsulatedPacket() || !msg->getEncapsulatedPacket()->getControlInfo());
00252 
00253     // register state
00254     rpcStates[nonce] = state;
00255 
00256     // schedule timeout message
00257     if (state.rto != 0)
00258         scheduleAt(simTime() + state.rto, state.timeoutMsg);
00259 
00260     // TODO: cleanup code to have only one type for source routes
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         // remove the original source route from the destination
00268         sourceRoute.back().clearSourceRoute();
00269     }
00270     sendRpcMessageWithTransport(transportType, destComp, routingType,
00271                                 sourceRoute, destKey, msg);
00272 
00273     return nonce;
00274 }
00275 
00276 
00277 //public
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 //protected
00293 void BaseRpc::internalHandleRpcMessage(BaseRpcMessage* msg)
00294 {
00295     // check if this is a rpc call message
00296     BaseCallMessage* rpCall = dynamic_cast<BaseCallMessage*>(msg);
00297     if (rpCall != NULL) {
00298         // verify the message signature
00299         //cryptoModule->verifyMessage(msg);
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     // get nonce
00323     int nonce = msg->getNonce();
00324 
00325     // nonce known? no -> delete message and return
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     // get state and remove from map
00336     RpcState state = rpcStates[nonce];
00337     rpcStates.erase(nonce);
00338 
00339     // is timeout message?
00340     if (msg->isSelfMessage() &&
00341         (dynamic_cast<RpcTimeoutMessage*>(msg) != NULL)) {
00342         // yes-> inform listener
00343 
00344         // retry?
00345         state.retries--;
00346         if (state.retries>=0) {
00347             // TODO: cleanup code to have only one type for source routes
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                 // remove the original source route from the destination
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         // inform neighborcache
00382         if (state.transportType == UDP_TRANSPORT ||
00383             (!state.dest->isUnspecified() && state.destKey.isUnspecified())) {
00384             neighborCache->setNodeTimeout(*state.dest);
00385         }
00386 
00387         // inform listener
00388         if (state.listener != NULL)
00389             state.listener->handleRpcTimeout(state);
00390 
00391         // inform overlay
00392         internalHandleRpcTimeout(state.callMsg, *state.dest, state.context,
00393                                  state.id, state.destKey);
00394         handleRpcTimeout(state);
00395 
00396     } else { // no-> handle rpc response
00397 
00398         // verify the message signature
00399         //cryptoModule->verifyMessage(msg);
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         // drop responses with wrong source key
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                     // restore state to trigger timeout message
00424                     rpcStates[nonce] = state;
00425                     delete msg;
00426                     return;
00427                 }
00428         }
00429 
00430         // get parameters
00431         simtime_t rtt = simTime() - state.timeSent;
00432         BaseResponseMessage* response
00433             = dynamic_cast<BaseResponseMessage*>(msg);
00434 
00435         //if (state.transportType == UDP_TRANSPORT)
00436         //    globalStatistics->recordOutVector("BaseRpc: UDP Round Trip Time",
00437         //                                      rtt);
00438 
00439         // neighborCache/vivaldi stuff
00440         if (state.transportType == UDP_TRANSPORT ||
00441             (state.transportType != INTERNAL_TRANSPORT &&
00442              response->getCallHopCount() == 1)) { //TODO
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         // inform listener
00465         if (state.listener != NULL)
00466             state.listener->handleRpcResponse(response, state, rtt);
00467 
00468         // inform overlay
00469         internalHandleRpcResponse(response, state.context, state.id, rtt);
00470         handleRpcResponse(response, state, rtt);
00471 
00472         // delete response
00473         delete response->removeControlInfo();
00474         delete response;
00475     }
00476 
00477     // delete messages
00478     delete state.callMsg;
00479     cancelAndDelete(state.timeoutMsg);
00480     delete state.dest;
00481 
00482     // clean up pointers
00483     state.dest = NULL;
00484     state.context = NULL;
00485     state.callMsg = NULL;
00486     state.timeoutMsg = NULL;
00487 }
00488 
00489 //private
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     // call rpc stubs
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 //virtual protected
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     // vivaldi: set coordinates and error estimation in response
00542     if (neighborCache->adaptingNcs()) { //TODO only for directly sent msgs
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); // one udp hop (?)
00573     }
00574 
00575     // source routing
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         // empty visited hops list => direct response
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 //protected
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     // "magic" transportType selection: internal
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 // ping RPC stuff
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 
Generated on Wed May 26 16:21:13 2010 for OverSim by  doxygen 1.6.3