- fd_set fset;
- struct timeval tv;
- int r;
-cp
- last_ping_time = time(NULL);
-
- for(;;)
- {
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- prune_conn_list();
- build_fdset(&fset);
-
- if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)
- {
- if(errno == EINTR) /* because of alarm */
- continue;
- syslog(LOG_ERR, "Error while waiting for input: %m");
- return;
- }
-
- if(r == 0 || last_ping_time + timeout < time(NULL))
- /* Timeout... hm... something might be wrong. */
- {
- check_dead_connections();
- send_broadcast_ping();
- continue;
+ struct timeval tv;
+ int r;
+ time_t last_ping_check;
+ tevent_t *event;
+ struct event timeout;
+ struct event sighup_event;
+
+ cp();
+
+ signal_set(&sighup_event, SIGHUP, sighup_handler, NULL);
+ signal_add(&sighup_event, NULL);
+
+ last_ping_check = now;
+
+ srand(now);
+
+ running = true;
+
+ while(running) {
+ now = time(NULL);
+
+ // tv.tv_sec = 1 + (rand() & 7); /* Approx. 5 seconds, randomized to prevent global synchronisation effects */
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ /* XXX: libevent transition: old timeout code in this loop */
+ timeout_set(&timeout, dummy, NULL);
+ timeout_add(&timeout, &tv);
+
+ r = build_fdset();
+ if(r < 0) {
+ logger(LOG_ERR, _("Error building fdset: %s"), strerror(errno));
+ cp_trace();
+ dump_connections();
+ return 1;
+ }
+
+ r = event_loop(EVLOOP_ONCE);
+ now = time(NULL);
+ if(r < 0) {
+ logger(LOG_ERR, _("Error while waiting for input: %s"),
+ strerror(errno));
+ cp_trace();
+ dump_connections();
+ return 1;
+ }
+
+ /* XXX: more libevent transition */
+ timeout_del(&timeout);
+
+ if(do_purge) {
+ purge();
+ do_purge = false;
+ }
+
+ /* Let's check if everybody is still alive */
+
+ if(last_ping_check + pingtimeout < now) {
+ check_dead_connections();
+ last_ping_check = now;
+
+ if(routing_mode == RMODE_SWITCH)
+ age_subnets();
+
+ age_past_requests();
+
+ /* Should we regenerate our key? */
+
+ if(keyexpires < now) {
+ ifdebug(STATUS) logger(LOG_INFO, _("Regenerating symmetric key"));
+
+ RAND_pseudo_bytes((unsigned char *)myself->key, myself->keylength);
+ if(myself->cipher)
+ EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, (unsigned char *)myself->key, (unsigned char *)myself->key + myself->cipher->key_len);
+ send_key_changed(broadcast, myself);
+ keyexpires = now + keylifetime;
+ }
+ }
+
+
+ while((event = get_expired_tevent())) {
+ event->handler(event->data);
+ free_tevent(event);
+ }
+
+ if(sigalrm) {
+ logger(LOG_INFO, _("Flushing event queue"));
+ flush_tevents();
+ sigalrm = false;
+ }
+