}
char *name = packmsg_get_str_dup(&in);
- packmsg_skip_element(&in); /* submesh */
+ char *submesh_name = packmsg_get_str_dup(&in);
dev_class_t devclass = packmsg_get_int32(&in);
uint32_t count = packmsg_get_array(&in);
- if(!name) {
- logger(mesh, MESHLINK_DEBUG, "No Name found in invitation!\n");
+ if(!name || !check_id(name)) {
+ logger(mesh, MESHLINK_DEBUG, "No valid Name found in invitation!\n");
+ free(name);
+ free(submesh_name);
return false;
}
- if(!check_id(name)) {
- logger(mesh, MESHLINK_DEBUG, "Invalid Name found in invitation: %s!\n", name);
+ if(!submesh_name || (strcmp(submesh_name, CORE_MESH) && !check_id(submesh_name))) {
+ logger(mesh, MESHLINK_DEBUG, "No valid Submesh found in invitation!\n");
free(name);
+ free(submesh_name);
return false;
}
if(!count) {
logger(mesh, MESHLINK_ERROR, "Incomplete invitation file!\n");
free(name);
+ free(submesh_name);
return false;
}
free(mesh->self->name);
mesh->name = name;
mesh->self->name = xstrdup(name);
+ mesh->self->submesh = strcmp(submesh_name, CORE_MESH) ? lookup_or_create_submesh(mesh, submesh_name) : NULL;
+ free(submesh_name);
mesh->self->devclass = devclass == DEV_CLASS_UNKNOWN ? mesh->devclass : devclass;
// Initialize configuration directory
}
if(!is_valid_hostname(address)) {
- logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", 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\n", address);
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in port: %s", address);
meshlink_errno = MESHLINK_EINVAL;
return false;
}
packmsg_add_int32(&out, mesh->self->devclass);
packmsg_add_bool(&out, mesh->self->status.blacklisted);
packmsg_add_bin(&out, ecdsa_get_public_key(mesh->private_key), 32);
- packmsg_add_str(&out, mesh->self->canonical_address ? mesh->self->canonical_address : "");
+
+ if(mesh->self->canonical_address && !strchr(mesh->self->canonical_address, ' ')) {
+ char *canonical_address = NULL;
+ xasprintf(&canonical_address, "%s %s", mesh->self->canonical_address, mesh->myport);
+ packmsg_add_str(&out, canonical_address);
+ free(canonical_address);
+ } else {
+ packmsg_add_str(&out, mesh->self->canonical_address ? mesh->self->canonical_address : "");
+ }
uint32_t count = 0;
}
}
+static void channel_retransmit(struct utcp_connection *utcp_connection) {
+ node_t *n = utcp_connection->utcp->priv;
+ meshlink_handle_t *mesh = n->mesh;
+
+ if(n->mtuprobes == 31) {
+ timeout_set(&mesh->loop, &n->mtutimeout, &(struct timespec) {
+ 0, 0
+ });
+ }
+}
+
static ssize_t channel_send(struct utcp *utcp, const void *data, size_t len) {
node_t *n = utcp->priv;
if(!n->utcp && n != mesh->self) {
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
utcp_set_mtu(n->utcp, n->mtu - sizeof(meshlink_packethdr_t));
+ utcp_set_retransmit_cb(n->utcp, channel_retransmit);
}
}
if(!n->utcp) {
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
utcp_set_mtu(n->utcp, n->mtu - sizeof(meshlink_packethdr_t));
+ utcp_set_retransmit_cb(n->utcp, channel_retransmit);
mesh->receive_cb = channel_receive;
if(!n->utcp) {
if(!n->utcp) {
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
utcp_set_mtu(n->utcp, n->mtu - sizeof(meshlink_packethdr_t));
+ utcp_set_retransmit_cb(n->utcp, channel_retransmit);
}
utcp_set_user_timeout(n->utcp, timeout);
if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) {
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
utcp_set_mtu(n->utcp, n->mtu - sizeof(meshlink_packethdr_t));
+ utcp_set_retransmit_cb(n->utcp, channel_retransmit);
}
if(mesh->node_status_cb) {