X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=examples%2Fmanynodes.c;h=61b5ece505c355d840e3d7e58ea7c1dd78d0cfcd;hb=f79cc0e0bba16a3aa42a5fa13098cda714623205;hp=99a3e5b2dd806a15d2f32fd5f337b653695691e6;hpb=fabbc781bb11f66383f2ef37ef84ec23094244d6;p=meshlink diff --git a/examples/manynodes.c b/examples/manynodes.c index 99a3e5b2..61b5ece5 100644 --- a/examples/manynodes.c +++ b/examples/manynodes.c @@ -4,7 +4,12 @@ #include #include #include + +#if !defined(_WIN32) && !defined(__APPLE__) #include +#elif defined(__APPLE__) +#include +#endif #include "../src/meshlink.h" #include "../src/devtools.h" @@ -15,9 +20,12 @@ #include #include +#include static int n = 10; static meshlink_handle_t **mesh; +static char *namesprefix = "machine1"; +static int nodeindex = 0; static meshlink_node_t **nodes; static size_t nnodes; @@ -30,28 +38,27 @@ static void log_message(meshlink_handle_t *mesh, meshlink_log_level_t level, con [MESHLINK_ERROR] = "\x1b[31mERROR", [MESHLINK_CRITICAL] = "\x1b[31mCRITICAL", }; - fprintf(stderr, "%s\t%s:\x1b[0m %s\n", mesh ? mesh->name : "global",levelstr[level], text); + fprintf(stderr, "%s\t%s:\x1b[0m %s\n", mesh ? mesh->name : "global", levelstr[level], text); } //Test mesh sending data -static void testmesh () { +static void testmesh() { for(int nindex = 0; nindex < n; nindex++) { - nodes = meshlink_get_all_nodes(mesh[nindex], nodes, &nnodes); - if(!nodes) { - fprintf(stderr, "Could not get list of nodes: %s\n", meshlink_strerror(meshlink_errno)); - } else { - printf("%zu known nodes:\n", nnodes); - for(int i = 0; i < nnodes; i++) { - //printf(" %s\n", nodes[i]->name); - if(!meshlink_send(mesh[nindex], nodes[i], "magic", strlen("magic") + 1)) { - fprintf(stderr, "Could not send message to '%s': %s\n", nodes[i]->name, meshlink_strerror(meshlink_errno)); - } - } - + nodes = meshlink_get_all_nodes(mesh[nindex], nodes, &nnodes); + if(!nodes) + fprintf(stderr, "Could not get list of nodes: %s\n", meshlink_strerror(meshlink_errno)); + else { + printf("%zu known nodes:\n", nnodes); + for(int i = 0; i < nnodes; i++) { + //printf(" %s\n", nodes[i]->name); + if(!meshlink_send(mesh[nindex], nodes[i], "magic", strlen("magic") + 1)) + fprintf(stderr, "Could not send message to '%s': %s\n", nodes[i]->name, meshlink_strerror(meshlink_errno)); } + } + } } // Make all nodes know about each other by importing each others public keys and addresses. @@ -70,31 +77,29 @@ static void linkmesh() { } } -static bool exportmeshgraph(const char* path) -{ +static bool exportmeshgraph(const char *path) { + assert(path); + struct stat ps; int psr = stat(path, &ps); - if(psr == 0 || errno != ENOENT) - { + if(psr == 0 || errno != ENOENT) { if(psr == -1) - { perror("stat"); } + perror("stat"); else - { fprintf(stderr, "%s exists already\n", path); } + fprintf(stderr, "%s exists already\n", path); return false; } - FILE* stream = fopen(path, "w"); + FILE *stream = fopen(path, "w"); - if(!stream) - { + if(!stream) { perror("stream"); return false; } - if(!devtool_export_json_all_edges_state(mesh[0], stream)) - { + if(!devtool_export_json_all_edges_state(mesh[0], stream)) { fclose(stream); fprintf(stderr, "could not export graph\n"); return false; @@ -105,39 +110,36 @@ static bool exportmeshgraph(const char* path) } -void exportmeshgraph_timer(int signum) -{ +void exportmeshgraph_timer(int signum) { struct timeval ts; gettimeofday(&ts, NULL); char name[1024]; - snprintf(name, sizeof(name), "graph_%ld_%03ld.json", ts.tv_sec, ts.tv_usec/1000); + snprintf(name, sizeof(name), "%sgraph_%ld_%03ld.json", namesprefix, ts.tv_sec, ts.tv_usec / 1000); exportmeshgraph(name); } +#ifndef _WIN32 static bool exportmeshgraph_started = false; -static bool exportmeshgraph_end(const char* none) -{ +static bool exportmeshgraph_end(const char *none) { if(!exportmeshgraph_started) - { return false; } + return false; struct itimerval zero_timer = { 0 }; - setitimer (ITIMER_REAL, &zero_timer, NULL); + setitimer(ITIMER_REAL, &zero_timer, NULL); exportmeshgraph_started = false; return true; } -static bool exportmeshgraph_begin(const char* timeout_str) -{ +static bool exportmeshgraph_begin(const char *timeout_str) { if(!timeout_str) return false; - if(exportmeshgraph_started) - { + if(exportmeshgraph_started) { if(!exportmeshgraph_end(NULL)) return false; } @@ -146,7 +148,7 @@ static bool exportmeshgraph_begin(const char* timeout_str) int timeout = atoi(timeout_str); if(timeout < 100) - { timeout = 100; } + timeout = 100; int timeout_sec = timeout / 1000; int timeout_msec = timeout % 1000; @@ -164,12 +166,21 @@ static bool exportmeshgraph_begin(const char* timeout_str) timer.it_interval.tv_usec = timeout_msec * 1000; /* Start a real timer. */ - setitimer (ITIMER_REAL, &timer, NULL); + setitimer(ITIMER_REAL, &timer, NULL); exportmeshgraph_started = true; return true; } +#else +static bool exportmeshgraph_end(const char *none) { + return false; +} + +static bool exportmeshgraph_begin(const char *timeout_str) { + return false; +} +#endif static void parse_command(char *buf) { char *arg = strchr(buf, ' '); @@ -184,7 +195,7 @@ static void parse_command(char *buf) { return; } - invitation = meshlink_invite(mesh[0], arg); + invitation = meshlink_invite(mesh[nodeindex], arg); if(!invitation) { fprintf(stderr, "Could not invite '%s': %s\n", arg, meshlink_strerror(meshlink_errno)); return; @@ -197,12 +208,14 @@ static void parse_command(char *buf) { fprintf(stderr, "/join requires an argument!\n"); return; } - meshlink_stop(mesh[0]); - if(!meshlink_join(mesh[0], arg)) + meshlink_stop(mesh[nodeindex]); + if(!meshlink_join(mesh[nodeindex], arg)) fprintf(stderr, "Could not join using invitation: %s\n", meshlink_strerror(meshlink_errno)); - else { + else fprintf(stderr, "Invitation accepted!\n"); - meshlink_start(mesh[0]); + if(!meshlink_start(mesh[nodeindex])) { + fprintf(stderr, "Could not restart MeshLink: %s\n", meshlink_strerror(meshlink_errno)); + exit(1); } } else if(!strcasecmp(buf, "kick")) { if(!arg) { @@ -210,63 +223,72 @@ static void parse_command(char *buf) { return; } - meshlink_node_t *node = meshlink_get_node(mesh[0], arg); + meshlink_node_t *node = meshlink_get_node(mesh[nodeindex], arg); if(!node) { fprintf(stderr, "Unknown node '%s'\n", arg); return; } - meshlink_blacklist(mesh[0], node); + meshlink_blacklist(mesh[nodeindex], node); printf("Node '%s' blacklisted.\n", arg); } else if(!strcasecmp(buf, "who")) { if(!arg) { - nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes); - if(!nodes) { + nodes = meshlink_get_all_nodes(mesh[nodeindex], nodes, &nnodes); + if(!nodes) fprintf(stderr, "Could not get list of nodes: %s\n", meshlink_strerror(meshlink_errno)); - } else { + else { printf("%zu known nodes:", nnodes); for(int i = 0; i < nnodes; i++) printf(" %s", nodes[i]->name); printf("\n"); } } else { - meshlink_node_t *node = meshlink_get_node(mesh[0], arg); - if(!node) { + meshlink_node_t *node = meshlink_get_node(mesh[nodeindex], arg); + if(!node) fprintf(stderr, "Unknown node '%s'\n", arg); - } else { - printf("Node %s found, pmtu %zd\n", arg, meshlink_get_pmtu(mesh[0], node)); - } + else + printf("Node %s found, pmtu %zd\n", arg, meshlink_get_pmtu(mesh[nodeindex], node)); } - } else if(!strcasecmp(buf, "link")) { + } else if(!strcasecmp(buf, "link")) linkmesh(); - } else if(!strcasecmp(buf, "eg")) { + else if(!strcasecmp(buf, "eg")) exportmeshgraph(arg); - } else if(!strcasecmp(buf, "egb")) { + else if(!strcasecmp(buf, "egb")) exportmeshgraph_begin(arg); - } else if(!strcasecmp(buf, "ege")) { + else if(!strcasecmp(buf, "ege")) exportmeshgraph_end(NULL); - } else if(!strcasecmp(buf, "test")) { + else if(!strcasecmp(buf, "test")) testmesh(); - } else if(!strcasecmp(buf, "quit")) { + else if(!strcasecmp(buf, "select")) { + if(!arg) { + fprintf(stderr, "/select requires an argument!\n"); + return; + } + nodeindex = atoi(arg); + printf("Index is now %d\n", nodeindex); + } else if(!strcasecmp(buf, "stop")) + meshlink_stop(mesh[nodeindex]); + else if(!strcasecmp(buf, "quit")) { printf("Bye!\n"); fclose(stdin); } else if(!strcasecmp(buf, "help")) { printf( - ": Send a message to the given node.\n" - " Subsequent messages don't need the : prefix.\n" - "/invite Create an invitation for a new node.\n" - "/join Join an existing mesh using an invitation.\n" - "/kick Blacklist the given node.\n" - "/who [] List all nodes or show information about the given node.\n" - "/link Link all nodes together.\n" - "/eg Export graph as json file.\n" - "/test Test functionality sending some data to all nodes\n" - "/quit Exit this program.\n" - ); - } else { + ": Send a message to the given node.\n" + " Subsequent messages don't need the : prefix.\n" + "/invite Create an invitation for a new node.\n" + "/join Join an existing mesh using an invitation.\n" + "/kick Blacklist the given node.\n" + "/who [] List all nodes or show information about the given node.\n" + "/link Link all nodes together.\n" + "/eg Export graph as json file.\n" + "/test Test functionality sending some data to all nodes\n" + "/select Select the active node running the user commands\n" + "/stop Call meshlink_stop, use /select first to select which node to stop\n" + "/quit Exit this program.\n" + ); + } else fprintf(stderr, "Unknown command '/%s'\n", buf); - } } static void parse_input(char *buf) { @@ -307,7 +329,7 @@ static void parse_input(char *buf) { if(*msg == ' ') msg++; - destination = meshlink_get_node(mesh[0], buf); + destination = meshlink_get_node(mesh[nodeindex], buf); if(!destination) { fprintf(stderr, "Unknown node '%s'\n", buf); return; @@ -319,7 +341,7 @@ static void parse_input(char *buf) { return; } - if(!meshlink_send(mesh[0], destination, msg, strlen(msg) + 1)) { + if(!meshlink_send(mesh[nodeindex], destination, msg, strlen(msg) + 1)) { fprintf(stderr, "Could not send message to '%s': %s\n", destination->name, meshlink_strerror(meshlink_errno)); return; } @@ -329,7 +351,6 @@ static void parse_input(char *buf) { int main(int argc, char *argv[]) { const char *basebase = ".manynodes"; - const char *namesprefix = "machine1"; const char *graphexporttimeout = NULL; char buf[1024]; @@ -350,19 +371,25 @@ int main(int argc, char *argv[]) { if(argc > 4) graphexporttimeout = argv[4]; - mesh = calloc(n, sizeof *mesh); + mesh = calloc(n, sizeof(*mesh)); - meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_message); + meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_message); +#ifndef _WIN32 mkdir(basebase, 0750); +#else + mkdir(basebase); +#endif char filename[PATH_MAX]; char nodename[100]; for(int i = 0; i < n; i++) { - snprintf(nodename, sizeof nodename, "%snode%d", namesprefix,i); - snprintf(filename, sizeof filename, "%s/%s", basebase, nodename); - bool itsnew = access(filename, R_OK); - mesh[i] = meshlink_open(filename, nodename, "manynodes", i%_DEV_CLASS_MAX); - meshlink_set_log_cb(mesh[i], MESHLINK_WARNING, log_message); + snprintf(nodename, sizeof(nodename), "%snode%d", namesprefix, i); + snprintf(filename, sizeof(filename), "%s/%s", basebase, nodename); + if(n / (i + 1) > n / 4) + mesh[i] = meshlink_open(filename, nodename, "manynodes", DEV_CLASS_BACKBONE); + else + mesh[i] = meshlink_open(filename, nodename, "manynodes", DEV_CLASS_PORTABLE); + meshlink_set_log_cb(mesh[i], MESHLINK_DEBUG, log_message); if(!mesh[i]) { fprintf(stderr, "errno is: %d\n", meshlink_errno); fprintf(stderr, "Could not open %s: %s\n", filename, meshlink_strerror(meshlink_errno)); @@ -385,12 +412,12 @@ int main(int argc, char *argv[]) { } if(graphexporttimeout) - { exportmeshgraph_begin(graphexporttimeout); } + exportmeshgraph_begin(graphexporttimeout); printf("%d nodes started.\nType /help for a list of commands.\n", started); // handle input - while(fgets(buf, sizeof buf, stdin)) + while(fgets(buf, sizeof(buf), stdin)) parse_input(buf); exportmeshgraph_end(NULL);