return meshlink_set_canonical_address(handle, node, address, port);
}
- /// Set the canonical Address for the local node.
- /** This function sets the canonical Address for the local node.
- * This address is stored permanently until it is changed by another call to this function,
- * unlike other addresses associated with a node,
- * such as those added with meshlink_hint_address() or addresses discovered at runtime.
+ /// Add an invitation address for the local node.
+ /** This function adds an address for the local node, which will be used only for invitation URLs.
+ * This address is not stored permanently.
+ * Multiple addresses can be added using multiple calls to this function.
*
* @param address A nul-terminated C string containing the address, which can be either in numeric format or a hostname.
* @param port A nul-terminated C string containing the port, which can be either in numeric or symbolic format.
*
* @return This function returns true if the address was added, false otherwise.
*/
- bool set_canonical_address(const char *address, const char *port = NULL) {
- return meshlink_set_canonical_address(handle, get_self(), address, port);
+ bool add_invitation_address(const char *address, const char *port) {
+ return meshlink_add_invitation_address(handle, address, port);
+ }
+
+ /// Clears all invitation address for the local node.
+ /** This function removes all addresses added with meshlink_add_invitation_address().
+ */
+ void clear_invitation_addresses() {
+ return meshlink_clear_invitation_addresses(handle);
}
/// Add an Address for the local node.
/** This function adds an Address for the local node, which will be used for invitation URLs.
+ * @deprecated This function is deprecated, use set_canonical_address() and/or add_invitation_address().
*
* @param address A string containing the address, which can be either in numeric format or a hostname.
*
* @return This function returns true if the address was added, false otherwise.
*/
- bool add_address(const char *address) {
- return meshlink_add_address(handle, address);
+ bool add_address(const char *address) __attribute__((__deprecated__("use set_canonical_address() and/or add_invitation_address() instead"))) {
+ return meshlink_set_canonical_address(handle, get_self(), address, NULL);
}
/** This function performs tries to discover the local node's external address
// This gets the hostname part for use in invitation URLs
static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) {
- char *hostname[4] = {NULL};
- char *port[4] = {NULL};
+ int count = 4 + (mesh->invitation_addresses ? mesh->invitation_addresses->count : 0);
+ int n = 0;
+ char *hostname[count];
+ char *port[count];
char *hostport = NULL;
+ memset(hostname, 0, sizeof(hostname));
+ memset(port, 0, sizeof(port));
+
if(!(flags & (MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_PUBLIC))) {
flags |= MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_PUBLIC;
}
flags |= MESHLINK_INVITE_IPV4 | MESHLINK_INVITE_IPV6;
}
+ // Add all explicitly set invitation addresses
+ if(mesh->invitation_addresses) {
+ for list_each(char, combo, mesh->invitation_addresses) {
+ hostname[n] = xstrdup(combo);
+ char *colon = strchr(hostname[n], ':');
+
+ if(colon) {
+ *colon = 0;
+ port[n] = colon + 1;
+ }
+
+ n++;
+ }
+ }
+
// Add local addresses if requested
if(flags & MESHLINK_INVITE_LOCAL) {
if(flags & MESHLINK_INVITE_IPV4) {
- hostname[0] = meshlink_get_local_address_for_family(mesh, AF_INET);
+ hostname[n++] = meshlink_get_local_address_for_family(mesh, AF_INET);
}
if(flags & MESHLINK_INVITE_IPV6) {
- hostname[1] = meshlink_get_local_address_for_family(mesh, AF_INET6);
+ hostname[n++] = meshlink_get_local_address_for_family(mesh, AF_INET6);
}
}
// Add public/canonical addresses if requested
if(flags & MESHLINK_INVITE_PUBLIC) {
// Try the CanonicalAddress first
- get_canonical_address(mesh->self, &hostname[2], &port[2]);
+ get_canonical_address(mesh->self, &hostname[n], &port[n]);
- if(!hostname[2]) {
+ if(!hostname[n] && count == 4) {
if(flags & MESHLINK_INVITE_IPV4) {
- hostname[2] = meshlink_get_external_address_for_family(mesh, AF_INET);
+ hostname[n++] = meshlink_get_external_address_for_family(mesh, AF_INET);
}
if(flags & MESHLINK_INVITE_IPV6) {
- hostname[3] = meshlink_get_external_address_for_family(mesh, AF_INET6);
+ hostname[n++] = meshlink_get_external_address_for_family(mesh, AF_INET6);
}
+ } else {
+ n++;
}
}
free(mesh->external_address_url);
ecdsa_free(mesh->private_key);
+ if(mesh->invitation_addresses) {
+ list_delete_list(mesh->invitation_addresses);
+ }
+
main_config_unlock(mesh);
pthread_mutex_unlock(&mesh->mutex);
return config_sync(mesh, "current");
}
+bool meshlink_add_invitation_address(struct meshlink_handle *mesh, const char *address, const char *port) {
+ if(!mesh || !address) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
+ if(!is_valid_hostname(address)) {
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", address);
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
+ if(port && !is_valid_port(port)) {
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in port: %s\n", address);
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
+ char *combo;
+
+ if(port) {
+ if(strchr(address, ':')) {
+ xasprintf(&combo, "[%s]:%s", address, port);
+ } else {
+ xasprintf(&combo, "%s:%s", address, port);
+ }
+ } else {
+ combo = xstrdup(address);
+ }
+
+ pthread_mutex_lock(&mesh->mutex);
+
+ if(!mesh->invitation_addresses) {
+ mesh->invitation_addresses = list_alloc((list_action_t)free);
+ }
+
+ list_insert_tail(mesh->invitation_addresses, combo);
+ pthread_mutex_unlock(&mesh->mutex);
+
+ return true;
+}
+
+void meshlink_clear_invitation_addresses(struct meshlink_handle *mesh) {
+ if(!mesh) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ pthread_mutex_lock(&mesh->mutex);
+
+ if(mesh->invitation_addresses) {
+ list_delete_list(mesh->invitation_addresses);
+ mesh->invitation_addresses = NULL;
+ }
+
+ pthread_mutex_unlock(&mesh->mutex);
+}
+
bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) {
return meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL);
}
return false;
}
- bool rval = meshlink_add_address(mesh, address);
+ bool rval = meshlink_set_canonical_address(mesh, (meshlink_node_t *)mesh->self, address, NULL);
free(address);
return rval;
*/
extern bool meshlink_set_canonical_address(struct meshlink_handle *mesh, struct meshlink_node *node, const char *address, const char *port) __attribute__((__warn_unused_result__));
+/// Add an invitation address for the local node.
+/** This function adds an address for the local node, which will be used only for invitation URLs.
+ * This address is not stored permanently.
+ * Multiple addresses can be added using multiple calls to this function.
+ *
+ * \memberof meshlink_handle
+ * @param mesh A handle which represents an instance of MeshLink.
+ * @param address A nul-terminated C string containing the address, which can be either in numeric format or a hostname.
+ * @param port A nul-terminated C string containing the port, which can be either in numeric or symbolic format.
+ * If it is NULL, the listening port's number will be used.
+ *
+ * @return This function returns true if the address was added, false otherwise.
+ */
+extern bool meshlink_add_invitation_address(struct meshlink_handle *mesh, const char *address, const char *port) __attribute__((__warn_unused_result__));
+
+/// Clears all invitation address for the local node.
+/** This function removes all addresses added with meshlink_add_invitation_address().
+ *
+ * \memberof meshlink_handle
+ * @param mesh A handle which represents an instance of MeshLink.
+ */
+extern void meshlink_clear_invitation_addresses(struct meshlink_handle *mesh);
+
/// Add an Address for the local node.
/** This function adds an Address for the local node, which will be used for invitation URLs.
+ * @deprecated This function is deprecated, use meshlink_set_canonical_address() and/or meshlink_add_invitation_address().
*
* \memberof meshlink_handle
* @param mesh A handle which represents an instance of MeshLink.
*
* @return This function returns true if the address was added, false otherwise.
*/
-extern bool meshlink_add_address(struct meshlink_handle *mesh, const char *address) __attribute__((__warn_unused_result__));
+extern bool meshlink_add_address(struct meshlink_handle *mesh, const char *address) __attribute__((__warn_unused_result__, __deprecated__("use meshlink_set_canonical_address() and/or meshlink_add_invitation_address() instead")));
/// Try to discover the external address for the local node.
/** This function performs tries to discover the local node's external address
/// Try to discover the external address for the local node, and add it to its list of addresses.
/** This function is equivalent to:
*
- * meshlink_add_address(mesh, meshlink_get_external_address(mesh));
+ * meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), meshlink_get_external_address(mesh), NULL);
*
* Read the description of meshlink_get_external_address() for the limitations of this function.
*
devtool_trybind_probe
meshlink_add_address
meshlink_add_external_address
+meshlink_add_invitation_address
meshlink_blacklist
meshlink_blacklist_by_name
meshlink_channel_aio_fd_receive
meshlink_channel_open_ex
meshlink_channel_send
meshlink_channel_shutdown
+meshlink_clear_invitation_addresses
meshlink_close
meshlink_destroy
meshlink_enable_discovery
FILE *lockfile;
void *config_key;
char *external_address_url;
+ struct list_t *invitation_addresses;
// Thread management
pthread_t thread;
assert(mesh[i]);
free(path);
- assert(meshlink_add_address(mesh[i], "localhost"));
+ assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
data[i] = meshlink_export(mesh[i]);
assert(data[i]);
meshlink_enable_discovery(mesh, false);
- assert(meshlink_add_address(mesh, "localhost"));
+ assert(meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), "localhost", NULL));
char *data = meshlink_export(mesh);
assert(data);
meshlink_enable_discovery(mesh, false);
- assert(meshlink_add_address(mesh, "localhost"));
+ assert(meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), "localhost", NULL));
char *data = meshlink_export(mesh);
assert(data);
for(int i = 0; i < 3; i++) {
meshlink_enable_discovery(mesh[i], false);
- assert(meshlink_add_address(mesh[i], "localhost"));
+ assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
char *data = meshlink_export(mesh[i]);
assert(data);
// Import and export both side's data
- assert(meshlink_add_address(mesh1, "localhost"));
- assert(meshlink_add_address(mesh2, "localhost"));
+ assert(meshlink_set_canonical_address(mesh1, meshlink_get_self(mesh1), "localhost", NULL));
+ assert(meshlink_set_canonical_address(mesh2, meshlink_get_self(mesh2), "localhost", NULL));
char *data = meshlink_export(mesh1);
assert(data);
meshlink_set_node_status_cb(mesh1, status_cb);
- assert(meshlink_add_address(mesh1, "localhost"));
+ assert(meshlink_set_canonical_address(mesh1, meshlink_get_self(mesh1), "localhost", NULL));
char *baz_url = meshlink_invite(mesh1, NULL, "baz");
assert(baz_url);
assert(mesh[i]);
free(path);
- assert(meshlink_add_address(mesh[i], "localhost"));
+ assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
data[i] = meshlink_export(mesh[i]);
assert(data[i]);
assert(mesh[i]);
free(path);
- assert(meshlink_add_address(mesh[i], "localhost"));
+ assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
data[i] = meshlink_export(mesh[i]);
assert(data[i]);
void link_meshlink_pair(meshlink_handle_t *a, meshlink_handle_t *b) {
// Import and export both side's data
- assert(meshlink_add_address(a, "localhost"));
- assert(meshlink_add_address(b, "localhost"));
+ assert(meshlink_set_canonical_address(a, meshlink_get_self(a), "localhost", NULL));
+ assert(meshlink_set_canonical_address(b, meshlink_get_self(b), "localhost", NULL));
char *data = meshlink_export(a);
assert(data);