X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Flibmeshlink.c;h=cd9e8a745f496ecdbe3e38a19aec652e364acfdc;hb=8fb3cf697d16e4870d7305866d03240acd49b386;hp=80f18a22e341187a192125ba7f8a32a072d8c518;hpb=c53b009f21e97379cad24c811c8033e647cb2bb9;p=meshlink diff --git a/src/libmeshlink.c b/src/libmeshlink.c index 80f18a22..cd9e8a74 100644 --- a/src/libmeshlink.c +++ b/src/libmeshlink.c @@ -1,6 +1,6 @@ /* libmeshlink.h -- Tincd Library - Copyright (C) 2014 Guus Sliepen Saverio Proto + Copyright (C) 2014 Guus Sliepen Saverio Proto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,14 +17,21 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "libmeshlink.h" -#include LZO1X_H -#ifdef HAVE_SYS_MMAN_H -#include -#endif +#include "system.h" + +#include + +#include "connection.h" #include "crypto.h" #include "ecdsagen.h" +#include "edge.h" +#include "libmeshlink.h" +#include "net.h" +#include "node.h" +#include "protocol.h" + char *hosts_dir = NULL; +recvdata_cb_t recv_callback; static char *name = NULL; char *tinc_conf = NULL; static bool tty = false; @@ -34,45 +41,6 @@ static bool tty = false; static bool do_mlock = false; #endif -/* - initialize network -*/ -bool setup_meshlink_network(void) { - init_connections(); - init_subnets(); - init_nodes(); - init_edges(); - init_requests(); - - if(get_config_int(lookup_config(config_tree, "PingInterval"), &pinginterval)) { - if(pinginterval < 1) { - pinginterval = 86400; - } - } else - pinginterval = 60; - - if(!get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) - pingtimeout = 5; - if(pingtimeout < 1 || pingtimeout > pinginterval) - pingtimeout = pinginterval; - - //TODO: check if this makes sense in libmeshlink - if(!get_config_int(lookup_config(config_tree, "MaxOutputBufferSize"), &maxoutbufsize)) - maxoutbufsize = 10 * MTU; - - if(!setup_myself()) - return false; - - if(!init_control()) - return false; - - /* Run subnet-up scripts for our own subnets */ - - subnet_update(myself, NULL, true); - - return true; -} - /* Open a file with the desired permissions, minus the umask. Also, if we want to create an executable file, we call fchmod() to set the executable bits. */ @@ -272,63 +240,6 @@ bool ecdsa_keygen(bool ask) { return true; } -/* - Generate a public/private RSA keypair, and ask for a file to store - them in. -*/ -bool rsa_keygen(int bits, bool ask) { - rsa_t *key; - FILE *f; - char *pubname, *privname; - - fprintf(stderr, "Generating %d bits keys:\n", bits); - - if(!(key = rsa_generate(bits, 0x10001))) { - fprintf(stderr, "Error during key generation!\n"); - return false; - } else - fprintf(stderr, "Done.\n"); - - xasprintf(&privname, "%s" SLASH "rsa_key.priv", confbase); - f = ask_and_open(privname, "private RSA key", "a", ask, 0600); - free(privname); - - if(!f) - return false; - - if(!rsa_write_pem_private_key(key, f)) { - fprintf(stderr, "Error writing private key!\n"); - fclose(f); - rsa_free(key); - return false; - } - - fclose(f); - - if(name) - xasprintf(&pubname, "%s" SLASH "hosts" SLASH "%s", confbase, name); - else - xasprintf(&pubname, "%s" SLASH "rsa_key.pub", confbase); - - f = ask_and_open(pubname, "public RSA key", "a", ask, 0666); - free(pubname); - - if(!f) - return false; - - if(!rsa_write_pem_public_key(key, f)) { - fprintf(stderr, "Error writing public key!\n"); - fclose(f); - rsa_free(key); - return false; - } - - fclose(f); - rsa_free(key); - - return true; -} - static bool try_bind(int port) { struct addrinfo *ai = NULL; struct addrinfo hint = { @@ -358,7 +269,7 @@ static bool try_bind(int port) { return true; } -int check_port(char *name) { +int check_port(const char *name) { if(try_bind(655)) return 655; @@ -388,8 +299,7 @@ int check_port(char *name) { } //tinc_setup() should basically do what cmd_init() from src/tincctl.c does, except it doesn't have to generate a tinc-up script. bool tinc_setup(const char* confbaseapi, const char* name) { - confbase = confbaseapi; - make_names(); + confbase = xstrdup(confbaseapi); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase); if(!access(tinc_conf, F_OK)) { @@ -402,11 +312,6 @@ bool tinc_setup(const char* confbaseapi, const char* name) { return false; } - if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) { - fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno)); - return false; - } - if(mkdir(confbase, 0777) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno)); return false; @@ -426,7 +331,7 @@ bool tinc_setup(const char* confbaseapi, const char* name) { fprintf(f, "Name = %s\n", name); fclose(f); - if(!rsa_keygen(2048, false) || !ecdsa_keygen(false)) + if(!ecdsa_keygen(false)) return false; check_port(name); @@ -438,87 +343,46 @@ bool tinc_setup(const char* confbaseapi, const char* name) { bool tinc_start(const char* confbaseapi) { pthread_t tincThread; - confbase = confbaseapi; - pthread_create(&tincThread,NULL,tinc_main_thread,confbaseapi); + confbase = xstrdup(confbaseapi); + pthread_create(&tincThread,NULL,tinc_main_thread,confbase); pthread_detach(tincThread); return true; } -bool tinc_main_thread(void * in) { +__attribute__((constructor)) static void meshlink_init(void) { + /* Slllluuuuuuurrrrp! */ -static bool status = false; + gettimeofday(&now, NULL); + srand(now.tv_sec + now.tv_usec); + crypto_init(); +} -/* If nonzero, write log entries to a separate file. */ -bool use_logfile = false; +__attribute__((destructor)) static void meshlink_exit(void) { + crypto_exit(); +} -confbase = (char*) in; - openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR); +void *tinc_main_thread(void * in) { + static bool status = false; + /* If nonzero, write log entries to a separate file. */ + bool use_logfile = false; - init_configuration(&config_tree); + confbase = (char*) in; - /* Slllluuuuuuurrrrp! */ + openlogger("tinc", LOGMODE_STDERR); - gettimeofday(&now, NULL); - srand(now.tv_sec + now.tv_usec); - crypto_init(); + init_configuration(&config_tree); if(!read_server_config()) return false; -#ifdef HAVE_LZO - if(lzo_init() != LZO_E_OK) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing LZO compressor!"); - return false; - } -#endif - //char *priority = NULL; //shoud be not needed in libmeshlink -#ifdef HAVE_MLOCKALL - /* Lock all pages into memory if requested. - * This has to be done after daemon()/fork() so it works for child. - * No need to do that in parent as it's very short-lived. */ - if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "mlockall", - strerror(errno)); - return 1; - } -#endif - /* Setup sockets and open device. */ - if(!setup_meshlink_network()) + if(!setup_network()) goto end; - /* Change process priority */ - //should be not needed in libmeshlink - //if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) { - // if(!strcasecmp(priority, "Normal")) { - // if (setpriority(NORMAL_PRIORITY_CLASS) != 0) { - // logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); - // goto end; - // } - // } else if(!strcasecmp(priority, "Low")) { - // if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) { - // logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); - // goto end; - // } - // } else if(!strcasecmp(priority, "High")) { - // if (setpriority(HIGH_PRIORITY_CLASS) != 0) { - // logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno)); - // goto end; - // } - // } else { - // logger(DEBUG_ALWAYS, LOG_ERR, "Invalid priority `%s`!", priority); - // goto end; - // } - //} - - /* drop privileges */ - //if (!drop_privs()) - // goto end; - /* Start main loop. It only exits when tinc is killed. */ logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); @@ -536,29 +400,35 @@ end: //free(priority); - crypto_exit(); - exit_configuration(&config_tree); - free(cmdline_conf); - free_names(); - - return status; + return (void *)status; } bool tinc_stop(); // can be called from any thread -bool tinc_send_packet(tincremotehost *receiver, const char* buf, unsigned int len) { +bool tinc_send_packet(node_t *receiver, const char* buf, unsigned int len) { vpn_packet_t packet; + tincpackethdr* hdr = (tincpackethdr *)packet.data; + if (sizeof(tincpackethdr) + len > MAXSIZE) { + + //log something + return false; + } + + packet.probe = false; + memset(hdr, 0, sizeof *hdr); + memcpy(hdr->destination,receiver->name,sizeof(hdr->destination)); + memcpy(hdr->source,mesh->self->name,sizeof(hdr->source)); - packet.priority = 0; - memcpy(packet.data,buf,len); + packet.len = sizeof(tincpackethdr) + len; + memcpy(packet.data+sizeof(tincpackethdr),buf,len); - myself->in_packets++; - myself->in_bytes += packet.len; - route(myself, &packet); + mesh->self->in_packets++; + mesh->self->in_bytes += packet.len; + route(mesh->self, &packet); return true; } @@ -570,7 +440,11 @@ bool tinc_set_packet_receive_handler(void (*handler)(const char* sender, const c //It might also be a good idea to add the option of looking up hosts by public //key (fingerprints) instead of names. -node_t *tinc_get_host(const char *name); +node_t *tinc_get_host(const char *name) { + + + +}; bool tinc_get_hosts(node_t** hosts); @@ -615,6 +489,8 @@ automatically distributed blacklist or whitelist would be the next step. */ bool tinc_blacklist(node_t *host); - +void recvdata_register_cb(recvdata_cb_t cb) { +recv_callback = cb; +};