+ return mesh->invitation_key;
+}
+
+bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *node, const char *address, const char *port) {
+ if(!mesh || !node || !address) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
+ if(!is_valid_hostname(address)) {
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s", address);
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
+ if((node_t *)node != mesh->self && !port) {
+ logger(mesh, MESHLINK_DEBUG, "Missing port number!");
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+
+ }
+
+ if(port && !is_valid_port(port)) {
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in port: %s", address);
+ meshlink_errno = MESHLINK_EINVAL;
+ return false;
+ }
+
+ char *canonical_address;
+
+ if(port) {
+ xasprintf(&canonical_address, "%s %s", address, port);
+ } else {
+ canonical_address = xstrdup(address);
+ }
+
+ pthread_mutex_lock(&mesh->mutex);
+
+ node_t *n = (node_t *)node;
+ free(n->canonical_address);
+ n->canonical_address = canonical_address;
+
+ if(!node_write_config(mesh, n)) {
+ pthread_mutex_unlock(&mesh->mutex);
+ return false;
+ }
+
+ pthread_mutex_unlock(&mesh->mutex);
+
+ return config_sync(mesh, "current");