+static void timeout_handler(event_loop_t *loop, void *data) {
+ meshlink_handle_t *mesh = loop->data;
+ logger(mesh, MESHLINK_DEBUG, "timeout_handler()");
+
+ for list_each(connection_t, c, mesh->connections) {
+ // Also make sure that if outstanding key requests for the UDP counterpart of a connection has timed out, we restart it.
+ if(c->node) {
+ if(c->node->status.waitingforkey && c->node->last_req_key + mesh->pingtimeout <= mesh->loop.now.tv_sec)
+ send_req_key(mesh, c->node);
+ }
+ if(c->last_ping_time + mesh->pingtimeout <= mesh->loop.now.tv_sec) {
+ if(c->status.active) {
+ if(c->status.pinged) {
+ logger(mesh, MESHLINK_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)mesh->loop.now.tv_sec - c->last_ping_time);
+ } else if(c->last_ping_time + mesh->pinginterval <= mesh->loop.now.tv_sec) {
+ send_ping(mesh, c);
+ continue;
+ } else {
+ continue;
+ }
+ } else {
+ if(c->status.connecting)
+ logger(mesh, MESHLINK_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
+ else
+ logger(mesh, MESHLINK_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
+ }
+ terminate_connection(mesh, c, c->status.active);
+ }
+ }
+
+ timeout_set(&mesh->loop, data, &(struct timeval){mesh->pingtimeout, rand() % 100000});
+}
+
+// devclass asc, last_successfull_connection desc
+static int node_compare_devclass_asc_lsc_desc(const void *a, const void *b)