diff --git a/Makefile b/Makefile index 75454088c..8c232c235 100644 --- a/Makefile +++ b/Makefile @@ -47,8 +47,8 @@ else endif REQUIRED_CFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c11 $(CFLAGS) $(DEBUG_FLAGS) $(VER_FLAGS) -Wall -fPIC -REQUIRED_CXXFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c++14 $(CXXFLAGS) $(DEBUG_FLAGS) $(VER_FLAGS) -Wall -fPIC -LIB_LDFLAGS = $(MALLOC_LIB) $(SODIUM_LIBS) $(LIBUV_LIBS) -lm -lstdc++ +REQUIRED_CXXFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c++17 $(CXXFLAGS) $(DEBUG_FLAGS) $(VER_FLAGS) -Wall -fPIC +LIB_LDFLAGS = $(MALLOC_LIB) $(SODIUM_LIBS) $(LIBUV_LIBS) -lm -lstdc++ -lstdc++fs REQUIRED_LDFLAGS = -L$(REPO) -lllarp TEST_LDFLAGS = $(STATIC_LIB) $(LIB_LDFLAGS) diff --git a/include/llarp/buffer.h b/include/llarp/buffer.h index bfa2a59de..582422500 100644 --- a/include/llarp/buffer.h +++ b/include/llarp/buffer.h @@ -1,9 +1,11 @@ #ifndef LLARP_BUFFER_H_ #define LLARP_BUFFER_H_ #include +#include #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -35,6 +37,8 @@ bool INLINE llarp_buffer_write(llarp_buffer_t *buff, const void *data, bool llarp_buffer_writef(llarp_buffer_t *buff, const char *fmt, ...); +bool llarp_buffer_readfile(llarp_buffer_t * buff, FILE * f,struct llarp_alloc * mem); + #ifdef __cplusplus } #endif diff --git a/include/llarp/net.h b/include/llarp/net.h index dda6621b3..79cd285c3 100644 --- a/include/llarp/net.h +++ b/include/llarp/net.h @@ -1,5 +1,5 @@ -#ifndef SARP_NET_H -#define SARP_NET_H +#ifndef LLARP_NET_H +#define LLARP_NET_H #include #include diff --git a/include/llarp/nodedb.h b/include/llarp/nodedb.h new file mode 100644 index 000000000..b8ea3d76b --- /dev/null +++ b/include/llarp/nodedb.h @@ -0,0 +1,59 @@ +#ifndef LLARP_NODEDB_H +#define LLARP_NODEDB_H +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + + struct llarp_nodedb; + + /** create an empty nodedb */ + struct llarp_nodedb * llarp_nodedb_new(); + + /** free a nodedb and all loaded rc */ + void llarp_nodedb_free(struct llarp_nodedb ** n); + + /** ensure a nodedb fs skiplist structure is at dir + create if not there. + */ + bool llarp_nodedb_ensure_dir(const char * dir); + + /** load entire nodedb from fs skiplist at dir */ + ssize_t llarp_nodedb_load_dir(struct llarp_nodedb * n, const char * dir); + + /** store entire nodedb to fs skiplist at dir */ + ssize_t llarp_nodedb_store_dir(struct llarp_nodedb * n, const char * dir); + + struct llarp_nodedb_iter + { + void * user; + struct llarp_rc * rc; + bool (*visit)(struct llarp_nodedb_iter *); + }; + + /** + iterate over all loaded rc with an iterator + */ + void llarp_nodedb_iterate_all(struct llarp_nodedb * n, struct llarp_nodedb_iter i); + + /** + find rc by rc.k being value k + returns true if found otherwise returns false + */ + bool llarp_nodedb_find_rc(struct llarp_nodedb * n, struct llarp_rc * rc, llarp_pubkey_t k); + + /** + put an rc into the node db + overwrites with new contents if already present + flushes the single entry to disk + returns true on success and false on error + */ + bool llarp_nodedb_put_rc(struct llarp_nodedb * n, struct llarp_rc * rc); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/llarp/router_contact.h b/include/llarp/router_contact.h index 762b246a0..5a876553e 100644 --- a/include/llarp/router_contact.h +++ b/include/llarp/router_contact.h @@ -16,10 +16,11 @@ struct llarp_rc { bool llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buf); bool llarp_rc_bencode(struct llarp_rc *rc, llarp_buffer_t *buf); -void llarp_rc_free(struct llarp_rc **rc); +void llarp_rc_free(struct llarp_rc *rc); bool llarp_rc_verify_sig(struct llarp_rc *rc); #ifdef __cplusplus + } #endif #endif diff --git a/llarp/buffer.cpp b/llarp/buffer.cpp index 325986565..9ddb86924 100644 --- a/llarp/buffer.cpp +++ b/llarp/buffer.cpp @@ -14,4 +14,22 @@ bool llarp_buffer_writef(llarp_buffer_t* buff, const char* fmt, ...) { buff->sz += written; return true; } + + bool llarp_buffer_readfile(llarp_buffer_t * buff, FILE * f, llarp_alloc * mem) + { + ssize_t len; + fseek(f, 0, SEEK_END); + len = ftell(f); + rewind(f); + if(len > 0) + { + buff->base = static_cast(mem->alloc(len, 8)); + buff->cur = buff->base; + buff->sz = len; + size_t sz = fread(buff->base, len, 1, f); + rewind(f); + return sz == len; + } + return false; + } } diff --git a/llarp/crypto.hpp b/llarp/crypto.hpp new file mode 100644 index 000000000..02dfda253 --- /dev/null +++ b/llarp/crypto.hpp @@ -0,0 +1,12 @@ +#ifndef LLARP_CRYPTO_HPP +#define LLARP_CRYPTO_HPP + +#include +#include + +namespace llarp +{ + typedef std::array pubkey; +} + +#endif diff --git a/llarp/fs.hpp b/llarp/fs.hpp new file mode 100644 index 000000000..49db7c5b8 --- /dev/null +++ b/llarp/fs.hpp @@ -0,0 +1,8 @@ +#ifndef LLARP_FS_HPP +#define LLARP_FS_HPP + +#include + +namespace fs = std::experimental::filesystem; + +#endif diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp new file mode 100644 index 000000000..8b3a1ab3e --- /dev/null +++ b/llarp/nodedb.cpp @@ -0,0 +1,115 @@ +#include +#include +#include "crypto.hpp" +#include "fs.hpp" +#include + + +static const char skiplist_subdirs[] = "0123456789ABCDEF"; + +struct llarp_nodedb +{ + std::map entries; + + ssize_t Load(const fs::path & path) + { + std::error_code ec; + if(!fs::exists(path, ec)) + { + return -1; + } + ssize_t loaded = 0; + + for (const char & ch : skiplist_subdirs) + { + fs::path sub = path / std::string(ch, 1); + for(auto & f : fs::directory_iterator(sub)) + { + ssize_t l = loadSubdir(f); + if(l > 0) loaded += l; + } + } + return loaded; + } + + bool loadfile(const fs::path & fpath) + { + llarp_rc * rc = new llarp_rc; + llarp_buffer_t buff; + FILE * f = fopen(fpath.c_str(), "rb"); + if(!f) return false; + if(!llarp_buffer_readfile(&buff, f, &llarp_g_mem)) + { + fclose(f); + return false; + } + fclose(f); + if(llarp_rc_bdecode(rc, &buff)) + { + if(llarp_rc_verify_sig(rc)) + { + llarp::pubkey pk; + memcpy(pk.data(), rc->pubkey, pk.size()); + entries[pk] = rc; + return true; + } + } + llarp_rc_free(rc); + delete rc; + return false; + } + + ssize_t loadSubdir(const fs::path & dir) + { + ssize_t sz = 0; + for (auto & path : fs::directory_iterator(dir)) + { + if(loadfile(path)) sz++; + } + return sz; + } + +}; + +extern "C" { + + struct llarp_nodedb * llarp_nodedb_new() + { + return new llarp_nodedb; + } + + void llarp_nodedb_free(struct llarp_nodedb ** n) + { + if(*n) + delete *n; + *n = nullptr; + } + + + bool llarp_nodedb_ensure_dir(const char * dir) + { + fs::path path(dir); + std::error_code ec; + if(!fs::exists(dir, ec)) + fs::create_directories(path, ec); + + if(ec) + return false; + + if (!fs::is_directory(path)) + return false; + + for (const char & ch : skiplist_subdirs) + { + fs::path sub = path / std::string(ch, 1); + fs::create_directory(sub, ec); + if(ec) return false; + } + return true; + } + + ssize_t llarp_nodedb_load_dir(struct llarp_nodedb * n, const char * dir) + { + return n->Load(dir); + } +} diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index aba48982f..3dacc4ee2 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -20,6 +20,15 @@ static bool bencode_rc_xi_write(struct llarp_xi_list_iter *i, } // namespace llarp extern "C" { + + void llarp_rc_free(struct llarp_rc *rc) + { + if(rc->exits) + llarp_xi_list_free(rc->exits); + if(rc->addrs) + llarp_ai_list_free(rc->addrs); + } + bool llarp_rc_bencode(struct llarp_rc *rc, llarp_buffer_t *buff) { /* write dict begin */ if (!bencode_start_dict(buff)) return false;