#include "utils.h"
#include "xalloc.h"
#include "ed25519/sha512.h"
+#include "discovery.h"
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
[MESHLINK_ENOENT] = "No such node",
};
-const char *meshlink_strerror(meshlink_errno_t errno) {
- return errstr[errno];
+const char *meshlink_strerror(meshlink_errno_t err) {
+ if(err < 0 || err >= sizeof errstr / sizeof *errstr)
+ return "Invalid error code";
+ return errstr[err];
}
static bool ecdsa_keygen(meshlink_handle_t *mesh) {
mesh->threadstarted=true;
+ // Start discovery
+ if(!discovery_start(mesh))
+ return false;
+
return true;
}
if(!mesh)
return;
+ // Stop discovery
+ discovery_stop(mesh);
+
// Shut down the listening sockets to signal the main thread to shut down
for(int i = 0; i < mesh->listen_sockets; i++) {
}
void meshlink_close(meshlink_handle_t *mesh) {
- if(!mesh)
+ if(!mesh || !mesh->confbase)
return;
// Close and free all resources used.
free(mesh->name);
free(mesh->confbase);
- free(mesh);
-
memset(mesh, 0, sizeof *mesh);
+
+ free(mesh);
}
void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) {
mesh->log_level = level;
}
-bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, unsigned int len) {
+bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
if(!mesh || !destination)
return false;
if(!len)
return ;
}
+ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) {
+ if(!mesh || !destination)
+ return -1;
+
+ node_t *n = (node_t *)destination;
+ if(!n->status.reachable)
+ return 0;
+ else if(n->mtuprobes > 30 && n->minmtu)
+ return n->minmtu;
+ else
+ return MTU;
+}
+
meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) {
if(!mesh || !name)
return NULL;
return (meshlink_node_t *)lookup_node(mesh, (char *)name); // TODO: make lookup_node() use const
}
-ssize_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t nmemb) {
+meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t *nmemb) {
if(!mesh || (nmemb && !nodes))
- return -1;
+ return NULL;
- size_t i = 0;
+ meshlink_node_t **result, **p;
//lock mesh->nodes
pthread_mutex_lock(&(mesh->nodes_mutex));
- for splay_each(node_t, n, mesh->nodes) {
- if(i < nmemb)
- nodes[i] = (meshlink_node_t *)n;
- i++;
+ *nmemb = mesh->nodes->count;
+ result = realloc(nodes, *nmemb * sizeof *nodes);
+
+ if(result) {
+ for splay_each(node_t, n, mesh->nodes)
+ *p++ = (meshlink_node_t *)n;
+ } else {
+ *nmemb = 0;
+ free(nodes);
+ meshlink_errno = MESHLINK_ENOMEM;
}
pthread_mutex_unlock(&(mesh->nodes_mutex));
- return i;
+ return result;
}
bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) {
return;
}
+void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) {
+ if(!mesh || !node)
+ return;
+
+ node_t *n = (node_t *)node;
+ n->status.blacklisted = false;
+
+ //TODO: remove blacklisted = yes from the config file
+
+ return;
+}
+
static void __attribute__((constructor)) meshlink_init(void) {
crypto_init();
}