diff --git a/src/xrpld/rpc/detail/Handler.cpp b/src/xrpld/rpc/detail/Handler.cpp index 956f38184..b2396de0e 100644 --- a/src/xrpld/rpc/detail/Handler.cpp +++ b/src/xrpld/rpc/detail/Handler.cpp @@ -100,6 +100,7 @@ Handler const handlerArray[]{ {"channel_authorize", byRef(&doChannelAuthorize), Role::USER, NO_CONDITION}, {"channel_verify", byRef(&doChannelVerify), Role::USER, NO_CONDITION}, {"connect", byRef(&doConnect), Role::ADMIN, NO_CONDITION}, + {"disconnect", byRef(&doDisconnect), Role::ADMIN, NO_CONDITION}, {"consensus_info", byRef(&doConsensusInfo), Role::ADMIN, NO_CONDITION}, {"deposit_authorized", byRef(&doDepositAuthorized), diff --git a/src/xrpld/rpc/handlers/Disconnect.cpp b/src/xrpld/rpc/handlers/Disconnect.cpp new file mode 100644 index 000000000..eda343df1 --- /dev/null +++ b/src/xrpld/rpc/handlers/Disconnect.cpp @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012-2014 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ripple { + +// { +// ip: , +// port: +// } +Json::Value +doDisconnect(RPC::JsonContext& context) +{ + if (context.app.config().standalone()) + { + return RPC::make_error(rpcNOT_SYNCED); + } + + if (!context.params.isMember(jss::ip)) + return RPC::missing_field_error(jss::ip); + + if (context.params.isMember(jss::port) && + !context.params[jss::port].isConvertibleTo(Json::intValue)) + { + return rpcError(rpcINVALID_PARAMS); + } + + int iPort; + + if (context.params.isMember(jss::port)) + iPort = context.params[jss::port].asInt(); + else + iPort = DEFAULT_PEER_PORT; + + auto const ipStr = context.params[jss::ip].asString(); + auto ip = beast::IP::Endpoint::from_string(ipStr); + + int disconnected = 0; + if (!is_unspecified(ip)) + { + auto const endpoint = ip.at_port(iPort); + for (auto const& peer : context.app.overlay().getActivePeers()) + { + if (peer && peer->getRemoteAddress() == endpoint) + { + // Explicit cast keeps this RPC local to the existing overlay + // implementation while preserving ip:port symmetry with connect. + if (auto p = std::dynamic_pointer_cast(peer)) + { + p->stop(); + ++disconnected; + } + } + } + } + + return RPC::makeObjectValue( + "disconnect requested for IP:" + ipStr + + " port: " + std::to_string(iPort) + + " peers: " + std::to_string(disconnected)); +} + +} // namespace ripple diff --git a/src/xrpld/rpc/handlers/Handlers.h b/src/xrpld/rpc/handlers/Handlers.h index c8ad98c57..83f9d2781 100644 --- a/src/xrpld/rpc/handlers/Handlers.h +++ b/src/xrpld/rpc/handlers/Handlers.h @@ -59,6 +59,8 @@ doChannelVerify(RPC::JsonContext&); Json::Value doConnect(RPC::JsonContext&); Json::Value +doDisconnect(RPC::JsonContext&); +Json::Value doConsensusInfo(RPC::JsonContext&); Json::Value doDepositAuthorized(RPC::JsonContext&);