+void handle_meta_connection_data(meshlink_handle_t *mesh, connection_t *c) {
+ if(!receive_meta(mesh, c)) {
+ terminate_connection(mesh, c, c->status.active);
+ return;
+ }
+}
+
+void retry(meshlink_handle_t *mesh) {
+ /* Reset the reconnection timers for all outgoing connections */
+ for list_each(outgoing_t, outgoing, mesh->outgoings) {
+ outgoing->timeout = 0;
+
+ if(outgoing->ev.cb) {
+ timeout_set(&mesh->loop, &outgoing->ev, &(struct timespec) {
+ 0, 0
+ });
+ }
+ }
+
+ /* For active connections, check if their addresses are still valid.
+ * If yes, reset their ping timers, otherwise terminate them. */
+ for list_each(connection_t, c, mesh->connections) {
+ if(!c->status.active) {
+ continue;
+ }
+
+ if(!c->status.pinged) {
+ c->last_ping_time = -3600;
+ }
+
+ sockaddr_t sa;
+ socklen_t salen = sizeof(sa);
+
+ if(getsockname(c->socket, &sa.sa, &salen)) {
+ continue;
+ }
+
+ switch(sa.sa.sa_family) {
+ case AF_INET:
+ sa.in.sin_port = 0;
+ break;
+
+ case AF_INET6:
+ sa.in6.sin6_port = 0;
+ break;
+
+ default:
+ continue;
+ }
+
+ int sock = socket(sa.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+
+ if(sock == -1) {
+ continue;
+ }
+
+ if(bind(sock, &sa.sa, salen) && errno == EADDRNOTAVAIL) {
+ logger(mesh, MESHLINK_DEBUG, "Local address for connection to %s no longer valid, terminating", c->name);
+ terminate_connection(mesh, c, c->status.active);
+ }
+
+ closesocket(sock);
+ }
+
+ /* Kick the ping timeout handler */
+ if(mesh->pingtimer.cb) {
+ timeout_set(&mesh->loop, &mesh->pingtimer, &(struct timespec) {
+ 0, 0
+ });
+ }
+}
+
+/*
+ this is where it all happens...
+*/
+void main_loop(meshlink_handle_t *mesh) {
+ timeout_add(&mesh->loop, &mesh->pingtimer, timeout_handler, &mesh->pingtimer, &(struct timespec) {
+ 1, prng(mesh, TIMER_FUDGE)
+ });
+ timeout_add(&mesh->loop, &mesh->periodictimer, periodic_handler, &mesh->periodictimer, &(struct timespec) {
+ 0, 0
+ });
+
+ //Add signal handler
+ mesh->datafromapp.signum = 0;
+ signal_add(&mesh->loop, &mesh->datafromapp, meshlink_send_from_queue, mesh, mesh->datafromapp.signum);
+
+ if(!event_loop_run(&mesh->loop, mesh)) {
+ logger(mesh, MESHLINK_ERROR, "Error while waiting for input: %s", strerror(errno));
+ call_error_cb(mesh, MESHLINK_ENETWORK);
+ }
+
+ signal_del(&mesh->loop, &mesh->datafromapp);
+ timeout_del(&mesh->loop, &mesh->periodictimer);
+ timeout_del(&mesh->loop, &mesh->pingtimer);