X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=d5ea5418e974c398ba181aa131dacf1cdd321df8;hb=43ed5b9a5d739c50317d5d24898de07526a9297f;hp=99e1704b89c929e18a97fddf4f9abcd95f78a102;hpb=7df6ece3865a0279b7728526eb8fefd4458fc2ea;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 99e1704b..d5ea5418 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 @@ -347,12 +350,7 @@ static bool try_bind(int port) { } static int check_port(meshlink_handle_t *mesh) { - if(try_bind(655)) - return 655; - - fprintf(stderr, "Warning: could not bind to port 655.\n"); - - for(int i = 0; i < 100; i++) { + for(int i = 0; i < 1000; i++) { int port = 0x1000 + (rand() & 0x7fff); if(try_bind(port)) { char filename[PATH_MAX]; @@ -365,7 +363,6 @@ static int check_port(meshlink_handle_t *mesh) { fprintf(f, "Port = %d\n", port); fclose(f); - fprintf(stderr, "MeshLink will instead listen on port %d.\n", port); return port; } } @@ -740,13 +737,12 @@ static bool meshlink_setup(meshlink_handle_t *mesh) { return true; } - -meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { - return meshlink_open_with_size(confbase, name, sizeof(meshlink_handle_t) ); +meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char* appname) { + return meshlink_open_with_size(confbase, name, appname, sizeof(meshlink_handle_t)); } +meshlink_handle_t *meshlink_open_with_size(const char *confbase, const char *name, const char* appname, size_t size) { -meshlink_handle_t *meshlink_open_with_size(const char *confbase, const char *name, size_t size) { // Validate arguments provided by the application bool usingname = false; @@ -756,6 +752,12 @@ meshlink_handle_t *meshlink_open_with_size(const char *confbase, const char *nam 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; @@ -771,6 +773,7 @@ meshlink_handle_t *meshlink_open_with_size(const char *confbase, const char *nam meshlink_handle_t *mesh = xzalloc(size); mesh->confbase = xstrdup(confbase); + mesh->appname = xstrdup(appname); if (usingname) mesh->name = xstrdup(name); pthread_mutex_init ( &(mesh->nodes_mutex), NULL); mesh->threadstarted = false; @@ -832,7 +835,9 @@ static void *meshlink_main_loop(void *arg) { try_outgoing_connections(mesh); + fprintf(stderr, "Starting main_loop...\n"); main_loop(mesh); + fprintf(stderr, "main_loop returned.\n"); return NULL; } @@ -863,26 +868,42 @@ bool meshlink_start(meshlink_handle_t *mesh) { mesh->threadstarted=true; + // Start discovery + if(!discovery_start(mesh)) + return false; + return true; } void meshlink_stop(meshlink_handle_t *mesh) { + if(!mesh) { meshlink_errno = MESHLINK_EINVAL; return; } - // Shut down the listening sockets to signal the main thread to shut down + // Stop discovery + discovery_stop(mesh); - for(int i = 0; i < mesh->listen_sockets; i++) { - shutdown(mesh->listen_socket[i].tcp.fd, SHUT_RDWR); - shutdown(mesh->listen_socket[i].udp.fd, SHUT_RDWR); - } + // Shut down a listening socket to signal the main thread to shut down + + listen_socket_t *s = &mesh->listen_socket[0]; + shutdown(s->tcp.fd, SHUT_RDWR); // Wait for the main thread to finish pthread_join(mesh->thread, NULL); mesh->threadstarted = false; + + // Fix the socket + + closesocket(s->tcp.fd); + io_del(&mesh->loop, &s->tcp); + s->tcp.fd = setup_listen_socket(&s->sa); + if(s->tcp.fd < 0) + logger(DEBUG_ALWAYS, LOG_ERR, "Could not repair listenen socket!"); + else + io_add(&mesh->loop, &s->tcp, handle_new_meta_connection, s, s->tcp.fd, IO_READ); } void meshlink_close(meshlink_handle_t *mesh) { @@ -1387,7 +1408,7 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { } if(!port) - port = "655"; + goto invalid; if(!b64decode(slash, mesh->hash, 18) || !b64decode(slash + 24, mesh->cookie, 18)) goto invalid; @@ -1648,6 +1669,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(); }