00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <platdep/sockets.h>
00025 #if not defined _WIN32
00026 #include <arpa/inet.h>
00027 #endif
00028
00029 #if not defined _WIN32 && not defined __APPLE__
00030 #include <netinet/ip6.h>
00031 #endif
00032
00033 #include <NodeVector.h>
00034 #include <P2pns.h>
00035 #include <sstream>
00036 #include "XmlRpcInterface.h"
00037
00038 using namespace XmlRpc;
00039
00040 Define_Module(XmlRpcInterface);
00041
00042
00043 class P2pnsRegister : public XmlRpcServerMethod
00044 {
00045 public:
00046 P2pnsRegister(XmlRpcServer* s) :
00047 XmlRpcServerMethod("register", s)
00048 {
00049 }
00050
00051 void execute(XmlRpcValue& params, XmlRpcValue& result)
00052 {
00053 (dynamic_cast<XmlRpcInterface*>(_server))->p2pnsRegister(params, result);
00054 }
00055
00056 std::string help()
00057 {
00058 return std::string("Register a name with P2PNS");
00059 }
00060 };
00061
00062
00063 class P2pnsResolve : public XmlRpcServerMethod
00064 {
00065 public:
00066 P2pnsResolve(XmlRpcServer* s) :
00067 XmlRpcServerMethod("resolve", s)
00068 {
00069 }
00070
00071 void execute(XmlRpcValue& params, XmlRpcValue& result)
00072 {
00073 (dynamic_cast<XmlRpcInterface*>(_server))->p2pnsResolve(params, result);
00074 }
00075
00076 std::string help()
00077 {
00078 return std::string("Resolve a name with P2PNS");
00079 }
00080 };
00081
00082
00083 class LocalLookup : public XmlRpcServerMethod
00084 {
00085 public:
00086 LocalLookup(XmlRpcServer* s) :
00087 XmlRpcServerMethod("local_lookup", s)
00088 {
00089 }
00090
00091 void execute(XmlRpcValue& params, XmlRpcValue& result)
00092 {
00093 (dynamic_cast<XmlRpcInterface*>(_server))->localLookup(params, result);
00094 }
00095
00096 std::string help()
00097 {
00098 return std::string("Lookup key in local "
00099 "routing table");
00100 }
00101 };
00102
00103
00104 class Lookup : public XmlRpcServerMethod
00105 {
00106 public:
00107 Lookup(XmlRpcServer* s) :
00108 XmlRpcServerMethod("lookup", s)
00109 {
00110 }
00111
00112 void execute(XmlRpcValue& params, XmlRpcValue& result)
00113 {
00114 (dynamic_cast<XmlRpcInterface*>(_server))->lookup(params, result);
00115 }
00116
00117 std::string help()
00118 {
00119 return std::string("Lookup key with KBR layer");
00120 }
00121 };
00122
00123
00124 class Put : public XmlRpcServerMethod
00125 {
00126 public:
00127 Put(XmlRpcServer* s) :
00128 XmlRpcServerMethod("put", s)
00129 {
00130 }
00131
00132 void execute(XmlRpcValue& params, XmlRpcValue& result)
00133 {
00134 (dynamic_cast<XmlRpcInterface*>(_server))->put(params, result);
00135 }
00136
00137 std::string help()
00138 {
00139 return std::string("Store a value in the DHT");
00140 }
00141 };
00142
00143
00144 class Get : public XmlRpcServerMethod
00145 {
00146 public:
00147 Get(XmlRpcServer* s) :
00148 XmlRpcServerMethod("get", s)
00149 {
00150 }
00151
00152 void execute(XmlRpcValue& params, XmlRpcValue& result)
00153 {
00154 (dynamic_cast<XmlRpcInterface*>(_server))->get(params, result);
00155 }
00156
00157 std::string help()
00158 {
00159 return std::string("Get a value from the DHT");
00160 }
00161 };
00162
00163
00164 class DumpDht : public XmlRpcServerMethod
00165 {
00166 public:
00167 DumpDht(XmlRpcServer* s) :
00168 XmlRpcServerMethod("dump_dht", s)
00169 {
00170 }
00171
00172 void execute(XmlRpcValue& params, XmlRpcValue& result)
00173 {
00174 (dynamic_cast<XmlRpcInterface*>(_server))->dumpDht(params, result);
00175 }
00176
00177 std::string help()
00178 {
00179 return std::string("Dump all local records from the DHT");
00180 }
00181 };
00182
00183
00184 class JoinOverlay : public XmlRpcServerMethod
00185 {
00186 public:
00187 JoinOverlay(XmlRpcServer* s) :
00188 XmlRpcServerMethod("join", s)
00189 {
00190 }
00191
00192 void execute(XmlRpcValue& params, XmlRpcValue& result)
00193 {
00194 (dynamic_cast<XmlRpcInterface*>(_server))->joinOverlay(params, result);
00195 }
00196
00197 std::string help()
00198 {
00199 return std::string("Join the overlay with a specific nodeID");
00200 }
00201 };
00202
00203 void XmlRpcInterface::p2pnsRegister(XmlRpcValue& params, XmlRpcValue& result)
00204 {
00205 if ((params.size() != 5) ||
00206 (params[0].getType() != XmlRpcValue::TypeBase64) ||
00207 (params[1].getType() != XmlRpcValue::TypeInt) ||
00208 (params[2].getType() != XmlRpcValue::TypeInt) ||
00209 (params[3].getType() != XmlRpcValue::TypeBase64) ||
00210 (params[4].getType() != XmlRpcValue::TypeInt))
00211 throw XmlRpcException("register(base64 name, int kind, int id, base64 address, int ttl): "
00212 "Invalid argument type");
00213
00214 if (overlay->getCompModule(TIER2_COMP) == NULL)
00215 throw XmlRpcException("register(base64 name, int kind, int id, base64 address, int ttl): "
00216 "No P2PNS service");
00217
00218 if (!isPrivileged()) {
00219 throw XmlRpcException("register(base64 name, int kind, base64 address, "
00220 "int ttl): Not allowed");
00221 }
00222
00223 state[curAppFd]._connectionState = EXECUTE_REQUEST;
00224
00225 P2pnsRegisterCall* registerCall = new P2pnsRegisterCall();
00226 registerCall->setP2pName(((const XmlRpcValue::BinaryData&)params[0]));
00227 registerCall->setKind((int)params[1]);
00228 registerCall->setId((int)params[2]);
00229 registerCall->setAddress(((const XmlRpcValue::BinaryData&)params[3]));
00230 registerCall->setTtl(params[4]);
00231
00232 sendInternalRpcWithTimeout(TIER2_COMP, registerCall);
00233 }
00234
00235 void XmlRpcInterface::p2pnsResolve(XmlRpcValue& params, XmlRpcValue& result)
00236 {
00237 if ((params.size() != 2) ||
00238 (params[0].getType() != XmlRpcValue::TypeBase64) ||
00239 (params[1].getType() != XmlRpcValue::TypeInt))
00240 throw XmlRpcException("resolve(base64 name, int kind): Invalid argument type");
00241
00242 if (overlay->getCompModule(TIER2_COMP) == NULL)
00243 throw XmlRpcException("resolve(base64 name, int kind): No P2PNS service");
00244
00245 state[curAppFd]._connectionState = EXECUTE_REQUEST;
00246
00247 P2pnsResolveCall* resolveCall = new P2pnsResolveCall();
00248
00249 resolveCall->setP2pName(((const XmlRpcValue::BinaryData&)params[0]));
00250 resolveCall->setKind((int)params[1]);
00251 resolveCall->setId(0);
00252
00253 sendInternalRpcWithTimeout(TIER2_COMP, resolveCall);
00254 }
00255
00256 void XmlRpcInterface::localLookup(XmlRpcValue& params, XmlRpcValue& result)
00257 {
00258 if ((params.size() != 3)
00259 || (params[0].getType() != XmlRpcValue::TypeBase64)
00260 || (params[1].getType() != XmlRpcValue::TypeInt)
00261 || (params[2].getType() != XmlRpcValue::TypeBoolean))
00262 throw XmlRpcException("local_lookup(base64 key, int num, "
00263 "boolean safe): Invalid argument type");
00264
00265 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0];
00266
00267 NodeVector* nextHops = NULL;
00268
00269 if (keyString.size() > 0) {
00270 nextHops = overlay->local_lookup(OverlayKey::sha1(keyString),
00271 params[1], params[2]);
00272 } else {
00273 nextHops = overlay->local_lookup(overlay->getThisNode().getKey(),
00274 params[1], params[2]);
00275 }
00276
00277 for (uint32_t i=0; i < nextHops->size(); i++) {
00278 result[i][0] = (*nextHops)[i].getAddress().str();
00279 result[i][1] = (*nextHops)[i].getPort();
00280 result[i][2] = (*nextHops)[i].getKey().toString(16);
00281 }
00282
00283 delete nextHops;
00284 }
00285
00286 void XmlRpcInterface::lookup(XmlRpcValue& params, XmlRpcValue& result)
00287 {
00288 if (((params.size() != 2)
00289 || (params[0].getType() != XmlRpcValue::TypeBase64)
00290 || (params[1].getType() != XmlRpcValue::TypeInt))
00291 && ((params.size() != 3)
00292 || (params[0].getType() != XmlRpcValue::TypeBase64)
00293 || (params[1].getType() != XmlRpcValue::TypeInt)
00294 || (params[2].getType() != XmlRpcValue::TypeInt)))
00295 throw XmlRpcException("lookup(base64 key, int numSiblings(, "
00296 "int RoutingType)): Invalid argument type");
00297
00298 if ((int)params[1] > overlay->getMaxNumSiblings())
00299 throw XmlRpcException("lookup(base64 key, int numSiblings(, "
00300 "int RoutingType)): numSibling to big");
00301
00302 if (params.size() == 3) {
00303 if (((int)params[2] != DEFAULT_ROUTING) &&
00304 ((int)params[2] != ITERATIVE_ROUTING) &&
00305 ((int)params[2] != EXHAUSTIVE_ITERATIVE_ROUTING) &&
00306 ((int)params[2] != SEMI_RECURSIVE_ROUTING) &&
00307 ((int)params[2] != FULL_RECURSIVE_ROUTING) &&
00308 ((int)params[2] != RECURSIVE_SOURCE_ROUTING)) {
00309
00310 throw XmlRpcException("lookup(base64 key, int numSiblings(, "
00311 "int RoutingType)): invalid routingType");
00312 }
00313 }
00314
00315 state[curAppFd]._connectionState = EXECUTE_REQUEST;
00316
00317 LookupCall* lookupCall = new LookupCall();
00318
00319 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0];
00320 lookupCall->setKey(OverlayKey::sha1(keyString));
00321 lookupCall->setNumSiblings(params[1]);
00322
00323 if (params.size() == 3) {
00324 lookupCall->setRoutingType(params[2]);
00325 }
00326
00327 sendInternalRpcWithTimeout(OVERLAY_COMP, lookupCall);
00328 }
00329
00330 void XmlRpcInterface::joinOverlay(XmlRpcValue& params, XmlRpcValue& result)
00331 {
00332 if ((params.size() != 1)
00333 || (params[0].getType() != XmlRpcValue::TypeBase64))
00334 throw XmlRpcException("join(base64 nodeID): Invalid argument type");
00335
00336 if (!isPrivileged()) {
00337 throw XmlRpcException("join(base64 nodeID): Not allowed");
00338 }
00339
00340 BinaryValue nodeID = (const XmlRpcValue::BinaryData&)params[0];
00341
00342 overlay->join(OverlayKey::sha1(nodeID));
00343
00344 result[0] = 0;
00345 }
00346
00347 void XmlRpcInterface::put(XmlRpcValue& params, XmlRpcValue& result)
00348 {
00349 if ((params.size() != 4)
00350 || (params[0].getType() != XmlRpcValue::TypeBase64)
00351 || (params[1].getType() != XmlRpcValue::TypeBase64)
00352 || (params[2].getType() != XmlRpcValue::TypeInt)
00353 || (params[3].getType() != XmlRpcValue::TypeString))
00354 throw XmlRpcException("put(base64 key, base64 value, int ttl "
00355 ", string application): Invalid argument type");
00356
00357 if (!isPrivileged()) {
00358 throw XmlRpcException("put(base64 key, base64 value, int ttl "
00359 ", string application): Not allowed");
00360 }
00361
00362 if (overlay->getCompModule(TIER1_COMP) == NULL)
00363 throw XmlRpcException("put(base64 key, base64 value, int ttl "
00364 ", string application): No DHT service");
00365
00366 state[curAppFd]._connectionState = EXECUTE_REQUEST;
00367
00368 DHTputCAPICall* dhtPutMsg = new DHTputCAPICall();
00369
00370 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0];
00371
00372 dhtPutMsg->setKey(OverlayKey::sha1(keyString));
00373 dhtPutMsg->setValue(((const XmlRpcValue::BinaryData&)params[1]));
00374 dhtPutMsg->setTtl(params[2]);
00375 dhtPutMsg->setIsModifiable(true);
00376
00377 sendInternalRpcWithTimeout(TIER1_COMP, dhtPutMsg);
00378 }
00379
00380 void XmlRpcInterface::get(XmlRpcValue& params, XmlRpcValue& result)
00381 {
00382 if ((params.size() != 4)
00383 || (params[0].getType() != XmlRpcValue::TypeBase64)
00384 || (params[1].getType() != XmlRpcValue::TypeInt)
00385 || (params[2].getType() != XmlRpcValue::TypeBase64)
00386 || (params[3].getType() != XmlRpcValue::TypeString))
00387 throw XmlRpcException("get(base64 key, int num, base64 placemark "
00388 ", string application): Invalid argument type");
00389
00390 if (overlay->getCompModule(TIER1_COMP) == NULL)
00391 throw XmlRpcException("get(base64 key, int num, base64 placemark "
00392 ", string application): No DHT service");
00393
00394 state[curAppFd]._connectionState = EXECUTE_REQUEST;
00395
00396 DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall();
00397
00398 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0];
00399 dhtGetMsg->setKey(OverlayKey::sha1(keyString));
00400
00401 sendInternalRpcWithTimeout(TIER1_COMP, dhtGetMsg);
00402 }
00403
00404 void XmlRpcInterface::dumpDht(XmlRpcValue& params, XmlRpcValue& result)
00405 {
00406 if (params.size() != 1) {
00407 throw XmlRpcException("dump_dht(int dummy): Invalid argument type");
00408 }
00409
00410 if (!isPrivileged()) {
00411 throw XmlRpcException("dump_dht(int dummy): Not allowed");
00412 }
00413
00414 if (overlay->getCompModule(TIER1_COMP) == NULL)
00415 throw XmlRpcException("dump_dht(): No DHT service");
00416
00417 state[curAppFd]._connectionState = EXECUTE_REQUEST;
00418
00419 DHTdumpCall* call = new DHTdumpCall();
00420
00421 sendInternalRpcWithTimeout(TIER1_COMP, call);
00422 }
00423
00424 bool XmlRpcInterface::isPrivileged()
00425 {
00426 if (limitAccess) {
00427 return state[curAppFd].localhost;
00428 } else {
00429 return true;
00430 }
00431 }
00432
00433 void XmlRpcInterface::initializeApp(int stage)
00434 {
00435
00436 if (stage != MAX_STAGE_APP)
00437 return;
00438
00439 packetNotification = new cMessage("packetNotification");
00440 mtu = par("mtu");
00441 limitAccess = par("limitAccess");
00442
00443 scheduler = check_and_cast<RealtimeScheduler *>(simulation.getScheduler());
00444 scheduler->setInterfaceModule(this, packetNotification, &packetBuffer, mtu,
00445 true);
00446
00447 appTunFd = scheduler->getAppTunFd();
00448
00449 p2pns = dynamic_cast<P2pns*>(overlay->getCompModule(TIER2_COMP));
00450
00451 XmlRpc::setVerbosity(1);
00452
00453 _localLookup = new LocalLookup(this);
00454 _lookup = new Lookup(this);
00455 _register = new P2pnsRegister(this);
00456 _resolve = new P2pnsResolve(this);
00457 _put = new Put(this);
00458 _get = new Get(this);
00459 _dumpDht = new DumpDht(this);
00460 _joinOverlay = new JoinOverlay(this);
00461
00462 enableIntrospection(true);
00463
00464 curAppFd = INVALID_SOCKET;
00465 }
00466
00467 XmlRpcInterface::XmlRpcInterface()
00468 {
00469 p2pns = NULL;
00470
00471 _localLookup = NULL;
00472 _lookup = NULL;
00473 _register = NULL;
00474 _resolve = NULL;
00475 _put = NULL;
00476 _get = NULL;
00477 _dumpDht = NULL;
00478 _joinOverlay = NULL;
00479
00480 packetNotification = NULL;
00481 }
00482
00483 XmlRpcInterface::~XmlRpcInterface()
00484 {
00485 delete _localLookup;
00486 delete _lookup;
00487 delete _register;
00488 delete _resolve;
00489 delete _put;
00490 delete _get;
00491 delete _dumpDht;
00492 delete _joinOverlay;
00493
00494 cancelAndDelete(packetNotification);
00495 }
00496
00497 void XmlRpcInterface::resetConnectionState()
00498 {
00499 if (state.count(curAppFd) && state[curAppFd].pendingRpc) {
00500 cancelRpcMessage(state[curAppFd].pendingRpc);
00501 }
00502
00503 state[curAppFd].appFd = INVALID_SOCKET;
00504 state[curAppFd].localhost = false;
00505 state[curAppFd]._header = "";
00506 state[curAppFd]._request = "";
00507 state[curAppFd]._response = "";
00508 state[curAppFd]._connectionState = READ_HEADER;
00509 state[curAppFd]._keepAlive = true;
00510 state[curAppFd].pendingRpc = 0;
00511 }
00512
00513 void XmlRpcInterface::closeConnection()
00514 {
00515 scheduler->closeAppSocket(curAppFd);
00516 resetConnectionState();
00517 }
00518
00519 void XmlRpcInterface::sendInternalRpcWithTimeout(CompType destComp,
00520 BaseCallMessage *call)
00521 {
00522 state[curAppFd].pendingRpc = sendInternalRpcCall(destComp, call, NULL,
00523 XMLRPC_TIMEOUT, 0,
00524 curAppFd);
00525 }
00526
00527 void XmlRpcInterface::handleMessage(cMessage *msg)
00528 {
00529
00530 if (msg==packetNotification) {
00531 EV << "[XmlRpcInterface::handleMessage() @ " << overlay->getThisNode().getAddress()
00532 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00533 << " Message from application. Queue length = " << packetBuffer.size()
00534 << endl;
00535 while (packetBuffer.size() > 0) {
00536
00537 RealtimeScheduler::PacketBufferEntry packet =
00538 *(packetBuffer.begin());
00539 packetBuffer.pop_front();
00540 curAppFd = packet.fd;
00541
00542 switch (packet.func) {
00543 case RealtimeScheduler::PacketBufferEntry::PACKET_APPTUN_DATA:
00544 handleAppTunPacket(packet.data, packet.length);
00545 break;
00546
00547 case RealtimeScheduler::PacketBufferEntry::PACKET_DATA:
00548 if (state.count(curAppFd) == 0) {
00549 throw cRuntimeError("XmlRpcInterface::handleMessage(): "
00550 "Received packet "
00551 "from unknown socket!");
00552 }
00553
00554 handleRealworldPacket(packet.data, packet.length);
00555 break;
00556
00557 case RealtimeScheduler::PacketBufferEntry::PACKET_FD_NEW:
00558 if (state.count(curAppFd)) {
00559 throw cRuntimeError("XmlRpcInterface::handleMessage(): "
00560 "Connection state table corrupt!");
00561 }
00562
00563 resetConnectionState();
00564
00565 if (packet.addr != NULL) {
00566 if (((sockaddr_in*)packet.addr)->sin_addr.s_addr
00567 == inet_addr("127.0.0.1")) {
00568 state[curAppFd].localhost = true;
00569 }
00570 delete packet.addr;
00571 packet.addr = NULL;
00572 }
00573 break;
00574
00575 case RealtimeScheduler::PacketBufferEntry::PACKET_FD_CLOSE:
00576 if (state.count(curAppFd) == 0) {
00577 throw cRuntimeError("XmlRpcInterface::handleMessage(): "
00578 "Trying to close unknown "
00579 "connection!");
00580 }
00581
00582 resetConnectionState();
00583 state.erase(curAppFd);
00584 }
00585
00586 if (packet.data) {
00587 delete[] packet.data;
00588 }
00589 }
00590 } else if (msg->isSelfMessage()) {
00591
00592 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00593 if (rpcMessage!=NULL) {
00594 internalHandleRpcMessage(rpcMessage);
00595 return;
00596 }
00597
00598 delete msg;
00599 } else {
00600
00601 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg);
00602 if (rpcMessage!=NULL) {
00603 internalHandleRpcMessage(rpcMessage);
00604 return;
00605 }
00606
00607 CommonAPIMessage* commonAPIMsg = dynamic_cast<CommonAPIMessage*>(msg);
00608 if (commonAPIMsg != NULL)
00609 handleCommonAPIPacket(commonAPIMsg);
00610
00611 CompReadyMessage* readyMsg = dynamic_cast<CompReadyMessage*>(msg);
00612 if (readyMsg != NULL)
00613 handleReadyMessage(readyMsg);
00614
00615 delete msg;
00616 }
00617 }
00618
00619 void XmlRpcInterface::handleRpcTimeout(BaseCallMessage* msg,
00620 const TransportAddress& dest,
00621 cPolymorphic* context, int rpcId,
00622 const OverlayKey&)
00623 {
00624 curAppFd = rpcId;
00625
00626 if (state.count(curAppFd) == 0)
00627 return;
00628
00629 std::cout << "XmlRpcInterface(): XML-RPC failed!" << endl;
00630 state[curAppFd]._response = generateFaultResponse("XML-RPC timeout", 22);
00631 state[curAppFd]._connectionState = WRITE_RESPONSE;
00632 if (!writeResponse() ) {
00633 closeConnection();
00634 }
00635 }
00636
00637 void XmlRpcInterface::handleReadyMessage(CompReadyMessage* msg)
00638 {
00639 if ((msg->getReady() == false) || (msg->getComp() != OVERLAY_COMP)) {
00640 return;
00641 }
00642
00643 if (appTunFd != INVALID_SOCKET) {
00644
00645
00646 const OverlayKey& key = overlay->getThisNode().getKey();
00647
00648 if (OverlayKey::getLength() < 100) {
00649 throw cRuntimeError("XmlRpcInterface::handleReadyMessage(): "
00650 "P2PNS needs at least 100 bit nodeIds!");
00651 }
00652
00653 std::stringstream addr;
00654 addr << "2001:001";
00655 for (int i = 0; i < 100/4; i++) {
00656 if (((i + 3) % 4) == 0) {
00657 addr << ":";
00658 }
00659 addr << std::hex << key.getBitRange(OverlayKey::getLength() -
00660 4 * (i + 1), 4);
00661 }
00662
00663 std::string cmd = "/sbin/ip addr add " + addr.str() + "/28 dev tun0";
00664
00665 EV << "XmlRpcInterface::handleOverlayReady(): "
00666 "Setting TUN interface address " << addr.str() << endl;
00667
00668 if (system(cmd.c_str()) != 0) {
00669 EV << "XmlRpcInterface::handleOverlayReady(): "
00670 "Failed to set TUN interface address!" << endl;
00671 }
00672
00673 if (system("/sbin/ip link set tun0 up") != 0) {
00674 EV << "XmlRpcInterface::handleOverlayReady(): "
00675 "Failed to set TUN interface up!" << endl;
00676 }
00677
00678 p2pns->registerId(addr.str());
00679 }
00680 }
00681
00682 void XmlRpcInterface::handleAppTunPacket(char *buf, uint32_t length)
00683 {
00684 #if not defined _WIN32 && not defined __APPLE__
00685 EV << "XmlRpcInterface::handleAppTunPacket(): packet of "
00686 << "length " << length << endl;
00687
00688 if (!p2pns) {
00689 throw cRuntimeError("XmlRpcInterface::handleAppTunPacket(): "
00690 "P2PNS module missing on tier2!");
00691 }
00692
00693 if (OverlayKey::getLength() < 100) {
00694 throw cRuntimeError("XmlRpcInterface::handleAppTunPacket(): "
00695 "P2PNS needs at least 100 bit nodeIds!");
00696 }
00697
00698 if (length < 40) {
00699 EV << "XmlRpcInterface::handleAppTunPacket(): packet too "
00700 << "short - discarding packet!" << endl;
00701 return;
00702 }
00703
00704 ip6_hdr* ip_buf = (ip6_hdr*) buf;
00705 if (((ip_buf->ip6_vfc & 0xf0) >> 4) != 6) {
00706 EV << "XmlRpcInterface::handleAppTunPacket(): received packet "
00707 "is no IPv6 - discarding packet!" << endl;
00708 return;
00709 }
00710
00711 OverlayKey destKey = OverlayKey(ntohl(ip_buf->ip6_dst.s6_addr32[0]));
00712
00713 for (int i = 1; i < 4; i++) {
00714 destKey = (destKey << 32) + OverlayKey(ntohl(ip_buf->ip6_dst.s6_addr32[i]));
00715 }
00716 destKey = destKey << (OverlayKey::getLength() - 100);
00717
00718 p2pns->tunnel(destKey, BinaryValue(buf, buf + length));
00719 #endif
00720 }
00721
00722 void XmlRpcInterface::deliverTunneledMessage(const BinaryValue& payload)
00723 {
00724 #if not defined _WIN32 && not defined __APPLE__
00725 Enter_Method_Silent();
00726
00727 if (payload.size() == 0) {
00728 return;
00729 }
00730
00731 int curBytesWritten = scheduler->sendBytes(&payload[0],
00732 payload.size(),
00733 0, 0, true, appTunFd);
00734
00735 if (curBytesWritten <= 0) {
00736 throw cRuntimeError("XmlRpcServerConnection::deliverTunneledMessage(): "
00737 "Error writing to application TUN device.");
00738 }
00739 #endif
00740 }
00741
00742 void XmlRpcInterface::handleRealworldPacket(char *buf, uint32_t length)
00743 {
00744 if (state[curAppFd]._connectionState == READ_HEADER) {
00745 if (!readHeader(buf, length)) {
00746
00747 state[curAppFd]._header = "";
00748 state[curAppFd]._request = "";
00749 state[curAppFd]._response = "";
00750 state[curAppFd]._connectionState = READ_HEADER;
00751 return;
00752 }
00753 }
00754
00755 if (state[curAppFd]._connectionState == READ_REQUEST)
00756 if (!readRequest(buf, length))
00757 return;
00758
00759 if (state[curAppFd]._connectionState == WRITE_RESPONSE)
00760 if (!writeResponse() ) {
00761 closeConnection();
00762 return;
00763 }
00764
00765 return;
00766 }
00767
00768 void XmlRpcInterface::handleRpcResponse(BaseResponseMessage* msg,
00769 cPolymorphic* context,
00770 int rpcId,
00771 simtime_t rtt)
00772 {
00773 curAppFd = rpcId;
00774
00775 if (state.count(curAppFd) == 0) {
00776 return;
00777 }
00778
00779 RPC_SWITCH_START(msg)
00780 RPC_ON_RESPONSE(Lookup) {
00781 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) break;
00782
00783 XmlRpcValue resultValue;
00784 resultValue.setSize(_LookupResponse->getSiblingsArraySize());
00785
00786 if (_LookupResponse->getIsValid() == true) {
00787 for (uint32_t i=0; i < _LookupResponse->getSiblingsArraySize();
00788 i++) {
00789 resultValue[i].setSize(3);
00790 resultValue[i][0] =
00791 _LookupResponse->getSiblings(i).getAddress().str();
00792 resultValue[i][1] =
00793 _LookupResponse->getSiblings(i).getPort();
00794 resultValue[i][2] =
00795 _LookupResponse->getSiblings(i).getKey().toString(16);
00796 }
00797 state[curAppFd]._response = generateResponse(resultValue.toXml());
00798 } else {
00799 std::cout << "XmlRpcInterface(): lookup() failed!" << endl;
00800 state[curAppFd]._response = generateFaultResponse("lookup() failed", 22);
00801 }
00802
00803 state[curAppFd]._connectionState = WRITE_RESPONSE;
00804 if (!writeResponse()) {
00805 closeConnection();
00806 }
00807 break;
00808 }
00809 RPC_ON_RESPONSE(P2pnsRegister) {
00810 if (state[curAppFd]._connectionState != EXECUTE_REQUEST)
00811 break;
00812
00813 XmlRpcValue resultValue;
00814
00815 if (_P2pnsRegisterResponse->getIsSuccess() == true) {
00816 resultValue = 0;
00817 state[curAppFd]._response = generateResponse(resultValue.toXml());
00818 } else {
00819 std::cout << "XmlRpcInterface(): register() failed!" << endl;
00820 state[curAppFd]._response = generateFaultResponse("register() failed", 22);
00821 }
00822
00823 state[curAppFd]._connectionState = WRITE_RESPONSE;
00824 if (!writeResponse() ) {
00825 closeConnection();
00826 }
00827 break;
00828 }
00829 RPC_ON_RESPONSE(P2pnsResolve) {
00830 if (state[curAppFd]._connectionState != EXECUTE_REQUEST)
00831 break;
00832
00833 XmlRpcValue resultValue;
00834 resultValue.setSize(_P2pnsResolveResponse->getAddressArraySize());
00835
00836 if (_P2pnsResolveResponse->getIsSuccess() == true) {
00837 for (uint i=0; i < _P2pnsResolveResponse->getAddressArraySize(); i++) {
00838 resultValue[i].setSize(3);
00839 BinaryValue& addr = _P2pnsResolveResponse->getAddress(i);
00840 resultValue[i][0] = XmlRpcValue(&addr[0], addr.size());
00841 resultValue[i][1] = (int)_P2pnsResolveResponse->getKind(i);
00842 resultValue[i][2] = (int)_P2pnsResolveResponse->getId(i);
00843 }
00844 state[curAppFd]._response = generateResponse(resultValue.toXml());
00845 } else {
00846 std::cout << "XmlRpcInterface(): resolve() failed!" << endl;
00847 state[curAppFd]._response = generateFaultResponse("resolve() failed: Name not found", 9);
00848 }
00849
00850 state[curAppFd]._connectionState = WRITE_RESPONSE;
00851 if (!writeResponse() ) {
00852 closeConnection();
00853 }
00854 break;
00855 }
00856 RPC_ON_RESPONSE(DHTputCAPI) {
00857 if (state[curAppFd]._connectionState != EXECUTE_REQUEST)
00858 break;
00859
00860 XmlRpcValue resultValue;
00861
00862 if (_DHTputCAPIResponse->getIsSuccess() == true) {
00863 resultValue = 0;
00864 state[curAppFd]._response = generateResponse(resultValue.toXml());
00865 } else {
00866 std::cout << "XmlRpcInterface(): put() failed!" << endl;
00867 state[curAppFd]._response = generateFaultResponse("put() failed", 22);
00868 }
00869
00870 state[curAppFd]._connectionState = WRITE_RESPONSE;
00871 if (!writeResponse() ) {
00872 closeConnection();
00873 }
00874 break;
00875 }
00876 RPC_ON_RESPONSE(DHTgetCAPI) {
00877 if (state[curAppFd]._connectionState != EXECUTE_REQUEST)
00878 break;
00879
00880 XmlRpcValue resultValue;
00881 resultValue.setSize(2);
00882 resultValue[0].setSize(_DHTgetCAPIResponse->getResultArraySize());
00883
00884 if (_DHTgetCAPIResponse->getIsSuccess() == true) {
00885 for (uint i=0; i < _DHTgetCAPIResponse->getResultArraySize(); i++) {
00886 resultValue[i].setSize(2);
00887 DhtDumpEntry& entry = _DHTgetCAPIResponse->getResult(i);
00888 resultValue[0][i] = XmlRpcValue(&(*(entry.getValue().begin())),
00889 entry.getValue().size());
00890 }
00891 resultValue[1] = std::string();
00892
00893
00894
00895
00896 state[curAppFd]._response = generateResponse(resultValue.toXml());
00897 } else {
00898 std::cout << "XmlRpcInterface(): get() failed!" << endl;
00899 state[curAppFd]._response = generateFaultResponse("get() failed", 22);
00900 }
00901
00902 state[curAppFd]._connectionState = WRITE_RESPONSE;
00903 if (!writeResponse() ) {
00904 closeConnection();
00905 }
00906 break;
00907 }
00908 RPC_ON_RESPONSE(DHTdump) {
00909 if (state[curAppFd]._connectionState != EXECUTE_REQUEST)
00910 break;
00911
00912 XmlRpcValue resultValue;
00913 resultValue.setSize(_DHTdumpResponse->getRecordArraySize());
00914
00915 for (uint32_t i=0; i < _DHTdumpResponse->getRecordArraySize();
00916 i++) {
00917 resultValue[i].setSize(3);
00918 resultValue[i][0] =
00919 _DHTdumpResponse->getRecord(i).getKey().toString(16);
00920 resultValue[i][1] = XmlRpcValue(
00921 &(*(_DHTdumpResponse->getRecord(i).getValue().begin())),
00922 _DHTdumpResponse->getRecord(i).getValue().size());
00923 resultValue[i][2] =
00924 _DHTdumpResponse->getRecord(i).getTtl();
00925 }
00926
00927 state[curAppFd]._response = generateResponse(resultValue.toXml());
00928
00929 state[curAppFd]._connectionState = WRITE_RESPONSE;
00930 if (!writeResponse()) {
00931 closeConnection();
00932 }
00933 break;
00934
00935 }
00936 RPC_SWITCH_END( )
00937 }
00938
00939 void XmlRpcInterface::handleCommonAPIPacket(cMessage *msg)
00940 {
00941 error("DHTXMLRealworldApp::handleCommonAPIPacket(): Unknown Packet!");
00942 }
00943
00944 bool XmlRpcInterface::readHeader(char* buf, uint32_t length)
00945 {
00946
00947 bool eof = false;
00948
00949 state[curAppFd]._header.append(std::string(buf, length));
00950
00951 if (length <= 0) {
00952
00953 if (state[curAppFd]._header.length() > 0)
00954 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: error "
00955 "while reading header.");
00956 return false;
00957 }
00958
00959 XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: read %d bytes.",
00960 state[curAppFd]._header.length());
00961 char *hp = (char*)state[curAppFd]._header.c_str();
00962 char *ep = hp + state[curAppFd]._header.length();
00963 char *bp = 0;
00964 char *lp = 0;
00965 char *kp = 0;
00966
00967 for (char *cp = hp; (bp == 0) && (cp < ep); ++cp) {
00968 if ((ep - cp > 16) && (strncasecmp(cp, "Content-length: ", 16) == 0))
00969 lp = cp + 16;
00970 else if ((ep - cp > 12) && (strncasecmp(cp, "Connection: ", 12) == 0))
00971 kp = cp + 12;
00972 else if ((ep - cp > 4) && (strncmp(cp, "\r\n\r\n", 4) == 0))
00973 bp = cp + 4;
00974 else if ((ep - cp > 2) && (strncmp(cp, "\n\n", 2) == 0))
00975 bp = cp + 2;
00976 }
00977
00978
00979 if (bp == 0) {
00980
00981 if (eof) {
00982 XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: EOF");
00983 if (state[curAppFd]._header.length() > 0)
00984 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: EOF while reading header");
00985 return false;
00986 }
00987
00988 return true;
00989 }
00990
00991
00992 if (lp == 0) {
00993 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: No Content-length specified");
00994 return false;
00995 }
00996
00997 state[curAppFd]._contentLength = atoi(lp);
00998 if (state[curAppFd]._contentLength <= 0) {
00999 XmlRpcUtil::error(
01000 "XmlRpcServerConnection::readHeader: Invalid Content-length specified (%d).",
01001 state[curAppFd]._contentLength);
01002 return false;
01003 }
01004
01005 XmlRpcUtil::log(
01006 3,
01007 "XmlRpcServerConnection::readHeader: specified content length is %d.",
01008 state[curAppFd]._contentLength);
01009
01010
01011 state[curAppFd]._request = bp;
01012
01013
01014 state[curAppFd]._keepAlive = true;
01015 if (state[curAppFd]._header.find("HTTP/1.0") != std::string::npos) {
01016 if (kp == 0 || strncasecmp(kp, "keep-alive", 10) != 0)
01017 state[curAppFd]._keepAlive = false;
01018 } else {
01019 if (kp != 0 && strncasecmp(kp, "close", 5) == 0)
01020 state[curAppFd]._keepAlive = false;
01021 }
01022 XmlRpcUtil::log(3, "KeepAlive: %d", state[curAppFd]._keepAlive);
01023
01024 state[curAppFd]._header = "";
01025 state[curAppFd]._connectionState = READ_REQUEST;
01026 return true;
01027 }
01028
01029 bool XmlRpcInterface::readRequest(char *buf, uint32_t length)
01030 {
01031
01032 if (int(state[curAppFd]._request.length()) < state[curAppFd]._contentLength) {
01033 bool eof = false;
01034
01035 state[curAppFd]._request.append(std::string(buf, length));
01036
01037 if (length <= 0) {
01038 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: read error.");
01039 return false;
01040 }
01041
01042
01043 if (int(state[curAppFd]._request.length()) < state[curAppFd]._contentLength) {
01044 if (eof) {
01045 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: EOF while reading request");
01046 return false;
01047 }
01048 return true;
01049 }
01050 }
01051
01052
01053 XmlRpcUtil::log(3, "XmlRpcServerConnection::readRequest read %d bytes.",
01054 state[curAppFd]._request.length());
01055
01056
01057 state[curAppFd]._connectionState = WRITE_RESPONSE;
01058
01059 return true;
01060 }
01061
01062 bool XmlRpcInterface::writeResponse()
01063 {
01064 if (state[curAppFd]._response.length() == 0) {
01065 state[curAppFd]._response = executeRequest(state[curAppFd]._request);
01066 state[curAppFd]._bytesWritten = 0;
01067
01068 if (state[curAppFd]._connectionState == EXECUTE_REQUEST)
01069 return true;
01070
01071 if (state[curAppFd]._response.length() == 0) {
01072 XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: empty response.");
01073 return false;
01074 }
01075 }
01076
01077
01078 int curBytesWritten = scheduler->sendBytes(state[curAppFd]._response.c_str(),
01079 state[curAppFd]._response.length(),
01080 0, 0, true, curAppFd);
01081
01082 if (curBytesWritten <= 0) {
01083 XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: write error.");
01084 return false;
01085 } else {
01086 state[curAppFd]._bytesWritten += curBytesWritten;
01087 }
01088
01089 XmlRpcUtil::log(3,
01090 "XmlRpcServerConnection::writeResponse: wrote %d of %d bytes.",
01091 state[curAppFd]._bytesWritten, state[curAppFd]._response.length());
01092
01093
01094 if (state[curAppFd]._bytesWritten == int(state[curAppFd]._response.length())) {
01095 state[curAppFd]._header = "";
01096 state[curAppFd]._request = "";
01097 state[curAppFd]._response = "";
01098 state[curAppFd]._connectionState = READ_HEADER;
01099 }
01100
01101 return state[curAppFd]._keepAlive;
01102 }