+/* --- @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; }
+}
+