X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=33af6c36272a4c05aac9c1f1cfab87c0f5f5ccf4;hb=ad85858f2a2383af2cf0bcdede7de11dcf60aa8f;hp=e4061f93de6194c73f071c44eb452b81ee14fd45;hpb=0334735f0ff7fc3fc004aaf91e8a19b9709f7289;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index e4061f93..33af6c36 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -21,6 +21,8 @@ #define VAR_MULTIPLE 4 /* Multiple statements allowed */ #define VAR_OBSOLETE 8 /* Should not be used anymore */ #define VAR_SAFE 16 /* Variable is safe when accepting invitations */ +#define MAX_ADDRESS_LENGTH 45 /* Max length of an (IPv6) address */ +#define MAX_PORT_LENGTH 5 /* 0-65535 */ typedef struct { const char *name; int type; @@ -39,6 +41,7 @@ typedef struct { #include "utils.h" #include "xalloc.h" #include "ed25519/sha512.h" +#include "discovery.h" #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 @@ -740,7 +743,7 @@ static bool meshlink_setup(meshlink_handle_t *mesh) { return true; } -meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { +meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char* appname) { // Validate arguments provided by the application bool usingname = false; @@ -750,6 +753,12 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { return NULL; } + if(!appname || !*appname) { + fprintf(stderr, "No appname given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + if(!name || !*name) { fprintf(stderr, "No name given!\n"); //return NULL; @@ -765,6 +774,7 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { meshlink_handle_t *mesh = xzalloc(sizeof *mesh); mesh->confbase = xstrdup(confbase); + mesh->appname = xstrdup(appname); if (usingname) mesh->name = xstrdup(name); pthread_mutex_init ( &(mesh->outpacketqueue_mutex), NULL); pthread_mutex_init ( &(mesh->nodes_mutex), NULL); @@ -858,6 +868,10 @@ bool meshlink_start(meshlink_handle_t *mesh) { mesh->threadstarted=true; + // Start discovery + if(!discovery_start(mesh)) + return false; + return true; } @@ -867,6 +881,9 @@ void meshlink_stop(meshlink_handle_t *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++) { @@ -1013,6 +1030,27 @@ ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) return MTU; } +char *meshlink_get_fingerprint(meshlink_handle_t *mesh, meshlink_node_t *node) { + if(!mesh || !node) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + node_t *n = (node_t *)node; + + if(!node_read_ecdsa_public_key(mesh, n) || !n->ecdsa) { + meshlink_errno = MESHLINK_EINTERNAL; + return false; + } + + char *fingerprint = ecdsa_get_base64_public_key(n->ecdsa); + + if(!fingerprint) + meshlink_errno = MESHLINK_EINTERNAL; + + return fingerprint; +} + meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) { if(!mesh || !name) { meshlink_errno = MESHLINK_EINVAL; @@ -1023,12 +1061,12 @@ meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) { } meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t *nmemb) { - if(!mesh || (nmemb && !nodes)) { + if(!mesh || !nmemb || (*nmemb && !nodes)) { meshlink_errno = MESHLINK_EINVAL; return NULL; } - meshlink_node_t **result, **p; + meshlink_node_t **result; //lock mesh->nodes pthread_mutex_lock(&(mesh->nodes_mutex)); @@ -1037,6 +1075,7 @@ meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_ result = realloc(nodes, *nmemb * sizeof *nodes); if(result) { + meshlink_node_t **p = result; for splay_each(node_t, n, mesh->nodes) *p++ = (meshlink_node_t *)n; } else { @@ -1625,6 +1664,47 @@ void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) { return; } +/* Hint that a hostname may be found at an address + * See header file for detailed comment. + */ +extern void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, struct sockaddr *addr) { + if(!mesh || !node || !addr) + return; + + char *addr_str = malloc(MAX_ADDRESS_LENGTH*sizeof(char)); + memset(addr_str, 0, MAX_ADDRESS_LENGTH*sizeof(char)); + + char *port_str = malloc(MAX_PORT_LENGTH*sizeof(char)); + memset(port_str, 0, MAX_PORT_LENGTH*sizeof(char)); + + // extra byte for a space, and one to make sure string is null-terminated + int full_addr_len = MAX_ADDRESS_LENGTH + MAX_PORT_LENGTH + 2; + + char *full_addr_str = malloc(full_addr_len*sizeof(char)); + memset(full_addr_str, 0, full_addr_len*sizeof(char)); + + // get address and port number + if(!get_ip_str(addr, addr_str, MAX_ADDRESS_LENGTH)) + goto fail; + if(!get_port_str(addr, port_str, MAX_ADDRESS_LENGTH)) + goto fail; + + // append_config_file expects an address, a space, and then a port number + strcat(full_addr_str, addr_str); + strcat(full_addr_str, " "); + strcat(full_addr_str, port_str); + + append_config_file(mesh, node->name, "Address", full_addr_str); + +fail: +done: + free(addr_str); + free(port_str); + free(full_addr_str); + + // @TODO do we want to fire off a connection attempt right away? +} + static void __attribute__((constructor)) meshlink_init(void) { crypto_init(); }