+static void check_network_activity(fd_set *readset, fd_set *writeset) {
+ connection_t *c;
+ avl_node_t *node;
+ int result, i;
+ socklen_t len = sizeof(result);
+ vpn_packet_t packet;
+ static int errors = 0;
+
+ /* check input from kernel */
+ if(device_fd >= 0 && FD_ISSET(device_fd, readset)) {
+ if(devops.read(&packet)) {
+ if(packet.len) {
+ errors = 0;
+ packet.priority = 0;
+ route(myself, &packet);
+ }
+ } else {
+ usleep(errors * 50000);
+ errors++;
+
+ if(errors > 10) {
+ logger(LOG_ERR, "Too many errors from %s, exiting!", device);
+ running = false;
+ }
+ }
+ }
+
+ /* check meta connections */
+ for(node = connection_tree->head; node; node = node->next) {
+ c = node->data;
+
+ if(c->status.remove) {
+ continue;
+ }
+
+ if(FD_ISSET(c->socket, writeset)) {
+ if(c->status.connecting) {
+ c->status.connecting = false;
+ getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len);
+
+ if(!result) {
+ finish_connecting(c);
+ } else {
+ ifdebug(CONNECTIONS) logger(LOG_DEBUG,
+ "Error while connecting to %s (%s): %s",
+ c->name, c->hostname, sockstrerror(result));
+ closesocket(c->socket);
+ do_outgoing_connection(c);
+ continue;
+ }
+ }
+
+ if(!flush_meta(c)) {
+ terminate_connection(c, c->status.active);
+ continue;
+ }
+ }
+
+ if(FD_ISSET(c->socket, readset)) {
+ if(!receive_meta(c)) {
+ c->status.tarpit = true;
+ terminate_connection(c, c->status.active);
+ continue;
+ }
+ }
+ }
+
+ for(i = 0; i < listen_sockets; i++) {
+ if(FD_ISSET(listen_socket[i].udp, readset)) {
+ handle_incoming_vpn_data(i);
+ }
+
+ if(FD_ISSET(listen_socket[i].tcp, readset)) {
+ handle_new_meta_connection(listen_socket[i].tcp);
+ }
+ }