pull/1/head
Jeff Becker 6 years ago
parent f557027692
commit 74112dd6f3
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -3,20 +3,23 @@ REPO := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
EXE = $(REPO)/sarpd
STATIC_LIB = $(REPO)/libsarp.a
STATIC_SRC = $(wildcard $(REPO)/libsarp/*.cpp)
STATIC_OBJ = $(STATIC_SRC:.cpp=.cpp.o)
STATIC_SRC_CPP = $(wildcard $(REPO)/libsarp/*.cpp)
STATIC_SRC_C = $(wildcard $(REPO)/libsarp/*.c)
STATIC_OBJ = $(STATIC_SRC_CPP:.cpp=.cpp.o) $(STATIC_SRC_C:.c=.c.o)
DAEMON_SRC = $(wildcard $(REPO)/daemon/*.c)
DAEMON_OBJ = $(DAEMON_SRC:.c=.o)
DAEMON_OBJ = $(DAEMON_SRC:.c=.c.o)
SODIUM_FLAGS = $(shell pkg-config --cflags libsodium)
SODIUM_LIBS = $(shell pkg-config --libs libsodium)
REQUIRED_CFLAGS = $(SODIUM_FLAGS) -I$(REPO)/include -std=c99
REQUIRED_CXXFLAGS = $(SODIUM_FLAGS) -I$(REPO)/include -std=c++17
REQUIRED_LDFLAGS = $(LDFLAGS) -ljemalloc $(SODIUM_LIBS)
CXXFLAGS := $(REQUIRED_CXXFLAGS)
CFLAGS := $(REQUIRED_CFLAGS)
LIBUV_FLAGS = $(shell pkg-config --cflags libuv)
LIBUV_LIBS = $(shell pkg-config --libs libuv)
REQUIRED_CFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c99 $(CFLAGS)
REQUIRED_CXXFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c++17 $(CXXFLAGS)
REQUIRED_LDFLAGS = $(LDFLAGS) -ljemalloc $(SODIUM_LIBS) $(LIBUV_LIBS)
all: build
@ -26,7 +29,10 @@ $(EXE): $(DAEMON_OBJ) $(STATIC_LIB)
$(CXX) $(DAEMON_OBJ) $(STATIC_LIB) $(REQUIRED_LDFLAGS) -o $(EXE)
%.cpp.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $<.o
$(CXX) $(REQUIRED_CXXFLAGS) -c $< -o $<.o
%.c.o: %.c
$(CC) $(REQUIRED_CFLAGS) -c $< -o $<.o
$(STATIC_LIB): $(STATIC_OBJ)
$(AR) -r $(STATIC_LIB) $(STATIC_OBJ)

@ -0,0 +1,2 @@
[router]

@ -1,10 +1,40 @@
#include <sarp.h>
#include <sarp/mem.h>
#include <sarp/ev.h>
#include <stdio.h>
struct sarp_router * router;
struct sarp_config * gconfig;
struct sarp_ev_loop * mainloop;
int main(int argc, char * argv[])
{
struct sarp_router * router = NULL;
struct sarp_alloc mem;
sarp_mem_jemalloc(&mem);
const char * conffname = "daemon.ini";
if (argc > 1)
conffname = argv[1];
sarp_mem_jemalloc();
sarp_new_config(&gconfig);
sarp_ev_loop_alloc(&mainloop);
if(sarp_load_config(gconfig, conffname))
{
printf("!!! failed to load %s\n", conffname);
}
else
{
printf("loaded config %s\n", conffname);
sarp_init_router(&router);
sarp_configure_router(router, gconfig);
printf("running...\n");
sarp_run_router(router, mainloop);
sarp_ev_loop_run(mainloop);
}
printf("shutting down.");
sarp_free_router(&router);
printf(".");
sarp_free_config(&gconfig);
printf(".");
sarp_ev_loop_free(&mainloop);
printf(".\n");
return 0;
}

@ -43,22 +43,24 @@ SE(k, n, x) is chacha20 encrypt data x using symettric key k and nounce n
SD(k, n, x) is chacha20 dectypt data x using symettric key k and nounce n
S(k, x) is sign x with ed25519 using seed k
V(k, x, sig) is verify x data using signature sig using public key k
DH(x, y) is a ecdh key exchange using ed25519 scalarmult base between
public keys x and y
DH(x, y) is a ecdh key exchange using ed25519 scalarmult between public keys x
and y
KE(x, y) is a ecdh key exchange using H(DH(x, y) + x)
---
invisible wire protocol version 0:
wire protocol:
inbound handshake:
as of version 0 plaintext sctp is used, future versions will use an encrypted udp transport (IWP).
IWP inbound handshake:
outbound handshake:
IWP outbound handshake:
@ -120,8 +122,9 @@ introducer (I)
introducer set (IS)
{
d: [ I, I, I, ... ],
a: "<64 bytes SA>",
e: "<1218 bytes ntru public encryption key>",
i: [ I, I, I, ... ],
z: "<64 bytes signature using service info signing key>"
}
@ -148,11 +151,12 @@ relay commit record (RCR)
record requesting path with tunnel id p relay messages for x seconds to router
on network who's i is equal to RC.k and decrypt data any messages using
KE(c, RC.k) as symettric key for encryption and decryption.
MD(n, KE(c, RC.k)) as symettric key for encryption and decryption.
{
c: "<32 byte public signing/encryption key used for further communication>",
i: "<32 byte public key of next hop>",
i: "<32 byte RC.k of next hop>",
n: "<32 bytes nounce for key exchange>",
p: path_id_uint64,
x: seconds_lifetime_uint64
}
@ -181,7 +185,8 @@ is RECOMMENDED.
b: miliseconds_backoff_uint64,
c: "r",
p: path_id_uint64,
r: "<insert optional reason metadata here>"
r: "<optional reason metadata here>",
x: "<N bytes arbirary padding>"
}
link relay accept record (LRAR)
@ -244,18 +249,17 @@ link relay exit message (LRXM)
sent to exit a previously commited path before it expires.
verify signature using cancel key c in relay commit message.
z is filled with zero, the previous value is used as a signature and then
the message is verified using the message digset of the newly encoded message
and the symmettric key provide in the corisponding link relay commit message.
{
a: "x",
b: [ list, of, exit, records, as, bytes ]
}
sig = msg.z
msg.z = "\x00" * 64
h = MD(BE(msg), k)
V(c, h, sig)
link relay exit record (LRXR)
{
a: "x",
c: "x",
p: path_id_uint64,
x: "<N bytes padding>",
z: "<64 bytes signature>"
}
@ -347,8 +351,13 @@ got introduction message (GIM)
publish introduction message (PIM)
publish one or many IM into the dht at once.
each IS will be placed in the dht at the location determined by the dht kdf
which uses a shared random source to obfuscate keyspace location
each IS will be placed in the dht
version 0 uses the SA of each IS as the keyspace location.
in the future the location will be determined by the dht kdf
which uses a shared random source to obfuscate keyspace location.
{
A: "P",
@ -358,16 +367,19 @@ which uses a shared random source to obfuscate keyspace location
acknoleged introduction message (AIM)
acknolege the publishing of a previous PIM
acknolege the publishing of a previous PIM, back off publishing for B ms.
nonzero B value indicates failure to publish.
{
A: "A",
B: backoff_milliseconds_uint64,
P: number_of_IS_published_uint,
T: transaction_id_uint64,
}
find router contact message (FRCM)
find a
find a router by public key
{
A: "F",

@ -0,0 +1,29 @@
#ifndef SARP_AI_H
#define SARP_AI_H
#include <sarp/crypto.h>
#include <sarp/net.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sarp_address_info
{
uint16_t rank;
sarp_pubkey_t enc_key;
char * dialect;
struct in6_addr ip;
uint16_t port;
};
bool sarp_address_info_bencode(struct sarp_address_info * ai, sarp_buffer_t * buff);
bool sarp_address_info_bdecode(struct sarp_address_info * ai, sarp_buffer_t buff);
struct sarp_address_info_list;
#ifdef __cplusplus
}
#endif
#endif

@ -6,11 +6,17 @@ extern "C" {
#include <stdlib.h>
#include <stdint.h>
typedef struct {
uint8_t * ptr;
size_t sz;
} sarp_buffer_t;
typedef struct sarp_buffer_t {
uint8_t * base;
size_t sz;
uint8_t * cur;
} sarp_buffer_t;
static inline size_t sarp_buffer_size_left(sarp_buffer_t * buff)
{
return buff->sz - (buff->cur - buff->base);
}
#ifdef __cplusplus
}
#endif

@ -1,6 +1,5 @@
#ifndef SARP_CONFIG_H_
#define SARP_CONFIG_H_
#include <sarp/mem.h>
#ifdef __cplusplus
extern "C" {
@ -8,10 +7,22 @@ extern "C" {
struct sarp_config;
void sarp_new_config(struct sarp_config ** conf, struct sarp_alloc * mem);
void sarp_new_config(struct sarp_config ** conf);
void sarp_free_config(struct sarp_config ** conf);
/** @brief return -1 on fail otherwiwse 0 */
int sarp_load_config(struct sarp_config * conf, const char * fname);
struct sarp_config_iterator
{
void * user;
/** set by sarp_config_iter */
struct sarp_config * conf;
/** visit (self, section, key, value) */
void (*visit)(struct sarp_config_iterator *, const char *, const char *, const char *);
};
void sarp_config_iter(struct sarp_config * conf, struct sarp_config_iterator iter);
#ifdef __cplusplus
}

@ -1,6 +1,8 @@
#ifndef SARP_EV_H
#define SARP_EV_H
#include <sarp/mem.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
@ -8,10 +10,22 @@ extern "C" {
struct sarp_ev_loop;
void sarp_ev_loop_alloc(struct sarp_ev_loop ** ev, struct sarp_alloc * mem);
void sarp_ev_loop_alloc(struct sarp_ev_loop ** ev);
void sarp_ev_loop_free(struct sarp_ev_loop ** ev);
int sarp_ev_loop_run(struct sarp_ev_loop * ev);
struct sarp_udp_listener
{
const char * host;
uint16_t port;
void * user;
void * impl;
void (*recvfrom)(struct sarp_udp_listener *, struct sockaddr, uint8_t *, size_t);
};
int sarp_ev_add_udp_listener(struct sarp_ev_loop * ev, struct sarp_udp_listener * listener);
int srap_ev_close_udp_listener(struct sarp_ev_loop * ev, struct sarp_udp_listener * listener);
#ifdef __cplusplus
}

@ -0,0 +1,20 @@
#ifndef SARP_XI_H
#define SARP_XI_H
#include <sarp/net.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sarp_exit_info
{
in6_addr address;
in6_addr netmask;
};
struct sarp_exit_info_list;
#ifdef __cplusplus
}
#endif
#endif

@ -7,16 +7,20 @@ extern "C" {
#include <stdlib.h>
struct sarp_alloc
{
void * (*malloc)(size_t sz);
void * (*realloc)(void * ptr, size_t sz);
void * (*calloc)(size_t n, size_t sz);
void (*free)(void * ptr);
};
void sarp_mem_jemalloc(struct sarp_alloc * mem);
void sarp_mem_libc(struct sarp_alloc * mem);
void sarp_mem_dmalloc(struct sarp_alloc * mem);
struct sarp_alloc
{
void * (*malloc)(size_t sz);
void * (*realloc)(void * ptr, size_t sz);
void * (*calloc)(size_t n, size_t sz);
void (*free)(void * ptr);
};
/** global memory allocator */
extern struct sarp_alloc sarp_g_mem;
void sarp_mem_jemalloc();
void sarp_mem_std();
void sarp_mem_dmalloc();
#ifdef __cplusplus
}

@ -0,0 +1,8 @@
#ifndef SARP_NET_H
#define SARP_NET_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif

@ -1,21 +1,21 @@
#ifndef SARP_ROUTER_H_
#define SARP_ROUTER_H_
#include <sarp/config.h>
#include <sarp/mem.h>
#include <sarp/ev.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sarp_router;
struct sarp_router;
void sarp_init_router(struct sarp_router ** router, struct sarp_alloc * mem);
void sarp_free_router(struct sarp_router ** router);
void sarp_init_router(struct sarp_router ** router);
void sarp_free_router(struct sarp_router ** router);
int sarp_configure_router(struct sarp_router * router, struct sarp_config * conf);
int sarp_configure_router(struct sarp_router * router, struct sarp_config * conf);
void sarp_run_router(struct sarp_router * router);
void sarp_stop_router(struct sarp_router * router);
void sarp_run_router(struct sarp_router * router, struct sarp_ev_loop * loop);
void sarp_stop_router(struct sarp_router * router);
#ifdef __cplusplus
}

@ -0,0 +1,29 @@
#ifndef SARP_RC_H
#define SARP_RC_H
#include <sarp/address_info.h>
#include <sarp/exit_info.h>
#include <sarp/crypto.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sarp_router_contact
{
sarp_buffer_t raw;
struct sarp_address_info_list * addreses;
sarp_pubkey_t pubkey;
struct sarp_exit_info_list * exits;
sarp_sig_t signature;
};
bool sarp_rc_bdecode(struct sarp_router_contact * rc, sarp_buffer_t buf);
bool sarp_rc_bencode(struct sarp_router_contact * rc, sarp_buffer_t * buf);
void sarp_rc_free(struct sarp_router_contact ** rc);
bool sarp_rc_verify_sig(struct sarp_rotuer_contact * rc);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,24 @@
#ifndef SARP_SI_H
#define SARP_SI_H
#include <sarp/crypto.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sarp_service_info
{
sarp_buffer_t name;
sarp_pubkey_t signingkey;
sarp_buffer_t vanity;
};
void sarp_service_info_hash(struct sarp_service_info * si, sarp_hash_t * h);
bool sarp_service_info_bencode(struct sarp_serivce_info * si, sarp_buffer_t * buff);
bool sarp_service_info_bdecode(struct sarp_serivce_info * si, sarp_buffer_t buff);
void sarp_service_info_free(struct sarp_service_info ** si);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,39 @@
#include <sarp/address_info.h>
#include <stdio.h>
#include <string.h>
bool sarp_address_info_bencode(struct sarp_address_info * ai, sarp_buffer_t * buff)
{
uint8_t * ptr = buff->cur;
size_t sz = sarp_buffer_size_left(buff);
uint8_t * end = ptr + sz;
int r = 0;
r = snprintf(ptr, (end - ptr), "d1:ci%de1:e32:", ai->rank);
if (r == -1) return false;
ptr += r;
if( ( end - ptr ) <= 0 ) return false;
memcpy(ptr, ai->enc_key, sizeof(ai->enc_key));
ptr += sizeof(ai->enc_key);
if( ( end - ptr ) <= 0 ) return false;
r = snprintf(ptr, (end - ptr), "1:d%ld:%s", strlen(ai->dialect), ai->dialect);
if (r == -1) return false;
ptr += r;
if( ( end - ptr ) <= 0 ) return false;
r = snprintf(ptr, (end - ptr), "1:i%ld:", sizeof(ai->ip));
if(r == -1) return false;
ptr += r;
if( ( end - ptr ) <= 0) return false;
memcpy(ptr, &ai->ip, sizeof(ai->ip));
ptr += sizeof(ai->ip);
if( ( end - ptr ) <= 0) return false;
r = snprintf(ptr, (end - ptr), "1:pi%dee", ai->port);
if( r == -1) return false;
ptr += r;
buff->cur = ptr;
return end - ptr <= sz;
}

@ -1,4 +1,5 @@
#include <sarp/config.h>
#include <sarp/mem.h>
#include "config.hpp"
#include "ini.hpp"
@ -29,22 +30,25 @@ namespace sarp
}
return false;
};
}
extern "C" {
void sarp_new_config(struct sarp_config ** conf, struct sarp_alloc * mem)
void sarp_new_config(struct sarp_config ** conf)
{
sarp_config * c = static_cast<sarp_config*>(mem->malloc(sizeof(struct sarp_config)));
c->mem = mem;
sarp_config * c = static_cast<sarp_config *>(sarp_g_mem.malloc(sizeof(sarp_config)));
*conf = c;
}
void sarp_free_config(struct sarp_config ** conf)
{
sarp_alloc * mem = (*conf)->mem;
mem->free(*conf);
if(*conf)
sarp_g_mem.free(*conf);
*conf = nullptr;
}
@ -53,4 +57,17 @@ extern "C" {
if(!conf->impl.Load(fname)) return -1;
return 0;
}
void sarp_config_iter(struct sarp_config * conf, struct sarp_config_iterator iter)
{
iter.conf = conf;
std::map<std::string, sarp::Config::section_t&> sections = {
{"router", conf->impl.router},
{"network", conf->impl.network},
{"netdb", conf->impl.netdb}
};
for(const auto & section : sections)
for(const auto & item : section.second)
iter.visit(&iter, section.first.c_str(), item.first.c_str(), item.second.c_str());
}
}

@ -25,7 +25,6 @@ extern "C" {
struct sarp_config
{
sarp::Config impl;
sarp_alloc * mem;
};
}

@ -9,7 +9,7 @@ namespace sarp
{
int xchacha20(sarp_buffer_t buff, sarp_symkey_t k, sarp_nounce_t n)
{
return crypto_stream_xchacha20_xor(buff.ptr, buff.ptr, buff.sz, n, k);
return crypto_stream_xchacha20_xor(buff.base, buff.base, buff.sz, n, k);
}
int dh(sarp_sharedkey_t * shared, uint8_t * client_pk, uint8_t * server_pk, uint8_t * remote_key, uint8_t * local_key)

@ -0,0 +1,81 @@
#include <sarp/ev.h>
#include <sarp/mem.h>
#include <uv.h>
struct sarp_ev_loop
{
uv_loop_t _loop;
uv_loop_t * loop() { return &_loop; }
};
namespace sarp
{
struct udp_listener
{
uv_udp_t _handle;
struct sarp_udp_listener * listener;
uv_udp_t * handle() { return &_handle; }
};
static void udp_alloc_cb(uv_handle_t * h, size_t sz, uv_buf_t * buf)
{
buf->base = static_cast<char *>(sarp_g_mem.malloc(sz));
buf->len = sz;
}
static void udp_recv_cb(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
{
udp_listener * l = static_cast<udp_listener *>(handle->data);
}
}
extern "C" {
void sarp_ev_loop_alloc(struct sarp_ev_loop ** ev)
{
*ev = static_cast<sarp_ev_loop*>(sarp_g_mem.malloc(sizeof(struct sarp_ev_loop)));
if (*ev)
{
uv_loop_init((*ev)->loop());
}
}
void sarp_ev_loop_free(struct sarp_ev_loop ** ev)
{
if(*ev)
{
uv_loop_close((*ev)->loop());
sarp_g_mem.free(*ev);
}
*ev = nullptr;
}
int sarp_ev_loop_run(struct sarp_ev_loop * ev)
{
return uv_run(ev->loop(), UV_RUN_DEFAULT);
}
int sarp_ev_add_udp_listener(struct sarp_ev_loop * ev, struct sarp_udp_listener * listener)
{
sockaddr_in6 addr;
uv_ip6_addr(listener->host, listener->port, &addr);
int ret = 0;
sarp::udp_listener * l = static_cast<sarp::udp_listener *>(sarp_g_mem.malloc(sizeof(sarp::udp_listener)));
listener->impl = l;
l->handle()->data = l;
l->listener = listener;
ret = uv_udp_init(ev->loop(), l->handle());
if (ret == 0)
{
ret = uv_udp_bind(l->handle(), (const sockaddr *)&addr, 0);
if (ret == 0)
{
ret = uv_udp_recv_start(l->handle(), sarp::udp_alloc_cb, sarp::udp_recv_cb);
}
}
}
}

@ -9,26 +9,27 @@ bool operator < (const sockaddr_in6 addr0, const sockaddr_in6 addr1)
namespace sarp
{
int Link::Run()
static void link_recv_from(struct sarp_udp_listener * l, struct sockaddr src, uint8_t * buff, size_t sz)
{
uint8_t recvbuff[1500];
sockaddr_in6 remote;
socklen_t remotelen;
ssize_t ret = 0;
do
if(src.sa_family == AF_INET6)
{
ret = recvfrom(sockfd, recvbuff, sizeof(recvbuff),0, (sockaddr *) &remote, &remotelen);
if(ret > 0)
Link * link = static_cast<Link*>(l->user);
struct sockaddr_in6 remote;
memcpy(&remote, &src, sizeof(sockaddr_in6));
auto itr = link->sessions.find(remote);
if(itr == link->sessions.end())
{
auto itr = sessions.find(remote);
if(itr == sessions.end())
{
sessions[remote] = std::make_unique<PeerSession>(crypto, remote);
}
sessions[remote]->RecvFrom(recvbuff, ret);
link->sessions[remote] = std::make_unique<PeerSession>(link->_crypto, remote);
}
link->sessions[remote]->RecvFrom(buff, sz);
}
while(ret != -1);
return -1;
}
Link::Link(sarp_crypto * crypto) : _crypto(crypto)
{
listener.user = this;
listener.recvfrom = link_recv_from;
}
}

@ -6,8 +6,12 @@
#include <map>
#include <memory>
#include <sarp/ev.h>
namespace sarp
{
struct Link;
struct PeerSession
{
sockaddr_in6 remoteAddr;
@ -38,7 +42,7 @@ namespace sarp
PeerSession & operator=(const PeerSession & other);
void SendTo(int sockfd, const uint8_t * buff, std::size_t sz);
void SendTo(Link * link, const uint8_t * buff, std::size_t sz);
void RecvFrom(const uint8_t * buff, std::size_t sz);
@ -50,14 +54,16 @@ namespace sarp
{
typedef std::map<sockaddr_in6, PeerSession_ptr> Sessions;
int sockfd;
Sessions sessions;
sarp_seckey_t transportSecKey;
sarp_pubkey_t transportPubKey;
sarp_crypto * crypto;
sarp_crypto * _crypto;
Link(sarp_crypto * crypto);
sarp_udp_listener listener;
int Run();
};
}

@ -0,0 +1,10 @@
#include <sarp/mem.h>
extern "C" {
struct sarp_alloc sarp_g_mem = {
.malloc = nullptr,
.realloc = nullptr,
.calloc = nullptr,
.free = nullptr
};
}

@ -25,11 +25,11 @@ namespace sarp
}
extern "C" {
void sarp_mem_jemalloc(struct sarp_alloc * mem)
void sarp_mem_jemalloc()
{
mem->malloc = sarp::jem_malloc;
mem->free = sarp::jem_free;
mem->calloc = sarp::jem_calloc;
mem->realloc = sarp::jem_realloc;
sarp_g_mem.malloc = sarp::jem_malloc;
sarp_g_mem.free = sarp::jem_free;
sarp_g_mem.calloc = sarp::jem_calloc;
sarp_g_mem.realloc = sarp::jem_realloc;
}
}

@ -31,11 +31,11 @@ namespace sarp
}
extern "C" {
void sarp_mem_std(struct sarp_alloc * mem)
void sarp_mem_std()
{
mem->malloc = sarp::std_malloc;
mem->free = sarp::std_free;
mem->calloc = sarp::std_calloc;
mem->realloc = sarp::std_realloc;
sarp_g_mem.malloc = sarp::std_malloc;
sarp_g_mem.free = sarp::std_free;
sarp_g_mem.calloc = sarp::std_calloc;
sarp_g_mem.realloc = sarp::std_realloc;
}
}

@ -7,7 +7,54 @@ namespace sarp
{
struct Router
{
std::vector<Link> activeLinks;
std::vector<Link> Links;
static void iter_config(sarp_config_iterator * iter, const char * section, const char * key, const char * val)
{
sarp_router * self = static_cast<sarp_router *>(iter->user);
}
bool Configured()
{
return false;
}
};
}
extern "C" {
struct sarp_router
{
sarp::Router impl;
};
void sarp_init_router(struct sarp_router ** router)
{
*router = static_cast<sarp_router *>(sarp_g_mem.malloc(sizeof(sarp_router)));
}
int sarp_configure_router(struct sarp_router * router, struct sarp_config * conf)
{
sarp_config_iterator iter;
iter.user = router;
iter.visit = sarp::Router::iter_config;
sarp_config_iter(conf, iter);
return router->impl.Configured() ? 0 : -1;
}
void sarp_run_router(struct sarp_router * router, struct sarp_ev_loop * loop)
{
for(auto & iter : router->impl.Links)
sarp_ev_add_udp_listener(loop, &iter.listener);
}
void sarp_free_router(struct sarp_router ** router)
{
if(*router)
sarp_g_mem.free(*router);
*router = nullptr;
}
}

Loading…
Cancel
Save