X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Flibmeshlink.c;h=76dae6bff008d49ccce96d28c2b111c683a7f573;hb=a86faaf34711d6b0f278b670d70a229a3cf0d479;hp=b4daff3d0a867b17cf670dbb23abbcd04db12c3e;hpb=78dbeddec72bc1c75165f1d1c8554e322c606fbe;p=meshlink diff --git a/src/libmeshlink.c b/src/libmeshlink.c index b4daff3d..76dae6bf 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 @@ -18,6 +18,10 @@ */ #include "libmeshlink.h" +#include LZO1X_H +#ifdef HAVE_SYS_MMAN_H +#include +#endif #include "crypto.h" #include "ecdsagen.h" char *hosts_dir = NULL; @@ -25,6 +29,42 @@ static char *name = NULL; char *tinc_conf = NULL; static bool tty = false; +#ifdef HAVE_MLOCKALL +/* If nonzero, disable swapping for this process. */ +static bool do_mlock = false; +#endif + +/* + initialize network +*/ +bool setup_meshlink_network(void) { + init_connections(); + 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; + + 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. */ @@ -340,8 +380,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)) { @@ -354,11 +393,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; @@ -388,12 +422,169 @@ bool tinc_setup(const char* confbaseapi, const char* name) { } -bool tinc_start(const char* path); +bool tinc_start(const char* confbaseapi) { + pthread_t tincThread; + confbase = confbaseapi; + pthread_create(&tincThread,NULL,tinc_main_thread,confbaseapi); + pthread_detach(tincThread); +return true; +} + +bool tinc_main_thread(void * in) { + static bool status = false; + + /* If nonzero, write log entries to a separate file. */ + bool use_logfile = false; + + confbase = (char*) in; + + openlogger("tinc", LOGMODE_STDERR); + + init_configuration(&config_tree); + + /* Slllluuuuuuurrrrp! */ + + gettimeofday(&now, NULL); + srand(now.tv_sec + now.tv_usec); + crypto_init(); + + 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()) + 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"); + + try_outgoing_connections(); + + status = main_loop(); + + /* Shutdown properly. */ + +end: + close_network_connections(); + + logger(DEBUG_ALWAYS, LOG_NOTICE, "Terminating"); + + //free(priority); + + crypto_exit(); + + exit_configuration(&config_tree); + free(cmdline_conf); + + return status; + +} bool tinc_stop(); +bool route_meshlink(node_t *source,vpn_packet_t *packet) { + + printf("data %s\n",packet->data); + printf("data 11%s\n",packet->data+11); + printf("data 32%s\n",packet->data+32); + node_t* owner = NULL; + + tincpackethdr* hdr = (tincpackethdr*)packet->data; + owner = lookup_node(hdr->destination); + + if (owner == NULL) { + //Lookup failed + printf("NULL\n"); + return false; + } + printf("lookupnode %s\n",owner->name); + + if(!owner->status.reachable) { + //Do some here + return false; + } + + //TODO: I skipped here a lot of checks ! + + send_packet(owner,packet); + +} // can be called from any thread -bool tinc_send_packet(node_t *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 = malloc(sizeof(tincpackethdr)); + + if (sizeof(hdr) + len > MAXSIZE) { + + //log something + return false; + } + + memcpy(hdr->destination,receiver->name,sizeof(hdr->destination)); + memcpy(hdr->source,myself->name,sizeof(hdr->source)); + + packet.priority = 0; + + memcpy(packet.data,hdr,32); + memcpy(packet.data+32,buf,len); + + myself->in_packets++; + myself->in_bytes += packet.len; + route_meshlink(myself, &packet); + +return true; +} // handler runs in tinc thread and should return immediately bool tinc_set_packet_receive_handler(void (*handler)(const char* sender, const char* buf, unsigned int len)); @@ -402,7 +593,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);