#include <XmlRpcInterface.h>
Public Member Functions | |
XmlRpcInterface () | |
~XmlRpcInterface () | |
virtual void | initializeApp (int stage) |
initializes derived class-attributes | |
virtual void | handleMessage (cMessage *msg) |
The "main loop". | |
void | handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &) |
This method is called if an RPC timeout has been reached. | |
void | localLookup (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | lookup (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | p2pnsRegister (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | p2pnsResolve (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | put (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | get (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | dumpDht (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
void | joinOverlay (XmlRpc::XmlRpcValue ¶ms, XmlRpc::XmlRpcValue &result) |
Protected Types | |
enum | ServerConnectionState { READ_HEADER, READ_REQUEST, EXECUTE_REQUEST, WRITE_RESPONSE } |
Possible IO states for the connection. More... | |
Protected Member Functions | |
bool | readHeader (char *buf, uint32_t length) |
Reads the http header. | |
bool | readRequest (char *buf, uint32_t length) |
Reads the request (based on the content-length header value). | |
bool | writeResponse () |
Executes the request and writes the resulting response. | |
void | handleRealworldPacket (char *buf, uint32_t len) |
void | handleCommonAPIPacket (cMessage *msg) |
void | handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
void | resetConnectionState () |
Reset the internal connection state. | |
void | closeConnection () |
void | sendInternalRpcWithTimeout (CompType destComp, BaseCallMessage *call) |
Protected Attributes | |
unsigned int | mtu |
cMessage * | packetNotification |
RealtimeScheduler::PacketBuffer | packetBuffer |
RealtimeScheduler * | scheduler |
std::map< int, XmlRpcConnectionState > | state |
int | curAppFd |
XmlRpc::XmlRpcServerMethod * | _localLookup |
XmlRpc::XmlRpcServerMethod * | _lookup |
XmlRpc::XmlRpcServerMethod * | _register |
XmlRpc::XmlRpcServerMethod * | _resolve |
XmlRpc::XmlRpcServerMethod * | _put |
XmlRpc::XmlRpcServerMethod * | _get |
XmlRpc::XmlRpcServerMethod * | _dumpDht |
XmlRpc::XmlRpcServerMethod * | _joinOverlay |
Classes | |
struct | XmlRpcConnectionState |
enum XmlRpcInterface::ServerConnectionState [protected] |
Possible IO states for the connection.
00038 { READ_HEADER, READ_REQUEST, EXECUTE_REQUEST, 00039 WRITE_RESPONSE };
XmlRpcInterface::XmlRpcInterface | ( | ) |
00391 { 00392 _localLookup = NULL; 00393 _lookup = NULL; 00394 _register = NULL; 00395 _resolve = NULL; 00396 _put = NULL; 00397 _get = NULL; 00398 _dumpDht = NULL; 00399 _joinOverlay = NULL; 00400 00401 packetNotification = NULL; 00402 }
XmlRpcInterface::~XmlRpcInterface | ( | ) |
00405 { 00406 delete _localLookup; 00407 delete _lookup; 00408 delete _register; 00409 delete _resolve; 00410 delete _put; 00411 delete _get; 00412 delete _dumpDht; 00413 delete _joinOverlay; 00414 00415 cancelAndDelete(packetNotification); 00416 }
bool XmlRpcInterface::readHeader | ( | char * | buf, | |
uint32_t | length | |||
) | [protected] |
Reads the http header.
Referenced by handleRealworldPacket().
00734 { 00735 // Read available data 00736 bool eof = false; 00737 00738 state[curAppFd]._header.append(std::string(buf, length)); 00739 00740 if (length <= 0) { 00741 // Its only an error if we already have read some data 00742 if (state[curAppFd]._header.length() > 0) 00743 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: error " 00744 "while reading header."); 00745 return false; 00746 } 00747 00748 XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: read %d bytes.", 00749 state[curAppFd]._header.length()); 00750 char *hp = (char*)state[curAppFd]._header.c_str(); // Start of header 00751 char *ep = hp + state[curAppFd]._header.length(); // End of string 00752 char *bp = 0; // Start of body 00753 char *lp = 0; // Start of content-length value 00754 char *kp = 0; // Start of connection value 00755 00756 for (char *cp = hp; (bp == 0) && (cp < ep); ++cp) { 00757 if ((ep - cp > 16) && (strncasecmp(cp, "Content-length: ", 16) == 0)) 00758 lp = cp + 16; 00759 else if ((ep - cp > 12) && (strncasecmp(cp, "Connection: ", 12) == 0)) 00760 kp = cp + 12; 00761 else if ((ep - cp > 4) && (strncmp(cp, "\r\n\r\n", 4) == 0)) 00762 bp = cp + 4; 00763 else if ((ep - cp > 2) && (strncmp(cp, "\n\n", 2) == 0)) 00764 bp = cp + 2; 00765 } 00766 00767 // If we haven't gotten the entire header yet, return (keep reading) 00768 if (bp == 0) { 00769 // EOF in the middle of a request is an error, otherwise its ok 00770 if (eof) { 00771 XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: EOF"); 00772 if (state[curAppFd]._header.length() > 0) 00773 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: EOF while reading header"); 00774 return false; // Either way we close the connection 00775 } 00776 00777 return true; // Keep reading 00778 } 00779 00780 // Decode content length 00781 if (lp == 0) { 00782 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: No Content-length specified"); 00783 return false; // We could try to figure it out by parsing as we read, but for now... 00784 } 00785 00786 state[curAppFd]._contentLength = atoi(lp); 00787 if (state[curAppFd]._contentLength <= 0) { 00788 XmlRpcUtil::error( 00789 "XmlRpcServerConnection::readHeader: Invalid Content-length specified (%d).", 00790 state[curAppFd]._contentLength); 00791 return false; 00792 } 00793 00794 XmlRpcUtil::log( 00795 3, 00796 "XmlRpcServerConnection::readHeader: specified content length is %d.", 00797 state[curAppFd]._contentLength); 00798 00799 // Otherwise copy non-header data to request buffer and set state to read request. 00800 state[curAppFd]._request = bp; 00801 00802 // Parse out any interesting bits from the header (HTTP version, connection) 00803 state[curAppFd]._keepAlive = true; 00804 if (state[curAppFd]._header.find("HTTP/1.0") != std::string::npos) { 00805 if (kp == 0 || strncasecmp(kp, "keep-alive", 10) != 0) 00806 state[curAppFd]._keepAlive = false; // Default for HTTP 1.0 is to close the connection 00807 } else { 00808 if (kp != 0 && strncasecmp(kp, "close", 5) == 0) 00809 state[curAppFd]._keepAlive = false; 00810 } 00811 XmlRpcUtil::log(3, "KeepAlive: %d", state[curAppFd]._keepAlive); 00812 00813 state[curAppFd]._header = ""; 00814 state[curAppFd]._connectionState = READ_REQUEST; 00815 return true; // Continue monitoring this source 00816 }
bool XmlRpcInterface::readRequest | ( | char * | buf, | |
uint32_t | length | |||
) | [protected] |
Reads the request (based on the content-length header value).
Referenced by handleRealworldPacket().
00819 { 00820 // If we dont have the entire request yet, read available data 00821 if (int(state[curAppFd]._request.length()) < state[curAppFd]._contentLength) { 00822 bool eof = false; 00823 00824 state[curAppFd]._request.append(std::string(buf, length)); 00825 00826 if (length <= 0) { 00827 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: read error."); 00828 return false; 00829 } 00830 00831 // If we haven't gotten the entire request yet, return (keep reading) 00832 if (int(state[curAppFd]._request.length()) < state[curAppFd]._contentLength) { 00833 if (eof) { 00834 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: EOF while reading request"); 00835 return false; // Either way we close the connection 00836 } 00837 return true; 00838 } 00839 } 00840 00841 // Otherwise, parse and dispatch the request 00842 XmlRpcUtil::log(3, "XmlRpcServerConnection::readRequest read %d bytes.", 00843 state[curAppFd]._request.length()); 00844 //XmlRpcUtil::log(5, "XmlRpcServerConnection::readRequest:\n%s\n", state[curAppFd]._request.c_str()); 00845 00846 state[curAppFd]._connectionState = WRITE_RESPONSE; 00847 00848 return true; // Continue monitoring this source 00849 }
bool XmlRpcInterface::writeResponse | ( | ) | [protected] |
Executes the request and writes the resulting response.
Referenced by handleRealworldPacket(), handleRpcResponse(), and handleRpcTimeout().
00852 { 00853 if (state[curAppFd]._response.length() == 0) { 00854 state[curAppFd]._response = executeRequest(state[curAppFd]._request); 00855 state[curAppFd]._bytesWritten = 0; 00856 00857 if (state[curAppFd]._connectionState == EXECUTE_REQUEST) 00858 return true; 00859 00860 if (state[curAppFd]._response.length() == 0) { 00861 XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: empty response."); 00862 return false; 00863 } 00864 } 00865 00866 // Try to write the response 00867 int curBytesWritten = scheduler->sendBytes(state[curAppFd]._response.c_str(), 00868 state[curAppFd]._response.length(), 00869 0, 0, true, curAppFd); 00870 00871 if (curBytesWritten <= 0) { 00872 XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: write error."); 00873 return false; 00874 } else { 00875 state[curAppFd]._bytesWritten += curBytesWritten; 00876 } 00877 00878 XmlRpcUtil::log( 00879 3, 00880 "XmlRpcServerConnection::writeResponse: wrote %d of %d bytes.", 00881 state[curAppFd]._bytesWritten, state[curAppFd]._response.length()); 00882 00883 // Prepare to read the next request 00884 if (state[curAppFd]._bytesWritten == int(state[curAppFd]._response.length())) { 00885 state[curAppFd]._header = ""; 00886 state[curAppFd]._request = ""; 00887 state[curAppFd]._response = ""; 00888 state[curAppFd]._connectionState = READ_HEADER; 00889 } 00890 00891 return state[curAppFd]._keepAlive; // Continue monitoring this source if true 00892 }
void XmlRpcInterface::handleRealworldPacket | ( | char * | buf, | |
uint32_t | len | |||
) | [protected] |
Referenced by handleMessage().
00543 { 00544 if (state[curAppFd]._connectionState == READ_HEADER) { 00545 if (!readHeader(buf, length)) { 00546 // discard data, if the header is invalid 00547 state[curAppFd]._header = ""; 00548 state[curAppFd]._request = ""; 00549 state[curAppFd]._response = ""; 00550 state[curAppFd]._connectionState = READ_HEADER; 00551 return; 00552 } 00553 } 00554 00555 if (state[curAppFd]._connectionState == READ_REQUEST) 00556 if (!readRequest(buf, length)) 00557 return; 00558 00559 if (state[curAppFd]._connectionState == WRITE_RESPONSE) 00560 if (!writeResponse() ) { 00561 closeConnection(); 00562 return; 00563 } 00564 00565 return; 00566 }
void XmlRpcInterface::handleCommonAPIPacket | ( | cMessage * | msg | ) | [protected] |
void XmlRpcInterface::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [protected, virtual] |
This method is called if an RPC response has been received.
msg | The response message. | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
rtt | The Round-Trip-Time of this RPC |
Reimplemented from RpcListener.
00572 { 00573 curAppFd = rpcId; 00574 00575 if (state.count(curAppFd) == 0) { 00576 return; 00577 } 00578 00579 RPC_SWITCH_START(msg) 00580 RPC_ON_RESPONSE(Lookup) { 00581 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) break; 00582 00583 XmlRpcValue resultValue; 00584 resultValue.setSize(_LookupResponse->getSiblingsArraySize()); 00585 00586 if (_LookupResponse->getIsValid() == true) { 00587 for (uint i=0; i < _LookupResponse->getSiblingsArraySize(); 00588 i++) { 00589 resultValue[i].setSize(3); 00590 resultValue[i][0] = 00591 _LookupResponse->getSiblings(i).ip.str(); 00592 resultValue[i][1] = 00593 _LookupResponse->getSiblings(i).port; 00594 resultValue[i][2] = 00595 _LookupResponse->getSiblings(i).key.toString(16); 00596 } 00597 state[curAppFd]._response = generateResponse(resultValue.toXml()); 00598 } else { 00599 std::cout << "XmlRpcInterface(): lookup() failed!" << endl; 00600 state[curAppFd]._response = generateFaultResponse("lookup() failed", 22); 00601 } 00602 00603 state[curAppFd]._connectionState = WRITE_RESPONSE; 00604 if (!writeResponse()) { 00605 closeConnection(); 00606 } 00607 break; 00608 } 00609 RPC_ON_RESPONSE(P2pnsRegister) { 00610 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) 00611 break; 00612 00613 XmlRpcValue resultValue; 00614 00615 if (_P2pnsRegisterResponse->getIsSuccess() == true) { 00616 resultValue = 0; 00617 state[curAppFd]._response = generateResponse(resultValue.toXml()); 00618 } else { 00619 std::cout << "XmlRpcInterface(): register() failed!" << endl; 00620 state[curAppFd]._response = generateFaultResponse("register() failed", 22); 00621 } 00622 00623 state[curAppFd]._connectionState = WRITE_RESPONSE; 00624 if (!writeResponse() ) { 00625 closeConnection(); 00626 } 00627 break; 00628 } 00629 RPC_ON_RESPONSE(P2pnsResolve) { 00630 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) 00631 break; 00632 00633 XmlRpcValue resultValue; 00634 resultValue.setSize(1); 00635 00636 if (_P2pnsResolveResponse->getIsSuccess() == true) { 00637 resultValue[0] = XmlRpcValue( 00638 &(*(_P2pnsResolveResponse->getAddress().begin())), 00639 _P2pnsResolveResponse->getAddress().size()); 00640 state[curAppFd]._response = generateResponse(resultValue.toXml()); 00641 } else { 00642 std::cout << "XmlRpcInterface(): resolve() failed!" << endl; 00643 state[curAppFd]._response = generateFaultResponse("resolve() failed: Name not found", 9); 00644 } 00645 00646 state[curAppFd]._connectionState = WRITE_RESPONSE; 00647 if (!writeResponse() ) { 00648 closeConnection(); 00649 } 00650 break; 00651 } 00652 RPC_ON_RESPONSE(DHTputCAPI) { 00653 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) 00654 break; 00655 00656 XmlRpcValue resultValue; 00657 00658 if (_DHTputCAPIResponse->getIsSuccess() == true) { 00659 resultValue = 0; 00660 state[curAppFd]._response = generateResponse(resultValue.toXml()); 00661 } else { 00662 std::cout << "XmlRpcInterface(): put() failed!" << endl; 00663 state[curAppFd]._response = generateFaultResponse("put() failed", 22); 00664 } 00665 00666 state[curAppFd]._connectionState = WRITE_RESPONSE; 00667 if (!writeResponse() ) { 00668 closeConnection(); 00669 } 00670 break; 00671 } 00672 RPC_ON_RESPONSE(DHTgetCAPI) { 00673 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) 00674 break; 00675 00676 XmlRpcValue resultValue; 00677 resultValue.setSize(2); 00678 resultValue[0].setSize(1); 00679 00680 if (_DHTgetCAPIResponse->getIsSuccess() == true) { 00681 resultValue[0][0] = XmlRpcValue( 00682 &(*(_DHTgetCAPIResponse->getValue().begin())), 00683 _DHTgetCAPIResponse->getValue().size()); 00684 resultValue[1] = std::string(); 00685 state[curAppFd]._response = generateResponse(resultValue.toXml()); 00686 } else { 00687 std::cout << "XmlRpcInterface(): get() failed!" << endl; 00688 state[curAppFd]._response = generateFaultResponse("get() failed", 22); 00689 } 00690 00691 state[curAppFd]._connectionState = WRITE_RESPONSE; 00692 if (!writeResponse() ) { 00693 closeConnection(); 00694 } 00695 break; 00696 } 00697 RPC_ON_RESPONSE(DHTdump) { 00698 if (state[curAppFd]._connectionState != EXECUTE_REQUEST) 00699 break; 00700 00701 XmlRpcValue resultValue; 00702 resultValue.setSize(_DHTdumpResponse->getRecordArraySize()); 00703 00704 for (uint i=0; i < _DHTdumpResponse->getRecordArraySize(); 00705 i++) { 00706 resultValue[i].setSize(3); 00707 resultValue[i][0] = 00708 _DHTdumpResponse->getRecord(i).key.toString(16); 00709 resultValue[i][1] = XmlRpcValue( 00710 &(*(_DHTdumpResponse->getRecord(i).value.begin())), 00711 _DHTdumpResponse->getRecord(i).value.size()); 00712 resultValue[i][2] = 00713 _DHTdumpResponse->getRecord(i).ttl; 00714 } 00715 00716 state[curAppFd]._response = generateResponse(resultValue.toXml()); 00717 00718 state[curAppFd]._connectionState = WRITE_RESPONSE; 00719 if (!writeResponse()) { 00720 closeConnection(); 00721 } 00722 break; 00723 00724 } 00725 RPC_SWITCH_END( ) 00726 }
void XmlRpcInterface::resetConnectionState | ( | ) | [protected] |
Reset the internal connection state.
This is called after a RPC has finished and the socket was closed.
Referenced by closeConnection(), and handleMessage().
00419 { 00420 if (state.count(curAppFd) && state[curAppFd].pendingRpc) { 00421 cancelRpcMessage(state[curAppFd].pendingRpc); 00422 } 00423 00424 state[curAppFd].appFd = -1; 00425 state[curAppFd]._header = ""; 00426 state[curAppFd]._request = ""; 00427 state[curAppFd]._response = ""; 00428 state[curAppFd]._connectionState = READ_HEADER; 00429 state[curAppFd]._keepAlive = true; 00430 state[curAppFd].pendingRpc = 0; 00431 }
void XmlRpcInterface::closeConnection | ( | ) | [protected] |
Referenced by handleRealworldPacket(), handleRpcResponse(), and handleRpcTimeout().
00434 { 00435 scheduler->closeAppSocket(curAppFd); 00436 resetConnectionState(); 00437 }
void XmlRpcInterface::sendInternalRpcWithTimeout | ( | CompType | destComp, | |
BaseCallMessage * | call | |||
) | [protected] |
Referenced by dumpDht(), get(), lookup(), p2pnsRegister(), p2pnsResolve(), and put().
00441 { 00442 state[curAppFd].pendingRpc = sendInternalRpcCall(destComp, call, NULL, 00443 XMLRPC_TIMEOUT, 0, 00444 curAppFd); 00445 }
void XmlRpcInterface::initializeApp | ( | int | stage | ) | [virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented from BaseApp.
00362 { 00363 // all initialization is done in the first stage 00364 if (stage != MIN_STAGE_APP) 00365 return; 00366 00367 packetNotification = new cMessage("packetNotification"); 00368 mtu = par("mtu"); 00369 00370 scheduler = check_and_cast<RealtimeScheduler *>(simulation.scheduler()); 00371 scheduler->setInterfaceModule(this, packetNotification, &packetBuffer, mtu, 00372 true); 00373 00374 XmlRpc::setVerbosity(1); 00375 00376 _localLookup = new LocalLookup(this); 00377 _lookup = new Lookup(this); 00378 _register = new P2pnsRegister(this); 00379 _resolve = new P2pnsResolve(this); 00380 _put = new Put(this); 00381 _get = new Get(this); 00382 _dumpDht = new DumpDht(this); 00383 _joinOverlay = new JoinOverlay(this); 00384 00385 enableIntrospection(true); 00386 00387 curAppFd = -1; 00388 }
void XmlRpcInterface::handleMessage | ( | cMessage * | msg | ) | [virtual] |
The "main loop".
Every message that is received or send is handled by this method
Reimplemented from BaseApp.
00448 { 00449 // Packet from the application... 00450 if (msg==packetNotification) { 00451 EV << "[DHTXMLRealworldApp::handleMessage() @ " << overlay->getThisNode().ip 00452 << " (" << overlay->getThisNode().key.toString(16) << ")]\n" 00453 << " Message from application. Queue length = " << packetBuffer.size() 00454 << endl; 00455 while (packetBuffer.size() > 0) { 00456 // get packet from buffer and parse it 00457 RealtimeScheduler::PacketBufferEntry packet = 00458 *(packetBuffer.begin()); 00459 packetBuffer.pop_front(); 00460 curAppFd = packet.fd; 00461 00462 switch (packet.func) { 00463 00464 case RealtimeScheduler::PacketBufferEntry::DATA: 00465 00466 if (state.count(curAppFd) == 0) { 00467 throw new cRuntimeError("XmlRpcInterface::handleMessage(): " 00468 "Received packet " 00469 "from unknown socket!"); 00470 } 00471 00472 handleRealworldPacket(packet.data, packet.length); 00473 break; 00474 00475 case RealtimeScheduler::PacketBufferEntry::FD_NEW: 00476 if (state.count(curAppFd)) { 00477 throw new cRuntimeError("XmlRpcInterface::handleMessage(): " 00478 "Connection state table corrupt!"); 00479 } 00480 00481 resetConnectionState(); 00482 break; 00483 00484 case RealtimeScheduler::PacketBufferEntry::FD_CLOSE: 00485 if (state.count(curAppFd) == 0) { 00486 throw new cRuntimeError("XmlRpcInterface::handleMessage(): " 00487 "Trying to close unknown " 00488 "connection!"); 00489 } 00490 00491 resetConnectionState(); 00492 state.erase(curAppFd); 00493 } 00494 00495 if (packet.data) { 00496 delete[] packet.data; 00497 } 00498 } 00499 } else if (msg->isSelfMessage()) { 00500 // process rpc self-messages 00501 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg); 00502 if (rpcMessage!=NULL) { 00503 internalHandleRpcMessage(rpcMessage); 00504 return; 00505 } 00506 00507 delete msg; 00508 } else { 00509 // RPCs 00510 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg); 00511 if (rpcMessage!=NULL) { 00512 internalHandleRpcMessage(rpcMessage); 00513 return; 00514 } 00515 // common API 00516 CommonAPIMessage* commonAPIMsg = dynamic_cast<CommonAPIMessage*>(msg); 00517 if (commonAPIMsg != NULL) 00518 handleCommonAPIPacket(commonAPIMsg); 00519 00520 delete msg; 00521 } 00522 }
void XmlRpcInterface::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
cPolymorphic * | context, | |||
int | rpcId, | |||
const OverlayKey & | destKey | |||
) | [virtual] |
This method is called if an RPC timeout has been reached.
msg | The original RPC message. | |
dest | The destination node | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
destKey | the destination OverlayKey |
Reimplemented from RpcListener.
00528 { 00529 curAppFd = rpcId; 00530 00531 if (state.count(curAppFd) == 0) 00532 return; 00533 00534 std::cout << "DHTXMLRealworldApp(): XML-RPC failed!" << endl; 00535 state[curAppFd]._response = generateFaultResponse("XML-RPC timeout", 22); 00536 state[curAppFd]._connectionState = WRITE_RESPONSE; 00537 if (!writeResponse() ) { 00538 closeConnection(); 00539 } 00540 }
void XmlRpcInterface::localLookup | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00235 { 00236 if ((params.size() != 3) 00237 || (params[0].getType() != XmlRpcValue::TypeBase64) 00238 || (params[1].getType() != XmlRpcValue::TypeInt) 00239 || (params[2].getType() != XmlRpcValue::TypeBoolean)) 00240 throw XmlRpcException("local_lookup(base64 key, int num, " 00241 "boolean safe): Invalid argument type"); 00242 00243 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0]; 00244 00245 NodeVector* nextHops = overlay->local_lookup(OverlayKey::sha1(keyString), 00246 params[1], params[2]); 00247 00248 for (uint i=0; i < nextHops->size(); i++) { 00249 result[i][0] = (*nextHops)[i].ip.str(); 00250 result[i][1] = (*nextHops)[i].port; 00251 result[i][2] = (*nextHops)[i].key.toString(16); 00252 } 00253 00254 delete nextHops; 00255 }
void XmlRpcInterface::lookup | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00258 { 00259 if ((params.size() != 2) 00260 || (params[0].getType() != XmlRpcValue::TypeBase64) 00261 || (params[1].getType() != XmlRpcValue::TypeInt)) 00262 throw XmlRpcException("lookup(base64 key, int numSiblings): " 00263 "Invalid argument type"); 00264 00265 if ((int)params[1] > overlay->getMaxNumSiblings()) 00266 throw XmlRpcException("lookup(base64 key, int numSiblings): " 00267 "numSibling to big"); 00268 00269 state[curAppFd]._connectionState = EXECUTE_REQUEST; 00270 00271 LookupCall* lookupCall = new LookupCall(); 00272 00273 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0]; 00274 lookupCall->setKey(OverlayKey::sha1(keyString)); 00275 lookupCall->setNumSiblings(params[1]); 00276 00277 sendInternalRpcWithTimeout(OVERLAY_COMP, lookupCall); 00278 }
void XmlRpcInterface::p2pnsRegister | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00193 { 00194 if ((params.size() != 3) || 00195 (params[0].getType() != XmlRpcValue::TypeBase64) || 00196 (params[1].getType() != XmlRpcValue::TypeBase64) || 00197 (params[2].getType() != XmlRpcValue::TypeInt)) 00198 throw XmlRpcException("register(base64 name, base64 address, int ttl): " 00199 "Invalid argument type"); 00200 00201 if (overlay->getCompModule(TIER2_COMP) == NULL) 00202 throw XmlRpcException("register(base64 name, base64 address, int ttl): " 00203 "No P2PNS service"); 00204 00205 state[curAppFd]._connectionState = EXECUTE_REQUEST; 00206 00207 P2pnsRegisterCall* registerCall = new P2pnsRegisterCall(); 00208 00209 registerCall->setP2pName(((const XmlRpcValue::BinaryData&)params[0])); 00210 registerCall->setAddress(((const XmlRpcValue::BinaryData&)params[1])); 00211 registerCall->setTtl(params[2]); 00212 00213 sendInternalRpcWithTimeout(TIER2_COMP, registerCall); 00214 }
void XmlRpcInterface::p2pnsResolve | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00217 { 00218 if ((params.size() != 1) || 00219 (params[0].getType() != XmlRpcValue::TypeBase64)) 00220 throw XmlRpcException("resolve(base64 name): Invalid argument type"); 00221 00222 if (overlay->getCompModule(TIER2_COMP) == NULL) 00223 throw XmlRpcException("resolve(base64 name): No P2PNS service"); 00224 00225 state[curAppFd]._connectionState = EXECUTE_REQUEST; 00226 00227 P2pnsResolveCall* resolveCall = new P2pnsResolveCall(); 00228 00229 resolveCall->setP2pName(((const XmlRpcValue::BinaryData&)params[0])); 00230 00231 sendInternalRpcWithTimeout(TIER2_COMP, resolveCall); 00232 }
void XmlRpcInterface::put | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00294 { 00295 if ((params.size() != 4) 00296 || (params[0].getType() != XmlRpcValue::TypeBase64) 00297 || (params[1].getType() != XmlRpcValue::TypeBase64) 00298 || (params[2].getType() != XmlRpcValue::TypeInt) 00299 || (params[3].getType() != XmlRpcValue::TypeString)) 00300 throw XmlRpcException("put(base64 key, base64 value, int ttl " 00301 ", string application): Invalid argument type"); 00302 00303 if (overlay->getCompModule(TIER1_COMP) == NULL) 00304 throw XmlRpcException("put(base64 key, base64 value, int ttl " 00305 ", string application): No DHT service"); 00306 00307 state[curAppFd]._connectionState = EXECUTE_REQUEST; 00308 00309 DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); 00310 00311 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0]; 00312 00313 dhtPutMsg->setKey(OverlayKey::sha1(keyString)); 00314 dhtPutMsg->setValue(((const XmlRpcValue::BinaryData&)params[1])); 00315 dhtPutMsg->setTtl(params[2]); 00316 dhtPutMsg->setIsModifiable(true); 00317 00318 sendInternalRpcWithTimeout(TIER1_COMP, dhtPutMsg); 00319 }
void XmlRpcInterface::get | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00322 { 00323 if ((params.size() != 4) 00324 || (params[0].getType() != XmlRpcValue::TypeBase64) 00325 || (params[1].getType() != XmlRpcValue::TypeInt) 00326 || (params[2].getType() != XmlRpcValue::TypeBase64) 00327 || (params[3].getType() != XmlRpcValue::TypeString)) 00328 throw XmlRpcException("get(base64 key, int num, base64 placemark " 00329 ", string application): Invalid argument type"); 00330 00331 if (overlay->getCompModule(TIER1_COMP) == NULL) 00332 throw XmlRpcException("get(base64 key, int num, base64 placemark " 00333 ", string application): No DHT service"); 00334 00335 state[curAppFd]._connectionState = EXECUTE_REQUEST; 00336 00337 DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall(); 00338 00339 BinaryValue keyString = (const XmlRpcValue::BinaryData&)params[0]; 00340 dhtGetMsg->setKey(OverlayKey::sha1(keyString)); 00341 00342 sendInternalRpcWithTimeout(TIER1_COMP, dhtGetMsg); 00343 }
void XmlRpcInterface::dumpDht | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00346 { 00347 if (params.size() != 1) { 00348 throw XmlRpcException("dump_dht(int dummy): Invalid argument type"); 00349 } 00350 00351 if (overlay->getCompModule(TIER1_COMP) == NULL) 00352 throw XmlRpcException("dump_dht(): No DHT service"); 00353 00354 state[curAppFd]._connectionState = EXECUTE_REQUEST; 00355 00356 DHTdumpCall* call = new DHTdumpCall(); 00357 00358 sendInternalRpcWithTimeout(TIER1_COMP, call); 00359 }
void XmlRpcInterface::joinOverlay | ( | XmlRpc::XmlRpcValue & | params, | |
XmlRpc::XmlRpcValue & | result | |||
) |
00281 { 00282 if ((params.size() != 1) 00283 || (params[0].getType() != XmlRpcValue::TypeBase64)) 00284 throw XmlRpcException("join(base64 nodeID): Invalid argument type"); 00285 00286 BinaryValue nodeID = (const XmlRpcValue::BinaryData&)params[0]; 00287 00288 overlay->join(OverlayKey::sha1(nodeID)); 00289 00290 result[0] = 0; 00291 }
unsigned int XmlRpcInterface::mtu [protected] |
Referenced by initializeApp().
cMessage* XmlRpcInterface::packetNotification [protected] |
Referenced by handleMessage(), initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
Referenced by handleMessage(), and initializeApp().
RealtimeScheduler* XmlRpcInterface::scheduler [protected] |
Referenced by closeConnection(), initializeApp(), and writeResponse().
std::map<int, XmlRpcConnectionState> XmlRpcInterface::state [protected] |
int XmlRpcInterface::curAppFd [protected] |
Referenced by closeConnection(), dumpDht(), get(), handleMessage(), handleRealworldPacket(), handleRpcResponse(), handleRpcTimeout(), initializeApp(), lookup(), p2pnsRegister(), p2pnsResolve(), put(), readHeader(), readRequest(), resetConnectionState(), sendInternalRpcWithTimeout(), and writeResponse().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_localLookup [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_lookup [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_register [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_resolve [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_put [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_get [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_dumpDht [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().
XmlRpc::XmlRpcServerMethod* XmlRpcInterface::_joinOverlay [protected] |
Referenced by initializeApp(), XmlRpcInterface(), and ~XmlRpcInterface().