Merge pull request #1 from neuroscr/master

RCUtil --list, --import, --export
pull/3/head
Ryan Tharp 6 years ago committed by GitHub
commit 39e11c2b7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -109,6 +109,7 @@ set(LIB_SRC
llarp/crypto_async.cpp
llarp/crypto_libsodium.cpp
llarp/dht.cpp
llarp/encode.cpp
llarp/encrypted_frame.cpp
llarp/ev.cpp
llarp/exit_info.cpp
@ -135,6 +136,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 +162,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,6 +191,7 @@ else()
add_executable(rcutil daemon/rcutil.cpp)
add_executable(${EXE} ${EXE_SRC})
add_executable(${CLIENT_EXE} ${CLIENT_SRC})
if(WITH_TESTS)
enable_testing()
@ -195,6 +208,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()

@ -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();
}

@ -1,190 +1,149 @@
#include <llarp.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <llarp/crypto.hpp>
#include "fs.hpp"
static void
progress()
{
printf(".");
fflush(stdout);
}
struct llarp_main
{
struct llarp_crypto crypto;
struct llarp_router *router = nullptr;
struct llarp_threadpool *worker = nullptr;
struct llarp_threadpool *thread = nullptr;
struct llarp_logic *logic = nullptr;
struct llarp_config *config = nullptr;
struct llarp_nodedb *nodedb = nullptr;
struct llarp_ev_loop *mainloop = nullptr;
char nodedb_dir[256];
int exitcode;
int
shutdown()
{
printf("Shutting down ");
progress();
if(mainloop)
llarp_ev_loop_stop(mainloop);
progress();
if(worker)
llarp_threadpool_stop(worker);
progress();
if(worker)
llarp_threadpool_join(worker);
#include "logger.hpp"
progress();
if(logic)
llarp_logic_stop(logic);
progress();
if(router)
llarp_stop_router(router);
progress();
llarp_free_router(&router);
progress();
llarp_free_config(&config);
progress();
llarp_ev_loop_free(&mainloop);
progress();
llarp_free_threadpool(&worker);
progress();
llarp_free_logic(&logic);
progress();
printf("\n");
fflush(stdout);
return exitcode;
}
};
void
iter_main_config(struct llarp_config_iterator *itr, const char *section,
const char *key, const char *val)
{
llarp_main *m = static_cast< llarp_main * >(itr->user);
if(!strcmp(section, "router"))
{
if(!strcmp(key, "threads"))
{
int workers = atoi(val);
if(workers > 0 && m->worker == nullptr)
{
m->worker = llarp_init_threadpool(workers, "llarp-worker");
}
}
}
if(!strcmp(section, "netdb"))
{
if(!strcmp(key, "dir"))
{
strncpy(m->nodedb_dir, val, sizeof(m->nodedb_dir));
}
}
}
struct llarp_main *ctx = 0;
llarp_main *sllarp = nullptr;
void
run_net(void *user)
{
llarp_ev_loop_run(static_cast< llarp_ev_loop * >(user));
}
void
handle_signal(int sig)
{
printf("\ninterrupted\n");
llarp_ev_loop_stop(sllarp->mainloop);
llarp_logic_stop(sllarp->logic);
if(ctx)
llarp_main_signal(ctx, sig);
}
#ifndef TESTNET
#define TESTNET 0
#endif
#include <getopt.h>
#include <llarp/router_contact.h>
#include <llarp/time.h>
#include <fstream>
#include "fs.hpp"
#include "buffer.hpp"
#include "crypto.hpp"
#include "router.hpp"
bool printNode(struct llarp_nodedb_iter *iter) {
char ftmp[68] = {0};
const char *hexname =
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(iter->rc->pubkey, ftmp);
printf("[%zu]=>[%s]\n", iter->index, hexname);
return false;
}
int
main(int argc, char *argv[])
{
// take -c to set location of daemon.ini
// --generate-blank /path/to/file.signed
// --update-ifs /path/to/file.signed
// --key /path/to/long_term_identity.key
// --import
// --export
// --generate /path/to/file.signed
// --update /path/to/file.signed
// printf("has [%d]options\n", argc);
if(argc < 3)
if(argc < 2)
{
printf(
"please specify --generate or --update with a path to a router contact "
"file\n");
"please specify: \n"
"--generate with a path to a router contact file\n"
"--update with a path to a router contact file\n"
"--list \n"
"--import with a path to a router contact file\n"
"--export with a path to a router contact file\n"
"\n");
return 0;
}
bool genMode = false;
bool updMode = false;
bool listMode = false;
bool importMode = false;
bool exportMode = false;
int c;
char *conffname;
char defaultConfName[] = "daemon.ini";
conffname = defaultConfName;
char *rcfname;
char defaultName[] = "other.signed";
rcfname = defaultName;
char defaultRcName[] = "other.signed";
rcfname = defaultRcName;
bool haveRequiredOptions = false;
while(1)
{
static struct option long_options[] = {
{"config", required_argument, 0, 'c'},
{"generate", required_argument, 0, 'g'},
{"update", required_argument, 0, 'u'},
{"list", no_argument, 0, 'l'},
{"import", required_argument, 0, 'i'},
{"export", required_argument, 0, 'e'},
{0, 0, 0, 0}};
int option_index = 0;
c = getopt_long(argc, argv, "gu", long_options, &option_index);
c = getopt_long(argc, argv, "cgluie", long_options, &option_index);
if(c == -1)
break;
switch(c)
{
case 0:
break;
case 'c':
conffname = optarg;
break;
case 'l':
haveRequiredOptions = true;
listMode = true;
break;
case 'i':
// printf ("option -g with value `%s'\n", optarg);
rcfname = optarg;
haveRequiredOptions = true;
importMode = true;
break;
case 'e':
// printf ("option -g with value `%s'\n", optarg);
rcfname = optarg;
haveRequiredOptions = true;
exportMode = true;
break;
case 'g':
// printf ("option -g with value `%s'\n", optarg);
rcfname = optarg;
haveRequiredOptions = true;
genMode = true;
break;
case 'u':
// printf ("option -u with value `%s'\n", optarg);
rcfname = optarg;
haveRequiredOptions = true;
updMode = true;
break;
default:
abort();
}
}
if (!haveRequiredOptions) {
llarp::Error("Parameters dont all have their required parameters.\n");
return 0;
}
printf("parsed options\n");
if(!genMode && !updMode)
if(!genMode && !updMode && !listMode &&!importMode && !exportMode)
{
printf("I don't know what to do, no generate or update parameter\n");
return 1;
llarp::Error("I don't know what to do, no generate or update parameter\n");
return 0;
}
sllarp = new llarp_main;
// llarp_new_config(&sllarp->config);
// llarp_ev_loop_alloc(&sllarp->mainloop);
llarp_crypto_libsodium_init(&sllarp->crypto);
ctx = llarp_main_init(conffname, !TESTNET);
if (!ctx) {
llarp::Error("Cant set up context");
return 0;
}
signal(SIGINT, handle_signal);
llarp_rc tmp;
if(genMode)
@ -202,12 +161,19 @@ main(int argc, char *argv[])
// load longterm identity
llarp_crypto crypt;
llarp_crypto_libsodium_init(&crypt);
// which is in daemon.ini config: router.encryption-privkey (defaults "encryption.key")
fs::path encryption_keyfile = "encryption.key";
llarp::SecretKey encryption;
llarp_findOrCreateEncryption(&crypt, encryption_keyfile.c_str(), &encryption);
llarp_rc_set_pubenckey(&tmp, llarp::seckey_topublic(encryption));
// get identity public sig key
fs::path ident_keyfile = "identity.key";
byte_t identity[SECKEYSIZE];
llarp_findOrCreateIdentity(&crypt, ident_keyfile.c_str(), identity);
// get identity public key
uint8_t *pubkey = llarp::seckey_topublic(identity);
llarp_rc_set_pubkey(&tmp, pubkey);
llarp_rc_set_pubsigkey(&tmp, llarp::seckey_topublic(identity));
// this causes a segfault
llarp_rc_sign(&crypt, identity, &tmp);
// set filename
@ -220,33 +186,10 @@ main(int argc, char *argv[])
if(updMode)
{
printf("rcutil.cpp - Loading [%s]\n", rcfname);
fs::path our_rc_file = rcfname;
std::error_code ec;
if(!fs::exists(our_rc_file, ec))
{
printf("File not found\n");
return 0;
}
std::ifstream f(our_rc_file, std::ios::binary);
if(!f.is_open())
{
printf("Can't open file\n");
return 0;
}
byte_t tmpc[MAX_RC_SIZE];
llarp_buffer_t buf;
buf.base = tmpc;
buf.cur = buf.base;
buf.sz = sizeof(tmpc);
f.read((char *)tmpc, sizeof(MAX_RC_SIZE));
// printf("contents[%s]\n", tmpc);
if(!llarp_rc_bdecode(&tmp, &buf))
{
printf("Can't decode\n");
return 0;
}
llarp_rc *rc = llarp_rc_read(rcfname);
// set updated timestamp
tmp.last_updated = llarp_time_now_ms();
rc->last_updated = llarp_time_now_ms();
// load longterm identity
llarp_crypto crypt;
llarp_crypto_libsodium_init(&crypt);
@ -255,16 +198,48 @@ main(int argc, char *argv[])
llarp_findOrCreateIdentity(&crypt, ident_keyfile.c_str(), identity);
// get identity public key
uint8_t *pubkey = llarp::seckey_topublic(identity);
llarp_rc_set_pubkey(&tmp, pubkey);
llarp_rc_sign(&crypt, identity, &tmp);
llarp_rc_set_pubsigkey(rc, pubkey);
llarp_rc_sign(&crypt, identity, rc);
// set filename
fs::path our_rc_file_out = "update_debug.rc";
// write file
llarp_rc_write(&tmp, our_rc_file_out.c_str());
// release memory for tmp lists
llarp_rc_free(&tmp);
}
if (listMode) {
llarp_main_loadDatabase(ctx);
llarp_nodedb_iter iter;
iter.visit = printNode;
llarp_main_iterateDatabase(ctx, iter);
}
if (importMode) {
llarp_main_loadDatabase(ctx);
llarp::Info("Loading ", rcfname);
llarp_rc *rc = llarp_rc_read(rcfname);
if (!rc)
{
llarp::Error("Can't load RC");
return 0;
}
llarp_main_putDatabase(ctx, rc);
}
if (exportMode) {
llarp_main_loadDatabase(ctx);
//llarp::Info("Looking for string: ", rcfname);
llarp::PubKey binaryPK;
llarp::HexDecode(rcfname, binaryPK.data());
delete sllarp;
return 1;
llarp::Info("Looking for binary: ", binaryPK);
struct llarp_rc *rc = llarp_main_getDatabase(ctx, binaryPK.data());
if (!rc) {
llarp::Error("Can't load RC from database");
}
std::string filename(rcfname);
filename.append(".signed");
llarp::Info("Writing out: ", filename);
llarp_rc_write(rc, filename.c_str());
}
llarp_main_free(ctx);
return 1; // success
}

@ -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

@ -12,25 +12,42 @@
extern "C" {
#endif
/** llarp application context for C api */
/// llarp application context for C api
struct llarp_main;
/** initialize application context and load config */
/// initialize application context and load config
struct llarp_main *
llarp_main_init(const char *fname, bool multiProcess);
/** handle signal for main context */
/// handle signal for main context
void
llarp_main_signal(struct llarp_main *ptr, int sig);
/** set custom dht message handler function */
/// set custom dht message handler function
void
llarp_main_set_dht_handler(struct llarp_main *ptr, llarp_dht_msg_handler h);
/** run main context */
/// run main context
int
llarp_main_run(struct llarp_main *ptr);
/// load nodeDB into memory
int
llarp_main_loadDatabase(struct llarp_main *ptr);
/// iterator on nodedb entries
int
llarp_main_iterateDatabase(struct llarp_main *ptr, struct llarp_nodedb_iter i);
/// put RC into nodeDB
bool
llarp_main_putDatabase(struct llarp_main *ptr, struct llarp_rc *rc);
struct llarp_rc *
llarp_main_getDatabase(struct llarp_main *ptr, byte_t *pk);
void
llarp_main_free(struct llarp_main *ptr);

@ -33,6 +33,18 @@ namespace llarp
void
Close();
int
LoadDatabase();
int
IterateDatabase(struct llarp_nodedb_iter i);
bool
PutDatabase(struct llarp_rc *rc);
struct llarp_rc *
GetDatabase(const byte_t *pk);
int
Run();

@ -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

@ -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

@ -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

@ -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

@ -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,6 +1,7 @@
#ifndef LLARP_ENCODE_HPP
#define LLARP_ENCODE_HPP
#include <cstdlib>
#include <stdint.h>
namespace llarp
{
@ -26,6 +27,9 @@ namespace llarp
*ptr = 0;
return &stack[0];
}
int char2int(char input);
void HexDecode(const char* src, uint8_t* target);
}
#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

@ -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

@ -41,11 +41,12 @@ struct llarp_nodedb_iter
{
void *user;
struct llarp_rc *rc;
size_t index;
bool (*visit)(struct llarp_nodedb_iter *);
};
/// iterate over all loaded rc with an iterator
void
int
llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i);
/// get a random rc that is loaded

@ -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);
@ -200,6 +203,7 @@ namespace llarp
bool
HandleDownstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r);
// Is this deprecated?
const PathID_t&
TXID() const;

@ -56,8 +56,17 @@ llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src);
void
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
struct llarp_ai_list *addr);
void
llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey);
void
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey);
llarp_rc_set_pubsigkey(struct llarp_rc *rc, const uint8_t *pubkey);
/// combo
void
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubenckey,
const uint8_t *pubsigkey);
void
llarp_rc_sign(struct llarp_crypto *crypto, const byte_t *seckey,
@ -69,6 +78,9 @@ llarp_rc_clear(struct llarp_rc *rc);
bool
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai);
struct llarp_rc *
llarp_rc_read(const char *fpath);
bool
llarp_rc_write(struct llarp_rc *rc, const char *our_rc_file);

@ -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;
};

@ -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

@ -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

@ -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

@ -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

@ -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

@ -29,20 +29,20 @@ namespace llarp
bool
Context::ReloadConfig()
{
llarp::Info("loading config at ", configfile);
if(!llarp_load_config(config, configfile.c_str()))
//llarp::Info("loading config at ", configfile);
if(llarp_load_config(config, configfile.c_str()))
{
llarp_free_config(&config);
llarp::Error("failed to load config file ", configfile);
return false;
}
llarp_config_iterator iter;
iter.user = this;
iter.visit = &iter_config;
llarp_config_iter(config, &iter);
llarp::Info("config loaded");
llarp::Info("config [", configfile, "] loaded");
return true;
}
llarp_free_config(&config);
llarp::Error("failed to load config file ", configfile);
return false;
}
void
Context::iter_config(llarp_config_iterator *itr, const char *section,
@ -78,10 +78,8 @@ namespace llarp
}
int
Context::Run()
Context::LoadDatabase()
{
llarp::Info("starting up");
llarp_ev_loop_alloc(&mainloop);
llarp_crypto_libsodium_init(&crypto);
nodedb = llarp_nodedb_new(&crypto);
if(!nodedb_dir[0])
@ -96,15 +94,42 @@ namespace llarp
llarp::Error("nodedb_dir is incorrect");
return 0;
}
llarp::Info("nodedb_dir configured!");
//llarp::Info("nodedb_dir [", nodedb_dir, "] configured!");
ssize_t loaded = llarp_nodedb_load_dir(nodedb, nodedb_dir);
llarp::Info("nodedb_dir loaded ", loaded, " RCs");
llarp::Info("nodedb_dir loaded ", loaded, " RCs from [", nodedb_dir, "]");
if(loaded < 0)
{
// shouldn't be possible
llarp::Error("nodedb_dir directory doesn't exist");
return 0;
}
return 1;
}
int
Context::IterateDatabase(struct llarp_nodedb_iter i)
{
return llarp_nodedb_iterate_all(nodedb, i);
}
bool
Context::PutDatabase(struct llarp_rc *rc)
{
return llarp_nodedb_put_rc(nodedb, rc);
}
struct llarp_rc *
Context::GetDatabase(const byte_t *pk)
{
return llarp_nodedb_get_rc(nodedb, pk);
}
int
Context::Run()
{
llarp::Info("starting up");
this->LoadDatabase();
llarp_ev_loop_alloc(&mainloop);
// ensure worker thread pool
if(!worker && !singleThreaded)
@ -290,6 +315,30 @@ llarp_main_run(struct llarp_main *ptr)
return ptr->ctx->Run();
}
int
llarp_main_loadDatabase(struct llarp_main *ptr)
{
return ptr->ctx->LoadDatabase();
}
int
llarp_main_iterateDatabase(struct llarp_main *ptr, struct llarp_nodedb_iter i)
{
return ptr->ctx->IterateDatabase(i);
}
bool
llarp_main_putDatabase(struct llarp_main *ptr, struct llarp_rc *rc)
{
return ptr->ctx->PutDatabase(rc);
}
struct llarp_rc *
llarp_main_getDatabase(struct llarp_main *ptr, byte_t *pk)
{
return ptr->ctx->GetDatabase(pk);
}
void
llarp_main_free(struct llarp_main *ptr)
{

@ -76,7 +76,7 @@ namespace llarp
{
result &= msg->HandleMessage(router, reply->msgs);
}
return result && router->SendToOrQueue(remote.data(), {reply});
return result && router->SendToOrQueue(remote.data(), reply);
}
namespace dht
@ -650,7 +650,7 @@ namespace llarp
dhtmsg->iterative = iterative;
msg->msgs.push_back(dhtmsg);
router->SendToOrQueue(askpeer, msg);
} // namespace dht
}
void
Context::LookupRouterViaJob(llarp_router_lookup_job *job)

@ -0,0 +1,27 @@
#include <llarp/encode.hpp>
#include <stdexcept>
namespace llarp
{
int char2int(char input)
{
if(input >= '0' && input <= '9')
return input - '0';
if(input >= 'A' && input <= 'F')
return input - 'A' + 10;
if(input >= 'a' && input <= 'f')
return input - 'a' + 10;
throw std::invalid_argument("Invalid input string");
}
void HexDecode(const char* src, uint8_t* target)
{
while(*src && src[1])
{
*(target++) = char2int(*src)*16 + char2int(src[1]);
src += 2;
}
}
}

@ -47,6 +47,24 @@ struct llarp_nodedb
return entries.find(pk) != entries.end();
}
/*
bool
Has(const byte_t *pk)
{
llarp::PubKey test(pk);
auto itr = this->entries.begin();
while(itr != this->entries.end())
{
llarp::Info("Has byte_t [", test.size(), "] vs [", itr->first.size(), "]");
if (memcmp(test.data(), itr->first.data(), 32) == 0) {
llarp::Info("Match");
}
itr++;
}
return entries.find(pk) != entries.end();
}
*/
bool
pubKeyExists(llarp_rc *rc)
{
@ -167,8 +185,9 @@ struct llarp_nodedb
auto itr = i.begin();
while(itr != itr.end())
{
if(loadfile(*itr))
if (fs::is_regular_file(itr->symlink_status()) && loadfile(*itr))
sz++;
++itr;
}
return sz;
@ -177,37 +196,41 @@ struct llarp_nodedb
bool
loadfile(const fs::path &fpath)
{
std::ifstream f(fpath, std::ios::binary);
if(!f.is_open())
#if __APPLE__ && __MACH__
// skip .DS_Store files
if (strstr(fpath.c_str(), ".DS_Store") != 0) {
return false;
byte_t tmp[MAX_RC_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
f.seekg(0, std::ios::end);
size_t sz = f.tellg();
f.seekg(0, std::ios::beg);
if(sz > buf.sz)
return false;
// TODO: error checking
f.read((char *)buf.base, sz);
buf.sz = sz;
llarp_rc rc;
llarp::Zero(&rc, sizeof(llarp_rc));
if(llarp_rc_bdecode(&rc, &buf))
}
#endif
llarp_rc *rc = llarp_rc_read(fpath.c_str());
if (!rc)
{
if(llarp_rc_verify_sig(crypto, &rc))
llarp::Error("Signature read failed", fpath);
return false;
}
if(!llarp_rc_verify_sig(crypto, rc))
{
llarp::PubKey pk(rc.pubkey);
entries[pk] = rc;
llarp::Error("Signature verify failed", fpath);
return false;
}
llarp::PubKey pk(rc->pubkey);
entries[pk] = *rc;
return true;
}
bool iterate(struct llarp_nodedb_iter i) {
i.index = 0;
auto itr = entries.begin();
while(itr != entries.end())
{
i.rc = &itr->second;
i.visit(&i);
// advance
i.index++;
itr++;
}
llarp_rc_free(&rc);
return false;
return true;
}
/*
@ -348,6 +371,17 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir)
return n->Load(dir);
}
bool
llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc) {
return n->setRC(rc);
}
int
llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i) {
n->iterate(i);
return n->entries.size();
}
void
llarp_nodedb_async_verify(struct llarp_async_verify_rc *job)
{
@ -367,6 +401,7 @@ llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job)
struct llarp_rc *
llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk)
{
//llarp::Info("llarp_nodedb_get_rc [", pk, "]");
if(n->Has(pk))
return n->getRC(pk);
else

@ -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)
{

@ -200,10 +200,15 @@ llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx)
void
llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job)
{
if (!job->context)
{
llarp::Error("failed to build path because no context is set in job");
return;
}
job->router = job->context->router;
if(job->selectHop == nullptr)
job->selectHop = &llarp_nodedb_select_random_hop;
llarp_logic_queue_job(job->router->logic,
{job, &llarp::pathbuilder_start_build});
}
}
} // end extern c

@ -180,7 +180,7 @@ llarp_router::try_connect(fs::path rcfile)
}
}
else
llarp::Error("failed to verify signature of RC");
llarp::Error("failed to verify signature of RC", rcfile);
}
else
llarp::Error("failed to decode RC");
@ -199,30 +199,8 @@ llarp_router::EnsureIdentity()
bool
llarp_router::EnsureEncryptionKey()
{
std::error_code ec;
if(!fs::exists(encryption_keyfile, ec))
{
llarp::Info("generating encryption key");
crypto.encryption_keygen(encryption);
std::ofstream f(encryption_keyfile, std::ios::binary);
if(!f.is_open())
{
llarp::Error("could not save encryption private key to ",
encryption_keyfile, " ", ec);
return false;
}
f.write((char *)encryption.data(), encryption.size());
}
std::ifstream f(encryption_keyfile, std::ios::binary);
if(!f.is_open())
{
llarp::Error("could not read ", encryption_keyfile);
return false;
}
f.read((char *)encryption.data(), encryption.size());
llarp::PubKey onionenckey = llarp::seckey_topublic(encryption);
llarp::Info("encryption key loaded ", onionenckey);
return true;
return llarp_findOrCreateEncryption(&crypto, encryption_keyfile.c_str(),
&this->encryption);
}
void
@ -614,9 +592,20 @@ llarp_router::Run()
link->get_our_address(link, &addr);
llarp_ai_list_pushback(rc.addrs, &addr);
};
// set public keys
memcpy(rc.enckey, llarp::seckey_topublic(encryption), PUBKEYSIZE);
llarp_rc_set_pubkey(&rc, pubkey());
// set public encryption key
llarp_rc_set_pubenckey(&rc, llarp::seckey_topublic(encryption));
char ftmp[68] = {0};
const char *hexKey = llarp::HexEncode< llarp::PubKey,
decltype(ftmp) >(llarp::seckey_topublic(encryption),
ftmp);
llarp::Info("Your Encryption pubkey ", hexKey);
// set public signing key
llarp_rc_set_pubsigkey(&rc, llarp::seckey_topublic(identity));
hexKey = llarp::HexEncode< llarp::PubKey,
decltype(ftmp) >(llarp::seckey_topublic(identity),
ftmp);
llarp::Info("Your Identity pubkey ", hexKey);
llarp_rc_sign(&crypto, identity, &rc);
@ -650,14 +639,16 @@ llarp_router::Run()
// initialize as service node
InitServiceNode();
// immediate connect all for service node
auto delay = rand() % 100;
uint64_t delay = rand() % 100;
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
//llarp_logic_call_later(logic, {static_cast<uint64_t>(delay), this, &ConnectAll});
}
else
{
// delayed connect all for clients
auto delay = ((rand() % 10) * 500) + 1000;
uint64_t delay = ((rand() % 10) * 500) + 1000;
llarp_logic_call_later(logic, {delay, this, &ConnectAll});
//llarp_logic_call_later(logic, {static_cast<uint64_t>(delay), this, &ConnectAll});
}
llarp::PubKey ourPubkey = pubkey();
@ -809,57 +800,84 @@ llarp_rc_clear(struct llarp_rc *rc)
llarp::Zero(rc, sizeof(llarp_rc));
}
bool
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
void
llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey)
{
struct llarp_rc *rc = (llarp_rc *)iter->user;
llarp_ai_list_pushback(rc->addrs, ai);
return true;
// set public encryption key
memcpy(rc->enckey, pubenckey, PUBKEYSIZE);
}
void
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
struct llarp_ai_list *addr)
llarp_rc_set_pubsigkey(struct llarp_rc *rc, const uint8_t *pubsigkey)
{
rc->addrs = llarp_ai_list_new();
struct llarp_ai_list_iter ai_itr;
ai_itr.user = rc;
ai_itr.visit = &llarp_rc_addr_list_iter;
llarp_ai_list_iterate(addr, &ai_itr);
// set public signing key
memcpy(rc->pubkey, pubsigkey, PUBKEYSIZE);
}
void
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey)
llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubenckey,
const uint8_t *pubsigkey)
{
// set public key
memcpy(rc->pubkey, pubkey, 32);
// set public encryption key
llarp_rc_set_pubenckey(rc, pubenckey);
// set public signing key
llarp_rc_set_pubsigkey(rc, pubsigkey);
}
bool
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
byte_t *secretkey)
struct llarp_rc *
llarp_rc_read(const char *fpath)
{
llarp::Debug("find or create ", fpath);
fs::path path(fpath);
fs::path our_rc_file(fpath);
std::error_code ec;
if(!fs::exists(path, ec))
{
llarp::Info("regenerated identity key");
crypto->identity_keygen(secretkey);
std::ofstream f(path, std::ios::binary);
if(f.is_open())
if(!fs::exists(our_rc_file, ec))
{
f.write((char *)secretkey, SECKEYSIZE);
printf("File[%s] not found\n", fpath);
return 0;
}
std::ifstream f(our_rc_file, std::ios::binary);
if(!f.is_open())
{
printf("Can't open file [%s]\n", fpath);
return 0;
}
std::ifstream f(path, std::ios::binary);
if(f.is_open())
byte_t tmp[MAX_RC_SIZE];
llarp_buffer_t buf = llarp::StackBuffer< decltype(tmp) >(tmp);
f.seekg(0, std::ios::end);
size_t sz = f.tellg();
f.seekg(0, std::ios::beg);
if(sz > buf.sz)
return 0;
f.read((char *)buf.base, sz);
//printf("contents[%s]\n", tmpc);
llarp_rc *rc = new llarp_rc;
llarp::Zero(rc, sizeof(llarp_rc));
if(!llarp_rc_bdecode(rc, &buf))
{
f.read((char *)secretkey, SECKEYSIZE);
return true;
printf("Can't decode [%s]\n", fpath);
return 0;
}
llarp::Info("failed to get identity key");
return false;
return rc;
}
bool
llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai)
{
struct llarp_rc *rc = (llarp_rc *)iter->user;
llarp_ai_list_pushback(rc->addrs, ai);
return true;
}
void
llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem,
struct llarp_ai_list *addr)
{
rc->addrs = llarp_ai_list_new();
struct llarp_ai_list_iter ai_itr;
ai_itr.user = rc;
ai_itr.visit = &llarp_rc_addr_list_iter;
llarp_ai_list_iterate(addr, &ai_itr);
}
bool
@ -931,6 +949,62 @@ llarp_router_override_path_selection(struct llarp_router *router,
if(func)
router->selectHopFunc = func;
}
bool
llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath,
byte_t *secretkey)
{
llarp::Debug("find or create ", fpath);
fs::path path(fpath);
std::error_code ec;
if(!fs::exists(path, ec))
{
llarp::Info("generating new identity key");
crypto->identity_keygen(secretkey);
std::ofstream f(path, std::ios::binary);
if(f.is_open())
{
f.write((char *)secretkey, SECKEYSIZE);
}
}
std::ifstream f(path, std::ios::binary);
if(f.is_open())
{
f.read((char *)secretkey, SECKEYSIZE);
return true;
}
llarp::Info("failed to get identity key");
return false;
}
} // end extern C
// C++ ...
bool
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
llarp::SecretKey *encryption)
{
llarp::Debug("find or create ", fpath);
fs::path path(fpath);
std::error_code ec;
if(!fs::exists(path, ec))
{
llarp::Info("generating new encryption key");
crypto->encryption_keygen(*encryption);
std::ofstream f(path, std::ios::binary);
if(f.is_open())
{
f.write((char *)encryption, SECKEYSIZE);
}
}
std::ifstream f(path, std::ios::binary);
if(f.is_open())
{
f.read((char *)encryption, SECKEYSIZE);
return true;
}
llarp::Info("failed to get encryption key");
return false;
}
namespace llarp

@ -29,6 +29,11 @@ namespace llarp
} // namespace llarp
/// c++
bool
llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath,
llarp::SecretKey *encryption);
struct llarp_router
{
bool ready;

@ -0,0 +1,11 @@
#include <llarp/messages/path_latency.hpp>
namespace llarp
{
namespace routing
{
PathLatencyMessage::PathLatencyMessage()
{
}
} // namespace routing
} // namespace llarp

@ -0,0 +1 @@
#include <llarp/service.hpp>

@ -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…
Cancel
Save