mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
some api code
This commit is contained in:
parent
47b4b5c536
commit
c88d3860b8
24 changed files with 768 additions and 58 deletions
|
@ -135,6 +135,10 @@ set(LIB_SRC
|
|||
llarp/testnet.c
|
||||
llarp/time.cpp
|
||||
llarp/timer.cpp
|
||||
llarp/api/create_session.cpp
|
||||
llarp/api/client.cpp
|
||||
llarp/api/message.cpp
|
||||
llarp/api/parser.cpp
|
||||
llarp/routing/message_parser.cpp
|
||||
llarp/routing/path_confirm.cpp
|
||||
vendor/cppbackport-master/lib/fs/rename.cpp
|
||||
|
@ -157,12 +161,19 @@ set(LIB_SRC
|
|||
|
||||
set(TEST_SRC
|
||||
test/main.cpp
|
||||
test/api_unittest.cpp
|
||||
test/dht_unittest.cpp
|
||||
test/encrypted_frame_unittest.cpp
|
||||
)
|
||||
set(TEST_EXE testAll)
|
||||
set(GTEST_DIR test/gtest)
|
||||
|
||||
set(CLIENT_EXE llarpc)
|
||||
|
||||
set(CLIENT_SRC
|
||||
client/main.cpp
|
||||
)
|
||||
|
||||
# TODO: exclude this from includes and expose stuff properly for rcutil
|
||||
include_directories(llarp)
|
||||
|
||||
|
@ -179,7 +190,8 @@ else()
|
|||
|
||||
add_executable(rcutil daemon/rcutil.cpp)
|
||||
add_executable(${EXE} ${EXE_SRC})
|
||||
|
||||
add_executable(${CLIENT_EXE} ${CLIENT_SRC})
|
||||
|
||||
if(WITH_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(${GTEST_DIR})
|
||||
|
@ -195,6 +207,7 @@ else()
|
|||
if(NOT WITH_SHARED)
|
||||
target_link_libraries(rcutil ${STATIC_LINK_LIBS} ${STATIC_LIB})
|
||||
target_link_libraries(${EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB})
|
||||
target_link_libraries(${CLIENT_EXE} ${STATIC_LINK_LIBS} ${STATIC_LIB})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
15
client/main.cpp
Normal file
15
client/main.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include <llarp/api.hpp>
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
std::string url = llarp::api::DefaultURL;
|
||||
if(argc > 1)
|
||||
{
|
||||
url = argv[1];
|
||||
}
|
||||
llarp::api::Client cl;
|
||||
if(!cl.Start(url))
|
||||
return 1;
|
||||
return cl.Mainloop();
|
||||
}
|
|
@ -137,14 +137,13 @@ s is the long term public signing key
|
|||
v is the protocol version
|
||||
x is a nounce value for generating vanity addresses that can be omitted
|
||||
|
||||
if x is included it MUST be less than or equal to 16 bytes, any larger and it is
|
||||
considered invalid.
|
||||
if x is included it MUST be equal to 16 bytes
|
||||
|
||||
{
|
||||
e: "<32 bytes public encryption key>",
|
||||
s: "<32 bytes public signing key>",
|
||||
v: 0,
|
||||
x: "<optional nounce for vanity>"
|
||||
x: "<optional 16 bytes nonce for vanity>"
|
||||
}
|
||||
|
||||
service address (SA)
|
||||
|
@ -314,10 +313,6 @@ h = HS(BE(w))
|
|||
|
||||
h has log_e(y) prefix of 0x00
|
||||
|
||||
y = 2 means prefix of 0x00
|
||||
y = 4 means prefix of 0x00 0x00
|
||||
y = 32 means prefix 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
this proof of work requirement is subject to change
|
||||
|
||||
if i is equal to RC.k then any LRDM.x values are decrypted and interpreted as
|
||||
|
@ -345,7 +340,7 @@ otherwise transmit a LRUM to the next hop
|
|||
p: p,
|
||||
v: 0,
|
||||
x: x1,
|
||||
y: HS(y)
|
||||
y: y
|
||||
}
|
||||
|
||||
link relay downstream message (LRDM)
|
||||
|
@ -542,7 +537,7 @@ transfer data between paths.
|
|||
P: "<16 bytes path id>",
|
||||
T: "<N bytes data>",
|
||||
V: 0,
|
||||
Y: "<32 bytes nounce>",
|
||||
Y: "<32 bytes nounce>"
|
||||
}
|
||||
|
||||
transfer data to another path with id P on the local router place Y and T values
|
||||
|
|
14
include/llarp/api.hpp
Normal file
14
include/llarp/api.hpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef LLARP_API_HPP
|
||||
#define LLARP_API_HPP
|
||||
|
||||
#include <llarp/api/client.hpp>
|
||||
#include <llarp/api/server.hpp>
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
const char DefaultURL[] = "127.0.0.1:34567";
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
29
include/llarp/api/client.hpp
Normal file
29
include/llarp/api/client.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef LLARP_API_CLIENT_HPP
|
||||
#define LLARP_API_CLIENT_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
struct ClientPImpl;
|
||||
|
||||
struct Client
|
||||
{
|
||||
Client();
|
||||
~Client();
|
||||
|
||||
bool
|
||||
Start(const std::string& apiURL);
|
||||
|
||||
int
|
||||
Mainloop();
|
||||
|
||||
private:
|
||||
ClientPImpl* m_Impl;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace llarp
|
||||
#endif
|
125
include/llarp/api/messages.hpp
Normal file
125
include/llarp/api/messages.hpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
#ifndef LLARP_API_MESSAGES_HPP
|
||||
#define LLARP_API_MESSAGES_HPP
|
||||
|
||||
#include <list>
|
||||
#include <llarp/aligned.hpp>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/crypto.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
// forward declare
|
||||
struct Client;
|
||||
struct Server;
|
||||
|
||||
/// base message
|
||||
struct IMessage : public IBEncodeMessage
|
||||
{
|
||||
uint64_t sessionID = 0;
|
||||
uint64_t msgID = 0;
|
||||
uint64_t version = 0;
|
||||
llarp::ShortHash hash;
|
||||
|
||||
// the function name this message belongs to
|
||||
virtual std::string
|
||||
FunctionName() const = 0;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
|
||||
|
||||
virtual std::list< IBEncodeMessage* >
|
||||
GetParams() const = 0;
|
||||
|
||||
virtual bool
|
||||
DecodeParams(llarp_buffer_t* buf) = 0;
|
||||
|
||||
bool
|
||||
IsWellFormed(llarp_crypto* c, const std::string& password);
|
||||
|
||||
void
|
||||
CalculateHash(llarp_crypto* c, const std::string& password);
|
||||
};
|
||||
|
||||
/// a "yes we got your command" type message
|
||||
struct AcknoledgeMessage : public IMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// start a session with the router
|
||||
struct CreateSessionMessage : public IMessage
|
||||
{
|
||||
std::list< IBEncodeMessage* >
|
||||
GetParams() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool
|
||||
DecodeParams(llarp_buffer_t* buf);
|
||||
|
||||
std::string
|
||||
FunctionName() const
|
||||
{
|
||||
return "CreateSession";
|
||||
}
|
||||
};
|
||||
|
||||
/// a keepalive ping
|
||||
struct SessionPingMessage : public IMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// end a session with the router
|
||||
struct DestroySessionMessage : public IMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// base messgae type for hidden service control and transmission
|
||||
struct HSMessage : public IMessage
|
||||
{
|
||||
llarp::PubKey pubkey;
|
||||
llarp::Signature sig;
|
||||
|
||||
/// validate signature on message (server side)
|
||||
bool
|
||||
SignatureIsValid(llarp_crypto* crypto) const;
|
||||
|
||||
/// sign message using secret key (client side)
|
||||
bool
|
||||
SignMessge(llarp_crypto* crypto, byte_t* seckey);
|
||||
};
|
||||
|
||||
/// create a new hidden service
|
||||
struct CreateServiceMessgae : public HSMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// end an already created hidden service we created
|
||||
struct DestroyServiceMessage : public HSMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// start lookup of another service's descriptor
|
||||
struct LookupServiceMessage : public IMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// publish our hidden service's descriptor
|
||||
struct PublishServiceMessage : public IMessage
|
||||
{
|
||||
};
|
||||
|
||||
/// send pre encrypted data down a path we own
|
||||
struct SendPathDataMessage : public IMessage
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
26
include/llarp/api/parser.hpp
Normal file
26
include/llarp/api/parser.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef LLARP_API_PARSER_HPP
|
||||
#define LLARP_API_PARSER_HPP
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/api/messages.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
struct MessageParser
|
||||
{
|
||||
MessageParser();
|
||||
|
||||
IMessage *
|
||||
ParseMessage(llarp_buffer_t buf);
|
||||
|
||||
private:
|
||||
static bool
|
||||
OnKey(dict_reader *r, llarp_buffer_t *key);
|
||||
IMessage *msg = nullptr;
|
||||
dict_reader r;
|
||||
};
|
||||
} // namespace api
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
29
include/llarp/api/server.hpp
Normal file
29
include/llarp/api/server.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef LLARP_API_SERVER_HPP
|
||||
#define LLARP_API_SERVER_HPP
|
||||
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/router.h>
|
||||
#include <string>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
struct ServerPImpl;
|
||||
|
||||
struct Server
|
||||
{
|
||||
Server(llarp_router* r);
|
||||
~Server();
|
||||
|
||||
bool
|
||||
Bind(const std::string& url, llarp_ev_loop* loop);
|
||||
|
||||
private:
|
||||
ServerPImpl* m_Impl;
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -12,6 +12,13 @@ namespace llarp
|
|||
return bencode_write_bytestring(buf, k, 1)
|
||||
&& bencode_write_bytestring(buf, t, 1);
|
||||
}
|
||||
template < typename Obj_t >
|
||||
bool
|
||||
BEncodeWriteDictString(const char* k, const Obj_t& str, llarp_buffer_t* buf)
|
||||
{
|
||||
return bencode_write_bytestring(buf, k, 1)
|
||||
&& bencode_write_bytestring(buf, str.c_str(), str.size());
|
||||
}
|
||||
|
||||
template < typename Obj_t >
|
||||
bool
|
||||
|
@ -79,6 +86,22 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
template < typename List_t >
|
||||
bool
|
||||
BEncodeWriteDictBEncodeList(const char* k, const List_t& l,
|
||||
llarp_buffer_t* buf)
|
||||
{
|
||||
if(!bencode_write_bytestring(buf, k, 1))
|
||||
return false;
|
||||
if(!bencode_start_list(buf))
|
||||
return false;
|
||||
|
||||
for(const auto& item : l)
|
||||
if(!item->BEncode(buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
template < typename Iter >
|
||||
bool
|
||||
BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf)
|
||||
|
@ -119,6 +142,19 @@ namespace llarp
|
|||
return bencode_write_bytestring(buf, k, 1)
|
||||
&& BEncodeWriteList(list.begin(), list.end(), buf);
|
||||
}
|
||||
|
||||
/// bencode serializable message
|
||||
struct IBEncodeMessage
|
||||
{
|
||||
virtual ~IBEncodeMessage(){};
|
||||
|
||||
virtual bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val) = 0;
|
||||
|
||||
virtual bool
|
||||
BEncode(llarp_buffer_t* buf) const = 0;
|
||||
};
|
||||
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef LLARP_LINK_MESSAGE_HPP
|
||||
#define LLARP_LINK_MESSAGE_HPP
|
||||
|
||||
#include <llarp/bencode.h>
|
||||
#include <llarp/link.h>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/router_id.hpp>
|
||||
|
||||
#include <queue>
|
||||
|
@ -15,7 +15,7 @@ namespace llarp
|
|||
typedef std::queue< ILinkMessage* > SendQueue;
|
||||
|
||||
/// parsed link layer message
|
||||
struct ILinkMessage
|
||||
struct ILinkMessage : public IBEncodeMessage
|
||||
{
|
||||
/// who did this message come from (rc.k)
|
||||
RouterID remote = {};
|
||||
|
@ -24,14 +24,6 @@ namespace llarp
|
|||
ILinkMessage() = default;
|
||||
ILinkMessage(const RouterID& id);
|
||||
|
||||
virtual ~ILinkMessage(){};
|
||||
|
||||
virtual bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) = 0;
|
||||
|
||||
virtual bool
|
||||
BEncode(llarp_buffer_t* buf) const = 0;
|
||||
|
||||
virtual bool
|
||||
HandleMessage(llarp_router* router) const = 0;
|
||||
};
|
||||
|
@ -63,6 +55,6 @@ namespace llarp
|
|||
llarp_link_session* from;
|
||||
ILinkMessage* msg = nullptr;
|
||||
};
|
||||
}
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
||||
|
|
28
include/llarp/messages/path_latency.hpp
Normal file
28
include/llarp/messages/path_latency.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef LLARP_MESSAGES_PATH_LATENCY_HPP
|
||||
#define LLARP_MESSAGES_PATH_LATENCY_HPP
|
||||
|
||||
#include <llarp/routing/message.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace routing
|
||||
{
|
||||
struct PathLatencyMessage : public IMessage
|
||||
{
|
||||
uint64_t T = 0;
|
||||
uint64_t L = 0;
|
||||
PathLatencyMessage();
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* val);
|
||||
|
||||
bool
|
||||
HandleMessage(IMessageHandler* r) const;
|
||||
};
|
||||
} // namespace routing
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -192,6 +192,9 @@ namespace llarp
|
|||
bool
|
||||
HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r);
|
||||
|
||||
bool
|
||||
HandleHiddenServiceData(llarp_buffer_t buf);
|
||||
|
||||
// handle data in upstream direction
|
||||
bool
|
||||
HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
#ifndef LLARP_ROUTING_HANDLER_HPP
|
||||
#define LLARP_ROUTING_HANDLER_HPP
|
||||
|
||||
#include <llarp/buffer.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace routing
|
||||
{
|
||||
// handles messages on owned paths
|
||||
struct IMessageHandler
|
||||
{
|
||||
virtual bool
|
||||
HandleHiddenServiceData(llarp_buffer_t buf) = 0;
|
||||
};
|
||||
} // namespace routing
|
||||
} // namespace llarp
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <llarp/buffer.h>
|
||||
#include <llarp/router.h>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/path_types.hpp>
|
||||
|
||||
namespace llarp
|
||||
|
@ -11,18 +12,10 @@ namespace llarp
|
|||
{
|
||||
struct IMessageHandler;
|
||||
|
||||
struct IMessage
|
||||
struct IMessage : public llarp::IBEncodeMessage
|
||||
{
|
||||
llarp::PathID_t from;
|
||||
|
||||
virtual ~IMessage(){};
|
||||
|
||||
virtual bool
|
||||
BEncode(llarp_buffer_t* buf) const = 0;
|
||||
|
||||
virtual bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf) = 0;
|
||||
|
||||
virtual bool
|
||||
HandleMessage(IMessageHandler* r) const = 0;
|
||||
};
|
||||
|
|
57
include/llarp/service.hpp
Normal file
57
include/llarp/service.hpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef LLARP_SERVICE_HPP
|
||||
#define LLARP_SERVICE_HPP
|
||||
#include <llarp/aligned.hpp>
|
||||
#include <llarp/bencode.hpp>
|
||||
#include <llarp/crypto.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace service
|
||||
{
|
||||
/// hidden service address
|
||||
typedef llarp::AlignedBuffer< 32 > Address;
|
||||
|
||||
typedef llarp::AlignedBuffer< 16 > VanityNonce;
|
||||
|
||||
struct Info : public llarp::IBEncodeMessage
|
||||
{
|
||||
llarp::PubKey enckey;
|
||||
llarp::PubKey signkey;
|
||||
uint64_t version = 0;
|
||||
VanityNonce vanity;
|
||||
|
||||
/// calculate our address
|
||||
void
|
||||
CalculateAddress(llarp_crypto* c, Address& addr) const;
|
||||
|
||||
bool
|
||||
BEncode(llarp_buffer_t* buf) const;
|
||||
|
||||
bool
|
||||
DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf);
|
||||
};
|
||||
|
||||
// private keys
|
||||
struct Identity : public llarp::IBEncodeMessage
|
||||
{
|
||||
llarp::SecretKey enckey;
|
||||
llarp::SecretKey signkey;
|
||||
uint64_t version = 0;
|
||||
VanityNonce vanity;
|
||||
|
||||
// public service info
|
||||
Info pub;
|
||||
|
||||
// regenerate secret keys
|
||||
void
|
||||
RegenerateKeys(llarp_crypto* c);
|
||||
|
||||
// load from file
|
||||
bool
|
||||
LoadFromFile(const std::string& fpath);
|
||||
};
|
||||
|
||||
}; // namespace service
|
||||
} // namespace llarp
|
||||
|
||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef LLARP_SI_H
|
||||
#define LLARP_SI_H
|
||||
#include <llarp/crypto.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct llarp_service_info
|
||||
{
|
||||
llarp_buffer_t name;
|
||||
llarp_pubkey_t signingkey;
|
||||
llarp_buffer_t vanity;
|
||||
};
|
||||
|
||||
void
|
||||
llarp_service_info_hash(struct llarp_service_info *si, llarp_hash_t *h);
|
||||
bool
|
||||
llarp_service_info_bencode(struct llarp_serivce_info *si, llarp_buffer_t *buff);
|
||||
bool
|
||||
llarp_service_info_bdecode(struct llarp_serivce_info *si, llarp_buffer_t buff);
|
||||
void
|
||||
llarp_service_info_free(struct llarp_service_info **si);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
145
llarp/api/client.cpp
Normal file
145
llarp/api/client.cpp
Normal file
|
@ -0,0 +1,145 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <llarp/ev.h>
|
||||
#include <llarp/logic.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <llarp/api/client.hpp>
|
||||
#include <llarp/api/messages.hpp>
|
||||
#include <llarp/api/parser.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
struct ClientPImpl
|
||||
{
|
||||
ClientPImpl()
|
||||
{
|
||||
llarp_ev_loop_alloc(&loop);
|
||||
worker = llarp_init_same_process_threadpool();
|
||||
logic = llarp_init_single_process_logic(worker);
|
||||
}
|
||||
|
||||
~ClientPImpl()
|
||||
{
|
||||
llarp_ev_loop_free(&loop);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleRecv(llarp_udp_io* u, const sockaddr* from, const void* buf,
|
||||
ssize_t sz)
|
||||
{
|
||||
static_cast< ClientPImpl* >(u->user)->RecvFrom(from, buf, sz);
|
||||
}
|
||||
|
||||
void
|
||||
RecvFrom(const sockaddr* from, const void* b, ssize_t sz)
|
||||
{
|
||||
if(from->sa_family != AF_INET
|
||||
|| ((sockaddr_in*)from)->sin_addr.s_addr != apiAddr.sin_addr.s_addr
|
||||
|| ((sockaddr_in*)from)->sin_port != apiAddr.sin_port)
|
||||
{
|
||||
// address missmatch
|
||||
llarp::Warn("got packet from bad address");
|
||||
return;
|
||||
}
|
||||
llarp_buffer_t buf;
|
||||
buf.base = (byte_t*)b;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = sz;
|
||||
IMessage* msg = m_MessageParser.ParseMessage(buf);
|
||||
if(msg)
|
||||
{
|
||||
delete msg;
|
||||
}
|
||||
else
|
||||
llarp::Warn("Got Invalid Message");
|
||||
}
|
||||
|
||||
bool
|
||||
BindDefault()
|
||||
{
|
||||
ouraddr.sin_family = AF_INET;
|
||||
ouraddr.sin_addr.s_addr = INADDR_LOOPBACK;
|
||||
ouraddr.sin_port = 0;
|
||||
udp.user = this;
|
||||
udp.recvfrom = &HandleRecv;
|
||||
return llarp_ev_add_udp(loop, &udp, (const sockaddr*)&ouraddr) != -1;
|
||||
}
|
||||
|
||||
bool
|
||||
StartSession(const std::string& addr, uint16_t port)
|
||||
{
|
||||
apiAddr.sin_family = AF_INET;
|
||||
if(inet_pton(AF_INET, addr.c_str(), &apiAddr.sin_addr.s_addr) == -1)
|
||||
return false;
|
||||
apiAddr.sin_port = htons(port);
|
||||
CreateSessionMessage msg;
|
||||
return SendMessage(&msg);
|
||||
}
|
||||
|
||||
bool
|
||||
SendMessage(const IMessage* msg)
|
||||
{
|
||||
llarp_buffer_t buf;
|
||||
byte_t tmp[1500];
|
||||
buf.base = tmp;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = sizeof(tmp);
|
||||
if(msg->BEncode(&buf))
|
||||
return llarp_ev_udp_sendto(&udp, (const sockaddr*)&apiAddr, buf.base,
|
||||
buf.sz)
|
||||
!= -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
Mainloop()
|
||||
{
|
||||
llarp_ev_loop_run_single_process(loop, worker, logic);
|
||||
return 0;
|
||||
}
|
||||
llarp_threadpool* worker;
|
||||
llarp_logic* logic;
|
||||
llarp_ev_loop* loop;
|
||||
sockaddr_in ouraddr;
|
||||
sockaddr_in apiAddr;
|
||||
llarp_udp_io udp;
|
||||
MessageParser m_MessageParser;
|
||||
};
|
||||
|
||||
Client::Client() : m_Impl(new ClientPImpl)
|
||||
{
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
delete m_Impl;
|
||||
}
|
||||
|
||||
bool
|
||||
Client::Start(const std::string& url)
|
||||
{
|
||||
if(url.find(":") == std::string::npos)
|
||||
return false;
|
||||
if(!m_Impl->BindDefault())
|
||||
return false;
|
||||
std::string addr = url.substr(0, url.find(":"));
|
||||
std::string strport = url.substr(url.find(":") + 1);
|
||||
int port = std::stoi(strport);
|
||||
if(port == -1)
|
||||
return false;
|
||||
return m_Impl->StartSession(addr, port);
|
||||
}
|
||||
|
||||
int
|
||||
Client::Mainloop()
|
||||
{
|
||||
return m_Impl->Mainloop();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace llarp
|
18
llarp/api/create_session.cpp
Normal file
18
llarp/api/create_session.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <list>
|
||||
#include <llarp/api/messages.hpp>
|
||||
#include <llarp/encrypted.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
|
||||
bool
|
||||
CreateSessionMessage::DecodeParams(llarp_buffer_t *buf)
|
||||
{
|
||||
std::list< llarp::Encrypted > params;
|
||||
return BEncodeReadList(params, buf);
|
||||
}
|
||||
} // namespace api
|
||||
} // namespace llarp
|
109
llarp/api/message.cpp
Normal file
109
llarp/api/message.cpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
#include <llarp/api/messages.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
bool
|
||||
IMessage::BEncode(llarp_buffer_t* buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictString("F", FunctionName(), buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt(buf, "I", sessionID))
|
||||
return false;
|
||||
if(!BEncodeWriteDictInt(buf, "M", msgID))
|
||||
return false;
|
||||
if(!BEncodeWriteDictBEncodeList("P", GetParams(), buf))
|
||||
return false;
|
||||
if(!BEncodeWriteDictEntry("Z", hash, buf))
|
||||
return false;
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
IMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* val)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "P"))
|
||||
{
|
||||
return DecodeParams(val);
|
||||
}
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadDictInt("I", sessionID, read, key, val))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictInt("M", msgID, read, key, val))
|
||||
return false;
|
||||
if(!BEncodeMaybeReadDictEntry("Z", hash, read, key, val))
|
||||
return false;
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
IMessage::IsWellFormed(llarp_crypto* crypto, const std::string& password)
|
||||
{
|
||||
// hash password
|
||||
llarp::ShortHash secret;
|
||||
llarp_buffer_t passbuf;
|
||||
passbuf.base = (byte_t*)password.c_str();
|
||||
passbuf.cur = passbuf.base;
|
||||
passbuf.sz = password.size();
|
||||
crypto->shorthash(secret, passbuf);
|
||||
|
||||
llarp::ShortHash digest, tmpHash;
|
||||
// save hash
|
||||
tmpHash = hash;
|
||||
// zero hash
|
||||
hash.Zero();
|
||||
|
||||
// bencode
|
||||
byte_t tmp[1500];
|
||||
llarp_buffer_t buf;
|
||||
buf.base = tmp;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = sizeof(tmp);
|
||||
if(!BEncode(&buf))
|
||||
return false;
|
||||
|
||||
// rewind buffer
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// calculate message auth
|
||||
crypto->hmac(digest, buf, secret);
|
||||
// restore hash
|
||||
hash = tmpHash;
|
||||
return tmpHash == digest;
|
||||
}
|
||||
|
||||
void
|
||||
IMessage::CalculateHash(llarp_crypto* crypto, const std::string& password)
|
||||
{
|
||||
// hash password
|
||||
llarp::ShortHash secret;
|
||||
llarp_buffer_t passbuf;
|
||||
passbuf.base = (byte_t*)password.c_str();
|
||||
passbuf.cur = passbuf.base;
|
||||
passbuf.sz = password.size();
|
||||
crypto->shorthash(secret, passbuf);
|
||||
|
||||
llarp::ShortHash digest;
|
||||
// zero hash
|
||||
hash.Zero();
|
||||
|
||||
// bencode
|
||||
byte_t tmp[1500];
|
||||
llarp_buffer_t buf;
|
||||
buf.base = tmp;
|
||||
buf.cur = buf.base;
|
||||
buf.sz = sizeof(tmp);
|
||||
if(BEncode(&buf))
|
||||
{
|
||||
// rewind buffer
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
// calculate message auth
|
||||
crypto->hmac(hash, buf, secret);
|
||||
}
|
||||
}
|
||||
} // namespace api
|
||||
} // namespace llarp
|
60
llarp/api/parser.cpp
Normal file
60
llarp/api/parser.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include <functional>
|
||||
#include <llarp/api/parser.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace api
|
||||
{
|
||||
std::map< std::string, std::function< IMessage*() > > funcmap = {
|
||||
{"CreateSession", []() { return new CreateSessionMessage; }},
|
||||
};
|
||||
|
||||
MessageParser::MessageParser()
|
||||
{
|
||||
r.user = this;
|
||||
r.on_key = &OnKey;
|
||||
}
|
||||
|
||||
bool
|
||||
MessageParser::OnKey(dict_reader* r, llarp_buffer_t* key)
|
||||
{
|
||||
MessageParser* self = static_cast< MessageParser* >(r->user);
|
||||
if(self->msg == nullptr && key == nullptr) // empty message
|
||||
return false;
|
||||
if(self->msg == nullptr && key)
|
||||
{
|
||||
// first message, function name
|
||||
if(!llarp_buffer_eq(*key, "f"))
|
||||
return false;
|
||||
llarp_buffer_t strbuf;
|
||||
if(!bencode_read_string(r->buffer, &strbuf))
|
||||
return false;
|
||||
std::string funcname((char*)strbuf.cur, strbuf.sz);
|
||||
auto itr = funcmap.find(funcname);
|
||||
if(itr == funcmap.end())
|
||||
return false;
|
||||
self->msg = itr->second();
|
||||
return true;
|
||||
}
|
||||
else if(self->msg && key)
|
||||
{
|
||||
return self->msg->DecodeKey(*key, r->buffer);
|
||||
}
|
||||
else if(self->msg && key == nullptr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IMessage*
|
||||
MessageParser::ParseMessage(llarp_buffer_t buf)
|
||||
{
|
||||
if(bencode_read_dict(&buf, &r))
|
||||
return msg;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace llarp
|
|
@ -276,6 +276,13 @@ namespace llarp
|
|||
return HandleRoutingMessage(buf, r);
|
||||
}
|
||||
|
||||
bool
|
||||
Path::HandleHiddenServiceData(llarp_buffer_t buf)
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r)
|
||||
{
|
||||
|
|
11
llarp/routing/path_latency.cpp
Normal file
11
llarp/routing/path_latency.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <llarp/messages/path_latency.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace routing
|
||||
{
|
||||
PathLatencyMessage::PathLatencyMessage()
|
||||
{
|
||||
}
|
||||
} // namespace routing
|
||||
} // namespace llarp
|
1
llarp/service.cpp
Normal file
1
llarp/service.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include <llarp/service.hpp>
|
27
test/api_unittest.cpp
Normal file
27
test/api_unittest.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <llarp/api/messages.hpp>
|
||||
|
||||
class APITest : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
llarp_crypto crypto;
|
||||
std::string apiPassword = "password";
|
||||
APITest()
|
||||
{
|
||||
llarp_crypto_libsodium_init(&crypto);
|
||||
}
|
||||
|
||||
~APITest()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(APITest, TestMessageWellFormed)
|
||||
{
|
||||
llarp::api::CreateSessionMessage msg;
|
||||
msg.msgID = 0;
|
||||
msg.sessionID = 12345;
|
||||
msg.CalculateHash(&crypto, apiPassword);
|
||||
llarp::Info("msghash=", msg.hash);
|
||||
ASSERT_TRUE(msg.IsWellFormed(&crypto, apiPassword));
|
||||
};
|
Loading…
Reference in a new issue