-int ack_h(connection_t *c)
-{
- char hisport[MAX_STRING_SIZE];
- char *hisaddress, *dummy;
- int weight;
- long int options;
- node_t *n;
-cp
- if(sscanf(c->buffer, "%*d "MAX_STRING" %d %lx", hisport, &weight, &options) != 3)
- {
- syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ACK", c->name, c->hostname);
- return -1;
- }
-
- /* Check if we already have a node_t for him */
-
- n = lookup_node(c->name);
-
- if(!n)
- {
- n = new_node();
- n->name = xstrdup(c->name);
- node_add(n);
- }
- else
- {
- if(n->connection)
- {
- /* Oh dear, we already have a connection to this node. */
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_DEBUG, _("Established a second connection with %s (%s), closing old connection"), n->name, n->hostname);
- terminate_connection(n->connection, 0);
- }
- }
-
- n->connection = c;
- c->node = n;
- c->options |= options;
-
- /* Activate this connection */
-
- c->allow_request = ALL;
- c->status.active = 1;
-
- if(debug_lvl >= DEBUG_CONNECTIONS)
- syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), c->name, c->hostname);
-
- /* Send him everything we know */
-
- send_everything(c);
-
- /* Create an edge_t for this connection */
-
- c->edge = new_edge();
-cp
- c->edge->from = myself;
- c->edge->to = n;
- sockaddr2str(&c->address, &hisaddress, &dummy);
- c->edge->address = str2sockaddr(hisaddress, hisport);
- free(hisaddress);
- free(dummy);
- c->edge->weight = (weight + c->estimated_weight) / 2;
- c->edge->connection = c;
- c->edge->options = c->options;
-cp
- edge_add(c->edge);
-
-cp
- /* Notify everyone of the new edge */
-
- send_add_edge(broadcast, c->edge);
-
- /* Run MST and SSSP algorithms */
-
- graph();
-cp
- return 0;
+bool ack_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
+ char hisport[MAX_STRING_SIZE];
+ char *hisaddress;
+ int devclass;
+ uint32_t options;
+ node_t *n;
+
+ if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &devclass, &options) != 3) {
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s", "ACK", c->name);
+ return false;
+ }
+
+ if(devclass < 0 || devclass > _DEV_CLASS_MAX) {
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s: %s", "ACK", c->name, "devclass invalid");
+ return false;
+ }
+
+ /* Check if we already have a node_t for him */
+
+ n = lookup_node(mesh, c->name);
+
+ if(!n) {
+ n = new_node();
+ n->name = xstrdup(c->name);
+ node_add(mesh, n);
+ } else {
+ if(n->connection) {
+ /* Oh dear, we already have a connection to this node. */
+ logger(mesh, MESHLINK_DEBUG, "Established a second connection with %s, closing old connection", n->connection->name);
+
+ if(n->connection->outgoing) {
+ if(c->outgoing)
+ logger(mesh, MESHLINK_WARNING, "Two outgoing connections to the same node!");
+ else
+ c->outgoing = n->connection->outgoing;
+
+ n->connection->outgoing = NULL;
+ }
+
+ terminate_connection(mesh, n->connection, false);
+ /* Run graph algorithm to keep things in sync */
+ graph(mesh);
+ }
+ }
+
+ n->devclass = devclass;
+ node_write_devclass(mesh, n);
+
+ n->last_successfull_connection = time(NULL);
+
+ n->connection = c;
+ c->node = n;
+ if(!(c->options & options & OPTION_PMTU_DISCOVERY)) {
+ c->options &= ~OPTION_PMTU_DISCOVERY;
+ options &= ~OPTION_PMTU_DISCOVERY;
+ }
+ c->options |= options;
+
+ /* Activate this connection */
+
+ c->allow_request = ALL;
+ c->status.active = true;
+
+ logger(mesh, MESHLINK_INFO, "Connection with %s activated", c->name);
+
+ /* Send him everything we know */
+
+ send_everything(mesh, c);
+
+ /* Create an edge_t for this connection */
+
+ assert(devclass >= 0 && devclass <= _DEV_CLASS_MAX);
+
+ c->edge = new_edge();
+ c->edge->from = mesh->self;
+ c->edge->to = n;
+ sockaddr2str(&c->address, &hisaddress, NULL);
+ c->edge->address = str2sockaddr(hisaddress, hisport);
+ free(hisaddress);
+ c->edge->weight = dev_class_traits[devclass].edge_weight;
+ c->edge->connection = c;
+ c->edge->options = c->options;
+
+ edge_add(mesh, c->edge);
+
+ /* Notify everyone of the new edge */
+
+ send_add_edge(mesh, mesh->everyone, c->edge);
+
+ /* Run MST and SSSP algorithms */
+
+ graph(mesh);
+
+ return true;