server/: Record port number with UDP socket, rather than querying.
[tripe] / server / admin.c
index 8a3e62c..85e8c23 100644 (file)
@@ -560,7 +560,7 @@ void a_quit(void)
 {
   close(sock.fd);
   unlink(sockname);
-  FOREACH_PEER(p, { p_destroy(p); });
+  FOREACH_PEER(p, { p_destroy(p, 1); });
   ps_quit();
   exit(0);
 }
@@ -1233,7 +1233,7 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
     { fam = "ANY"; af = AF_UNSPEC; i++; }
   else for (j = 0; j < NADDRFAM; j++) {
     if (mystrieq(av[i], aftab[j].name)) {
-      if (udpsock[j].fd < 0) {
+      if (udpsock[j].sf.fd < 0) {
        a_fail(a, "disabled-address-family", "%s", aftab[j].name, A_END);
        goto fail;
       }
@@ -1286,7 +1286,7 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
   aihint.ai_flags = AI_NUMERICHOST;
   if (!getaddrinfo(av[i], 0, &aihint, &ailist)) {
     for (ai = ailist; ai; ai = ai->ai_next) {
-      if ((j = afix(ai->ai_family)) >= 0 && udpsock[j].fd >= 0)
+      if ((j = afix(ai->ai_family)) >= 0 && udpsock[j].sf.fd >= 0)
        break;
     }
     if (!ai) {
@@ -1315,7 +1315,7 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
 #ifdef HAVE_LIBADNS
   qf = adns_qf_search;
   for (j = 0; j < NADDRFAM; j++) {
-    if ((af == AF_UNSPEC || af == aftab[i].af) && udpsock[j].fd >= 0)
+    if ((af == AF_UNSPEC || af == aftab[i].af) && udpsock[j].sf.fd >= 0)
       qf |= aftab[j].qf;
   }
   if ((err = adns_submit(ads, r->addr, adns_r_addr, qf, r, &r->q)) != 0) {
@@ -1331,7 +1331,7 @@ static void a_resolve(admin *a, admin_resop *r, const char *tag,
     a_bgfail(&r->bg, "resolve-error", "%s", r->addr, A_END);
     goto fail_release;
   }
-  if (udpsock[AFIX_INET].fd < 0) {
+  if (udpsock[AFIX_INET].sf.fd < 0) {
     a_bgfail(&r->bg, "disabled-address-family", "INET", A_END);
     goto fail_release;
   }
@@ -1421,6 +1421,7 @@ static void a_doadd(admin_resop *r, int rc)
 
   if (add->peer.tag) xfree(add->peer.tag);
   if (add->peer.privtag) xfree(add->peer.privtag);
+  if (add->peer.knock) xfree(add->peer.knock);
   xfree(add->peer.name);
 }
 
@@ -1446,6 +1447,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
   add->peer.name = 0;
   add->peer.tag = 0;
   add->peer.privtag = 0;
+  add->peer.knock = 0;
   add->peer.t_ka = 0;
   add->peer.tops = tun_default;
   add->peer.f = 0;
@@ -1469,15 +1471,21 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
     })
     OPTTIME("-keepalive", t, { add->peer.t_ka = t; })
     OPT("-cork", { add->peer.f |= KXF_CORK; })
+    OPT("-ephemeral", { add->peer.f |= PSF_EPHEM; })
     OPTARG("-key", arg, {
       if (add->peer.tag) xfree(add->peer.tag);
       add->peer.tag = xstrdup(arg);
     })
-    OPT("-mobile", { add->peer.f |= PSF_MOBILE; })
+    OPT("-mobile", { add->peer.f |= PSF_MOBILE | PSF_EPHEM; })
     OPTARG("-priv", arg, {
       if (add->peer.privtag) xfree(add->peer.privtag);
       add->peer.privtag = xstrdup(arg);
     })
+    OPTARG("-knock", arg, {
+      if (add->peer.knock) xfree(add->peer.knock);
+      add->peer.knock = xstrdup(arg);
+      add->peer.f |= PSF_EPHEM;
+    })
   });
 
   /* --- Make sure someone's not got there already --- */
@@ -1504,6 +1512,7 @@ fail:
   if (add->peer.name) xfree(add->peer.name);
   if (add->peer.tag) xfree(add->peer.tag);
   if (add->peer.privtag) xfree(add->peer.privtag);
+  if (add->peer.knock) xfree(add->peer.knock);
   xfree(add);
   return;
 }
@@ -1861,16 +1870,16 @@ static void acmd_port(admin *a, unsigned ac, char *av[])
     a_fail(a, "unknown-address-family", "%s", av[0], A_END);
     return;
   found:
-    if (udpsock[i].fd < 0) {
+    if (udpsock[i].sf.fd < 0) {
       a_fail(a, "disabled-address-family", "%s", aftab[i].name, A_END);
       return;
     }
   } else {
     for (i = 0; i < NADDRFAM; i++)
-      if (udpsock[i].fd >= 0) goto found;
+      if (udpsock[i].sf.fd >= 0) goto found;
     abort();
   }
-  a_info(a, "%u", p_port(i), A_END);
+  a_info(a, "%u", udpsock[i].port, A_END);
   a_ok(a);
 }
 
@@ -1982,7 +1991,7 @@ static void acmd_getchal(admin *a, unsigned ac, char *av[])
   buf b;
 
   buf_init(&b, buf_i, PKBUFSZ);
-  c_new(&b);
+  c_new(0, 0, &b);
   a_info(a, "?B64", BBASE(&b), (size_t)BLEN(&b), A_END);
   a_ok(a);
 }
@@ -1999,7 +2008,7 @@ static void acmd_checkchal(admin *a, unsigned ac, char *av[])
     a_fail(a, "bad-base64", "%s", codec_strerror(err), A_END);
   else {
     buf_init(&b, d.buf, d.len);
-    if (c_check(&b) || BBAD(&b) || BLEFT(&b))
+    if (c_check(0, 0, &b) || BBAD(&b) || BLEFT(&b))
       a_fail(a, "invalid-challenge", A_END);
     else
       a_ok(a);
@@ -2049,6 +2058,7 @@ static void acmd_peerinfo(admin *a, unsigned ac, char *av[])
   if ((p = a_findpeer(a, av[0])) != 0) {
     ps = p_spec(p);
     a_info(a, "tunnel=%s", ps->tops->name, A_END);
+    if (ps->knock) a_info(a, "knock=%s", ps->knock, A_END);
     a_info(a, "key=%s", p_tag(p),
           "current-key=%s", p->kx.kpub->tag, A_END);
     if ((ptag = p_privtag(p)) == 0) ptag = "(default)";
@@ -2057,6 +2067,7 @@ static void acmd_peerinfo(admin *a, unsigned ac, char *av[])
     a_info(a, "keepalive=%lu", ps->t_ka, A_END);
     a_info(a, "corked=%s", BOOL(p->kx.f&KXF_CORK),
           "mobile=%s", BOOL(ps->f&PSF_MOBILE),
+          "ephemeral=%s", BOOL(ps->f&PSF_EPHEM),
           A_END);
     a_ok(a);
   }
@@ -2112,7 +2123,7 @@ static void acmd_kill(admin *a, unsigned ac, char *av[])
   peer *p;
 
   if ((p = a_findpeer(a, av[0])) != 0) {
-    p_destroy(p);
+    p_destroy(p, 1);
     a_ok(a);
   }
 }