chiark / gitweb /
server/peer.c, server/tests.at: Handle NAT swapping over peer addresses.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 7 May 2012 13:37:05 +0000 (14:37 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 7 May 2012 14:32:06 +0000 (15:32 +0100)
Previously, we'd notice when a mobile peer switched address (e.g., due
to NAT) to one that wasn't currently known; but it seems that some
particularly awful NAT boxes will actually swap over the addresses
assigned to two peers on the wrong side of it.  The static hub peer will
see this as a bunch of decryption failures but not do anything about
it.  Eventually the mobile peers will notice a ping timeout and
reconnect, but this can take a while.

So, when we get a decryption failure from a mobile peer, see whether any
other mobile peers are interested in it.

server/peer.c
server/tests.at

index 02fceed5b423096972d6b8e7c43e4fae614ad54c..308ab1d1cb32c8145d4bd7d44cb4e89046a77b38 100644 (file)
@@ -215,20 +215,21 @@ static int p_decrypt(peer **pp, addr *a, size_t n,
 
   /* --- See whether any mobile peer is interested --- */
 
-  FOREACH_PEER(pp, {
-    if (pp == q || !(pp->spec.f & PSF_MOBILE)) continue;
-    if ((err = ksl_decrypt(&pp->ks, ty, bin, bout)) == KSERR_DECRYPT) {
+  p = 0;
+  FOREACH_PEER(qq, {
+    if (qq == q || !(qq->spec.f & PSF_MOBILE)) continue;
+    if ((err = ksl_decrypt(&qq->ks, ty, bin, bout)) == KSERR_DECRYPT) {
       T( trace(T_PEER, "peer: peer `%s' failed to decrypt",
-              p_name(pp)); )
+              p_name(qq)); )
        continue;
     } else {
-      p = pp;
+      p = qq;
       IF_TRACING(T_PEER, {
        if (!err)
-         trace(T_PEER, "peer: peer `%s' reports success", p_name(pp));
+         trace(T_PEER, "peer: peer `%s' reports success", p_name(qq));
        else {
          trace(T_PEER, "peer: peer `%s' reports decryption error %d",
-               p_name(pp), err);
+               p_name(qq), err);
        }
       })
       break;
@@ -239,7 +240,13 @@ static int p_decrypt(peer **pp, addr *a, size_t n,
 
 searched:
   if (!p) {
-    a_warn("PEER", "-", "unexpected-source", "?ADDR", a, A_END);
+    if (!q)
+      a_warn("PEER", "-", "unexpected-source", "?ADDR", a, A_END);
+    else {
+      a_warn("PEER", "?PEER", p, "decrypt-failed",
+            "error-code", "%d", err, A_END);
+      p_rxupdstats(q, n);
+    }
     return (-1);
   }
 
@@ -252,6 +259,7 @@ searched:
    */
 
   if (!err) {
+    *pp = p;
     if (!q) {
       T( trace(T_PEER, "peer: updating address for `%s'", p_name(p)); )
       pa = am_find(&byaddr, a, sizeof(peer_byaddr), &f); assert(!f);
index c490ff2b36d3cfa19e8ca007e61f06bfe92681e7..ab64c538ff3a47634075ea05e15af1cc39f76409 100644 (file)
@@ -38,6 +38,8 @@ m4_define([TRIPE],
      $abs_top_builddir/server/tripe -F -d. -aadmin -p0 -b127.0.0.1 -talice])
 m4_define([TRIPECTL], [$abs_top_builddir/client/tripectl -d. -aadmin])
 m4_define([USLIP], [$abs_top_builddir/uslip/tripe-uslip])
+m4_define([PKSTREAM],
+  [$abs_top_builddir/pkstream/pkstream -b127.0.0.1 -p127.0.0.1])
 
 ## Sequences.  (These are used for testing the replay protection machinery.)
 m4_define([R32], [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   dnl
@@ -228,13 +230,15 @@ m4_define([AWAIT_KXDONE], [
   TRIPECTL -d$4 WARN test POP
 ])
 
-## ESTABLISH(adir, aname, aopts, bdir, bname, bopts)
+## ESTABLISH(adir, aname, aopts, bdir, bname, bopts, [aport], [bport])
 m4_define([ESTABLISH], [
 
   ## Set up the establishment.
   AWAIT_KXDONE([$1], [$2], [$4], [$5], [
-    AT_CHECK([TRIPECTL -d$1 ADD -cork $6 $5 INET 127.0.0.1 $(cat $4/port)])
-    AT_CHECK([TRIPECTL -d$4 ADD $3 $2 INET 127.0.0.1 $(cat $1/port)])
+    AT_CHECK([TRIPECTL -d$1 ADD -cork $6 $5 INET 127.0.0.1 \
+      m4_if([$8], [], [$(cat $4/port)], [$8])])
+    AT_CHECK([TRIPECTL -d$4 ADD $3 $2 INET 127.0.0.1 \
+      m4_if([$7], [], [$(cat $1/port)], [$7])])
   ])
 
   ## Check transport pinging.
@@ -354,6 +358,71 @@ WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [
 
 AT_CLEANUP
 
+###--------------------------------------------------------------------------
+### Mobile peer tracking.
+
+AT_SETUP([peer tracking])
+AT_KEYWORDS([mobile])
+export TRIPE_SLIPIF=USLIP
+
+for p in alice bob carol; do (mkdir $p; cd $p; SETUPDIR([alpha])); done
+
+## WITH_PKSTREAM(adir, aport, bdir, bport, body)
+m4_define([WITH_PKSTREAM], [
+  echo >&2 "pkstream: $1 <--> :$2 <-pkstream-> :$4 <--> $3"
+  PKSTREAM -l$4 127.0.0.1:$4 127.0.0.1:$(cat $3/port)& pkstream_$3_$1=$!
+  sleep 1
+  PKSTREAM -c127.0.0.1:$4 127.0.0.1:$2 127.0.0.1:$(cat $1/port)&
+  pkstream_$1_$3=$!
+  set +x
+  $5
+  kill $pkstream_$3_$1 $pkstream_$1_$3
+])
+
+WITH_3TRIPES([alice], [bob], [carol], [-nslip],
+            [-talice], [-tbob], [-tcarol], [
+
+  ## We need an indirection layer between the two peers so that we can
+  ## simulate the effects of NAT remapping.  The nearest thing we have to
+  ## this is pkstream, so we may as well use that.
+  ##
+  ## alice <--> :5311 <-pkstream-> :5312 <--> bob
+  ## alice <--> :5321 <-pkstream-> :5322 <--> carol
+
+  WITH_PKSTREAM([alice], [5311], [bob], [5312], [
+    ESTABLISH([alice], [alice], [], [bob], [bob], [-mobile], [5312], [5311])
+  ])
+
+  WITH_PKSTREAM([alice], [5319], [bob], [5312], [
+    COMMS_EPING([bob], [bob], [alice], [alice])
+    COMMS_SLIP([bob], [bob], [alice], [alice])
+  ])
+
+  WITH_PKSTREAM([alice], [5321], [carol], [5322], [
+    ESTABLISH([alice], [alice], [], [carol], [carol], [-mobile],
+       [5322], [5321])
+  ])
+
+  WITH_PKSTREAM([alice], [5311], [bob], [5312], [
+  WITH_PKSTREAM([alice], [5321], [carol], [5322], [
+    COMMS_EPING([bob], [bob], [alice], [alice])
+    COMMS_EPING([carol], [carol], [alice], [alice])
+    COMMS_SLIP([bob], [bob], [alice], [alice])
+    COMMS_SLIP([carol], [carol], [alice], [alice])
+  ])])
+
+  WITH_PKSTREAM([alice], [5321], [bob], [5312], [
+  WITH_PKSTREAM([alice], [5311], [carol], [5322], [
+    COMMS_EPING([bob], [bob], [alice], [alice])
+    COMMS_EPING([carol], [carol], [alice], [alice])
+    COMMS_SLIP([bob], [bob], [alice], [alice])
+    COMMS_SLIP([carol], [carol], [alice], [alice])
+  ])])
+  wait
+])
+
+AT_CLEANUP
+
 ###--------------------------------------------------------------------------
 ### Services.