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");
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;
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) {
return false;
}
+ mesh->threadstarted=true;
+
return true;
}
}
bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, unsigned int len) {
+
+ /* If there is no outgoing list yet, create one. */
+
+ if(!mesh->outpacketqueue)
+ mesh->outpacketqueue = list_alloc(NULL);
+
+ //add packet to the queue
+ outpacketqueue_t *packet_in_queue = xzalloc(sizeof *packet_in_queue);
+ packet_in_queue->destination=destination;
+ packet_in_queue->data=data;
+ packet_in_queue->len=len;
+ pthread_mutex_lock(&(mesh->outpacketqueue_mutex));
+ list_insert_head(mesh->outpacketqueue,packet_in_queue);
+ pthread_mutex_unlock(&(mesh->outpacketqueue_mutex));
+
+ //notify event loop
+ signal_trigger(&(mesh->loop),&(mesh->datafromapp));
+ return true;
+}
+
+void meshlink_send_from_queue(event_loop_t* el,meshlink_handle_t *mesh) {
vpn_packet_t packet;
meshlink_packethdr_t *hdr = (meshlink_packethdr_t *)packet.data;
- if (sizeof(meshlink_packethdr_t) + len > MAXSIZE) {
+
+ outpacketqueue_t* p = list_get_tail(mesh->outpacketqueue);
+ if (p)
+ list_delete_tail(mesh->outpacketqueue);
+ else return ;
+
+ if (sizeof(meshlink_packethdr_t) + p->len > MAXSIZE) {
//log something
- return false;
+ return ;
}
packet.probe = false;
memset(hdr, 0, sizeof *hdr);
- memcpy(hdr->destination, destination->name, sizeof hdr->destination);
+ memcpy(hdr->destination, p->destination->name, sizeof hdr->destination);
memcpy(hdr->source, mesh->self->name, sizeof hdr->source);
- packet.len = sizeof *hdr + len;
- memcpy(packet.data + sizeof *hdr, data, len);
+ packet.len = sizeof *hdr + p->len;
+ memcpy(packet.data + sizeof *hdr, p->data, p->len);
mesh->self->in_packets++;
mesh->self->in_bytes += packet.len;
route(mesh, mesh->self, &packet);
- return false;
+ return ;
}
meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) {
size_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t nmemb) {
size_t i = 0;
+ //lock mesh->nodes
+ pthread_mutex_lock(&(mesh->nodes_mutex));
+
for splay_each(node_t, n, mesh->nodes) {
if(i < nmemb)
nodes[i] = (meshlink_node_t *)n;
i++;
}
+ pthread_mutex_unlock(&(mesh->nodes_mutex));
+
return i;
}
*port++ = 0;
}
- if(!*port)
+ if(!port)
port = "655";
if(!b64decode(slash, mesh->hash, 18) || !b64decode(slash + 24, mesh->cookie, 18))
char *b64key = ecdsa_get_base64_public_key(key);
+ //Before doing meshlink_join make sure we are not connected to another mesh
+ if ( mesh->threadstarted ){
+ goto invalid;
+ }
+
// Connect to the meshlink daemon mentioned in the URL.
struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM);
if(!ai)
return true;
invalid:
- fprintf(stderr, "Invalid invitation URL.\n");
+ fprintf(stderr, "Invalid invitation URL or you are already connected to a Mesh ?\n");
return false;
}