Beispiel #1
0
bool key_changed_h(connection_t *c) {
	char name[MAX_STRING_SIZE];
	node_t *n;

	if(sscanf(c->buffer, "%*d %*x " MAX_STRING, name) != 1) {
		logger(LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
			   c->name, c->hostname);
		return false;
	}

	if(!check_id(name)) {
		logger(LOG_ERR, "Got bad %s from %s (%s): %s", "KEY_CHANGED", c->name, c->hostname, "invalid name");
		return false;
	}

	if(seen_request(c->buffer))
		return true;

	n = lookup_node(name);

	if(!n) {
		logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
			   "KEY_CHANGED", c->name, c->hostname, name);
		return true;
	}

	n->status.validkey = false;
	n->last_req_key = 0;

	/* Tell the others */

	if(!tunnelserver)
		forward_request(c);

	return true;
}
Beispiel #2
0
bool add_edge_h(connection_t *c) {
	edge_t *e;
	node_t *from, *to;
	char from_name[MAX_STRING_SIZE];
	char to_name[MAX_STRING_SIZE];
	char to_address[MAX_STRING_SIZE];
	char to_port[MAX_STRING_SIZE];
	sockaddr_t address;
	uint32_t options;
	int weight;

	if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d",
			  from_name, to_name, to_address, to_port, &options, &weight) != 6) {
		logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
			   c->hostname);
		return false;
	}

	/* Check if names are valid */

	if(!check_id(from_name) || !check_id(to_name)) {
		logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "invalid name");
		return false;
	}

	if(seen_request(c->buffer))
		return true;

	/* Lookup nodes */

	from = lookup_node(from_name);
	to = lookup_node(to_name);

	if(tunnelserver &&
	   from != myself && from != c->node &&
	   to != myself && to != c->node) {
		/* ignore indirect edge registrations for tunnelserver */
		ifdebug(PROTOCOL) logger(LOG_WARNING,
		   "Ignoring indirect %s from %s (%s)",
		   "ADD_EDGE", c->name, c->hostname);
		return true;
	}

	if(!from) {
		from = new_node();
		from->name = xstrdup(from_name);
		node_add(from);
	}

	if(!to) {
		to = new_node();
		to->name = xstrdup(to_name);
		node_add(to);
	}


	/* Convert addresses */

	address = str2sockaddr(to_address, to_port);

	/* Check if edge already exists */

	e = lookup_edge(from, to);

	if(e) {
		if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
			if(from == myself) {
				ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
						   "ADD_EDGE", c->name, c->hostname);
				send_add_edge(c, e);
				return true;
			} else {
				ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not match existing entry",
						   "ADD_EDGE", c->name, c->hostname);
				edge_del(e);
				graph();
			}
		} else
			return true;
	} else if(from == myself) {
		ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist",
				   "ADD_EDGE", c->name, c->hostname);
		contradicting_add_edge++;
		e = new_edge();
		e->from = from;
		e->to = to;
		send_del_edge(c, e);
		free_edge(e);
		return true;
	}

	e = new_edge();
	e->from = from;
	e->to = to;
	e->address = address;
	e->options = options;
	e->weight = weight;
	edge_add(e);

	/* Tell the rest about the new edge */

	if(!tunnelserver)
		forward_request(c);

	/* Run MST before or after we tell the rest? */

	graph();

	return true;
}
Beispiel #3
0
bool del_edge_h(connection_t *c) {
	edge_t *e;
	char from_name[MAX_STRING_SIZE];
	char to_name[MAX_STRING_SIZE];
	node_t *from, *to;

	if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) {
		logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name,
			   c->hostname);
		return false;
	}

	/* Check if names are valid */

	if(!check_id(from_name) || !check_id(to_name)) {
		logger(LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name,
			   c->hostname, "invalid name");
		return false;
	}

	if(seen_request(c->buffer))
		return true;

	/* Lookup nodes */

	from = lookup_node(from_name);
	to = lookup_node(to_name);

	if(tunnelserver &&
	   from != myself && from != c->node &&
	   to != myself && to != c->node) {
		/* ignore indirect edge registrations for tunnelserver */
		ifdebug(PROTOCOL) logger(LOG_WARNING,
		   "Ignoring indirect %s from %s (%s)",
		   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	if(!from) {
		ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree",
				   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	if(!to) {
		ifdebug(PROTOCOL) logger(LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree",
				   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	/* Check if edge exists */

	e = lookup_edge(from, to);

	if(!e) {
		ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree",
				   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	if(e->from == myself) {
		ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself",
				   "DEL_EDGE", c->name, c->hostname);
		contradicting_del_edge++;
		send_add_edge(c, e);	/* Send back a correction */
		return true;
	}

	/* Tell the rest about the deleted edge */

	if(!tunnelserver)
		forward_request(c);

	/* Delete the edge */

	edge_del(e);

	/* Run MST before or after we tell the rest? */

	graph();

	/* If the node is not reachable anymore but we remember it had an edge to us, clean it up */

	if(!to->status.reachable) {
		e = lookup_edge(to, myself);
		if(e) {
			if(!tunnelserver)
				send_del_edge(broadcast, e);
			edge_del(e);
		}
	}

	return true;
}
Beispiel #4
0
bool add_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
	edge_t *e;
	node_t *from, *to;
	char from_name[MAX_STRING_SIZE];
	int from_devclass;
	char to_name[MAX_STRING_SIZE];
	char to_address[MAX_STRING_SIZE];
	char to_port[MAX_STRING_SIZE];
	int to_devclass;
	sockaddr_t address;
	uint32_t options;
	int weight;

	if(sscanf(request, "%*d %*x "MAX_STRING" %d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %x %d",
			  from_name, &from_devclass, to_name, to_address, to_port, &to_devclass, &options, &weight) != 8) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
			   c->hostname);
		return false;
	}

	/* Check if names are valid */

	if(!check_id(from_name) || !check_id(to_name)) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "invalid name");
		return false;
	}

	// Check if devclasses are valid

	if(from_devclass < 0 || from_devclass > _DEV_CLASS_MAX) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "from devclass invalid");
		return false;
	}

	if(to_devclass < 0 || to_devclass > _DEV_CLASS_MAX) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "to devclass invalid");
		return false;
	}

	if(seen_request(mesh, request))
		return true;

	/* Lookup nodes */

	from = lookup_node(mesh, from_name);
	to = lookup_node(mesh, to_name);

	if(!from) {
		from = new_node();
		from->status.blacklisted = mesh->default_blacklist;
		from->name = xstrdup(from_name);
		node_add(mesh, from);
	}

	from->devclass = from_devclass;
	node_write_devclass(mesh, from);

	if(!to) {
		to = new_node();
		to->status.blacklisted = mesh->default_blacklist;
		to->name = xstrdup(to_name);
		node_add(mesh, to);
	}

	to->devclass = to_devclass;
	node_write_devclass(mesh, to);

	/* Convert addresses */

	address = str2sockaddr(to_address, to_port);

	/* Check if edge already exists */

	e = lookup_edge(from, to);

	if(e) {
		if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
			if(from == mesh->self) {
				logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
						   "ADD_EDGE", c->name, c->hostname);
				send_add_edge(mesh, c, e);
				return true;
			} else {
				logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) which does not match existing entry",
						   "ADD_EDGE", c->name, c->hostname);
				edge_del(mesh, e);
				graph(mesh);
			}
		} else
			return true;
	} else if(from == mesh->self) {
		logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself which does not exist",
				   "ADD_EDGE", c->name, c->hostname);
		mesh->contradicting_add_edge++;
		e = new_edge();
		e->from = from;
		e->to = to;
		send_del_edge(mesh, c, e);
		free_edge(e);
		return true;
	}

	e = new_edge();
	e->from = from;
	e->to = to;
	e->address = address;
	e->options = options;
	e->weight = weight;
	edge_add(mesh, e);

	/* Tell the rest about the new edge */

	forward_request(mesh, c, request);

	/* Run MST before or after we tell the rest? */

	graph(mesh);

	return true;
}
Beispiel #5
0
bool del_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
	edge_t *e;
	char from_name[MAX_STRING_SIZE];
	char to_name[MAX_STRING_SIZE];
	node_t *from, *to;

	if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name,
			   c->hostname);
		return false;
	}

	/* Check if names are valid */

	if(!check_id(from_name) || !check_id(to_name)) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name,
			   c->hostname, "invalid name");
		return false;
	}

	if(seen_request(mesh, request))
		return true;

	/* Lookup nodes */

	from = lookup_node(mesh, from_name);
	to = lookup_node(mesh, to_name);

	if(!from) {
		logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) which does not appear in the edge tree",
				   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	if(!to) {
		logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) which does not appear in the edge tree",
				   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	/* Check if edge exists */

	e = lookup_edge(from, to);

	if(!e) {
		logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) which does not appear in the edge tree",
				   "DEL_EDGE", c->name, c->hostname);
		return true;
	}

	if(e->from == mesh->self) {
		logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself",
				   "DEL_EDGE", c->name, c->hostname);
		mesh->contradicting_del_edge++;
		send_add_edge(mesh, c, e);    /* Send back a correction */
		return true;
	}

	/* Tell the rest about the deleted edge */

	forward_request(mesh, c, request);

	/* Delete the edge */

	edge_del(mesh, e);

	/* Run MST before or after we tell the rest? */

	graph(mesh);

	/* If the node is not reachable anymore but we remember it had an edge to us, clean it up */

	if(!to->status.reachable) {
		e = lookup_edge(to, mesh->self);
		if(e) {
			send_del_edge(mesh, mesh->everyone, e);
			edge_del(mesh, e);
		}
	}

	return true;
}