]> git.meshlink.io Git - meshlink/commitdiff
Merge branch 'channels'
authorGuus Sliepen <guus@meshlink.io>
Fri, 22 Aug 2014 08:58:47 +0000 (10:58 +0200)
committerGuus Sliepen <guus@meshlink.io>
Fri, 22 Aug 2014 09:00:15 +0000 (11:00 +0200)
Conflicts:
.gitmodules
src/node.h

1  2 
.gitmodules
src/Makefile.am
src/meshlink.c
src/meshlink_internal.h
src/node.h

diff --cc .gitmodules
index 0e6f5440dc21eb7dad698f958e642815ae489de5,add1976b253c2319bc2b7113934679b1b4fb05d4..e938b09181fe4913bb679de84d167cd8917664c7
@@@ -1,4 -1,3 +1,7 @@@
 +[submodule "avahi"]
 +      path = avahi
 +      url = git@chicago.everbase.net:meshlink/avahi-noptr.git
 +      branch = noptr
+ [submodule "src/utcp"]
+       path = src/utcp
+       url = git://meshlink.io/utcp
diff --cc src/Makefile.am
index cae2ab95458666bd89d738bae7eab34890788914,c1d887e9759d2e0687bcda210aafd92c01a66bcd..a2a9305ac54e32f219be1439581d728b5fb66f13
@@@ -99,13 -101,13 +102,14 @@@ libmeshlink_la_SOURCES = 
        system.h \
        utils.c utils.h \
        xalloc.h \
 +      devtools.c devtools.h \
        $(ed25519_SOURCES) \
-       $(chacha_poly1305_SOURCES)
+       $(chacha_poly1305_SOURCES) \
+       $(utcp_SOURCES)
  
 -libmeshlink_la_CFLAGS = -fPIC
 +libmeshlink_la_CFLAGS = -fPIC -I../avahi/
  
 -libmeshlink_la_LIBADD = -lpthread
 +libmeshlink_la_LIBADD = -lpthread -luuid ../avahi/avahi-core/.libs/libavahi-core.a ../avahi/avahi-common/.libs/libavahi-common.a
  
  libmeshlink_la_SOURCES += \
        ed25519/ecdh.c \
diff --cc src/meshlink.c
index ddaa740b88a4b7fd501b02e2f95e7e105260e403,f44dba47b7a7dec9ec2ed7ec394c24e934b01ae3..ef02580ea93d641059eb203c7e3a8a17b14c1ab9
@@@ -1798,122 -1377,80 +1798,192 @@@ void meshlink_blacklist(meshlink_handle
  
        //Make blacklisting persistent in the config file
        append_config_file(mesh, n->name, "blacklisted", "yes");
 -    return;
  
 +      pthread_mutex_unlock(&(mesh->mesh_mutex));
 +      return;
 +}
 +
 +void meshlink_whitelist(meshlink_handle_t *mesh, meshlink_node_t *node) {
 +      if(!mesh || !node) {
 +              meshlink_errno = MESHLINK_EINVAL;
 +              return;
 +      }
 +
 +      pthread_mutex_lock(&(mesh->mesh_mutex));
 +      
 +      node_t *n = (node_t *)node;
 +      n->status.blacklisted = false;
 +
 +      //TODO: remove blacklisted = yes from the config file
 +
 +      pthread_mutex_unlock(&(mesh->mesh_mutex));
 +      return;
 +}
 +
 +/* Hint that a hostname may be found at an address
 + * See header file for detailed comment.
 + */
 +void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const struct sockaddr *addr) {
 +      if(!mesh || !node || !addr)
 +              return;
 +      
 +      pthread_mutex_lock(&(mesh->mesh_mutex));
 +      
 +      char *host = NULL, *port = NULL, *str = NULL;
 +      sockaddr2str((const sockaddr_t *)addr, &host, &port);
 +
 +      if(host && port) {
 +              xasprintf(&str, "%s %s", host, port);
 +              if ( (strncmp ("fe80",host,4) != 0) && ( strncmp("127.",host,4) != 0 ) && ( strcmp("localhost",host) !=0 ) )
 +                      append_config_file(mesh, node->name, "Address", str);
 +              else
 +                      logger(mesh, MESHLINK_DEBUG, "Not adding Link Local IPv6 Address to config\n");
 +      }
 +
 +      free(str);
 +      free(host);
 +      free(port);
 +
 +      pthread_mutex_unlock(&(mesh->mesh_mutex));
 +      // @TODO do we want to fire off a connection attempt right away?
 +}
 +
 +/* Return an array of edges in the current network graph.
 + * Data captures the current state and will not be updated.
 + * Caller must deallocate data when done.
 + */
 +meshlink_edge_t **meshlink_get_all_edges_state(meshlink_handle_t *mesh, meshlink_edge_t **edges, size_t *nmemb) {
 +      if(!mesh || !nmemb || (*nmemb && !edges)) {
 +              meshlink_errno = MESHLINK_EINVAL;
 +              return NULL;
 +      }
 +
 +      pthread_mutex_lock(&(mesh->mesh_mutex));
 +      
 +      meshlink_edge_t **result = NULL;
 +      meshlink_edge_t *copy = NULL;
 +      int result_size = 0;
 +
 +      result_size = mesh->edges->count;
 +
 +      // if result is smaller than edges, we have to dealloc all the excess meshlink_edge_t
 +      if(result_size > *nmemb) {
 +              result = realloc(edges, result_size * sizeof (meshlink_edge_t*));
 +      } else {
 +              result = edges;
 +      }
 +
 +      if(result) {
 +              meshlink_edge_t **p = result;
 +              int n = 0;
 +              for splay_each(edge_t, e, mesh->edges) {
 +                      // skip edges that do not represent a two-directional connection
 +                      if((!e->reverse) || (e->reverse->to != e->from)) {
 +                              result_size--;
 +                              continue;
 +                      }
 +                      n++;
 +                      // the first *nmemb members of result can be re-used
 +                      if(n > *nmemb) {
 +                              copy = xzalloc(sizeof *copy);
 +                      }
 +                      else {
 +                              copy = *p;
 +                      }
 +                      copy->from = (meshlink_node_t*)e->from;
 +                      copy->to = (meshlink_node_t*)e->to;
 +                      copy->address = e->address.storage;
 +                      copy->options = e->options;
 +                      copy->weight = e->weight;
 +                      *p++ = copy;
 +              }
 +              // shrink result to the actual amount of memory used
 +              for(int i = *nmemb; i > result_size; i--) {
 +                      free(result[i - 1]);
 +              }
 +              result = realloc(result, result_size * sizeof (meshlink_edge_t*));
 +              *nmemb = result_size;
 +      } else {
 +              *nmemb = 0;
 +              free(result);
 +              meshlink_errno = MESHLINK_ENOMEM;
 +      }
 +
 +      pthread_mutex_unlock(&(mesh->mesh_mutex));
 +
 +      return result;
  }
  
+ 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();
  }
Simple merge
diff --cc src/node.h
index c86c3cee9a650225137f9c1f17f73cc96effd306,427bc83a000907c6f8fb7e65602dd704ab651397..5761e4d747e5544c2d5189fdaed074eaa597ac12
@@@ -40,9 -41,9 +41,10 @@@ typedef struct node_status_t 
  
  typedef struct node_t {
        char *name;                             /* name of this node */
+       void *priv;
        uint32_t options;                       /* options turned on for this node */
-       void *priv;
 +      dev_class_t devclass;
  
        struct meshlink_handle *mesh;           /* The mesh this node belongs to */