server/: Build a proper interface for handling tunnel classes.
[tripe] / server / tripe.c
index b4f4cc9..637400a 100644 (file)
@@ -38,6 +38,7 @@ static sel_timer it;
 
 static unsigned iv_nreasons = 0;
 static struct timeval iv_next = { 0, 0 };
+static int lpdone = 0;
 
 /*----- The interval timer ------------------------------------------------*/
 
@@ -121,6 +122,17 @@ void lp_init(void)
   sig_init(&sel);
 }
 
+/* --- @lp_end@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Requests an exit from the main loop.
+ */
+
+void lp_end(void) { lpdone = 1; }
+
 /* --- @lp_run@ --- *
  *
  * Arguments:  ---
@@ -136,6 +148,7 @@ int lp_run(void)
 
   for (;;) {
     a_preselect();
+    if (lpdone) break;
     if (!sel_select(&sel)) nerr = 0;
     else if (errno != EINTR && errno != EAGAIN) {
       a_warn("SERVER", "select-error", "?ERRNO", A_END);
@@ -146,9 +159,25 @@ int lp_run(void)
       }
     }
   }
+  lpdone = 0;
   return (0);
 }
 
+/*----- Tunnel table ------------------------------------------------------*/
+
+static const tunnel_ops *tunnels[] = {
+#ifdef TUN_LINUX
+  &tun_linux,
+#endif
+#ifdef TUN_BSD
+  &tun_bsd,
+#endif
+#ifdef TUN_UNET
+  &tun_unet,
+#endif
+  &tun_slip,
+};
+
 /*----- Main code ---------------------------------------------------------*/
 
 /* --- @main@ --- *
@@ -215,6 +244,7 @@ int main(int argc, char *argv[])
   const char *p;
   const char *bindhost = 0, *bindsvc = STR(TRIPE_PORT);
   struct addrinfo aihint = { 0 }, *ailist;
+  const tunnel_ops *dflt = 0;
   unsigned f = 0;
   int i;
   int err;
@@ -233,7 +263,6 @@ int main(int argc, char *argv[])
     dir = p;
   if ((p = getenv("TRIPESOCK")) != 0)
     csock = p;
-  tun_default = tunnels[0];
   aihint.ai_family = AF_UNSPEC;
 
   for (;;) {
@@ -309,13 +338,11 @@ int main(int argc, char *argv[])
        break;
       case 'n': {
        int i;
-       for (i = 0;; i++) {
-         if (!tunnels[i])
-           die(EXIT_FAILURE, "unknown tunnel `%s'", optarg);
+       for (i = 0; i < N(tunnels); i++)
          if (mystrieq(optarg, tunnels[i]->name))
-           break;
-       }
-       tun_default = tunnels[i];
+           { dflt = tunnels[i]; goto found_tun; }
+       die(EXIT_FAILURE, "unknown tunnel `%s'", optarg);
+      found_tun:;
       } break;
       case 'd':
        dir = optarg;
@@ -345,7 +372,7 @@ int main(int argc, char *argv[])
 #endif
       case '0': {
        int i;
-       for (i = 0; tunnels[i]; i++)
+       for (i = 0; i < N(tunnels); i++)
          puts(tunnels[i]->name);
        exit(0);
       } break;
@@ -392,8 +419,9 @@ int main(int argc, char *argv[])
   }
 
   p_init();
-  for (i = 0; tunnels[i]; i++)
-    tunnels[i]->init();
+  for (i = 0; i < N(tunnels); i++)
+    p_addtun(tunnels[i]);
+  if (dflt) p_setdflttun(dflt);
   p_bind(ailist); freeaddrinfo(ailist);
 
   for (i = 0; tunnels[i]; i++) {
@@ -418,9 +446,13 @@ int main(int argc, char *argv[])
     a_switcherr();
   }
 
-  iv_addreason();
-
   lp_run();
+
+  p_destroyall();
+  p_unbind();
+  a_unlisten();
+  km_clear();
+  ps_quit();
   return (0);
 }