mirror of https://github.com/oxen-io/lokinet
initial admin api infra
parent
bb3bed11dc
commit
475ac63f4a
@ -1,8 +1,6 @@
|
||||
#include <llarp/logger.h>
|
||||
#include <llarp/logger.hpp>
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,74 +0,0 @@
|
||||
|
||||
## Building on Linux
|
||||
|
||||
# or your OS or distro's package manager
|
||||
$ sudo apt install build-essential libtool autoconf cmake git
|
||||
$ git clone --recursive https://github.com/loki-project/lokinet-builder
|
||||
$ cd lokinet-builder
|
||||
$ make
|
||||
|
||||
## Building on Windows (mingw-w64 native, or wow64/linux/unix cross-compiler)
|
||||
|
||||
#i686 or x86_64
|
||||
#if cross-compiling from anywhere other than wow64, export CC and CXX to
|
||||
#$ARCH-w64-mingw32-g[cc++] respectively
|
||||
$ pacman -Sy base-devel mingw-w64-$ARCH-toolchain git libtool autoconf cmake
|
||||
$ git clone --recursive https://github.com/loki-project/lokinet-builder
|
||||
$ cd lokinet-builder
|
||||
$ make ensure sodium
|
||||
$ cd build
|
||||
$ cmake ../deps/llarp -DSODIUM_LIBRARIES=./prefix/lib/libsodium.a -DSODIUM_INCLUDE_DIR=./prefix/include -G "Unix Makefiles" -DHAVE_CXX17_FILESYSTEM=ON
|
||||
$ make
|
||||
$ cp llarpd ../lokinet.exe
|
||||
|
||||
## Building on Windows using Microsoft C/C++ (Visual Studio 2017)
|
||||
|
||||
* clone https://github.com/loki-project/lokinet-builder from git-bash or whatever git browser you use
|
||||
* open `%CLONE_PATH%/lokinet-builder/deps/sodium/builds/msvc/vs2017/libsodium.sln` and build one of the targets
|
||||
* create a `build` folder in `%CLONE_PATH%/lokinet-builder`
|
||||
* run cmake-gui from `%CLONE_PATH%/lokinet-builder/deps/llarp` as the source directory
|
||||
* define `SODIUM_LIB` to `%CLONE_PATH%/lokinet-builder/deps/sodium/bin/win32/%CONFIG%/%TOOLSET%/%TARGET%/libsodium.lib`
|
||||
* define `SODIUM_INCLUDE_DIR` to `%CLONE_PATH%/lokinet-builder/deps/sodium/src/libsodium/include`
|
||||
* define `HAVE_CXX17_FILESYSTEM` to `TRUE`
|
||||
* select `Visual Studio 2017 15 %ARCH%` as the generator
|
||||
* enter a custom toolset if desired (usually `v141_xp`)
|
||||
* generate the developer studio project files and open in the IDE
|
||||
* select a configuration
|
||||
* press F7 to build everything
|
||||
|
||||
## Running
|
||||
|
||||
$ ./lokinet
|
||||
|
||||
or press `Debug`/`Local Windows Debugger` in the visual studio standard toolbar
|
||||
|
||||
### Development
|
||||
|
||||
Please note development builds are likely to be unstable.
|
||||
|
||||
##### Build requirements:
|
||||
|
||||
* CMake
|
||||
* ninja (for unit testing with Google Tests)
|
||||
* libsodium >= 1.0.14 (included here)
|
||||
* c++ 11 capable C++ compiler
|
||||
* if you have C++17 `<filesystem>` or `<experimental/filesystem>` declared and defined in your platform's C++ toolchain, re-run CMake (in `lokinet-builder/build`) with `-DHAVE_CXX17_FILESYSTEM=ON`.
|
||||
* since each platform seems to have its own idea of where `std::[experimental::]filesystem` is defined, you will need to manually specify its library in `LDFLAGS` or `CMAKE_x_LINKER_FLAGS` as well.
|
||||
|
||||
##### Windows:
|
||||
|
||||
* Mingw-w64 is recommended for 32 or 64-bit builds.
|
||||
* It *is* possible to compile with Microsoft C++ (v19 or later from VS2015+).
|
||||
* `cpp17::filesystem` in `vendor/cppbackport-master` is not available for Windows.
|
||||
|
||||
#### Boxed warning
|
||||
<div style="border:5px solid #f00;padding:5px">
|
||||
<p>Inbound sessions are unsupported on Windows Server systems.</p>
|
||||
<p><strong><em>Ignore this warning at your own peril.</em></strong></p>
|
||||
</div>
|
||||
|
||||
##### Building a debug build:
|
||||
|
||||
#in lokinet-builder/
|
||||
$ cd build
|
||||
$ make
|
@ -0,0 +1,154 @@
|
||||
LokiNET admin api
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in RFC 2119 [RFC2119].
|
||||
|
||||
|
||||
|
||||
message format is jsonrpc 2.0 like api serialized with bittorrent encoding (BEncode) over
|
||||
TCP
|
||||
|
||||
messages are prefixed with big endian 16 bit length field indicating how many bytes the next
|
||||
message is.
|
||||
|
||||
a version 1 aRPC message is structured as the following message:
|
||||
|
||||
{
|
||||
"aRPC-method": "llarp",
|
||||
"id" : "some-id-here",
|
||||
"params": {
|
||||
"key1": "val1",
|
||||
"key2": "val2"
|
||||
},
|
||||
"v" : version_integer,
|
||||
"z-key" : "<optional 32 bytes public key>",
|
||||
"z-sig" : "<64 bytes siganture of the entire message requried if z-key is provided>"
|
||||
}
|
||||
|
||||
serialzied it would be:
|
||||
|
||||
d13:aRPC-method5:llarp2:id12:some-id-here6:paramsd4:key14:val14:key24:val2e5:z-key32:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5:z-sig64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAe
|
||||
|
||||
given the signature is 64 bytes of 'A' and the public key is 32 bytes of 'A'
|
||||
|
||||
responses are signed by the identity key and MUST be verified by the caller.
|
||||
|
||||
an example of a call to llarp.nodedb.getrc:
|
||||
|
||||
{
|
||||
"aRPC-method": "llarp.nodedb.rc.getbykey",
|
||||
"id" : "<12 bytes random>",
|
||||
"params": {
|
||||
"key" : "<32 bytes identity key>"
|
||||
}
|
||||
}
|
||||
|
||||
the reply MUST be signed by the router's identity key
|
||||
|
||||
{
|
||||
"aRPC-method" : "llarp.nodedb.rc.getbykey",
|
||||
"id" : "<12 bytes from before>",
|
||||
"return": {
|
||||
"value" : [RC, RC, RC]
|
||||
}
|
||||
"time": uint64_milliseconds_since_epoch_timestamp_now,
|
||||
"z-key": "<32 bytes identity public key>",
|
||||
"z-sig": "<64 bytes sig>"
|
||||
}
|
||||
|
||||
and on error:
|
||||
|
||||
{
|
||||
"aRPC-method" : "llarp.nodedb.rc.getbykey",
|
||||
"id" : "<12 bytes from before>",
|
||||
"return": {
|
||||
"error": "error message goes here"
|
||||
},
|
||||
"time": uint64_milliseconds_since_epoch_timestamp_now,
|
||||
"z-key": "<32 bytes identity public key>",
|
||||
"z-sig": "<64 bytes sig>"
|
||||
}
|
||||
|
||||
if requests are signed then they are authenticated by the signer's public key
|
||||
requesters can be granted access based on their public key, some methods MAY
|
||||
require this in order to be called.
|
||||
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
the methods currently provided are:
|
||||
|
||||
|
||||
llarp.rpc.ping
|
||||
|
||||
get a pong back
|
||||
|
||||
required parameters:
|
||||
|
||||
ping: integer
|
||||
|
||||
returns:
|
||||
|
||||
ping
|
||||
|
||||
llarp.nodedb.rc.getbykey
|
||||
|
||||
get rc by public identity key
|
||||
|
||||
required parameters:
|
||||
|
||||
key: 32 bytes public identity key
|
||||
|
||||
returns:
|
||||
|
||||
a list of RCs (see protocol v0 spec) that have this public identity key
|
||||
usually 0 or 1 RCs
|
||||
|
||||
|
||||
llarp.nodedb.rc.getbycidr
|
||||
|
||||
get a list of RCs in an address range
|
||||
|
||||
required parameters:
|
||||
|
||||
cidr: ipv6 network cidr string, i.e. "::ffff.21.0.0.0/8" or "fc00::/7"
|
||||
limit: integer max number of items to fetch, zero or positive integer,
|
||||
if zero no limit.
|
||||
|
||||
returns:
|
||||
|
||||
a list of 0 to limit RCs that advertise themselves as being reachble via an
|
||||
address in the given CIDR.
|
||||
|
||||
|
||||
llarp.admin.sys.uptime (authentication required)
|
||||
|
||||
required paramters:
|
||||
|
||||
(none)
|
||||
|
||||
returns:
|
||||
|
||||
an integer milliseconds since unix epoch we've been online
|
||||
|
||||
llarp.admin.link.neighboors (authentication required)
|
||||
|
||||
get a list of connected service nodes on all links
|
||||
|
||||
required parameters:
|
||||
|
||||
(none)
|
||||
|
||||
returns:
|
||||
|
||||
list of 0 to N dicts in the following format:
|
||||
|
||||
{
|
||||
"connected" : uint64_milliseconds_timestamp_connected_at
|
||||
"ident" : "<32 bytes public identity key>",
|
||||
"laddr" : "local address",
|
||||
"raddr" : "remote address"
|
||||
}
|
@ -1 +0,0 @@
|
||||
insert lokinet api overview here
|
@ -0,0 +1,64 @@
|
||||
#ifndef LLARP_ARPC_HPP
|
||||
#define LLARP_ARPC_HPP
|
||||
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/crypto.hpp>
|
||||
#include <llarp/logger.hpp>
|
||||
#include <llarp/time.h>
|
||||
#include <llarp/endian.h>
|
||||
#include <llarp/ev.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#include <llarp/net.hpp>
|
||||
|
||||
// forward declare
|
||||
struct llarp_router;
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace arpc
|
||||
{
|
||||
// forward declare
|
||||
struct BaseMessage;
|
||||
|
||||
struct Server
|
||||
{
|
||||
llarp_tcp_acceptor m_acceptor;
|
||||
|
||||
llarp_router* router;
|
||||
Server(llarp_router* r);
|
||||
|
||||
static void
|
||||
OnAccept(llarp_tcp_acceptor* a, llarp_tcp_conn* conn);
|
||||
|
||||
bool
|
||||
Start(const std::string& bindaddr);
|
||||
|
||||
const llarp_crypto*
|
||||
Crypto() const;
|
||||
|
||||
const byte_t*
|
||||
SigningPublicKey() const
|
||||
{
|
||||
return llarp::seckey_topublic(SigningPrivateKey());
|
||||
}
|
||||
|
||||
const byte_t*
|
||||
SigningPrivateKey() const;
|
||||
|
||||
bool
|
||||
Sign(BaseMessage* msg) const;
|
||||
};
|
||||
|
||||
} // namespace arpc
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
@ -0,0 +1,405 @@
|
||||
#include <llarp/arpc.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace arpc
|
||||
{
|
||||
/// interface for request messages
|
||||
struct IRequest
|
||||
{
|
||||
/// returns false if errmsg is set
|
||||
/// returns true if retval is set
|
||||
virtual bool
|
||||
HandleRequest(Server* ctx, std::unique_ptr< BaseMessage >& retval,
|
||||
std::string& errmsg) const = 0;
|
||||
};
|
||||
|
||||
struct BaseMessage : public llarp::IBEncodeMessage, public IRequest
|
||||
{
|
||||
static constexpr size_t MaxIDSize = 128;
|
||||
/// maximum size of a message
|
||||
static constexpr size_t MaxSize = 1024 * 8;
|
||||
|
||||
BaseMessage()
|
||||
{
|
||||
timestamp = llarp_time_now_ms();
|
||||
zkey.Zero();
|
||||
zsig.Zero();
|
||||
}
|
||||
|
||||
std::string m_id;
|
||||
llarp_time_t timestamp;
|
||||
llarp::PubKey zkey;
|
||||
llarp::Signature zsig;
|
||||
|
||||
/// override me
|
||||
virtual std::string
|
||||
Method() const = 0;
|
||||
|
||||
/// encode the entire message
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictString("aRPC-method", Method(), buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictString("id", m_id, buf))
|
||||
return false;
|
||||
if(!BEncodeBody(buf))
|
||||
return false;
|
||||
if(!zkey.IsZero())
|
||||
{
|
||||
if(!BEncodeWriteDictEntry("z-key", zkey, buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("z-sig", zsig, buf))
|
||||
return false;
|
||||
}
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t k, llarp_buffer_t* buf)
|
||||
{
|
||||
if(llarp_buffer_eq(k, "id"))
|
||||
{
|
||||
return DecodeID(buf);
|
||||
}
|
||||
if(llarp_buffer_eq(k, "params"))
|
||||
{
|
||||
return DecodeParams(buf);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef bool (*ParamDecoder)(dict_reader*, llarp_buffer_t*);
|
||||
|
||||
virtual ParamDecoder
|
||||
GetParamDecoder() const = 0;
|
||||
|
||||
bool
|
||||
DecodeParams(llarp_buffer_t* buf)
|
||||
{
|
||||
dict_reader r;
|
||||
r.user = this;
|
||||
r.on_key = GetParamDecoder();
|
||||
return bencode_read_dict(buf, &r);
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeID(llarp_buffer_t* buf)
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
if(!bencode_read_string(buf, &strbuf))
|
||||
return false;
|
||||
if(strbuf.sz > MaxIDSize) // too big
|
||||
return false;
|
||||
m_id = std::string((char*)strbuf.base, strbuf.sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// encode body of message
|
||||
virtual bool
|
||||
BEncodeBody(llarp_buffer_t* buf) const = 0;
|
||||
};
|
||||
|
||||
struct ConnHandler
|
||||
{
|
||||
ConnHandler(Server* s, llarp_tcp_conn* c) : parent(s), m_conn(c)
|
||||
{
|
||||
left = 0;
|
||||
readingHeader = true;
|
||||
}
|
||||
|
||||
bool readingHeader;
|
||||
Server* parent;
|
||||
llarp_tcp_conn* m_conn;
|
||||
AlignedBuffer< BaseMessage::MaxSize > buf;
|
||||
uint16_t left;
|
||||
|
||||
void
|
||||
ParseMessage();
|
||||
|
||||
void
|
||||
Close()
|
||||
{
|
||||
llarp_tcp_conn_close(m_conn);
|
||||
}
|
||||
|
||||
static void
|
||||
OnClosed(llarp_tcp_conn* conn)
|
||||
{
|
||||
ConnHandler* self = static_cast< ConnHandler* >(conn->user);
|
||||
delete self;
|
||||
}
|
||||
|
||||
static void
|
||||
OnRead(llarp_tcp_conn* conn, const void* buf, size_t sz)
|
||||
{
|
||||
ConnHandler* self = static_cast< ConnHandler* >(conn->user);
|
||||
const byte_t* ptr = (const byte_t*)buf;
|
||||
do
|
||||
{
|
||||
if(self->readingHeader)
|
||||
{
|
||||
self->left = bufbe16toh(ptr);
|
||||
sz -= 2;
|
||||
ptr += 2;
|
||||
self->readingHeader = false;
|
||||
}
|
||||
size_t dlt = std::min((size_t)self->left, sz);
|
||||
memcpy(self->buf.data() + (self->buf.size() - self->left), ptr, dlt);
|
||||
self->left -= dlt;
|
||||
sz -= dlt;
|
||||
if(self->left == 0)
|
||||
{
|
||||
self->ParseMessage();
|
||||
self->readingHeader = true;
|
||||
}
|
||||
} while(sz > 0);
|
||||
}
|
||||
};
|
||||
|
||||
/// base type for ping req/resp
|
||||
struct Ping : public BaseMessage
|
||||
{
|
||||
Ping() : BaseMessage()
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t ping;
|
||||
|
||||
std::string
|
||||
Method() const
|
||||
{
|
||||
return "llarp.rpc.ping";
|
||||
}
|
||||
|
||||
bool
|
||||
BEncodeBody(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_write_bytestring(buf, "params", 6))
|
||||
return false;
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictInt("ping", ping, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
static bool
|
||||
OnParamKey(dict_reader* r, llarp_buffer_t* k)
|
||||
{
|
||||
Ping* self = static_cast< Ping* >(r->user);
|
||||
if(k && llarp_buffer_eq(*k, "ping"))
|
||||
{
|
||||
return bencode_read_integer(r->buffer, &self->ping);
|
||||
}
|
||||
else
|
||||
return k == nullptr;
|
||||
}
|
||||
|
||||
virtual ParamDecoder
|
||||
GetParamDecoder() const
|
||||
{
|
||||
return &OnParamKey;
|
||||
}
|
||||
};
|
||||
|
||||
struct PingResponse : public Ping
|
||||
{
|
||||
PingResponse(uint64_t p) : Ping()
|
||||
{
|
||||
ping = p;
|
||||
}
|
||||
|
||||
bool
|
||||
HandleRequest(Server*, std::unique_ptr< BaseMessage >&,
|
||||
std::string&) const
|
||||
{
|
||||
/// TODO: handle client response
|
||||
llarp::LogInfo(Method(), "pong ", ping);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct PingRequest : public Ping
|
||||
{
|
||||
bool
|
||||
HandleRequest(Server* serv, std::unique_ptr< BaseMessage >& retval,
|
||||
std::string& errmsg) const
|
||||
{
|
||||
PingResponse* resp = new PingResponse(ping);
|
||||
if(!serv->Sign(resp))
|
||||
{
|
||||
errmsg = "failed to sign response";
|
||||
return false;
|
||||
}
|
||||
retval.reset(resp);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct MessageReader
|
||||
{
|
||||
dict_reader m_reader;
|
||||
BaseMessage* msg = nullptr;
|
||||
|
||||
MessageReader()
|
||||
{
|
||||
m_reader.user = this;
|
||||
m_reader.on_key = &OnKey;
|
||||
}
|
||||
|
||||
static bool
|
||||
OnKey(dict_reader* r, llarp_buffer_t* key)
|
||||
{
|
||||
static std::unordered_map< std::string,
|
||||
const std::function< BaseMessage*(void) > >
|
||||
msgConstructors = {
|
||||
{"llarp.rpc.ping",
|
||||
[]() -> BaseMessage* { return new PingRequest(); }},
|
||||
};
|
||||
|
||||
MessageReader* self = static_cast< MessageReader* >(r->user);
|
||||
if(self->msg == nullptr)
|
||||
{
|
||||
// first key
|
||||
if(key == nullptr || !llarp_buffer_eq(*key, "aRPC-method"))
|
||||
{
|
||||
// bad value
|
||||
return false;
|
||||
}
|
||||
llarp_buffer_t strbuf;
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
return false;
|
||||
std::string method = std::string((char*)strbuf.base, strbuf.sz);
|
||||
auto itr = msgConstructors.find(method);
|
||||
if(itr == msgConstructors.end())
|
||||
{
|
||||
// no such method
|
||||
return false;
|
||||
}
|
||||
else
|
||||
self->msg = itr->second();
|
||||
return true;
|
||||
}
|
||||
else if(key)
|
||||
return self->msg->DecodeKey(*key, r->buffer);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeMessage(llarp_buffer_t* buf,
|
||||
std::unique_ptr< BaseMessage >& request)
|
||||
{
|
||||
msg = nullptr;
|
||||
if(!bencode_read_dict(buf, &m_reader))
|
||||
return false;
|
||||
request.reset(msg);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Server::Server(llarp_router* r)
|
||||
{
|
||||
router = r;
|
||||
m_acceptor.user = this;
|
||||
m_acceptor.accepted = &OnAccept;
|
||||
}
|
||||
|
||||
bool
|
||||
Server::Start(const std::string& bindaddr)
|
||||
{
|
||||
llarp::Addr addr;
|
||||
sockaddr* saddr = nullptr;
|
||||
#ifndef _WIN32
|
||||
sockaddr_un unaddr;
|
||||
if(bindaddr.find("unix:") == 0)
|
||||
{
|
||||
unaddr.sun_family = AF_UNIX;
|
||||
|
||||
strncpy(unaddr.sun_path, bindaddr.substr(5).c_str(),
|
||||
sizeof(unaddr.sun_path));
|
||||
saddr = (sockaddr*)&unaddr;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// TODO: ipv6
|
||||
auto idx = bindaddr.find(':');
|
||||
std::string host = bindaddr.substr(0, idx);
|
||||
uint16_t port = std::stoi(bindaddr.substr(idx + 1));
|
||||
addr = llarp::Addr(host, port);
|
||||
saddr = addr.getSockAddr();
|
||||
}
|
||||
return llarp_tcp_serve(&m_acceptor, saddr);
|
||||
}
|
||||
|
||||
void
|
||||
Server::OnAccept(llarp_tcp_acceptor* a, llarp_tcp_conn* conn)
|
||||
{
|
||||
Server* self = static_cast< Server* >(a->user);
|
||||
conn->user = new ConnHandler(self, conn);
|
||||
conn->read = &ConnHandler::OnRead;
|
||||
conn->closed = &ConnHandler::OnClosed;
|
||||
}
|
||||
|
||||
bool
|
||||
Server::Sign(BaseMessage* msg) const
|
||||
{
|
||||
msg->zkey = SigningPublicKey();
|
||||
msg->zsig.Zero();
|
||||
llarp::Signature sig;
|
||||
//
|
||||
byte_t tmp[BaseMessage::MaxSize];
|
||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
||||
|
||||
if(!msg->BEncode(&buf))
|
||||
return false;
|
||||
// rewind buffer
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
|
||||
if(!Crypto()->sign(sig, SigningPrivateKey(), buf))
|
||||
return false;
|
||||
|
||||
msg->zsig = sig;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ConnHandler::ParseMessage()
|
||||
{
|
||||
std::unique_ptr< BaseMessage > msg;
|
||||
std::unique_ptr< BaseMessage > response;
|
||||
std::string errmsg;
|
||||
MessageReader r;
|
||||
auto tmp = llarp::Buffer(buf);
|
||||
if(!r.DecodeMessage(&tmp, msg))
|
||||
{
|
||||
llarp::LogError("failed to decode message");
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// handle request
|
||||
if(!msg->HandleRequest(parent, response, errmsg))
|
||||
{
|
||||
// TODO: send error reply
|
||||
llarp::LogError("failed to handle api message: ", errmsg);
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!parent->Sign(response.get()))
|
||||
{
|
||||
llarp::LogError("failed to sign response");
|
||||
Close();
|
||||
}
|
||||
}
|
||||
} // namespace arpc
|
||||
} // namespace llarp
|
Loading…
Reference in New Issue