X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=f44dba47b7a7dec9ec2ed7ec394c24e934b01ae3;hb=refs%2Fheads%2Fchannels;hp=9a53d67aefae1c7e4e238fe9c784436c843bd58c;hpb=ef2f0d4510168a77a6da16822b9401d1f14b69e0;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 9a53d67a..f44dba47 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -16,7 +16,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define VAR_SERVER 1 /* Should be in tinc.conf */ +#define VAR_SERVER 1 /* Should be in meshlink.conf */ #define VAR_HOST 2 /* Can be in host config file */ #define VAR_MULTIPLE 4 /* Multiple statements allowed */ #define VAR_OBSOLETE 8 /* Should not be used anymore */ @@ -190,9 +190,9 @@ static char *get_my_hostname(meshlink_handle_t* mesh) { // If that doesn't work, guess externally visible hostname fprintf(stderr, "Trying to discover externally visible hostname...\n"); - struct addrinfo *ai = str2addrinfo("tinc-vpn.org", "80", SOCK_STREAM); + struct addrinfo *ai = str2addrinfo("meshlink.io", "80", SOCK_STREAM); struct addrinfo *aip = ai; - static const char request[] = "GET http://tinc-vpn.org/host.cgi HTTP/1.0\r\n\r\n"; + static const char request[] = "GET http://meshlink.io/host.cgi HTTP/1.0\r\n\r\n"; while(aip) { int s = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); @@ -398,7 +398,7 @@ static bool finalize_join(meshlink_handle_t *mesh) { return false; } - // Filter first chunk on approved keywords, split between tinc.conf and hosts/Name + // Filter first chunk on approved keywords, split between meshlink.conf and hosts/Name // Other chunks go unfiltered to their respective host config files const char *p = mesh->data; char *l, *value; @@ -715,6 +715,7 @@ static bool meshlink_setup(meshlink_handle_t *mesh) { meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { // Validate arguments provided by the application + bool usingname = false; if(!confbase || !*confbase) { fprintf(stderr, "No confbase given!\n"); @@ -723,19 +724,22 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name) { if(!name || !*name) { fprintf(stderr, "No name given!\n"); - return NULL; + //return NULL; } + else { //check name only if there is a name != NULL - if(!check_id(name)) { - fprintf(stderr, "Invalid name given!\n"); - return NULL; + if(!check_id(name)) { + fprintf(stderr, "Invalid name given!\n"); + return NULL; + } else { usingname = true;} } meshlink_handle_t *mesh = xzalloc(sizeof *mesh); mesh->confbase = xstrdup(confbase); - mesh->name = xstrdup(name); + if (usingname) mesh->name = xstrdup(name); pthread_mutex_init ( &(mesh->outpacketqueue_mutex), NULL); pthread_mutex_init ( &(mesh->nodes_mutex), NULL); + mesh->threadstarted = false; event_loop_init(&mesh->loop); mesh->loop.data = mesh; @@ -791,6 +795,12 @@ void *meshlink_main_loop(void *arg) { bool meshlink_start(meshlink_handle_t *mesh) { // TODO: open listening sockets first + //Check that a valid name is set + if(!mesh->name ) { + fprintf(stderr, "No name given!\n"); + return false; + } + // Start the main thread if(pthread_create(&mesh->thread, NULL, meshlink_main_loop, mesh) != 0) { @@ -799,6 +809,8 @@ bool meshlink_start(meshlink_handle_t *mesh) { return false; } + mesh->threadstarted=true; + return true; } @@ -825,6 +837,8 @@ void meshlink_close(meshlink_handle_t *mesh) { exit_configuration(&mesh->config); event_loop_exit(&mesh->loop); + free(mesh); + #ifdef HAVE_MINGW WSACleanup(); #endif @@ -913,12 +927,23 @@ size_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, return i; } -char *meshlink_sign(meshlink_handle_t *mesh, const char *data, size_t len) { - return NULL; +bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) { + if(*siglen < MESHLINK_SIGLEN) + return false; + if(!ecdsa_sign(mesh->self->connection->ecdsa, data, len, signature)) + return false; + *siglen = MESHLINK_SIGLEN; + return true; } -bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const char *data, size_t len, const char *signature) { - return false; +bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len, const void *signature, size_t siglen) { + if(siglen != MESHLINK_SIGLEN) + return false; + struct node_t *n = (struct node_t *)source; + node_read_ecdsa_public_key(mesh, n); + if(!n->ecdsa) + return false; + return ecdsa_verify(((struct node_t *)source)->ecdsa, data, len, signature); } static bool refresh_invitation_key(meshlink_handle_t *mesh) { @@ -1172,8 +1197,7 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { char *b64key = ecdsa_get_base64_public_key(key); //Before doing meshlink_join make sure we are not connected to another mesh - if ( pthread_kill(mesh->thread,0) == 0){ - printf("HELLO\n"); + if ( mesh->threadstarted ){ goto invalid; } @@ -1357,6 +1381,76 @@ void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) { } +static bool channel_pre_accept(struct utcp *utcp, uint16_t port) { + //TODO: implement + return false; +} + +static void channel_accept(struct utcp_connection *utcp_connection, uint16_t port) { + //TODO: implement +} + +static int channel_recv(struct utcp_connection *connection, const void *data, size_t len) { + meshlink_channel_t *channel = connection->priv; + node_t *n = channel->node; + meshlink_handle_t *mesh = n->mesh; + if(!channel->receive_cb) + return -1; + else { + channel->receive_cb(mesh, channel, data, len); + return 0; + } +} + +static int channel_send(struct utcp *utcp, const void *data, size_t len) { + node_t *n = utcp->priv; + meshlink_handle_t *mesh = n->mesh; + return meshlink_send(mesh, (meshlink_node_t *)n, data, len) ? len : -1; +} + +void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) { + mesh->channel_accept_cb = cb; +} + +void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb) { + channel->receive_cb = cb; +} + +meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) { + node_t *n = (node_t *)node; + if(!n->utcp) { + n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n); + if(!n->utcp) + return NULL; + } + meshlink_channel_t *channel = xzalloc(sizeof *channel); + channel->node = n; + channel->receive_cb = cb; + channel->c = utcp_connect(n->utcp, port, channel_recv, channel); + if(!channel->c) { + free(channel); + return NULL; + } + return channel; +} + +void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *channel, int direction) { + utcp_shutdown(channel->c, direction); +} + +void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel) { + utcp_close(channel->c); + free(channel); +} + +ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) { + // TODO: locking. + // Ideally we want to put the data into the UTCP connection's send buffer. + // Then, preferrably only if there is room in the receiver window, + // kick the meshlink thread to go send packets. + return utcp_send(channel->c, data, len); +} + static void __attribute__((constructor)) meshlink_init(void) { crypto_init(); }