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     rpcExponentialBackoff = par("rpcExponentialBackoff");
00100 
00101     rpcsPending = 0;
00102     rpcStates.clear();
00103 
00104     defaultRpcListener = new RpcListener();
00105 
00106     //set ping cache
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     // set overlay pointer
00118     overlay = OverlayAccess().get(this);
00119 
00120     // register component
00121     thisCompType = getThisCompType();
00122     overlay->registerComp(thisCompType, this);
00123 
00124     // get pointer to the neighborCache
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     // get pointer to the cryptoModule
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 //private
00146 void BaseRpc::finishRpcs()
00147 {
00148     cancelAllRpcs();
00149 
00150     // delete default rpc listener
00151     if (defaultRpcListener != NULL) {
00152         delete defaultRpcListener;
00153         defaultRpcListener = NULL;
00154     }
00155 }
00156 
00157 void BaseRpc::cancelAllRpcs()
00158 {
00159     // stop all rpcs
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     // create nonce, timeout and set default parameters
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     // create state
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     //state.transportType = (destKey.isUnspecified() && (dest.getSourceRouteSize() == 0)
00227     //        ? UDP_TRANSPORT : transportType); //test
00228     state.routingType = routingType;
00229     state.context = context;
00230 
00231     if (rpcStates.count(nonce) > 0)
00232         throw cRuntimeError("RPC nonce collision");
00233 
00234     // set message parameters
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     // sign the message
00243     // if (transportType != INTERNAL_TRANSPORT) cryptoModule->signMessage(msg);
00244 
00245     // save copy of call message in RpcState
00246     state.callMsg = dynamic_cast<BaseCallMessage*>(msg->dup());
00247     assert(!msg->getEncapsulatedMsg() || !msg->getEncapsulatedMsg()->getControlInfo());
00248 
00249     // register state
00250     rpcStates[nonce] = state;
00251 
00252     // schedule timeout message
00253     if (state.rto != 0)
00254         scheduleAt(simTime() + state.rto, state.timeoutMsg);
00255 
00256     // TODO: cleanup code to have only one type for source routes
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         // remove the original source route from the destination
00264         sourceRoute.back().clearSourceRoute();
00265     }
00266     sendRpcMessageWithTransport(transportType, destComp, routingType,
00267                                 sourceRoute, destKey, msg);
00268 
00269     return nonce;
00270 }
00271 
00272 
00273 //public
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 //protected
00289 void BaseRpc::internalHandleRpcMessage(BaseRpcMessage* msg)
00290 {
00291     // check if this is a rpc call message
00292     BaseCallMessage* rpCall = dynamic_cast<BaseCallMessage*>(msg);
00293     if (rpCall != NULL) {
00294         // verify the message signature
00295         //cryptoModule->verifyMessage(msg);
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     // get nonce
00319     int nonce = msg->getNonce();
00320 
00321     // nonce known? no -> delete message and return
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     // get state and remove from map
00332     RpcState state = rpcStates[nonce];
00333     rpcStates.erase(nonce);
00334 
00335     // is timeout message?
00336     if (msg->isSelfMessage() &&
00337         (dynamic_cast<RpcTimeoutMessage*>(msg) != NULL)) {
00338         // yes-> inform listener
00339 
00340         // retry?
00341         state.retries--;
00342         if (state.retries>=0) {
00343             // TODO: cleanup code to have only one type for source routes
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                 // remove the original source route from the destination
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         // inform neighborcache
00373         if (state.transportType == UDP_TRANSPORT ||
00374             (!state.dest->isUnspecified() && state.destKey.isUnspecified())) {
00375             neighborCache->setNodeTimeout(*state.dest);
00376         }
00377 
00378         // inform listener
00379         if (state.listener != NULL)
00380             state.listener->handleRpcTimeout(state);
00381 
00382         // inform overlay
00383         internalHandleRpcTimeout(state.callMsg, *state.dest, state.context,
00384                                  state.id, state.destKey);
00385         handleRpcTimeout(state);
00386 
00387     } else { // no-> handle rpc response
00388 
00389         // verify the message signature
00390         //cryptoModule->verifyMessage(msg);
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         // drop responses with wrong source key
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                     // restore state to trigger timeout message
00415                     rpcStates[nonce] = state;
00416                     delete msg;
00417                     return;
00418                 }
00419         }
00420 
00421         // get parameters
00422         simtime_t rtt = simTime() - state.timeSent;
00423         BaseResponseMessage* response
00424             = dynamic_cast<BaseResponseMessage*>(msg);
00425 
00426         //if (state.transportType == UDP_TRANSPORT)
00427         //    globalStatistics->recordOutVector("BaseRpc: UDP Round Trip Time",
00428         //                                      rtt);
00429 
00430         // neighborCache/vivaldi stuff
00431         if (state.transportType == UDP_TRANSPORT ||
00432             (state.transportType != INTERNAL_TRANSPORT &&
00433              response->getCallHopCount() == 1)) { //TODO
00434             if (neighborCache->vivaldiEnabled()) {
00435                 // vivaldi: get coordinates/error estimation from message
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         // inform listener
00453         if (state.listener != NULL)
00454             state.listener->handleRpcResponse(response, state, rtt);
00455 
00456         // inform overlay
00457         internalHandleRpcResponse(response, state.context, state.id, rtt);
00458         handleRpcResponse(response, state, rtt);
00459 
00460         // delete response
00461         delete response->removeControlInfo();
00462         delete response;
00463     }
00464 
00465     // delete messages
00466     delete state.callMsg;
00467     cancelAndDelete(state.timeoutMsg);
00468     delete state.dest;
00469 
00470     // clean up pointers
00471     state.dest = NULL;
00472     state.context = NULL;
00473     state.callMsg = NULL;
00474     state.timeoutMsg = NULL;
00475 }
00476 
00477 //private
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     // call rpc stubs
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 //virtual protected
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     // vivaldi: set coordinates and error estimation in response
00530     if (neighborCache->vivaldiEnabled()) { //TODO only for directly sent msgs
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); // one udp hop (?)
00561     }
00562 
00563     // source routing
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         // empty visited hops list => direct response
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 //protected
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     // "magic" transportType selection: internal
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 // ping RPC stuff
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     //Rtt rtt(0.0, RTTSTATE_UNKNOWN);
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 //Prox BaseRpc::getProx(const TransportAddress &node,
00713 //                      int type,
00714 //                      NeighborCacheQueryType /*int*/ rpcId,
00715 //                      ProxListener *listener,
00716 //                      cPolymorphic *contextPointer)
00717 //{
00718 //    if (neighborCache) {
00719 //        return neighborCache->getProx(node, (NeighborCacheQueryType)type,
00720 //                                      rpcId, listener, contextPointer);
00721 //    } else {
00722 //        //TODO
00723 //        pingNode(node, -1, 0, contextPointer, NULL, NULL,
00724 //                 rpcId, UDP_TRANSPORT, true);
00725 //        return Prox::PROX_UNKNOWN;
00726 //    }
00727 //}

Generated on Tue Sep 8 17:26:51 2009 for OverSim by  doxygen 1.5.8