server/keyexch.c: Abstract out the common message-handling behaviour.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 4 Sep 2017 00:02:02 +0000 (01:02 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 16 Jun 2018 18:13:41 +0000 (19:13 +0100)
Add new functions for resetting the key-exchange state on reception, and
updating the statistics on send and receive.

server/keyexch.c

index f1d0a56..6b77122 100644 (file)
@@ -373,6 +373,66 @@ static void rs_time(retry *rs, struct timeval *tv, const struct timeval *now)
 
 static void rs_reset(retry *rs) { rs->t = 0; }
 
+/* --- @notice_message@ --- *
+ *
+ * Arguments:  @keyexch *kx@ = pointer to key-exchange block
+ *
+ * Returns:    Zero if OK; @-1@ if the public key is in a bad state.
+ *
+ * Use:                Updates the key-exchange state following a received message.
+ *             Specifically, if there's no currently active key-exchange in
+ *             progress, and we're not in the cooling-off period, then
+ *             commence a new one; reset the retry timers; and if we're
+ *             corked then pop the cork so that we can reply.
+ */
+
+static int checkpub(keyexch *kx);
+static void stop(keyexch *kx);
+static void start(keyexch *kx, time_t now);
+
+static int notice_message(keyexch *kx)
+{
+  struct timeval now, tv;
+
+  gettimeofday(&now, 0);
+  rs_reset(&kx->rs);
+  if (kx->f & KXF_CORK) {
+    start(kx, now.tv_sec);
+    rs_time(&kx->rs, &tv, &now);
+    settimer(kx, &tv);
+    a_notify("KXSTART", "?PEER", kx->p, A_END);
+  }
+  if (checkpub(kx)) return (-1);
+  if (!VALIDP(kx, now.tv_sec)) {
+    stop(kx);
+    start(kx, now.tv_sec);
+  }
+  return (0);
+}
+
+/* --- @update_stats_tx@, @update_stats_rx@ --- *
+ *
+ * Arguments:  @keyexch *kx@ = pointer to key-exchange block
+ *             @int ok@ = nonzero if the message was valid (for @rx@)
+ *             @size_t sz@ = size of sent message
+ *
+ * Returns:    ---
+ *
+ * Use:                Records that a key-exchange message was sent to, or received
+ *             from, the peer.
+ */
+
+static void update_stats_tx(keyexch *kx, size_t sz)
+  { stats *st = p_stats(kx->p); st->n_kxout++; st->sz_kxout += sz; }
+
+static void update_stats_rx(keyexch *kx, int ok, size_t sz)
+{
+  stats *st = p_stats(kx->p);
+
+  if (!ok) st->n_reject++;
+  else { st->n_kxin++; st->sz_kxin += sz; }
+}
+
 /*----- Challenge management ----------------------------------------------*/
 
 /* --- Notes on challenge management --- *
@@ -527,7 +587,6 @@ static void kxc_timer(struct timeval *tv, void *v)
 
 static void kxc_answer(keyexch *kx, kxchal *kxc)
 {
-  stats *st = p_stats(kx->p);
   buf *b = p_txstart(kx->p, MSG_KEYEXCH | KX_REPLY);
   const dhgrp *g = kx->kpriv->grp;
   struct timeval tv;
@@ -545,8 +604,7 @@ static void kxc_answer(keyexch *kx, kxchal *kxc)
   /* --- Update the statistics --- */
 
   if (BOK(b)) {
-    st->n_kxout++;
-    st->sz_kxout += BLEN(b);
+    update_stats_tx(kx, BLEN(b));
     p_txend(kx->p);
   }
 
@@ -574,7 +632,6 @@ static void kxc_answer(keyexch *kx, kxchal *kxc)
 
 static int doprechallenge(keyexch *kx, buf *b)
 {
-  stats *st = p_stats(kx->p);
   const dhgrp *g = kx->kpriv->grp;
   dhge *C = 0;
   ghash *h;
@@ -603,8 +660,7 @@ static int doprechallenge(keyexch *kx, buf *b)
   hashge(h, g, C);
   sendchallenge(kx, b, C, GH_DONE(h, 0));
   GH_DESTROY(h);
-  st->n_kxout++;
-  st->sz_kxout += BLEN(b);
+  update_stats_tx(kx, BLEN(b));
   p_txend(kx->p);
 
   /* --- Done --- */
@@ -823,7 +879,6 @@ static void resend(keyexch *kx)
 {
   kxchal *kxc;
   buf bb;
-  stats *st = p_stats(kx->p);
   struct timeval tv;
   const dhgrp *g = kx->kpriv->grp;
   buf *b;
@@ -863,8 +918,7 @@ static void resend(keyexch *kx)
   }
 
   if (BOK(b)) {
-    st->n_kxout++;
-    st->sz_kxout += BLEN(b);
+    update_stats_tx(kx, BLEN(b));
     p_txend(kx->p);
   }
 
@@ -1277,27 +1331,11 @@ void kx_start(keyexch *kx, int forcep)
 
 void kx_message(keyexch *kx, unsigned msg, buf *b)
 {
-  struct timeval now, tv;
-  stats *st = p_stats(kx->p);
   size_t sz = BSZ(b);
   int rc;
 
-  gettimeofday(&now, 0);
-  rs_reset(&kx->rs);
-  if (kx->f & KXF_CORK) {
-    start(kx, now.tv_sec);
-    rs_time(&kx->rs, &tv, &now);
-    settimer(kx, &tv);
-    a_notify("KXSTART", "?PEER", kx->p, A_END);
-  }
-
-  if (checkpub(kx))
-    return;
+  if (notice_message(kx)) return;
 
-  if (!VALIDP(kx, now.tv_sec)) {
-    stop(kx);
-    start(kx, now.tv_sec);
-  }
   T( trace(T_KEYEXCH, "keyexch: processing %s packet from `%s'",
           msg < KX_NMSG ? pkname[msg] : "unknown", p_name(kx->p)); )
 
@@ -1323,12 +1361,7 @@ void kx_message(keyexch *kx, unsigned msg, buf *b)
       break;
   }
 
-  if (rc)
-    st->n_reject++;
-  else {
-    st->n_kxin++;
-    st->sz_kxin += sz;
-  }
+  update_stats_rx(kx, !rc, sz);
 }
 
 /* --- @kx_free@ --- *