chiark / gitweb /
server: Add a peer without sending key-exchange packets.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 18 Mar 2008 20:21:11 +0000 (20:21 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Tue, 18 Mar 2008 20:21:11 +0000 (20:21 +0000)
When contacting a passive peer, the initial pre-challenge will cause the
peer to complain about an unsolicited packet.  The -cork option to ADD
makes the new peer silent until contacted by the (presumably awoken)
passive peer.

doc/tripe-admin.5.in
server/admin.c
server/keyexch.c
server/peer.c
server/tripe.h

index 968400e..caaf255 100644 (file)
@@ -287,6 +287,10 @@ be contacted.  The following options are recognised.
 Run the command in the background, using the given
 .IR tag .
 .TP
+.B "\-cork"
+Don't send an immediate challenge to the peer; instead, wait until it
+sends us something before responding.
+.TP
 .BI "\-keepalive " time
 Send a no-op packet if we've not sent a packet to the peer in the last
 .I time
index 135a589..73c7107 100644 (file)
@@ -1210,6 +1210,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
   add->peer.name = 0;
   add->peer.t_ka = 0;
   add->peer.tops = tun_default;
+  add->peer.kxf = 0;
 
   /* --- Parse options --- */
 
@@ -1229,6 +1230,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[])
       }
     })
     OPTTIME("-keepalive", t, { add->peer.t_ka = t; })
+    OPT("-cork", { add->peer.kxf |= KXF_CORK; })
   });
 
   /* --- Make sure someone's not got there already --- */
index df70774..e705272 100644 (file)
@@ -1065,7 +1065,7 @@ static void start(keyexch *kx, time_t now)
 
   assert(kx->f & KXF_DEAD);
 
-  kx->f &= ~KXF_DEAD;
+  kx->f &= ~(KXF_DEAD | KXF_CORK);
   kx->nr = 0;
   kx->alpha = mprand_range(MP_NEW, gg->r, &rand_global, 0);
   kx->c = G_CREATE(gg); G_EXP(gg, kx->c, gg->g, kx->alpha);
@@ -1161,6 +1161,12 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
   size_t sz = BSZ(b);
   int rc;
 
+  if (kx->f & KXF_CORK) {
+    start(kx, now);
+    settimer(kx, now + T_RETRY);
+    a_notify("KXSTART", A_END);
+  }
+
   if (checkpub(kx))
     return;
 
@@ -1168,7 +1174,6 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
     stop(kx);
     start(kx, now);
   }
-
   T( trace(T_KEYEXCH, "keyexch: processing %s packet from `%s'",
           msg < KX_NMSG ? pkname[msg] : "unknown", p_name(kx->p)); )
 
@@ -1248,6 +1253,7 @@ void kx_newkeys(keyexch *kx)
  * Arguments:  @keyexch *kx@ = pointer to key exchange context
  *             @peer *p@ = pointer to peer context
  *             @keyset **ks@ = pointer to keyset list
+ *             @unsigned f@ = various useful flags
  *
  * Returns:    Zero if OK, nonzero if it failed.
  *
@@ -1256,7 +1262,7 @@ void kx_newkeys(keyexch *kx)
  *             exchange.
  */
 
-int kx_init(keyexch *kx, peer *p, keyset **ks)
+int kx_init(keyexch *kx, peer *p, keyset **ks, unsigned f)
 {
   kx->ks = ks;
   kx->p = p;
@@ -1265,10 +1271,12 @@ int kx_init(keyexch *kx, peer *p, keyset **ks)
     G_DESTROY(gg, kx->kpub);
     return (-1);
   }
-  kx->f = KXF_DEAD | KXF_PUBKEY;
-  start(kx, time(0));
-  resend(kx);
-  /* Don't notify here: the ADD message hasn't gone out yet. */
+  kx->f = KXF_DEAD | KXF_PUBKEY | f;
+  if (!(kx->f & KXF_CORK)) {
+    start(kx, time(0));
+    resend(kx);
+    /* Don't notify here: the ADD message hasn't gone out yet. */
+  }
   return (0);
 }
 
index 99d4447..675ceff 100644 (file)
@@ -706,7 +706,7 @@ peer *p_create(peerspec *spec)
   if ((p->t = spec->tops->create(p, &p->ifname)) == 0)
     goto tidy_0;
   p_setkatimer(p);
-  if (kx_init(&p->kx, p, &p->ks))
+  if (kx_init(&p->kx, p, &p->ks, p->spec.kxf))
     goto tidy_1;
   p->next = peers;
   if (peers)
@@ -717,8 +717,10 @@ peer *p_create(peerspec *spec)
            "%s", p->ifname,
            "?ADDR", &p->spec.sa,
            A_END);
-  a_notify("KXSTART", "?PEER", p, A_END);
+  if (!(p->spec.kxf & KXF_CORK)) {
+    a_notify("KXSTART", "?PEER", p, A_END);
     /* Couldn't tell anyone before */
+  }
   return (p);
 
 tidy_1:
index 44b4e04..9c9653e 100644 (file)
@@ -249,6 +249,7 @@ typedef struct keyexch {
 #define KXF_TIMER 1u                   /* Waiting for a timer to go off */
 #define KXF_DEAD 2u                    /* The key-exchanger isn't up */
 #define KXF_PUBKEY 4u                  /* Key exchanger has a public key */
+#define KXF_CORK 8u                    /* Don't send anything yet */
 
 enum {
   KXS_DEAD,                            /* Uninitialized state (magical) */
@@ -310,6 +311,7 @@ typedef struct peerspec {
   unsigned long t_ka;                  /* Keep alive interval */
   addr sa;                             /* Socket address to speak to */
   size_t sasz;                         /* Socket address size */
+  unsigned kxf;                                /* Key exchange flags to set */
 } peerspec;
 
 typedef struct peer {
@@ -576,6 +578,7 @@ extern void kx_newkeys(keyexch */*kx*/);
  * Arguments:  @keyexch *kx@ = pointer to key exchange context
  *             @peer *p@ = pointer to peer context
  *             @keyset **ks@ = pointer to keyset list
+ *             @unsigned f@ = various useful flags
  *
  * Returns:    Zero if OK, nonzero if it failed.
  *
@@ -584,7 +587,8 @@ extern void kx_newkeys(keyexch */*kx*/);
  *             exchange.
  */
 
-extern int kx_init(keyexch */*kx*/, peer */*p*/, keyset **/*ks*/);
+extern int kx_init(keyexch */*kx*/, peer */*p*/,
+                  keyset **/*ks*/, unsigned /*f*/);
 
 /*----- Keysets and symmetric cryptography --------------------------------*/