Browse Source

Return anyhow::Error from Iface_DEFUN functions rather than an integer error type

Caleb James DeLisle 2 years ago
parent
commit
9a9ffd57d5
64 changed files with 414 additions and 372 deletions
  1. 3 3
      admin/Admin.c
  2. 2 2
      admin/angel/InterfaceWaiter.c
  3. 6 5
      client/AdminClient.c
  4. 2 2
      crypto/CryptoAuth.c
  5. 1 0
      crypto/CryptoAuth.h
  6. 3 3
      crypto/test/CryptoAuthFuzz.c
  7. 9 6
      crypto/test/CryptoAuth_test.c
  8. 1 1
      crypto/test/CryptoAuth_unit_test.c
  9. 10 10
      crypto/test/TestCa.c
  10. 1 0
      crypto/test/TestCa.h
  11. 15 15
      dht/Pathfinder.c
  12. 2 2
      interface/ASynchronizer.c
  13. 1 1
      interface/ETHInterface_darwin.c
  14. 1 1
      interface/ETHInterface_linux.c
  15. 6 6
      interface/FramingIface.c
  16. 2 2
      interface/Iface.c
  17. 9 9
      interface/Iface.h
  18. 8 7
      interface/UDPInterface.c
  19. 3 2
      interface/addressable/AddrIfaceMuxer.c
  20. 3 3
      interface/addressable/PacketHeaderToUDPAddrIface.c
  21. 1 1
      interface/test/FramingIface_fuzz_test.c
  22. 1 1
      interface/test/RustIface_test.c
  23. 3 3
      interface/tuntap/AndroidWrapper.c
  24. 2 2
      interface/tuntap/BSDMessageTypeWrapper.c
  25. 3 3
      interface/tuntap/SocketWrapper.c
  26. 3 3
      interface/tuntap/TAPWrapper.c
  27. 1 1
      interface/tuntap/test/BSDMessageTypeWrapper_test.c
  28. 2 1
      interface/tuntap/test/TUNInterface_ipv4_root_test.c
  29. 4 3
      interface/tuntap/test/TUNTools.c
  30. 2 2
      interface/tuntap/windows/TAPInterface.c
  31. 18 18
      net/ControlHandler.c
  32. 11 10
      net/EventEmitter.c
  33. 20 19
      net/InterfaceController.c
  34. 17 17
      net/SessionManager.c
  35. 15 15
      net/SwitchPinger.c
  36. 6 5
      net/TUNAdapter.c
  37. 10 9
      net/UpperDistributor.c
  38. 17 8
      node_build/builder.js
  39. 3 0
      rust/cjdns_sys/RTypes.h
  40. 2 1
      rust/cjdns_sys/RTypesPrefix.h
  41. 6 0
      rust/cjdns_sys/Rffi.h
  42. 2 1
      rust/cjdns_sys/RffiPrefix.h
  43. 33 58
      rust/cjdns_sys/src/cffi.rs
  44. 1 1
      rust/cjdns_sys/src/crypto/crypto_auth.rs
  45. 17 15
      rust/cjdns_sys/src/external/interface/cif.rs
  46. 40 0
      rust/cjdns_sys/src/rffi.rs
  47. 5 0
      rust/cjdns_sys/src/rtypes.rs
  48. 10 9
      subnode/MsgCore.c
  49. 1 1
      subnode/MsgCore.h
  50. 5 4
      subnode/PingResponder.c
  51. 12 12
      subnode/SubnodePathfinder.c
  52. 1 1
      subnode/SupernodeHunter.c
  53. 4 4
      switch/SwitchCore.c
  54. 2 2
      test/Beacon_test.c
  55. 1 1
      test/Main_fuzz_test.c
  56. 22 22
      tunnel/IpTunnel.c
  57. 2 2
      tunnel/test/IpTunnel_test.c
  58. 2 1
      util/events/libuv/FakeNetwork.c
  59. 2 2
      util/events/libuv/Pipe.c
  60. 1 1
      util/events/libuv/PipeServer.c
  61. 4 4
      util/events/libuv/UDPAddrIface.c
  62. 2 2
      util/test/Process_test.c
  63. 1 1
      util/test/Seccomp_test.c
  64. 9 26
      wire/Error.h

+ 3 - 3
admin/Admin.c

@@ -113,7 +113,7 @@ struct Admin_pvt
     Identity
 };
 
-static struct Error_s sendMessage(
+static struct RTypes_Error_t* sendMessage(
     struct Message* message, struct Sockaddr* dest, struct Admin_pvt* admin)
 {
     // stack overflow when used with admin logger.
@@ -122,7 +122,7 @@ static struct Error_s sendMessage(
     return Iface_send(&admin->iface, message);
 }
 
-static struct Error_s sendBenc(Dict* message,
+static struct RTypes_Error_t* sendBenc(Dict* message,
                                struct Sockaddr* dest,
                                struct Allocator* alloc,
                                struct Admin_pvt* admin,
@@ -476,7 +476,7 @@ static Iface_DEFUN receiveMessage(struct Message* message, struct Iface* iface)
     Allocator_free(alloc);
     // We don't return errors here because the caller can't make use of them
     // instead we reply with anything which went wrong.
-    return Error(NONE);
+    return NULL;
 }
 
 void Admin_registerFunctionWithArgCount(char* name,

+ 2 - 2
admin/angel/InterfaceWaiter.c

@@ -44,13 +44,13 @@ static void timeout(void* vcontext)
 static Iface_DEFUN receiveMessage(struct Message* message, struct Iface* iface)
 {
     struct Context* ctx = Identity_check((struct Context*) iface);
-    if (ctx->messageReceived) { return Error(NONE); }
+    if (ctx->messageReceived) { return NULL; }
     ctx->message = Message_clone(message, ctx->alloc);
 
     Timeout_clearTimeout(ctx->timeout);
     EventBase_endLoop(ctx->eventBase);
 
-    return Error(NONE);
+    return NULL;
 }
 
 struct Message* InterfaceWaiter_waitForData(struct Iface* iface,

+ 6 - 5
client/AdminClient.c

@@ -23,6 +23,7 @@
 #include "util/events/Timeout.h"
 #include "util/Identity.h"
 #include "wire/Message.h"
+#include "wire/Error.h"
 
 #include <sodium/crypto_hash_sha256.h>
 
@@ -124,7 +125,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* addrIface)
                  Sockaddr_print(&source.addr, Message_getAlloc(msg)),
                  Sockaddr_print(ctx->targetAddr, Message_getAlloc(msg)));
         // The UDP interface can't make use of an error but we'll inform anyway
-        return Error(INVALID);
+        return Error(msg, "INVALID source addr");
     }
 
     // we don't yet know with which message this data belongs,
@@ -134,17 +135,17 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* addrIface)
     int origLen = Message_getLength(msg);
     Dict* d = NULL;
     const char* err = BencMessageReader_readNoExcept(msg, alloc, &d);
-    if (err) { return Error(INVALID); }
+    if (err) { return Error(msg, "Error decoding benc: %s", err); }
     Er_assert(Message_eshift(msg, origLen));
 
     String* txid = Dict_getStringC(d, "txid");
-    if (!txid || txid->len != 8) { return Error(INVALID); }
+    if (!txid || txid->len != 8) { return Error(msg, "INVALID missing or wrong size txid"); }
 
     // look up the result
     uint32_t handle = ~0u;
     Hex_decode((uint8_t*)&handle, 4, txid->bytes, 8);
     int idx = Map_OfRequestByHandle_indexForHandle(handle, &ctx->outstandingRequests);
-    if (idx < 0) { return Error(INVALID); }
+    if (idx < 0) { return Error(msg, "INVALID no such handle"); }
 
     struct Request* req = ctx->outstandingRequests.values[idx];
 
@@ -159,7 +160,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* addrIface)
     Bits_memset(req->res.messageBytes, 0, AdminClient_MAX_MESSAGE_SIZE);
     Bits_memcpy(req->res.messageBytes, msg->msgbytes, len);
     done(req, AdminClient_Error_NONE);
-    return Error(NONE);
+    return NULL;
 }
 
 static int requestOnFree(struct Allocator_OnFreeJob* job)

+ 2 - 2
crypto/CryptoAuth.c

@@ -1059,7 +1059,7 @@ static Iface_DEFUN plaintextMsg(struct Message* msg, struct Iface* iface)
     struct CryptoAuth_Session_pvt* sess =
         Identity_containerOf(iface, struct CryptoAuth_Session_pvt, pub.plaintext);
     if (encryptPacket(sess, msg)) {
-        return Error(INTERNAL);
+        return Error(msg, "INTERNAL");
     }
     return Iface_next(&sess->pub.ciphertext, msg);
 }
@@ -1069,7 +1069,7 @@ static Iface_DEFUN ciphertextMsg(struct Message* msg, struct Iface* iface)
     struct CryptoAuth_Session_pvt* sess =
         Identity_containerOf(iface, struct CryptoAuth_Session_pvt, pub.ciphertext);
     if (Message_getLength(msg) < 16) {
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
     uint8_t firstSixteen[16];
     Bits_memcpy(firstSixteen, msg->msgbytes, 16);

+ 1 - 0
crypto/CryptoAuth.h

@@ -16,6 +16,7 @@
 #define CryptoAuth_H
 
 #include "rust/cjdns_sys/RTypes.h"
+#include "interface/Iface.h"
 #include "benc/String.h"
 #include "crypto/random/Random.h"
 #include "crypto/ReplayProtector.h"

+ 3 - 3
crypto/test/CryptoAuthFuzz.c

@@ -266,7 +266,7 @@ static Iface_DEFUN afterEncrypt(struct Message* msg, struct Iface* iface)
 {
     struct Node* n = Identity_containerOf(iface, struct Node, ciphertext);
     sendFrom(n->ctx, n, msg);
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* iface)
@@ -283,7 +283,7 @@ static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* iface)
         if (to == &to->ctx->nodeB) {
             // 1/10 chance the node decides not to reply.
             if (maybe(to->ctx, 10)) {
-                return Error(NONE);
+                return NULL;
             }
             //Assert_true(!TestCa_encrypt(to->session, msg));
             to->sendCounter++;
@@ -295,7 +295,7 @@ static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* iface)
             to->ctx->successMessageCount++;
         }
     }
-    return Error(NONE);
+    return NULL;
 }
 
 void* CryptoAuthFuzz_init(struct Allocator* alloc, struct Random* rand, enum TestCa_Config cfg)

+ 9 - 6
crypto/test/CryptoAuth_test.c

@@ -14,6 +14,7 @@
  */
 #include "crypto/random/Random.h"
 #include "crypto/Ca.h"
+#include "crypto/CryptoAuth.h"
 #include "benc/String.h"
 #include "memory/MallocAllocator.h"
 #include "util/events/EventBase.h"
@@ -82,7 +83,7 @@ static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* if1)
     n->expectErr = CryptoAuth_DecryptErr_NONE;
     if (!n->expectPlaintext) {
         if (e) {
-            return Error(NONE);
+            return NULL;
         }
         Assert_failure("expected <NULL>, got [%s](%d)\n", msg->msgbytes, Message_getLength(msg));
     }
@@ -93,12 +94,12 @@ static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* if1)
             n->expectPlaintext, (int)CString_strlen(n->expectPlaintext), msg->msgbytes, Message_getLength(msg));
     }
     n->expectPlaintext = NULL;
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN afterEncrypt(struct Message* msg, struct Iface* if1)
 {
-    return Error(NONE);
+    return NULL;
 }
 
 static struct Context* init(uint8_t* privateKeyA,
@@ -163,9 +164,11 @@ static struct Message* encryptMsg(struct Context* ctx,
     CString_strcpy(msg->msgbytes, x);
     Er_assert(Message_truncate(msg, CString_strlen(x)));
     //msg->bytes[Message_getLength(msg)] = 0;
-    struct Error_s e = Iface_send(&n->plaintext, msg);
-    printf("%x\n", e.e);
-    Assert_true(e.e == Error_NONE);
+    struct RTypes_Error_t* e = Iface_send(&n->plaintext, msg);
+    if (e) {
+        printf("%s\n", Rffi_printError(e, ctx->alloc));
+        Assert_failure("error was not null");
+    }
     Assert_true(Message_getLength(msg) > ((int)CString_strlen(x) + 4));
     return msg;
 }

+ 1 - 1
crypto/test/CryptoAuth_unit_test.c

@@ -56,7 +56,7 @@ struct Context
 
 static Iface_DEFUN doNothingSuccessfully(struct Message* msg, struct Iface* iface)
 {
-    return Error(NONE);
+    return NULL;
 }
 
 static struct Context* setUp(uint8_t* myPrivateKey,

+ 10 - 10
crypto/test/TestCa.c

@@ -126,7 +126,7 @@ static Iface_DEFUN messagePlaintext(Message_t *msg, struct Iface* iface)
             msg = NULL;
         }
     }
-    struct Error_s i1 = Error(NONE);
+    struct RTypes_Error_t* i1 = NULL;
     if (sess->s) {
         int flag = sess->s2 ? STOP : PASS;
         Er_assert(Message_epushAd(msg, &flag, sizeof flag));
@@ -140,9 +140,9 @@ static Iface_DEFUN messagePlaintext(Message_t *msg, struct Iface* iface)
         int flag = sess->s ? VERIFY : PASS;
         Er_assert(Message_epushAd(m2, &flag, sizeof flag));
         printf("Send2 [%d]\n", flag);
-        struct Error_s i2 = Iface_send(&sess->s2Plain, m2);
+        struct RTypes_Error_t* i2 = Iface_send(&sess->s2Plain, m2);
         if (sess->s) {
-            Assert_true(i2.e == i1.e);
+            Assert_true((i2 == NULL) == (i1 == NULL));
         }
         printf("Send2 done\n");
         return i2;
@@ -162,7 +162,7 @@ static Iface_DEFUN messageCiphertext(Message_t *msg, struct Iface* iface)
             msg = NULL;
         }
     }
-    struct Error_s i1 = Error(NONE);
+    struct RTypes_Error_t* i1 = NULL;
     if (sess->s) {
         int flag = sess->s2 ? STOP : PASS;
         Er_assert(Message_epushAd(msg, &flag, sizeof flag));
@@ -176,9 +176,9 @@ static Iface_DEFUN messageCiphertext(Message_t *msg, struct Iface* iface)
             flag = VERIFY;
         }
         Er_assert(Message_epushAd(m2, &flag, sizeof flag));
-        struct Error_s i2 = Iface_send(&sess->s2Cipher, m2);
+        struct RTypes_Error_t* i2 = Iface_send(&sess->s2Cipher, m2);
         if (sess->s) {
-            Assert_true(i2.e == i1.e);
+            Assert_true((i2 == NULL) == (i1 == NULL));
         }
         return i2;
     }
@@ -219,28 +219,28 @@ static bool check(Message_t *msg, TestCa_Session_pvt_t* sess)
 static Iface_DEFUN sPlainRecv(Message_t *msg, struct Iface* iface)
 {
     TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, sPlain);
-    if (check(msg, sess)) { return Error(NONE); }
+    if (check(msg, sess)) { return NULL; }
     return Iface_next(&sess->pub.plaintext, msg);
 }
 
 static Iface_DEFUN s2PlainRecv(Message_t *msg, struct Iface* iface)
 {
     TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, s2Plain);
-    if (check(msg, sess)) { return Error(NONE); }
+    if (check(msg, sess)) { return NULL; }
     return Iface_next(&sess->pub.plaintext, msg);
 }
 
 static Iface_DEFUN sCipherRecv(Message_t *msg, struct Iface* iface)
 {
     TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, sCipher);
-    if (check(msg, sess)) { return Error(NONE); }
+    if (check(msg, sess)) { return NULL; }
     return Iface_next(&sess->pub.ciphertext, msg);
 }
 
 static Iface_DEFUN s2CipherRecv(Message_t *msg, struct Iface* iface)
 {
     TestCa_Session_pvt_t* sess = Identity_containerOf(iface, TestCa_Session_pvt_t, s2Cipher);
-    if (check(msg, sess)) { return Error(NONE); }
+    if (check(msg, sess)) { return NULL; }
     return Iface_next(&sess->pub.ciphertext, msg);
 }
 

+ 1 - 0
crypto/test/TestCa.h

@@ -17,6 +17,7 @@
 
 #include "benc/String.h"
 #include "rust/cjdns_sys/RTypes.h"
+#include "interface/Iface.h"
 #include "util/events/EventBase.h"
 #include "crypto/random/Random.h"
 #include "util/Linker.h"

+ 15 - 15
dht/Pathfinder.c

@@ -243,7 +243,7 @@ static Iface_DEFUN connected(struct Pathfinder_pvt* pf, struct Message* msg)
 
     pf->state = Pathfinder_pvt_state_RUNNING;
 
-    return Error(NONE);
+    return NULL;
 }
 
 static void addressForNode(struct Address* addrOut, struct Message* msg)
@@ -268,7 +268,7 @@ static Iface_DEFUN switchErr(struct Message* msg, struct Pathfinder_pvt* pf)
     uint8_t pathStr[20];
     AddrTools_printPath(pathStr, path);
     int err = Endian_bigEndianToHost32(switchErr.ctrlErr.errorType_be);
-    Log_debug(pf->log, "switch err from [%s] type [%s][%d]", pathStr, Error_strerror(err), err);
+    Log_debug(pf->log, "switch err from [%s] type [%d]", pathStr, err);
 
     struct Node_Link* link = NodeStore_linkForPath(pf->nodeStore, path);
     uint8_t nodeAddr[16];
@@ -283,7 +283,7 @@ static Iface_DEFUN switchErr(struct Message* msg, struct Pathfinder_pvt* pf)
         SearchRunner_search(nodeAddr, 20, 3, pf->searchRunner, pf->alloc);
     }
 
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN searchReq(struct Message* msg, struct Pathfinder_pvt* pf)
@@ -292,7 +292,7 @@ static Iface_DEFUN searchReq(struct Message* msg, struct Pathfinder_pvt* pf)
     Er_assert(Message_epop(msg, addr, 16));
     Er_assert(Message_epop32be(msg));
     uint32_t version = Er_assert(Message_epop32be(msg));
-    if (version && version >= 20) { return Error(NONE); }
+    if (version && version >= 20) { return NULL; }
     Assert_true(!Message_getLength(msg));
     uint8_t printedAddr[40];
     AddrTools_printIp(printedAddr, addr);
@@ -304,7 +304,7 @@ static Iface_DEFUN searchReq(struct Message* msg, struct Pathfinder_pvt* pf)
     } else {
         SearchRunner_search(addr, 20, 3, pf->searchRunner, pf->alloc);
     }
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN peer(struct Message* msg, struct Pathfinder_pvt* pf)
@@ -321,7 +321,7 @@ static Iface_DEFUN peer(struct Message* msg, struct Pathfinder_pvt* pf)
         && Node_getBestParent(link->child)->parent->address.path == 1
         && Node_getBestParent(link->child)->cannonicalLabel == addr.path)
     {
-        return Error(NONE);
+        return NULL;
     }
     //RumorMill_addNode(pf->rumorMill, &addr);
     Router_sendGetPeers(pf->router, &addr, 0, 0, pf->alloc);
@@ -355,7 +355,7 @@ static Iface_DEFUN session(struct Message* msg, struct Pathfinder_pvt* pf)
         SearchRunner_search(addr.ip6.bytes, 20, 3, pf->searchRunner, pf->alloc);
     }*/
 
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN sessionEnded(struct Message* msg, struct Pathfinder_pvt* pf)
@@ -364,7 +364,7 @@ static Iface_DEFUN sessionEnded(struct Message* msg, struct Pathfinder_pvt* pf)
     addressForNode(&addr, msg);
     String* str = Address_toString(&addr, Message_getAlloc(msg));
     Log_debug(pf->log, "Session ended [%s]", str->bytes);
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN discoveredPath(struct Message* msg, struct Pathfinder_pvt* pf)
@@ -373,22 +373,22 @@ static Iface_DEFUN discoveredPath(struct Message* msg, struct Pathfinder_pvt* pf
     addressForNode(&addr, msg);
 
     // We're somehow aware of this path (even if it's unused)
-    if (NodeStore_linkForPath(pf->nodeStore, addr.path)) { return Error(NONE); }
+    if (NodeStore_linkForPath(pf->nodeStore, addr.path)) { return NULL; }
 
     // If we don't already care about the destination, then don't do anything.
     struct Node_Two* nn = NodeStore_nodeForAddr(pf->nodeStore, addr.ip6.bytes);
-    if (!nn) { return Error(NONE); }
+    if (!nn) { return NULL; }
 
     // Our best path is "shorter" (label bits which is somewhat representitive of hop count)
     // basically this is just to dampen the flood to the RM because otherwise it prevents Janitor
     // from getting any actual work done.
-    if (nn->address.path < addr.path) { return Error(NONE); }
+    if (nn->address.path < addr.path) { return NULL; }
 
     addr.protocolVersion = nn->address.protocolVersion;
 
     Log_debug(pf->log, "Discovered path [%s]", Address_toString(&addr, Message_getAlloc(msg))->bytes);
     RumorMill_addNode(pf->rumorMill, &addr);
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN handlePing(struct Message* msg, struct Pathfinder_pvt* pf)
@@ -401,7 +401,7 @@ static Iface_DEFUN handlePing(struct Message* msg, struct Pathfinder_pvt* pf)
 static Iface_DEFUN handlePong(struct Message* msg, struct Pathfinder_pvt* pf)
 {
     Log_debug(pf->log, "Received pong");
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf)
@@ -433,7 +433,7 @@ static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf)
         return Iface_next(&pf->pub.eventIf, msg);
     }
 
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventIf)
@@ -459,7 +459,7 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventI
         case PFChan_Core_PONG: return handlePong(msg, pf);
         case PFChan_Core_UNSETUP_SESSION:
         case PFChan_Core_LINK_STATE:
-        case PFChan_Core_CTRL_MSG: return Error(NONE);
+        case PFChan_Core_CTRL_MSG: return NULL;
         default:;
     }
     Assert_failure("unexpected event [%d]", ev);

+ 2 - 2
interface/ASynchronizer.c

@@ -101,7 +101,7 @@ static Iface_DEFUN fromA(struct Message* msg, struct Iface* ifA)
     Allocator_adopt(as->cycleAlloc, Message_getAlloc(msg));
     ArrayList_Messages_add(as->msgsToB, msg);
     checkTimeout(as);
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN fromB(struct Message* msg, struct Iface* ifB)
@@ -112,7 +112,7 @@ static Iface_DEFUN fromB(struct Message* msg, struct Iface* ifB)
     Allocator_adopt(as->cycleAlloc, Message_getAlloc(msg));
     ArrayList_Messages_add(as->msgsToA, msg);
     checkTimeout(as);
-    return Error(NONE);
+    return NULL;
 }
 
 struct ASynchronizer* ASynchronizer_new(struct Allocator* alloc,

+ 1 - 1
interface/ETHInterface_darwin.c

@@ -109,7 +109,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
     if (Message_getLength(msg) != write(ctx->socket, msg->msgbytes, Message_getLength(msg))) {
         Log_debug(ctx->logger, "Error writing to eth device [%s]", strerror(errno));
     }
-    return Error(NONE);
+    return NULL;
 }
 
 static void handleEvent2(struct ETHInterface_pvt* context,

+ 1 - 1
interface/ETHInterface_linux.c

@@ -129,7 +129,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
     };
     Er_assert(Message_epush(msg, &hdr, ETHInterface_Header_SIZE));
     sendMessageInternal(msg, &addr, ctx);
-    return Error(NONE);
+    return NULL;
 }
 
 static void handleEvent2(struct ETHInterface_pvt* context, struct Allocator* messageAlloc)

+ 6 - 6
interface/FramingIface.c

@@ -81,7 +81,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* streamIf)
     if (fi->bytesRemaining > fi->maxMessageSize) {
         // Oversize message
         Assert_ifTesting(0);
-        return Error(OVERSIZE_MESSAGE);
+        return Error(msg, "OVERSIZE_MESSAGE");
     }
 
     if (fi->frameParts) {
@@ -95,7 +95,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* streamIf)
             // Run the message through again since it's almost certainly not perfect size.
             Iface_CALL(receiveMessage, wholeMessage, streamIf);
             Allocator_free(frameAlloc);
-            return Error(NONE);
+            return NULL;
         }
         fi->bytesRemaining -= Message_getLength(msg);
         Allocator_adopt(fi->frameAlloc, Message_getAlloc(msg));
@@ -103,13 +103,13 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* streamIf)
         parts->msg = msg;
         parts->next = fi->frameParts;
         fi->frameParts = parts;
-        return Error(NONE);
+        return NULL;
     }
 
     for (;;) {
         while (fi->headerIndex < 4) {
             if (!Message_getLength(msg)) {
-                return Error(NONE);
+                return NULL;
             }
             fi->header.bytes[fi->headerIndex] = msg->msgbytes[0];
             Er_assert(Message_eshift(msg, -1));
@@ -121,7 +121,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* streamIf)
         if (fi->bytesRemaining > fi->maxMessageSize) {
             // oversize
             Assert_ifTesting(0);
-            return Error(OVERSIZE_MESSAGE);
+            return Error(msg, "OVERSIZE_MESSAGE");
         }
 
         if (fi->bytesRemaining == (uint32_t)Message_getLength(msg)) {
@@ -151,7 +151,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* streamIf)
             fi->frameParts->msg = m;
             fi->frameParts->next = NULL;
         }
-        return Error(NONE);
+        return NULL;
     }
 }
 

+ 2 - 2
interface/Iface.c

@@ -13,15 +13,15 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "interface/Iface.h"
-#include "interface/Iface.h"
 #include "memory/Allocator.h"
 #include "util/Identity.h"
+#include "wire/Error.h"
 
 // This needs to be in a C file in order to be accessible from Rust
 Iface_DEFUN Iface_incomingFromRust(struct Message* message, struct Iface* thisInterface)
 {
     if (!thisInterface->connectedIf) {
-        return Error(INTERNAL);
+        return Error(message, "No connected interface");
     }
     return Iface_send(thisInterface, message);
 }

+ 9 - 9
interface/Iface.h

@@ -17,7 +17,7 @@
 
 #include <stdint.h>
 
-#include "wire/Error.h"
+#include "rust/cjdns_sys/RTypes.h"
 #include "wire/Message.h"
 #include "util/Defined.h"
 #include "util/Linker.h"
@@ -29,11 +29,11 @@ struct Iface;
  * @param thisInterface the interface which contains the sendMessage function pointer.
  * @param message the message
  */
-typedef struct Error_s (* Iface_Callback)(struct Message* message, struct Iface* thisInterface);
+typedef struct RTypes_Error_t* (* Iface_Callback)(struct Message* message, struct Iface* thisInterface);
 
-#define Iface_DEFUN __attribute__ ((warn_unused_result)) struct Error_s
+#define Iface_DEFUN __attribute__ ((warn_unused_result)) struct RTypes_Error_t*
 
-typedef struct Iface
+struct Iface
 {
     /** Send a message through this interface. */
     Iface_Callback send;
@@ -45,7 +45,7 @@ typedef struct Iface
 
     /** Interface to which this one is connected (if connected) */
     struct Iface* connectedIf;
-} Iface_t;
+} /* Iface_t defined in RffiPrefix.h */;
 
 // This needs to be in a C file in order to be accessible from Rust
 Iface_DEFUN Iface_incomingFromRust(struct Message* message, struct Iface* thisInterface);
@@ -58,7 +58,7 @@ Iface_DEFUN Iface_incomingFromRust(struct Message* message, struct Iface* thisIn
  * assertion error, in order to forward the message which you received, you must use Iface_next()
  * and it must be a tail-call.
  */
-static inline struct Error_s Iface_send(struct Iface* iface, struct Message* msg)
+static inline struct RTypes_Error_t* Iface_send(struct Iface* iface, struct Message* msg)
 {
     struct Iface* conn = iface->connectedIf;
 
@@ -71,7 +71,7 @@ static inline struct Error_s Iface_send(struct Iface* iface, struct Message* msg
         conn->currentMsg = msg;
     #endif
 
-    struct Error_s ret = conn->send(msg, conn);
+    struct RTypes_Error_t* ret = conn->send(msg, conn);
 
     #ifdef PARANOIA
         msg->currentIface = NULL;
@@ -100,7 +100,7 @@ static inline Iface_DEFUN Iface_next(struct Iface* iface, struct Message* msg)
         conn->currentMsg = NULL;
     #endif
 
-    struct Error_s ret = Iface_send(iface, msg);
+    struct RTypes_Error_t* ret = Iface_send(iface, msg);
 
     #ifdef PARANOIA
         conn->currentMsg = currentMsg;
@@ -128,7 +128,7 @@ static inline Iface_DEFUN Iface_next(struct Iface* iface, struct Message* msg)
             Assert_true(!msg->currentIface);                \
             struct Iface Iface_y = { .currentMsg = msg };   \
             msg->currentIface = &Iface_y;                   \
-            struct Error_s ret = func(msg, __VA_ARGS__); \
+            struct RTypes_Error_t* ret = func(msg, __VA_ARGS__); \
             msg->currentIface = NULL;                       \
             ret; \
         }))

+ 8 - 7
interface/UDPInterface.c

@@ -18,6 +18,7 @@
 #include "wire/Message.h"
 #include "util/events/UDPAddrIface.h"
 #include "util/GlobalConfig.h"
+#include "wire/Error.h"
 
 #define ArrayList_TYPE struct Sockaddr
 #define ArrayList_NAME Sockaddr
@@ -124,7 +125,7 @@ static Iface_DEFUN sendPacket(struct Message* m, struct Iface* iface)
     if (!(sa->flags & Sockaddr_flags_BCAST)) { return Iface_next(&ctx->commSock, m); }
 
     if (updateBcastAddrs(ctx)) {
-        return Error(INTERNAL);
+        return Error(m, "updateBcastAddrs check logs");
     }
 
     // bcast
@@ -146,7 +147,7 @@ static Iface_DEFUN sendPacket(struct Message* m, struct Iface* iface)
         Allocator_free(tmpAlloc);
     }
 
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN fromCommSock(struct Message* m, struct Iface* iface)
@@ -163,14 +164,14 @@ static Iface_DEFUN fromBcastSock(struct Message* m, struct Iface* iface)
 
     if (Message_getLength(m) < UDPInterface_BroadcastHeader_SIZE + Sockaddr_OVERHEAD) {
         Log_debug(ctx->log, "DROP runt bcast");
-        return Error(RUNT);
+        return Error(m, "RUNT bcast");
     }
 
     struct Sockaddr_storage ss;
     Er_assert(Message_epop(m, &ss, Sockaddr_OVERHEAD));
     if (Message_getLength(m) < UDPInterface_BroadcastHeader_SIZE + ss.addr.addrLen - Sockaddr_OVERHEAD) {
         Log_debug(ctx->log, "DROP runt bcast");
-        return Error(RUNT);
+        return Error(m, "RUNT bcast");
     }
     Er_assert(Message_epop(m, &ss.nativeAddr, ss.addr.addrLen - Sockaddr_OVERHEAD));
 
@@ -180,17 +181,17 @@ static Iface_DEFUN fromBcastSock(struct Message* m, struct Iface* iface)
     if (hdr.fffffffc_be != Endian_hostToBigEndian32(0xfffffffc)) {
         Log_debug(ctx->log, "DROP bcast bad magic, expected 0xfffffffc got [%08x]",
             Endian_bigEndianToHost32(hdr.fffffffc_be));
-        return Error(INVALID);
+        return Error(m, "INVALID bcast, bad magic");
     }
 
     if (hdr.version != UDPInterface_CURRENT_VERSION) {
         Log_debug(ctx->log, "DROP bcast bad version [%u]", hdr.version);
-        return Error(INVALID);
+        return Error(m, "INVALID bcast, bad version");
     }
 
     if (hdr.zero) {
         Log_debug(ctx->log, "DROP bcast malformed (zero not zero)");
-        return Error(INVALID);
+        return Error(m, "INVALID bcast, hdr.zero isn't 0");
     }
 
     uint16_t commPort = Endian_bigEndianToHost16(hdr.commPort_be);

+ 3 - 2
interface/addressable/AddrIfaceMuxer.c

@@ -18,6 +18,7 @@
 #include "util/Assert.h"
 #include "util/Identity.h"
 #include "wire/Message.h"
+#include "wire/Error.h"
 
 #include "util/Hex.h"
 
@@ -61,7 +62,7 @@ static Iface_DEFUN incomingFromAddrIf(struct Message* msg, struct Iface* addrIf)
     int idx = Map_Ifaces_indexForHandle(handle, &ctx->ifaces);
     if (idx < 0) {
         Log_info(ctx->log, "DROP message to nonexistant iface [0x%x]", handle);
-        return Error(UNHANDLED);
+        return Error(msg, "UNHANDLED (no such iface)");
     }
     return Iface_next(&ctx->ifaces.values[idx]->iface, msg);
 }
@@ -73,7 +74,7 @@ static Iface_DEFUN incomingFromInputIf(struct Message* msg, struct Iface* inputI
     struct AddrIfaceMuxer_pvt* ctx = Identity_check(cli->muxer);
     if (Message_getLength(msg) < (int)sizeof(struct Sockaddr)) {
         Log_info(ctx->log, "DROP runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     uint16_t addrLen = Bits_get16(msg->msgbytes);

+ 3 - 3
interface/addressable/PacketHeaderToUDPAddrIface.c

@@ -72,14 +72,14 @@ static Iface_DEFUN incomingFromHeaderIf(struct Message* message, struct Iface* i
 
     if (Message_getLength(message) < Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE) {
         // runt
-        return Error(RUNT);
+        return Error(message, "RUNT");
     }
 
     struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->msgbytes;
 
     // udp
     if (ip->nextHeader != 17) {
-        return Error(INVALID);
+        return Error(message, "INVALID (not UDP)");
     }
 
     struct Allocator* alloc = Allocator_child(Message_getAlloc(message));
@@ -93,7 +93,7 @@ static Iface_DEFUN incomingFromHeaderIf(struct Message* message, struct Iface* i
 
     if (Sockaddr_getPort(context->pub.udpIf.addr) != Endian_bigEndianToHost16(udp->destPort_be)) {
         // not the right port
-        return Error(INVALID);
+        return Error(message, "INVALID port");
     }
 
     Er_assert(Message_eshift(message, -(Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE)));

+ 1 - 1
interface/test/FramingIface_fuzz_test.c

@@ -40,7 +40,7 @@ static Iface_DEFUN ifaceRecvMsg(struct Message* message, struct Iface* thisInter
     Assert_true(Message_getLength(ctx->buf) == 0);
     Assert_true(!Bits_memcmp(ctx->bufPtr, message->msgbytes, ctx->messageLen));
     ctx->success = 1;
-    return Error(NONE);
+    return NULL;
 }
 
 void CJDNS_FUZZ_MAIN(void* vctx, struct Message* fuzz)

+ 1 - 1
interface/test/RustIface_test.c

@@ -60,7 +60,7 @@ static Iface_DEFUN sendOutside(struct Message* msg, struct Iface* outside)
     Assert_true(top == 0x00000800);
     Assert_true(!(ctx->received & 1));
     ctx->received |= 1;
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN sendInside(struct Message* msg, struct Iface* inside)

+ 3 - 3
interface/tuntap/AndroidWrapper.c

@@ -43,7 +43,7 @@ Iface_DEFUN AndroidWrapper_incomingFromWire(struct Message* msg, struct Iface* e
 
     if (!ctx->pub.internalIf.connectedIf) {
         Log_debug(ctx->logger, "DROP message for android tun not inited");
-        return Error(UNHANDLED);
+        return Error(msg, "UNHANDLED");
     }
 
     int version = Headers_getIpVersion(msg->msgbytes);
@@ -54,7 +54,7 @@ Iface_DEFUN AndroidWrapper_incomingFromWire(struct Message* msg, struct Iface* e
         ethertype = Ethernet_TYPE_IP6;
     } else {
         Log_debug(ctx->logger, "Message is not IP/IPv6, dropped.");
-        return Error(INVALID);
+        return Error(msg, "INVALID not IP");
     }
 
     Er_assert(Message_eshift(msg, 4));
@@ -71,7 +71,7 @@ Iface_DEFUN AndroidWrapper_incomingFromUs(struct Message* msg, struct Iface* int
 
     if (!ctx->pub.externalIf.connectedIf) {
         Log_debug(ctx->logger, "DROP message for android tun not inited");
-        return Error(UNHANDLED);
+        return Error(msg, "UNHANDLED");
     }
 
     Er_assert(Message_eshift(msg, -4));

+ 2 - 2
interface/tuntap/BSDMessageTypeWrapper.c

@@ -42,7 +42,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* wireSide)
     struct BSDMessageTypeWrapper_pvt* ctx =
         Identity_containerOf(wireSide, struct BSDMessageTypeWrapper_pvt, pub.wireSide);
 
-    if (Message_getLength(msg) < 4) { return Error(RUNT); }
+    if (Message_getLength(msg) < 4) { return Error(msg, "RUNT"); }
 
     uint16_t afType_be = ((uint16_t*) msg->msgbytes)[1];
     uint16_t ethertype = 0;
@@ -53,7 +53,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* wireSide)
     } else {
         Log_debug(ctx->logger, "Message of unhandled aftype [0x%04x]",
                   Endian_bigEndianToHost16(afType_be));
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     ((uint16_t*) msg->msgbytes)[0] = 0;
     ((uint16_t*) msg->msgbytes)[1] = ethertype;

+ 3 - 3
interface/tuntap/SocketWrapper.c

@@ -37,7 +37,7 @@ static Iface_DEFUN incomingFromSocket(struct Message* msg, struct Iface* externa
 
     if (!ctx->pub.internalIf.connectedIf) {
         Log_debug(ctx->logger, "DROP message for socket not inited");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     // get ess packet type
@@ -51,7 +51,7 @@ static Iface_DEFUN incomingFromSocket(struct Message* msg, struct Iface* externa
     }
 
     // skip all other types
-    return Error(INVALID);
+    return Error(msg, "INVALID");
 }
 
 static Iface_DEFUN incomingFromUs(struct Message* msg, struct Iface* internalIf)
@@ -61,7 +61,7 @@ static Iface_DEFUN incomingFromUs(struct Message* msg, struct Iface* internalIf)
 
     if (!ctx->pub.externalIf.connectedIf) {
         Log_debug(ctx->logger, "DROP message for socket not inited");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     // send payload length

+ 3 - 3
interface/tuntap/TAPWrapper.c

@@ -36,7 +36,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* external)
 
     if (Message_getLength(msg) < Ethernet_SIZE-2) {
         Log_debug(tw->log, "runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     // wacky 14 byte headers, back off into outer-space to create the padding...
@@ -66,7 +66,7 @@ static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* external)
                 AddrTools_printMac(printedMac, eth.srcAddr);
                 Log_debug(tw->log, "DROP Packet with unexpected source MAC [%s]", printedMac);
             #endif
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
     }
     Er_assert(TUNMessageType_push(msg, eth.ethertype));
@@ -83,7 +83,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* internal)
     Bits_memcpy(eth.destAddr, tw->pub.peerAddress, Ethernet_ADDRLEN);
     if (Bits_isZero(tw->pub.peerAddress, Ethernet_ADDRLEN)) {
         Log_debug(tw->log, "DROP Packet because peers MAC is not yet known");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     Er_assert(Message_epush(msg, &eth, sizeof(struct Ethernet)));

+ 1 - 1
interface/tuntap/test/BSDMessageTypeWrapper_test.c

@@ -34,7 +34,7 @@ static Iface_DEFUN sendInside(struct Message* msg, struct Iface* inside)
     Assert_true(top == 0x00000800);
     Assert_true(!(ctx->received & 1));
     ctx->received |= 1;
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN sendOutside(struct Message* msg, struct Iface* outside)

+ 2 - 1
interface/tuntap/test/TUNInterface_ipv4_root_test.c

@@ -20,6 +20,7 @@
 #include "util/log/Log.h"
 #include "util/log/FileWriterLog.h"
 #include "util/events/Timeout.h"
+#include "wire/Error.h"
 #include "wire/Ethernet.h"
 #include "wire/Headers.h"
 #include "util/platform/netdev/NetDev.h"
@@ -36,7 +37,7 @@ static Iface_DEFUN receiveMessageTUN(struct Message* msg, struct TUNTools* tt)
     if (ethertype != Ethernet_TYPE_IP4) {
         Log_debug(tt->log, "Spurious packet with ethertype [%u]\n",
                   Endian_bigEndianToHost16(ethertype));
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     struct Headers_IP4Header* header = (struct Headers_IP4Header*) msg->msgbytes;

+ 4 - 3
interface/tuntap/test/TUNTools.c

@@ -19,6 +19,7 @@
 #include "util/events/Timeout.h"
 #include "wire/Ethernet.h"
 #include "wire/Headers.h"
+#include "wire/Error.h"
 
 #ifdef win32
     #include <windows.h>
@@ -83,7 +84,7 @@ Iface_DEFUN TUNTools_genericIP6Echo(struct Message* msg, struct TUNTools* tt)
     if (ethertype != Ethernet_TYPE_IP6) {
         Log_debug(tt->log, "Spurious packet with ethertype [%04x]\n",
                   Endian_bigEndianToHost16(ethertype));
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     struct Headers_IP6Header* header = (struct Headers_IP6Header*) msg->msgbytes;
@@ -92,7 +93,7 @@ Iface_DEFUN TUNTools_genericIP6Echo(struct Message* msg, struct TUNTools* tt)
         int type = (Message_getLength(msg) >= Headers_IP6Header_SIZE) ? header->nextHeader : -1;
         Log_debug(tt->log, "Message of unexpected length [%u] ip6->nextHeader: [%d]\n",
                   Message_getLength(msg), type);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     uint8_t* address;
     Sockaddr_getAddress(tt->tunDestAddr, &address);
@@ -127,7 +128,7 @@ static Iface_DEFUN receiveMessageUDP(struct Message* msg, struct Iface* udpIface
         EventBase_endLoop(ctx->pub.base);
     }
 
-    return Error(NONE);
+    return NULL;
 }
 
 static void fail(void* ignored)

+ 2 - 2
interface/tuntap/windows/TAPInterface.c

@@ -229,7 +229,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
     struct TAPInterface_pvt* tap = Identity_check((struct TAPInterface_pvt*) iface);
     if (tap->writeMessageCount >= WRITE_MESSAGE_SLOTS) {
         Log_info(tap->log, "DROP message because the tap is lagging");
-        return Error(OVERFLOW);
+        return Error(msg, "OVERFLOW");
     }
     if (!tap->pendingWritesAlloc) {
         tap->pendingWritesAlloc = Allocator_child(tap->alloc);
@@ -239,7 +239,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
     if (tap->writeMessageCount == 1) {
         postWrite(tap);
     }
-    return Error(NONE);
+    return NULL;
 }
 
 Er_DEFUN(struct TAPInterface* TAPInterface_new(const char* preferredName,

+ 18 - 18
net/ControlHandler.c

@@ -47,7 +47,7 @@ static Iface_DEFUN handleError(struct Message* msg,
 {
     if (Message_getLength(msg) < handleError_MIN_SIZE) {
         Log_info(ch->log, "DROP runt error packet from [%s]", labelStr);
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
     Er_assert(Message_truncate(msg, handleError_MIN_SIZE));
     Er_assert(Message_epush(msg, &rh->sh, SwitchHeader_SIZE));
@@ -68,7 +68,7 @@ static Iface_DEFUN handlePing(struct Message* msg,
 {
     if (Message_getLength(msg) < handlePing_MIN_SIZE) {
         Log_info(ch->log, "DROP runt ping");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     struct Control* ctrl = (struct Control*) msg->msgbytes;
@@ -79,7 +79,7 @@ static Iface_DEFUN handlePing(struct Message* msg,
     uint32_t herVersion = Endian_bigEndianToHost32(ping->version_be);
     if (!Version_isCompatible(Version_CURRENT_PROTOCOL, herVersion)) {
         Log_debug(ch->log, "DROP ping from incompatible version [%d]", herVersion);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     if (messageType_be == Control_KEYPING_be) {
@@ -87,15 +87,15 @@ static Iface_DEFUN handlePing(struct Message* msg,
         if (Message_getLength(msg) < Control_KeyPing_HEADER_SIZE) {
             // min keyPing size is longer
             Log_debug(ch->log, "DROP runt keyPing");
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
         if (Message_getLength(msg) > Control_KeyPing_MAX_SIZE) {
             Log_debug(ch->log, "DROP long keyPing");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
         if (ping->magic != Control_KeyPing_MAGIC) {
             Log_debug(ch->log, "DROP keyPing (bad magic)");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
 
         struct Control_KeyPing* keyPing = (struct Control_KeyPing*) msg->msgbytes;
@@ -108,7 +108,7 @@ static Iface_DEFUN handlePing(struct Message* msg,
         //Log_debug(ch->log, "got switch ping from [%s]", labelStr);
         if (ping->magic != Control_Ping_MAGIC) {
             Log_debug(ch->log, "DROP ping (bad magic)");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
         ping->magic = Control_Pong_MAGIC;
         ctrl->header.type_be = Control_PONG_be;
@@ -147,7 +147,7 @@ static Iface_DEFUN handleRPathQuery(struct Message* msg,
     Log_debug(ch->log, "Incoming RPATH query");
     if (Message_getLength(msg) < handleRPathQuery_MIN_SIZE) {
         Log_info(ch->log, "DROP runt RPATH query");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     struct Control* ctrl = (struct Control*) msg->msgbytes;
@@ -155,7 +155,7 @@ static Iface_DEFUN handleRPathQuery(struct Message* msg,
 
     if (rpa->magic != Control_RPATH_QUERY_MAGIC) {
         Log_debug(ch->log, "DROP RPATH query (bad magic)");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     ctrl->header.type_be = Control_RPATH_REPLY_be;
@@ -188,7 +188,7 @@ static Iface_DEFUN handleGetSnodeQuery(struct Message* msg,
     Log_debug(ch->log, "incoming getSupernode query");
     if (Message_getLength(msg) < handleGetSnodeQuery_MIN_SIZE) {
         Log_info(ch->log, "DROP runt getSupernode query");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     struct Control* ctrl = (struct Control*) msg->msgbytes;
@@ -196,14 +196,14 @@ static Iface_DEFUN handleGetSnodeQuery(struct Message* msg,
 
     if (snq->magic != Control_GETSNODE_QUERY_MAGIC) {
         Log_debug(ch->log, "DROP getSupernode query (bad magic)");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     uint32_t herVersion = Endian_bigEndianToHost32(snq->version_be);
     if (!Version_isCompatible(Version_CURRENT_PROTOCOL, herVersion)) {
         Log_debug(ch->log, "DROP getSupernode query from incompatible version [%d]", herVersion);
         // Nothing wrong with the query but we're just not going to answer it
-        return Error(NONE);
+        return NULL;
     }
 
     ctrl->header.type_be = Control_GETSNODE_REPLY_be;
@@ -265,14 +265,14 @@ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* coreIf)
 
     if (Message_getLength(msg) < 4 + Control_Header_SIZE) {
         Log_info(ch->log, "DROP runt ctrl packet from [%s]", labelStr);
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     Assert_true(routeHdr.flags & RouteHeader_flags_CTRLMSG);
 
     if (Checksum_engine_be(msg->msgbytes, Message_getLength(msg))) {
         Log_info(ch->log, "DROP ctrl packet from [%s] with invalid checksum", labelStr);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     struct Control* ctrl = (struct Control*) msg->msgbytes;
@@ -313,7 +313,7 @@ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* coreIf)
     Log_info(ch->log, "DROP control packet of unknown type from [%s], type [%d]",
              labelStr, Endian_bigEndianToHost16(ctrl->header.type_be));
 
-    return Error(INVALID);
+    return Error(msg, "INVALID");
 }
 
 // Forward from switch pinger directly to core.
@@ -345,7 +345,7 @@ static Iface_DEFUN changeSnode(struct Message* msg, struct Iface* eventIf)
             log = "Found snode";
         } else {
             // didn't know the snode before, still don't
-            return Error(NONE);
+            return NULL;
         }
     } else if (!node.path_be) {
         // We had one, now we don't
@@ -359,7 +359,7 @@ static Iface_DEFUN changeSnode(struct Message* msg, struct Iface* eventIf)
             log = "Changing snode protocolVersion";
         } else {
             // Nothing has changed
-            return Error(NONE);
+            return NULL;
         }
     }
 
@@ -380,7 +380,7 @@ static Iface_DEFUN changeSnode(struct Message* msg, struct Iface* eventIf)
         Address_toStringKey(&old, Message_getAlloc(msg))->bytes,
         Address_toStringKey(&addr, Message_getAlloc(msg))->bytes);
 
-    return Error(NONE);
+    return NULL;
 }
 
 struct ControlHandler* ControlHandler_new(struct Allocator* allocator,

+ 11 - 10
net/EventEmitter.c

@@ -17,6 +17,7 @@
 #include "net/EventEmitter.h"
 #include "util/Identity.h"
 #include "util/log/Log.h"
+#include "wire/Error.h"
 
 #include <stdbool.h>
 
@@ -85,7 +86,7 @@ static struct ArrayList_Ifaces* getHandlers(struct EventEmitter_pvt* ee,
 
 static Iface_DEFUN sendToPathfinder(struct Message* msg, struct Pathfinder* pf)
 {
-    if (!pf || pf->state != Pathfinder_state_CONNECTED) { return Error(NONE); }
+    if (!pf || pf->state != Pathfinder_state_CONNECTED) { return NULL; }
     if (pf->bytesSinceLastPing < 8192 && pf->bytesSinceLastPing + Message_getLength(msg) >= 8192) {
         struct Message* ping = Message_new(0, 512, Message_getAlloc(msg));
         Er_assert(Message_epush32be(ping, pf->bytesSinceLastPing));
@@ -192,7 +193,7 @@ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* trickIf)
             Iface_CALL(sendToPathfinder, messageClone, pf);
         }
     }
-    return Error(NONE);
+    return NULL;
 }
 
 static struct Message* pathfinderMsg(enum PFChan_Core ev,
@@ -283,34 +284,34 @@ static Iface_DEFUN incomingFromPathfinder(struct Message* msg, struct Iface* ifa
     struct EventEmitter_pvt* ee = Identity_check((struct EventEmitter_pvt*) pf->ee);
     if (Message_getLength(msg) < 4) {
         Log_debug(ee->log, "DROPPF runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
     enum PFChan_Pathfinder ev = Er_assert(Message_epop32be(msg));
     Er_assert(Message_epush32be(msg, pf->pathfinderId));
     Er_assert(Message_epush32be(msg, ev));
     if (ev <= PFChan_Pathfinder__TOO_LOW || ev >= PFChan_Pathfinder__TOO_HIGH) {
         Log_debug(ee->log, "DROPPF invalid type [%d]", ev);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     if (!PFChan_Pathfinder_sizeOk(ev, Message_getLength(msg))) {
         Log_debug(ee->log, "DROPPF incorrect length[%d] for type [%d]", Message_getLength(msg), ev);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     if (pf->state == Pathfinder_state_DISCONNECTED) {
         if (ev != PFChan_Pathfinder_CONNECT) {
             Log_debug(ee->log, "DROPPF disconnected and event != CONNECT event:[%d]", ev);
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
     } else if (pf->state != Pathfinder_state_CONNECTED) {
         Log_debug(ee->log, "DROPPF error state");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
-    if (handleFromPathfinder(ev, msg, ee, pf)) { return Error(NONE); }
+    if (handleFromPathfinder(ev, msg, ee, pf)) { return NULL; }
 
     struct ArrayList_Ifaces* handlers = getHandlers(ee, ev, false);
-    if (!handlers) { return Error(NONE); }
+    if (!handlers) { return NULL; }
     for (int i = 0; i < handlers->length; i++) {
         struct Message* messageClone = Message_clone(msg, Message_getAlloc(msg));
         struct Iface* iface = ArrayList_Ifaces_get(handlers, i);
@@ -320,7 +321,7 @@ static Iface_DEFUN incomingFromPathfinder(struct Message* msg, struct Iface* ifa
         Assert_true(iface->send);
         Iface_CALL(iface->send, messageClone, iface);
     }
-    return Error(NONE);
+    return NULL;
 }
 
 void EventEmitter_regCore(struct EventEmitter* eventEmitter,

+ 20 - 19
net/InterfaceController.c

@@ -35,6 +35,7 @@
 #include "wire/Message.h"
 #include "wire/Headers.h"
 #include "wire/Metric.h"
+#include "wire/CryptoHeader.h"
 
 /** After this number of milliseconds, a node will be regarded as unresponsive. */
 #define UNRESPONSIVE_AFTER_MILLISECONDS (20*1024)
@@ -518,7 +519,7 @@ static Iface_DEFUN sendFromSwitch(struct Message* msg, struct Iface* switchIf)
                 Address_toString(&ep->addr, Message_getAlloc(msg))->bytes, ep->addr.protocolVersion);
         }
         ep->state = InterfaceController_PeerState_INCOMPATIBLE;
-        return Error(UNHANDLED);
+        return Error(msg, "UNHANDLED");
     }
 
     ep->bytesOut += Message_getLength(msg);
@@ -584,19 +585,19 @@ static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_
         // accepting beacons disabled.
         Log_debug(ic->logger, "[%s] Dropping beacon because beaconing is disabled",
                   ici->pub.name->bytes);
-        return Error(NONE);
+        return NULL;
     }
 
     if (Message_getLength(msg) < Sockaddr_OVERHEAD) {
         Log_debug(ic->logger, "[%s] Dropping runt beacon", ici->pub.name->bytes);
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     struct Sockaddr* lladdrInmsg = (struct Sockaddr*) msg->msgbytes;
 
     if (Message_getLength(msg) < lladdrInmsg->addrLen + Headers_Beacon_SIZE) {
         Log_debug(ic->logger, "[%s] Dropping runt beacon", ici->pub.name->bytes);
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     // clear the bcast flag
@@ -625,10 +626,10 @@ static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_
 
     if (!AddressCalc_validAddress(addr.ip6.bytes)) {
         Log_debug(ic->logger, "handleBeacon invalid key [%s]", printedAddr->bytes);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     } else if (!Bits_memcmp(ic->ourPubKey, addr.key, 32)) {
         // receive beacon from self, drop silent
-        return Error(NONE);
+        return NULL;
     }
 
     if (knownIncompatibleVersion(addr.protocolVersion)) {
@@ -637,7 +638,7 @@ static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_
                       "our version is [%d] making them incompatable", ici->pub.name->bytes,
                       printedAddr->bytes, addr.protocolVersion, Version_CURRENT_PROTOCOL);
         }
-        return Error(UNHANDLED);
+        return Error(msg, "UNHANDLED");
     }
 
     String* beaconPass = String_newBinary(beacon.password, Headers_Beacon_PASSWORD_LEN, Message_getAlloc(msg));
@@ -646,7 +647,7 @@ static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_
         // The password might have changed!
         struct Peer* ep = ici->peerMap.values[epIndex];
         Ca_setAuth(beaconPass, NULL, ep->caSession);
-        return Error(NONE);
+        return NULL;
     }
 
     bool useNoise = addr.protocolVersion >= 22;
@@ -662,7 +663,7 @@ static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_
     if (SwitchCore_addInterface(ic->switchCore, &ep->switchIf, ep->alloc, &ep->addr.path)) {
         Log_debug(ic->logger, "handleBeacon() SwitchCore out of space");
         Allocator_free(ep->alloc);
-        return Error(UNHANDLED);
+        return Error(msg, "UNHANDLED");
     }
 
     // We want the node to immedietly be pinged but we don't want it to appear unresponsive because
@@ -676,7 +677,7 @@ static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_
 
     // Ping them immediately, this prevents beacon tests from taking 1 second each
     sendPing(ep);
-    return Error(NONE);
+    return NULL;
 }
 
 /**
@@ -689,7 +690,7 @@ static Iface_DEFUN handleUnexpectedIncoming(struct Message* msg,
     struct Sockaddr* lladdr = (struct Sockaddr*) msg->msgbytes;
     Er_assert(Message_eshift(msg, -lladdr->addrLen));
     if (Message_getLength(msg) < CryptoHeader_SIZE) {
-        return Error(RUNT);
+        return Error(msg, "RUNT length: %d", Message_getLength(msg));
     }
 
     Assert_true(!((uintptr_t)msg->msgbytes % 4) && "alignment fault");
@@ -700,7 +701,7 @@ static Iface_DEFUN handleUnexpectedIncoming(struct Message* msg,
     {
         // This cuts down on processing and logger noise because any packet
         // which is not a setup packet will be summarily dropped.
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     // Don't force noise for this message because we really have no idea what we're dealing with
@@ -709,7 +710,7 @@ static Iface_DEFUN handleUnexpectedIncoming(struct Message* msg,
 
     if (!AddressCalc_validAddress(ep->addr.ip6.bytes)) {
         Allocator_free(ep->alloc);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     uint32_t nonce = Endian_bigEndianToHost32(ch->nonce);
@@ -727,7 +728,7 @@ static Iface_DEFUN handleIncomingFromWire(struct Message* msg, struct Iface* add
     struct Sockaddr* lladdr = (struct Sockaddr*) msg->msgbytes;
     if (Message_getLength(msg) < Sockaddr_OVERHEAD || Message_getLength(msg) < lladdr->addrLen) {
         Log_debug(ici->ic->logger, "DROP runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     Assert_true(!((uintptr_t)msg->msgbytes % 4) && "alignment fault");
@@ -758,7 +759,7 @@ static Iface_DEFUN handleIncomingFromWire(struct Message* msg, struct Iface* add
                 Address_toString(&ep->addr, Message_getAlloc(msg))->bytes, ep->addr.protocolVersion);
         }
         ep->state = InterfaceController_PeerState_INCOMPATIBLE;
-        return Error(NONE);
+        return NULL;
     }
 
     Ca_resetIfTimeout(ep->caSession);
@@ -789,14 +790,14 @@ static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* plaintext)
             // We got an unexpected message and it did not validate, drop the allocator
             Allocator_free(ep->alloc);
         }
-        return Error(AUTHENTICATION);
+        return Error(msg, "AUTHENTICATION");
     } else if (unexpected) {
         // We got an unexpected message and it's valid, load the peer
 
         if (SwitchCore_addInterface(ic->switchCore, &ep->switchIf, ep->alloc, &ep->addr.path)) {
             Log_debug(ic->logger, "handleUnexpectedIncoming() SwitchCore out of space");
             Allocator_free(ep->alloc);
-            return Error(UNHANDLED);
+            return Error(msg, "UNHANDLED");
         }
 
         // TODO(cjd): when this becomes threaded, there will be a race here
@@ -825,7 +826,7 @@ static Iface_DEFUN afterDecrypt(struct Message* msg, struct Iface* plaintext)
         // directs it to *this* router.
         if (Message_getLength(msg) < 8 || msg->msgbytes[7] != 1) {
             Log_info(ic->logger, "DROP message because CA is not established.");
-            return Error(UNHANDLED);
+            return Error(msg, "UNHANDLED");
         } else {
             // When a "server" gets a new connection from a "client" the router doesn't
             // know about that client so if the client sends a packet to the server, the
@@ -1131,7 +1132,7 @@ static Iface_DEFUN incomingFromEventEmitterIf(struct Message* msg, struct Iface*
             sendPeer(pathfinderId, PFChan_Core_PEER, peer, 0xffff);
         }
     }
-    return Error(NONE);
+    return NULL;
 }
 
 struct InterfaceController* InterfaceController_new(Ca_t* ca,

+ 17 - 17
net/SessionManager.c

@@ -485,7 +485,7 @@ static Iface_DEFUN incomingFromSwitchIf(struct Message* msg, struct Iface* iface
     // SwitchHeader, handle, 0 or more bytes of control frame
     if (Message_getLength(msg) < SwitchHeader_SIZE + 4) {
         Log_debug(sm->log, "DROP runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     struct SwitchHeader switchHeader;
@@ -506,7 +506,7 @@ static Iface_DEFUN incomingFromSwitchIf(struct Message* msg, struct Iface* iface
     // handle, small cryptoAuth header
     if (Message_getLength(msg) < 4 + 20) {
         Log_debug(sm->log, "DROP runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     if (nonceOrHandle > 3) {
@@ -514,32 +514,32 @@ static Iface_DEFUN incomingFromSwitchIf(struct Message* msg, struct Iface* iface
         session = sessionForHandle(nonceOrHandle, sm);
         if (!session) {
             Log_debug(sm->log, "DROP message with unrecognized handle [%u]", nonceOrHandle);
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
         Er_assert(Message_eshift(msg, -4));
         uint32_t nonce = Endian_bigEndianToHost32(((uint32_t*)msg->msgbytes)[0]);
         if (nonce < 4) {
             Log_debug(sm->log, "DROP setup message [%u] with specified handle [%u]",
                 nonce, nonceOrHandle);
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
     } else {
         // handle + big cryptoauth header
         if (Message_getLength(msg) < CryptoHeader_SIZE + 4) {
             Log_debug(sm->log, "DROP runt");
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
         struct CryptoHeader* caHeader = (struct CryptoHeader*) msg->msgbytes;
         uint8_t ip6[16];
         // a packet which claims to be "from us" causes problems
         if (!AddressCalc_addressForPublicKey(ip6, caHeader->publicKey)) {
             Log_debug(sm->log, "DROP Handshake with non-fc key");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
 
         if (!Bits_memcmp(caHeader->publicKey, sm->ourPubKey, 32)) {
             Log_debug(sm->log, "DROP Handshake from 'ourselves'");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
 
         uint64_t label = Endian_bigEndianToHost64(switchHeader.label_be);
@@ -735,11 +735,11 @@ static Iface_DEFUN outgoingCtrlFrame(struct Message* msg, struct SessionManager_
     struct RouteHeader* header = (struct RouteHeader*) msg->msgbytes;
     if (!Bits_isZero(header->publicKey, 32) || !Bits_isZero(header->ip6, 16)) {
         Log_debug(sm->log, "DROP Ctrl frame with non-zero destination key or IP");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     if (!(header->flags & RouteHeader_flags_CTRLMSG)) {
         Log_debug(sm->log, "DROP Ctrl frame w/o RouteHeader_flags_CTRLMSG flag");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     struct SwitchHeader sh;
     Bits_memcpy(&sh, &header->sh, SwitchHeader_SIZE);
@@ -772,7 +772,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface
                               ((header->sh.label_be) ? Metric_SM_SEND : Metric_DEAD_LINK));
         } else {
             needsLookup(sm, msg);
-            return Error(NONE);
+            return NULL;
         }
     }
 
@@ -785,7 +785,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface
 
     if (!sess->pub.version) {
         needsLookup(sm, msg);
-        return Error(NONE);
+        return NULL;
     }
 
     if (header->sh.label_be) {
@@ -796,7 +796,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface
         SwitchHeader_setVersion(&header->sh, SwitchHeader_CURRENT_VERSION);
     } else {
         needsLookup(sm, msg);
-        return Error(NONE);
+        return NULL;
     }
 
     // Forward secrecy, only send dht messages until the session is setup.
@@ -813,7 +813,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Message* msg, struct Iface* iface
                 Endian_bigEndianToHost64(header->sh.label_be), "user traffic, unsetupSession");
             bufferPacket(sm, msg);
             unsetupSession(sm, sess);
-            return Error(NONE);
+            return NULL;
         }
     }
 
@@ -828,7 +828,7 @@ static Iface_DEFUN sessions(struct SessionManager_pvt* sm,
         struct SessionManager_Session_pvt* sess = sm->ifaceMap.values[i];
         sendSession(sess, &sess->pub.paths[0], sourcePf, PFChan_Core_SESSION);
     }
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* iface)
@@ -849,9 +849,9 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* iface)
     struct SessionManager_Session_pvt* sess = sessionForIp6(node.ip6, sm);
     if (!sess) {
         // Node we don't care about.
-        if (index == -1) { return Error(NONE); }
+        if (index == -1) { return NULL; }
         // Broken path to a node we don't have a session for...
-        if (node.metric_be == Metric_DEAD_LINK) { return Error(NONE); }
+        if (node.metric_be == Metric_DEAD_LINK) { return NULL; }
     }
     sess = getSession(sm,
                       node.ip6,
@@ -867,7 +867,7 @@ static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* iface)
         Map_BufferedMessages_remove(index, &sm->bufMap);
         Allocator_free(bm->alloc);
     }
-    return Error(NONE);
+    return NULL;
 }
 
 struct SessionManager* SessionManager_new(struct Allocator* allocator,

+ 15 - 15
net/SwitchPinger.c

@@ -103,12 +103,12 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
             ctx->incomingVersion = Endian_bigEndianToHost32(pongHeader->version_be);
             if (pongHeader->magic != Control_Pong_MAGIC) {
                 Log_debug(ctx->logger, "dropped invalid switch pong");
-                return Error(INVALID);
+                return Error(msg, "INVALID");
             }
             Er_assert(Message_eshift(msg, -Control_Pong_HEADER_SIZE));
         } else {
             Log_debug(ctx->logger, "got runt pong message, length: [%d]", Message_getLength(msg));
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
 
     } else if (ctrl->header.type_be == Control_KEYPONG_be) {
@@ -119,16 +119,16 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
             ctx->incomingVersion = Endian_bigEndianToHost32(pongHeader->version_be);
             if (pongHeader->magic != Control_KeyPong_MAGIC) {
                 Log_debug(ctx->logger, "dropped invalid switch key-pong");
-                return Error(INVALID);
+                return Error(msg, "INVALID");
             }
             Bits_memcpy(ctx->incomingKey, pongHeader->key, 32);
             Er_assert(Message_eshift(msg, -Control_KeyPong_HEADER_SIZE));
         } else if (Message_getLength(msg) > Control_KeyPong_MAX_SIZE) {
             Log_debug(ctx->logger, "got overlong key-pong message, length: [%d]", Message_getLength(msg));
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         } else {
             Log_debug(ctx->logger, "got runt key-pong message, length: [%d]", Message_getLength(msg));
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
 
     } else if (ctrl->header.type_be == Control_GETSNODE_REPLY_be) {
@@ -136,20 +136,20 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
         ctx->error = Error_NONE;
         if (Message_getLength(msg) < Control_GetSnode_HEADER_SIZE) {
             Log_debug(ctx->logger, "got runt GetSnode message, length: [%d]", Message_getLength(msg));
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
         struct Control_GetSnode* hdr = (struct Control_GetSnode*) msg->msgbytes;
         if (hdr->magic != Control_GETSNODE_REPLY_MAGIC) {
             Log_debug(ctx->logger, "dropped invalid GetSnode");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
         if (Bits_isZero(hdr->snodeKey, 32)) {
             Log_debug(ctx->logger, "Peer doesn't have an snode");
-            return Error(NONE);
+            return NULL;
         }
         if (!AddressCalc_addressForPublicKey(ctx->incomingSnodeAddr.ip6.bytes, hdr->snodeKey)) {
             Log_debug(ctx->logger, "dropped invalid GetSnode key");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
         ctx->incomingVersion = Endian_hostToBigEndian32(hdr->version_be);
         Bits_memcpy(ctx->incomingSnodeAddr.key, hdr->snodeKey, 32);
@@ -165,12 +165,12 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
         ctx->error = Error_NONE;
         if (Message_getLength(msg) < Control_RPath_HEADER_SIZE) {
             Log_debug(ctx->logger, "got runt RPath message, length: [%d]", Message_getLength(msg));
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
         struct Control_RPath* hdr = (struct Control_RPath*) msg->msgbytes;
         if (hdr->magic != Control_RPATH_REPLY_MAGIC) {
             Log_debug(ctx->logger, "dropped invalid RPATH (bad magic)");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
         ctx->incomingVersion = Endian_hostToBigEndian32(hdr->version_be);
         uint64_t rpath_be;
@@ -183,7 +183,7 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
         Assert_true((uint8_t*)&ctrl->content.error.errorType_be == msg->msgbytes);
         if (Message_getLength(msg) < (Control_Error_HEADER_SIZE + SwitchHeader_SIZE + Control_Header_SIZE)) {
             Log_debug(ctx->logger, "runt error packet");
-            return Error(RUNT);
+            return Error(msg, "RUNT");
         }
 
         ctx->error = Er_assert(Message_epop32be(msg));
@@ -193,8 +193,8 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
 
         struct Control* origCtrl = (struct Control*) msg->msgbytes;
 
-        Log_debug(ctx->logger, "error [%s] was caused by our [%s]",
-                  Error_strerror(ctx->error),
+        Log_debug(ctx->logger, "error [%d] was caused by our [%s]",
+                  ctx->error,
                   Control_typeString(origCtrl->header.type_be));
 
         int shift;
@@ -218,7 +218,7 @@ static Iface_DEFUN messageFromControlHandler(struct Message* msg, struct Iface*
     String* msgStr = &(String) { .bytes = (char*) msg->msgbytes, .len = Message_getLength(msg) };
     Pinger_pongReceived(msgStr, ctx->pinger);
     Bits_memset(ctx->incomingKey, 0, 32);
-    return Error(NONE);
+    return NULL;
 }
 
 static void onPingResponse(String* data, uint32_t milliseconds, void* vping)

+ 6 - 5
net/TUNAdapter.c

@@ -24,6 +24,7 @@
 #include "crypto/AddressCalc.h"
 #include "util/Defined.h"
 #include "util/AddrTools.h"
+#include "wire/Error.h"
 
 struct TUNAdapter_pvt
 {
@@ -45,7 +46,7 @@ static Iface_DEFUN incomingFromTunIf(struct Message* msg, struct Iface* tunIf)
     {
         Log_debug(ud->log, "DROP packet because ip version [%d] "
                   "doesn't match ethertype [%u].", version, Endian_bigEndianToHost16(ethertype));
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     if (ethertype == Ethernet_TYPE_IP4) {
@@ -54,12 +55,12 @@ static Iface_DEFUN incomingFromTunIf(struct Message* msg, struct Iface* tunIf)
     if (ethertype != Ethernet_TYPE_IP6) {
         Log_debug(ud->log, "DROP packet unknown ethertype [%u]",
                   Endian_bigEndianToHost16(ethertype));
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     if (Message_getLength(msg) < Headers_IP6Header_SIZE) {
         Log_debug(ud->log, "DROP runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
 
     struct Headers_IP6Header* header = (struct Headers_IP6Header*) msg->msgbytes;
@@ -76,7 +77,7 @@ static Iface_DEFUN incomingFromTunIf(struct Message* msg, struct Iface* tunIf)
                       "DROP packet from [%s] because all messages must have source address [%s]",
                       packetSource, expectedSource);
         }
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     if (!Bits_memcmp(header->destinationAddr, ud->myIp6, 16)) {
         // I'm Gonna Sit Right Down and Write Myself a Letter
@@ -111,7 +112,7 @@ static Iface_DEFUN sendToTunIf(struct Message* msg, struct TUNAdapter_pvt* ud)
     if (!ud->pub.tunIf.connectedIf) {
         Log_debug(ud->log, "DROP message for tun because no device is defined");
         // Nothing inherently wrong with this message
-        return Error(NONE);
+        return NULL;
     }
     return Iface_next(&ud->pub.tunIf, msg);
 }

+ 10 - 9
net/UpperDistributor.c

@@ -24,6 +24,7 @@
 #include "wire/DataHeader.h"
 #include "wire/RouteHeader.h"
 #include "wire/Headers.h"
+#include "wire/Error.h"
 
 struct UpperDistributor_Handler_pvt
 {
@@ -62,11 +63,11 @@ static Iface_DEFUN fromHandler(struct Message* msg, struct UpperDistributor_pvt*
     enum ContentType type = DataHeader_getContentType(&dh);
     if (type != ContentType_IP6_UDP) {
         Log_debug(ud->log, "DROP Message from handler with invalid type [%d]", type);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     if (Message_getLength(msg) < Headers_UDPHeader_SIZE + RouteHeader_SIZE + DataHeader_SIZE) {
         Log_debug(ud->log, "DROP runt");
-        return Error(RUNT);
+        return Error(msg, "RUNT");
     }
     uint8_t srcAndDest[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
     AddressCalc_makeValidAddress(&srcAndDest[16]);
@@ -74,18 +75,18 @@ static Iface_DEFUN fromHandler(struct Message* msg, struct UpperDistributor_pvt*
     struct Headers_UDPHeader* udp = (struct Headers_UDPHeader*) msg->msgbytes;
     if (Checksum_udpIp6_be(srcAndDest, msg->msgbytes, Message_getLength(msg))) {
         Log_debug(ud->log, "DROP Bad checksum");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     if (udp->destPort_be != Endian_bigEndianToHost16(MAGIC_PORT)) {
         Log_debug(ud->log, "DROP Message to unknown port [%d]",
             Endian_bigEndianToHost16(udp->destPort_be));
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     int udpPort = Endian_bigEndianToHost16(udp->srcPort_be);
     int index = Map_OfHandlers_indexForKey(&udpPort, ud->handlers);
     if (index < 0) {
         Log_debug(ud->log, "DROP Message from unregistered port [%d]", udpPort);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     Er_assert(Message_epop(msg, NULL, Headers_UDPHeader_SIZE));
 
@@ -101,13 +102,13 @@ static Iface_DEFUN fromHandler(struct Message* msg, struct UpperDistributor_pvt*
     if (DataHeader_getContentType(dataHeader) == ContentType_CJDHT) {
         if (Bits_isZero(hdr->publicKey, 32)) {
             Log_debug(ud->log, "DROP message with no pubkey");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         } else if (hdr->sh.label_be == 0) {
             Log_debug(ud->log, "DROP message with no label");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         } else if (hdr->version_be == 0) {
             Log_debug(ud->log, "DROP message with no version");
-            return Error(INVALID);
+            return Error(msg, "INVALID");
         }
     }
 
@@ -241,7 +242,7 @@ static Iface_DEFUN incomingFromSessionManagerIf(struct Message* msg, struct Ifac
         return Iface_next(&ud->pub.ipTunnelIf, msg);
     }
     Log_debug(ud->log, "DROP message with unknown type [%d]", type);
-    return Error(INVALID);
+    return Error(msg, "INVALID");
 }
 
 int UpperDistributor_unregisterHandler(struct UpperDistributor* upper, int udpPort)

+ 17 - 8
node_build/builder.js

@@ -568,19 +568,28 @@ const getLinkOrder = function (cFile, files) /*:string[]*/ {
 // make sure everything is present.
 const needsToLink = function (ctx, cFile) {
     const nlCache = {};
+    const nll = [];
     const nl = (cFile) => {
         if (nlCache[cFile]) { return false; }
-        //debug('  ' + cFile);
-        if (typeof(ctx.state.cFiles[cFile]) !== 'object') {
-            return true;
+        if (nll.indexOf(cFile) > -1) {
+            throw new Error(`File ${cFile} is self-referencial:\n${nll.join('\n')}\n\n`);
         }
-        for (const l of ctx.state.cFiles[cFile].links) {
-            if (l !== cFile && nl(l)) {
+        nll.push(cFile);
+        const out = (() => {
+            //debug('  ' + cFile);
+            if (typeof(ctx.state.cFiles[cFile]) !== 'object') {
                 return true;
             }
-        }
-        nlCache[cFile] = true;
-        return false;
+            for (const l of ctx.state.cFiles[cFile].links) {
+                if (l !== cFile && nl(l)) {
+                    return true;
+                }
+            }
+            nlCache[cFile] = true;
+            return false;
+        })();
+        if (nll.pop() !== cFile) { throw new Error(); }
+        return out;
     };
     return nl(cFile);
 };

+ 3 - 0
rust/cjdns_sys/RTypes.h

@@ -33,6 +33,8 @@ typedef enum {
   RTypes_CryptoAuth_State_t_Established = 100,
 } RTypes_CryptoAuth_State_t;
 
+typedef struct RTypes_Error_t RTypes_Error_t;
+
 typedef struct {
   Iface_t *internal;
   Iface_t *external;
@@ -77,6 +79,7 @@ typedef struct {
   RTypes_CryptoAuth_State_t c;
   RTypes_CryptoStats_t d;
   RTypes_CryptoAuth2_Session_t e;
+  RTypes_Error_t *f;
 } RTypes_ExportMe;
 
 #endif /* RTypes_H */

+ 2 - 1
rust/cjdns_sys/RTypesPrefix.h

@@ -2,6 +2,7 @@
 #define RTYPESPREFIX_H
 
 #include "benc/String.h"
-#include "interface/Iface.h"
+
+typedef struct Iface Iface_t;
 
 #endif

+ 6 - 0
rust/cjdns_sys/Rffi.h

@@ -56,4 +56,10 @@ void Rffi_panic(const char *msg);
 
 void Rffi_setLogger(Log_t *l);
 
+RTypes_Error_t *Rffi_error(const char *msg, Allocator_t *alloc);
+
+RTypes_Error_t *Rffi_error_fl(const char *msg, const char *file, int line, Allocator_t *alloc);
+
+const char *Rffi_printError(RTypes_Error_t *e, Allocator_t *alloc);
+
 #endif /* rffi_H */

+ 2 - 1
rust/cjdns_sys/RffiPrefix.h

@@ -2,6 +2,7 @@
 #define RFFIPREFIX_H
 
 #include "rust/cjdns_sys/RTypes.h"
-#include "rust/cjdns_sys/cffi.h"
+#include "util/log/Log.h"
+#include "crypto/random/Random.h"
 
 #endif

+ 33 - 58
rust/cjdns_sys/src/cffi.rs

@@ -248,28 +248,36 @@ extern "C" {
         line: ::std::os::raw::c_int,
     ) -> *mut Allocator;
 }
+pub type Iface_t = Iface;
 #[repr(u32)]
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum Error_e {
-    Error_NONE = 0,
-    Error_MALFORMED_ADDRESS = 1,
-    Error_FLOOD = 2,
-    Error_LINK_LIMIT_EXCEEDED = 3,
-    Error_OVERSIZE_MESSAGE = 4,
-    Error_RUNT = 5,
-    Error_AUTHENTICATION = 6,
-    Error_INVALID = 7,
-    Error_UNDELIVERABLE = 8,
-    Error_LOOP_ROUTE = 9,
-    Error_RETURN_PATH_INVALID = 10,
-    Error_UNHANDLED = 11,
-    Error_OVERFLOW = 12,
-    Error_INTERNAL = 13,
+pub enum RTypes_CryptoAuth_State_t {
+    RTypes_CryptoAuth_State_t_Init = 0,
+    RTypes_CryptoAuth_State_t_SentHello = 1,
+    RTypes_CryptoAuth_State_t_ReceivedHello = 2,
+    RTypes_CryptoAuth_State_t_SentKey = 3,
+    RTypes_CryptoAuth_State_t_ReceivedKey = 4,
+    RTypes_CryptoAuth_State_t_Established = 100,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RTypes_Error_t {
+    _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct RTypes_StrList_t {
+    pub len: usize,
+    pub items: *mut *mut String_t,
 }
 #[repr(C)]
 #[derive(Debug, Copy, Clone)]
-pub struct Error_s {
-    pub e: Error_e,
+pub struct RTypes_CryptoStats_t {
+    pub lost_packets: u64,
+    pub received_unexpected: u64,
+    pub received_packets: u64,
+    pub duplicate_packets: u64,
+    pub noise_proto: bool,
 }
 #[repr(C)]
 #[derive(Debug, Copy, Clone)]
@@ -330,7 +338,7 @@ extern "C" {
     pub fn Message_clone(toClone: *mut Message, alloc: *mut Allocator) -> *mut Message;
 }
 pub type Iface_Callback = ::std::option::Option<
-    unsafe extern "C" fn(message: *mut Message, thisInterface: *mut Iface) -> Error_s,
+    unsafe extern "C" fn(message: *mut Message, thisInterface: *mut Iface) -> *mut RTypes_Error_t,
 >;
 #[repr(C)]
 #[derive(Debug, Copy, Clone)]
@@ -339,9 +347,11 @@ pub struct Iface {
     pub currentMsg: *mut Message,
     pub connectedIf: *mut Iface,
 }
-pub type Iface_t = Iface;
 extern "C" {
-    pub fn Iface_incomingFromRust(message: *mut Message, thisInterface: *mut Iface) -> Error_s;
+    pub fn Iface_incomingFromRust(
+        message: *mut Message,
+        thisInterface: *mut Iface,
+    ) -> *mut RTypes_Error_t;
 }
 extern "C" {
     pub fn RustIface_gotIncoming();
@@ -352,30 +362,6 @@ extern "C" {
 extern "C" {
     pub fn RustIface_dropped();
 }
-#[repr(u32)]
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum RTypes_CryptoAuth_State_t {
-    RTypes_CryptoAuth_State_t_Init = 0,
-    RTypes_CryptoAuth_State_t_SentHello = 1,
-    RTypes_CryptoAuth_State_t_ReceivedHello = 2,
-    RTypes_CryptoAuth_State_t_SentKey = 3,
-    RTypes_CryptoAuth_State_t_ReceivedKey = 4,
-    RTypes_CryptoAuth_State_t_Established = 100,
-}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RTypes_StrList_t {
-    pub len: usize,
-    pub items: *mut *mut String_t,
-}
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct RTypes_CryptoStats_t {
-    pub lost_packets: u64,
-    pub received_unexpected: u64,
-    pub received_packets: u64,
-    pub duplicate_packets: u64,
-}
 #[repr(C)]
 #[derive(Copy, Clone)]
 pub struct Except {
@@ -427,14 +413,6 @@ extern "C" {
         ...
     );
 }
-extern "C" {
-    pub fn Log_shouldLog(
-        log: *mut Log,
-        logLevel: Log_Level,
-        file: *const ::std::os::raw::c_char,
-        line: ::std::os::raw::c_int,
-    ) -> bool;
-}
 extern "C" {
     pub fn Log_print0(
         log: *mut Log,
@@ -565,17 +543,15 @@ extern "C" {
         useNoise: bool,
     ) -> *mut CryptoAuth_Session;
 }
-#[cfg(test)]
-extern "C" { // Used in unit tests only
+extern "C" {
     pub fn CryptoAuth_encrypt(
         session: *mut CryptoAuth_Session,
         msg: *mut Message,
     ) -> ::std::os::raw::c_int;
 }
-#[cfg(test)]
 #[repr(u32)]
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum CryptoAuth_DecryptErr { // Used in unit tests only
+pub enum CryptoAuth_DecryptErr {
     CryptoAuth_DecryptErr_NONE = 0,
     CryptoAuth_DecryptErr_RUNT = 1,
     CryptoAuth_DecryptErr_NO_SESSION = 2,
@@ -593,8 +569,7 @@ pub enum CryptoAuth_DecryptErr { // Used in unit tests only
     CryptoAuth_DecryptErr_REPLAY = 14,
     CryptoAuth_DecryptErr_DECRYPT = 15,
 }
-#[cfg(test)]
-extern "C" { // Used in unit tests only
+extern "C" {
     pub fn CryptoAuth_decrypt(
         sess: *mut CryptoAuth_Session,
         msg: *mut Message,

+ 1 - 1
rust/cjdns_sys/src/crypto/crypto_auth.rs

@@ -1208,7 +1208,7 @@ impl IfRecv for CiphertextRecv {
                 }
             }
             Err(e) => {
-                log::debug!("Error decrypting {} {}", e, m.len());
+                log::debug!("Error decrypting {}", e);
                 let ee = match e.downcast_ref::<DecryptError>() {
                     Some(ee) => match ee {
                         DecryptError::DecryptErr(ee) => ee,

+ 17 - 15
rust/cjdns_sys/src/external/interface/cif.rs

@@ -1,6 +1,7 @@
-use anyhow::{bail, Result};
+use anyhow::Result;
 
-use crate::cffi::{self, Allocator, Error_e, Error_s};
+use crate::cffi::{self, Allocator};
+use crate::rtypes::RTypes_Error_t;
 use crate::external::interface::iface::{self, IfRecv, Iface, IfacePvt};
 use crate::external::memory::allocator;
 use crate::interface::wire::message::Message;
@@ -12,12 +13,12 @@ struct CRecv {
 impl IfRecv for CRecv {
     fn recv(&self, m: &mut Message) -> Result<()> {
         let c_msg = m.as_c_message();
-        let ers = unsafe { cffi::Iface_incomingFromRust(c_msg, self.c_iface) };
-        match ers.e {
-            Error_e::Error_NONE => Ok(()),
-            _ => {
-                bail!("Error from C code {}", ers.e as usize);
-            }
+        unsafe {
+            (cffi::Iface_incomingFromRust(c_msg, self.c_iface) as *mut RTypes_Error_t).as_mut()
+                .map(|e|e.e.take())
+                .flatten()
+                .map(|e|Err(e))
+                .unwrap_or(Ok(()))
         }
     }
 }
@@ -34,7 +35,7 @@ struct CIface {
 // This is an assertion to make sure we're being passed something legit from C
 const IFACE_IDENT: u32 = 0xdeadbeef;
 
-unsafe extern "C" fn from_c(msg: *mut cffi::Message, iface_p: *mut cffi::Iface) -> Error_s {
+unsafe extern "C" fn from_c(msg: *mut cffi::Message, iface_p: *mut cffi::Iface) -> *mut cffi::RTypes_Error_t {
     let iface = (iface_p as *mut CIface).as_ref().unwrap();
 
     // We're getting called from C with a ffi::Iface which is supposed to be one of ours
@@ -42,15 +43,16 @@ unsafe extern "C" fn from_c(msg: *mut cffi::Message, iface_p: *mut cffi::Iface)
     // check that this field id_tag is equal to the value we set it to initially.
     assert!(iface.id_tag == IFACE_IDENT);
 
+    let alloc = (*msg)._alloc;
+
     let mut msg = Message::from_c_message(msg);
     match iface.rif.send(&mut msg) {
         // TODO: we need better error handling
-        Ok(_) => Error_s {
-            e: Error_e::Error_NONE,
-        },
-        Err(_) => Error_s {
-            e: Error_e::Error_INTERNAL,
-        },
+        Ok(_) => std::ptr::null_mut(),
+        Err(e) => {
+            let e: *mut RTypes_Error_t = allocator::adopt(alloc, RTypes_Error_t { e: Some(e) });
+            e as *mut cffi::RTypes_Error_t
+        }
     }
 }
 

+ 40 - 0
rust/cjdns_sys/src/rffi.rs

@@ -268,3 +268,43 @@ pub unsafe extern "C" fn Rffi_panic(msg: *const c_char) -> ! {
 pub unsafe extern "C" fn Rffi_setLogger(l: *mut cffi::Log_t) {
     crate::cjdnslog::set_ffi_logger(l);
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn Rffi_error(
+    msg: *const c_char,
+    alloc: *mut Allocator_t,
+) -> *mut RTypes_Error_t {
+    let s = std::ffi::CStr::from_ptr(msg).to_string_lossy();
+    allocator::adopt(alloc, RTypes_Error_t { e: Some(anyhow::anyhow!(s)) })
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Rffi_error_fl(
+    msg: *const c_char,
+    file: *const c_char,
+    line: c_int,
+    alloc: *mut Allocator_t,
+) -> *mut RTypes_Error_t {
+    let s = std::ffi::CStr::from_ptr(msg).to_string_lossy();
+    let f = std::ffi::CStr::from_ptr(file).to_string_lossy();
+    let ss = format!("{}:{}: {}", f, line, s);
+    allocator::adopt(alloc, RTypes_Error_t { e: Some(anyhow::anyhow!(ss)) })
+}
+
+fn str_to_c(s: &str, alloc: *mut Allocator_t) -> *const c_char {
+    let c_str = std::ffi::CString::new(s).unwrap();
+    let adopted = allocator::adopt(alloc, c_str);
+    return (*adopted).as_ptr()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Rffi_printError(
+    e: *mut RTypes_Error_t,
+    alloc: *mut Allocator_t,
+) -> *const c_char {
+    e.as_ref()
+        .map(|e|e.e.as_ref())
+        .flatten()
+        .map(|e|str_to_c(&format!("{:?}", e), alloc))
+        .unwrap_or_else(std::ptr::null)
+}

+ 5 - 0
rust/cjdns_sys/src/rtypes.rs

@@ -64,6 +64,10 @@ pub struct RTypes_CryptoAuth2_Session_t {
     pub ciphertext: *mut cffi::Iface_t,
 }
 
+pub struct RTypes_Error_t {
+    pub e: Option<anyhow::Error>,
+}
+
 #[allow(dead_code)]
 #[repr(C)]
 pub struct RTypes_ExportMe {
@@ -72,4 +76,5 @@ pub struct RTypes_ExportMe {
     c: RTypes_CryptoAuth_State_t,
     d: RTypes_CryptoStats_t,
     e: RTypes_CryptoAuth2_Session_t,
+    f: *mut RTypes_Error_t,
 }

+ 10 - 9
subnode/MsgCore.c

@@ -27,6 +27,7 @@
 #include "wire/Message.h"
 #include "wire/DataHeader.h"
 #include "wire/RouteHeader.h"
+#include "wire/Error.h"
 
 #define DEFAULT_TIMEOUT_MILLISECONDS 6000
 
@@ -83,7 +84,7 @@ static Iface_DEFUN replyMsg(struct MsgCore_pvt* mcp,
     String* txid = Dict_getStringC(content, "txid");
     if (!txid) {
         Log_debug(mcp->log, "DROP Message with no txid");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     struct ReplyContext* rc = Allocator_calloc(Message_getAlloc(msg), sizeof(struct ReplyContext), 1);
@@ -96,7 +97,7 @@ static Iface_DEFUN replyMsg(struct MsgCore_pvt* mcp,
     // Pops out in pingerOnResponse() if the reply is indeed valid...
     Pinger_pongReceived(txid, mcp->pinger);
     mcp->currentReply = NULL;
-    return Error(NONE);
+    return NULL;
 }
 
 static void pingerOnResponse(String* data, uint32_t milliseconds, void* context)
@@ -244,7 +245,7 @@ static Iface_DEFUN queryMsg(struct MsgCore_pvt* mcp,
     } else {
         return qh->pub.cb(content, src, Message_getAlloc(msg), &qh->pub);
     }
-    return Error(INVALID);
+    return Error(msg, "INVALID");
 }
 
 static int qhOnFree(struct Allocator_OnFreeJob* job)
@@ -301,18 +302,18 @@ static Iface_DEFUN incoming(struct Message* msg, struct Iface* interRouterIf)
     if (!content) {
         char* esc = Escape_getEscaped(msgBytes, length, Message_getAlloc(msg));
         Log_debug(mcp->log, "DROP Malformed message [%s]", esc);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     int64_t* verP = Dict_getIntC(content, "p");
     if (!verP) {
         Log_debug(mcp->log, "DROP Message without version");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
     addr.protocolVersion = *verP;
     if (!addr.protocolVersion) {
         Log_debug(mcp->log, "DROP Message with zero version");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     String* q = Dict_getStringC(content, "q");
@@ -320,7 +321,7 @@ static Iface_DEFUN incoming(struct Message* msg, struct Iface* interRouterIf)
     String* txid = Dict_getStringC(content, "txid");
     if (!txid || !txid->len) {
         Log_debug(mcp->log, "Message with no txid [%s]", q ? (q->bytes) : "(no query)");
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     if (q) {
@@ -328,14 +329,14 @@ static Iface_DEFUN incoming(struct Message* msg, struct Iface* interRouterIf)
             return queryMsg(mcp, content, &addr, msg);
         } else {
             // Let the old pathfinder handle every query if it is present
-            return Error(NONE);
+            return NULL;
         }
     } else if (txid->len >= 2 && txid->bytes[0] == '0' && txid->bytes[1] == '1') {
         txid->bytes = &txid->bytes[2];
         txid->len -= 2;
         return replyMsg(mcp, content, &addr, msg);
     }
-    return Error(INVALID);
+    return Error(msg, "INVALID");
 }
 
 struct MsgCore* MsgCore_new(struct EventBase* base,

+ 1 - 1
subnode/MsgCore.h

@@ -29,7 +29,7 @@ Linker_require("subnode/MsgCore.c")
 struct MsgCore_Handler;
 struct MsgCore;
 
-typedef struct Error_s (* MsgCore_HandlerCb)(Dict* msg,
+typedef struct RTypes_Error_t* (* MsgCore_HandlerCb)(Dict* msg,
                                              struct Address* src,
                                              struct Allocator* tmpAlloc,
                                              struct MsgCore_Handler* handler);

+ 5 - 4
subnode/PingResponder.c

@@ -15,6 +15,7 @@
 #include "benc/Dict.h"
 #include "subnode/PingResponder.h"
 #include "util/Identity.h"
+#include "wire/Error.h"
 
 struct PingResponder_pvt
 {
@@ -29,7 +30,7 @@ struct PingResponder_pvt
     Identity
 };
 
-static struct Error_s onPing(Dict* msg,
+static struct RTypes_Error_t* onPing(Dict* msg,
                              struct Address* src,
                              struct Allocator* tmpAlloc,
                              struct MsgCore_Handler* handler)
@@ -40,7 +41,7 @@ static struct Error_s onPing(Dict* msg,
     String* txid = Dict_getStringC(msg, "txid");
     if (!txid) {
         Log_debug(prp->log, "ping missing txid");
-        return Error(INVALID);
+        return Rffi_error("INVALID", tmpAlloc);
     }
 
     Dict* responseDict = Dict_new(tmpAlloc);
@@ -59,14 +60,14 @@ static struct Error_s onPing(Dict* msg,
             "respect do-not-disturb",
             Address_toString(src, tmpAlloc)->bytes,
             src->protocolVersion);
-        return Error(UNHANDLED);
+        return Rffi_error("UNHANDLED", tmpAlloc);
     }
 
     Dict_putStringC(responseDict, "txid", txid, tmpAlloc);
     Dict_putIntC(msg, "dnd", 1, tmpAlloc); // do not disturb
     BoilerplateResponder_addBoilerplate(prp->br, responseDict, src, tmpAlloc);
     MsgCore_sendResponse(prp->msgCore, responseDict, src, tmpAlloc);
-    return Error(NONE);
+    return NULL;
 }
 
 struct PingResponder* PingResponder_new(struct Allocator* allocator,

+ 12 - 12
subnode/SubnodePathfinder.c

@@ -118,7 +118,7 @@ static Iface_DEFUN connected(struct SubnodePathfinder_pvt* pf, struct Message* m
 {
     Log_debug(pf->log, "INIT");
     pf->state = SubnodePathfinder_pvt_state_RUNNING;
-    return Error(NONE);
+    return NULL;
 }
 
 static uint32_t addressForNode(struct Address* addrOut, struct Message* msg)
@@ -147,8 +147,8 @@ static Iface_DEFUN switchErr(struct Message* msg, struct SubnodePathfinder_pvt*
         uint8_t pathStr[20];
         AddrTools_printPath(pathStr, path);
         int err = Endian_bigEndianToHost32(switchErr.ctrlErr.errorType_be);
-        Log_debug(pf->log, "switch err from active snode [%s] type [%s][%d]",
-            pathStr, Error_strerror(err), err);
+        Log_debug(pf->log, "switch err from active snode [%s] type [%d]",
+            pathStr, err);
         pf->pub.snh->snodeIsReachable = false;
         if (pf->pub.snh->onSnodeUnreachable) {
             pf->pub.snh->onSnodeUnreachable(pf->pub.snh, 0, 0);
@@ -159,7 +159,7 @@ static Iface_DEFUN switchErr(struct Message* msg, struct SubnodePathfinder_pvt*
     // we only really have the ability to report a node with known IPv6 address
     // so we will need to add a new event type to PFChan.
 
-    return Error(NONE);
+    return NULL;
 }
 
 struct SnodeQuery {
@@ -243,7 +243,7 @@ static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt*
     Er_assert(Message_epop(msg, addr, 16));
     Er_assert(Message_epop32be(msg));
     uint32_t version = Er_assert(Message_epop32be(msg));
-    if (version && version < 20) { return Error(UNHANDLED); }
+    if (version && version < 20) { return Error(msg, "UNHANDLED"); }
     Assert_true(!Message_getLength(msg));
     uint8_t printedAddr[40];
     AddrTools_printIp(printedAddr, addr);
@@ -268,7 +268,7 @@ static Iface_DEFUN searchReq(struct Message* msg, struct SubnodePathfinder_pvt*
     }
 
     queryRs(pf, addr, printedAddr);
-    return Error(NONE);
+    return NULL;
 }
 
 static void rcChange(struct ReachabilityCollector* rc,
@@ -385,7 +385,7 @@ static Iface_DEFUN session(struct Message* msg, struct SubnodePathfinder_pvt* pf
     String* str = Address_toString(&addr, Message_getAlloc(msg));
     Log_debug(pf->log, "Session [%s]", str->bytes);
     //if (addr.protocolVersion) { NodeCache_discoverNode(pf->nc, &addr); }
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN sessionEnded(struct Message* msg, struct SubnodePathfinder_pvt* pf)
@@ -395,7 +395,7 @@ static Iface_DEFUN sessionEnded(struct Message* msg, struct SubnodePathfinder_pv
     String* str = Address_toString(&addr, Message_getAlloc(msg));
     Log_debug(pf->log, "Session ended [%s]", str->bytes);
     //NodeCache_forgetNode(pf->nc, &addr);
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN discoveredPath(struct Message* msg, struct SubnodePathfinder_pvt* pf)
@@ -404,7 +404,7 @@ static Iface_DEFUN discoveredPath(struct Message* msg, struct SubnodePathfinder_
     //addressForNode(&addr, msg);
     //Log_debug(pf->log, "discoveredPath(%s)", Address_toString(&addr, Message_getAlloc(msg))->bytes);
     //if (addr.protocolVersion) { NodeCache_discoverNode(pf->nc, &addr); }
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN handlePing(struct Message* msg, struct SubnodePathfinder_pvt* pf)
@@ -417,7 +417,7 @@ static Iface_DEFUN handlePing(struct Message* msg, struct SubnodePathfinder_pvt*
 static Iface_DEFUN handlePong(struct Message* msg, struct SubnodePathfinder_pvt* pf)
 {
     //Log_debug(pf->log, "Received pong");
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN ctrlMsgFromSwitchPinger(struct Message* msg, struct Iface* iface)
@@ -445,7 +445,7 @@ static Iface_DEFUN unsetupSession(struct Message* msg, struct SubnodePathfinder_
     Bits_memcpy(addr.ip6.bytes, node.ip6, 16);
     Bits_memcpy(addr.key, node.publicKey, 32);
     pingNode(pf, &addr);
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingMsg(struct Message* msg, struct SubnodePathfinder_pvt* pf)
@@ -465,7 +465,7 @@ static Iface_DEFUN linkState(struct Message* msg, struct SubnodePathfinder_pvt*
             lse.sumOfDrops,
             lse.sumOfKb);
     }
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingFromMsgCore(struct Message* msg, struct Iface* iface)

+ 1 - 1
subnode/SupernodeHunter.c

@@ -243,7 +243,7 @@ static void updateSnodePath(struct SupernodeHunter_pvt* snp)
     Dict* msg = qp->msg = Dict_new(qp->alloc);
     qp->cb = updateSnodePath2;
     qp->userData = q;
-    qp->target = Address_clone(&snp->pub.snodeAddr, qp->alloc);;
+    qp->target = Address_clone(&snp->pub.snodeAddr, qp->alloc);
 
     Log_debug(snp->log, "Update snode [%s] path", Address_toString(qp->target, qp->alloc)->bytes);
     Dict_putStringCC(msg, "sq", "gr", qp->alloc);

+ 4 - 4
switch/SwitchCore.c

@@ -71,14 +71,14 @@ static inline Iface_DEFUN sendError(struct SwitchInterface* iface,
 {
     if (Message_getLength(cause) < SwitchHeader_SIZE + 4) {
         Log_debug(logger, "runt");
-        return Error(RUNT);
+        return Error(cause, "RUNT");
     }
 
     struct SwitchHeader* causeHeader = (struct SwitchHeader*) cause->msgbytes;
 
     if (SwitchHeader_getSuppressErrors(causeHeader)) {
         // don't send errors if they're asking us to suppress them!
-        return Error(NONE);
+        return NULL;
     }
 
     // limit of 256 bytes
@@ -120,7 +120,7 @@ static Iface_DEFUN receiveMessage(struct Message* message, struct Iface* iface)
 
     if (Message_getLength(message) < SwitchHeader_SIZE) {
         Log_debug(core->logger, "DROP runt");
-        return Error(RUNT);
+        return Error(message, "RUNT");
     }
 
     struct SwitchHeader* header = (struct SwitchHeader*) message->msgbytes;
@@ -214,7 +214,7 @@ static Iface_DEFUN receiveMessage(struct Message* message, struct Iface* iface)
     if (labelShift > 63) {
         // TODO(cjd): hmm should we return an error packet?
         Log_debug(core->logger, "Label rolled over");
-        return Error(UNDELIVERABLE);
+        return Error(message, "UNDELIVERABLE");
     }
     SwitchHeader_setLabelShift(header, labelShift);
     SwitchHeader_setTrafficClass(header, 0xffff);

+ 2 - 2
test/Beacon_test.c

@@ -76,7 +76,7 @@ static Iface_DEFUN incomingTunB(struct Message* msg, struct Iface* tunB)
     Er_assert(Message_eshift(msg, -Headers_IP6Header_SIZE));
     printf("Message from TUN in node B [%s]\n", msg->msgbytes);
     tn->messageFrom = TUNB;
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingTunA(struct Message* msg, struct Iface* tunA)
@@ -89,7 +89,7 @@ static Iface_DEFUN incomingTunA(struct Message* msg, struct Iface* tunA)
     Hex_encode(buff, 1024, msg->msgbytes, Message_getLength(msg));
     printf("Message from TUN in node A [%s] [%d] [%s]\n", msg->msgbytes, Message_getLength(msg), buff);
     tn->messageFrom = TUNA;
-    return Error(NONE);
+    return NULL;
 }
 
 static void notLinkedYet(struct TwoNodes* ctx)

+ 1 - 1
test/Main_fuzz_test.c

@@ -54,7 +54,7 @@ struct Context
 
 static Iface_DEFUN incomingTun(struct Message* msg, struct Iface* tunB)
 {
-    return Error(NONE);
+    return NULL;
 }
 
 static void notLinkedYet(struct Context* ctx)

+ 22 - 22
tunnel/IpTunnel.c

@@ -361,7 +361,7 @@ static Iface_DEFUN requestForAddresses(Dict* request,
 
     if (conn->isOutgoing) {
         Log_warn(context->logger, "got request for addresses from outgoing connection");
-        return Error(INVALID);
+        return Rffi_error("INVALID", requestAlloc);
     }
     Dict* addresses = Dict_new(requestAlloc);
     bool noAddresses = true;
@@ -396,7 +396,7 @@ static Iface_DEFUN requestForAddresses(Dict* request,
     if (noAddresses) {
         Log_warn(context->logger, "no addresses to provide");
         // The message is ok, this one is our fault
-        return Error(NONE);
+        return NULL;
     }
 
     Dict* msg = Dict_new(requestAlloc);
@@ -408,7 +408,7 @@ static Iface_DEFUN requestForAddresses(Dict* request,
     }
 
     sendControlMessage(msg, conn, requestAlloc, context);
-    return Error(NONE);
+    return NULL;
 }
 
 static void addAddress(char* printedAddr, uint8_t prefixLen,
@@ -456,20 +456,20 @@ static Iface_DEFUN incomingAddresses(Dict* d,
 {
     if (!conn->isOutgoing) {
         Log_warn(context->logger, "got offer of addresses from incoming connection");
-        return Error(INVALID);
+        return Rffi_error("INVALID", alloc);
     }
 
     String* txid = Dict_getStringC(d, "txid");
     if (!txid || txid->len != 4) {
         Log_info(context->logger, "missing or wrong length txid");
-        return Error(INVALID);
+        return Rffi_error("INVALID", alloc);
     }
 
     int number;
     Bits_memcpy(&number, txid->bytes, 4);
     if (number < 0 || number >= (int)context->nextConnectionNumber) {
         Log_info(context->logger, "txid out of range");
-        return Error(INVALID);
+        return Rffi_error("INVALID", alloc);
     }
 
     if (number != conn->number) {
@@ -480,7 +480,7 @@ static Iface_DEFUN incomingAddresses(Dict* d,
                                 32))
                 {
                     Log_info(context->logger, "txid doesn't match origin");
-                    return Error(INVALID);
+                    return Rffi_error("INVALID", alloc);
                 } else {
                     conn = &context->pub.connectionList.connections[i];
                 }
@@ -557,16 +557,16 @@ static Iface_DEFUN incomingAddresses(Dict* d,
         String* tunName = GlobalConfig_getTunName(context->globalConf);
         if (!tunName) {
             Log_error(context->logger, "Failed to set routes because TUN interface is not setup");
-            return Error(INVALID);
+            return Rffi_error("INVALID", alloc);
         }
         struct Er_Ret* er = NULL;
         Er_check(&er, RouteGen_commit(context->rg, tunName->bytes, alloc));
         if (er) {
             Log_error(context->logger, "Error setting routes for TUN [%s]", er->message);
-            return Error(INVALID);
+            return Rffi_error("INVALID", alloc);
         }
     }
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN incomingControlMessage(struct Message* message,
@@ -581,7 +581,7 @@ static Iface_DEFUN incomingControlMessage(struct Message* message,
 
     // This aligns the message on the content.
     if (isControlMessageInvalid(message, context)) {
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
 
     Log_debug(context->logger, "Message content [%s]",
@@ -593,7 +593,7 @@ static Iface_DEFUN incomingControlMessage(struct Message* message,
     const char* err = BencMessageReader_readNoExcept(message, alloc, &d);
     if (err) {
         Log_info(context->logger, "Failed to parse message [%s]", err);
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
 
     if (Dict_getDictC(d, "addresses")) {
@@ -605,7 +605,7 @@ static Iface_DEFUN incomingControlMessage(struct Message* message,
         return requestForAddresses(d, conn, alloc, context);
     }
     Log_warn(context->logger, "Message which is unhandled");
-    return Error(INVALID);
+    return Error(message, "INVALID");
 }
 
 #define GET64(buffer) \
@@ -699,7 +699,7 @@ static Iface_DEFUN incomingFromTun(struct Message* message, struct Iface* tunIf)
 
     if (Message_getLength(message) < 20) {
         Log_debug(context->logger, "DROP runt");
-        return Error(RUNT);
+        return Error(message, "RUNT");
     }
 
     struct IpTunnel_Connection* conn = NULL;
@@ -713,12 +713,12 @@ static Iface_DEFUN incomingFromTun(struct Message* message, struct Iface* tunIf)
         conn = findConnection(NULL, header->sourceAddr, true, context);
     } else {
         Log_debug(context->logger, "Message of unknown type from TUN");
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
 
     if (!conn) {
         Log_debug(context->logger, "Message with unrecognized address from TUN");
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
 
     return sendToNode(message, conn, context);
@@ -734,13 +734,13 @@ static Iface_DEFUN ip6FromNode(struct Message* message,
             return incomingControlMessage(message, conn, context);
         }
         Log_debug(context->logger, "Got message with zero address");
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
     if (!isValidAddress6(header->sourceAddr, false, conn)) {
         uint8_t addr[40];
         AddrTools_printIp(addr, header->sourceAddr);
         Log_debug(context->logger, "Got message with wrong address for connection [%s]", addr);
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
 
     Er_assert(TUNMessageType_push(message, Ethernet_TYPE_IP6));
@@ -754,7 +754,7 @@ static Iface_DEFUN ip4FromNode(struct Message* message,
     struct Headers_IP4Header* header = (struct Headers_IP4Header*) message->msgbytes;
     if (Bits_isZero(header->sourceAddr, 4) || Bits_isZero(header->destAddr, 4)) {
         Log_debug(context->logger, "Got message with zero address");
-        return Error(INVALID);
+        return Error(message, "INVALID");
     } else if (!isValidAddress4(header->sourceAddr, false, conn)) {
         Log_debug(context->logger, "Got message with wrong address [%d.%d.%d.%d] for connection "
                                    "[%d.%d.%d.%d/%d:%d]",
@@ -763,7 +763,7 @@ static Iface_DEFUN ip4FromNode(struct Message* message,
                   conn->connectionIp4[0], conn->connectionIp4[1],
                   conn->connectionIp4[2], conn->connectionIp4[3],
                   conn->connectionIp4Alloc, conn->connectionIp4Prefix);
-        return Error(INVALID);
+        return Error(message, "INVALID");
     }
 
     Er_assert(TUNMessageType_push(message, Ethernet_TYPE_IP4));
@@ -788,7 +788,7 @@ static Iface_DEFUN incomingFromNode(struct Message* message, struct Iface* nodeI
             AddrTools_printIp(addr, rh->ip6);
             Log_debug(context->logger, "Got message from unrecognized node [%s]", addr);
         }
-        return Error(NONE);
+        return NULL;
     }
 
     Er_assert(Message_eshift(message, -(RouteHeader_SIZE + DataHeader_SIZE)));
@@ -809,7 +809,7 @@ static Iface_DEFUN incomingFromNode(struct Message* message, struct Iface* nodeI
                   (Message_getLength(message) > 1) ? Headers_getIpVersion(message->msgbytes) : 0,
                   addr);
     }
-    return Error(INVALID);
+    return Error(message, "INVALID");
 }
 
 static void timeout(void* vcontext)

+ 2 - 2
tunnel/test/IpTunnel_test.c

@@ -97,7 +97,7 @@ static Iface_DEFUN responseWithIpCallback(struct Message* message, struct Iface*
     Assert_true(!Bits_memcmp(message->msgbytes, ctx->expectedResponse->bytes, Message_getLength(message)));
     ctx->called |= 2;
 
-    return Error(NONE);
+    return NULL;
 }
 
 static Iface_DEFUN messageToTun(struct Message* msg, struct Iface* iface)
@@ -120,7 +120,7 @@ static Iface_DEFUN messageToTun(struct Message* msg, struct Iface* iface)
         Assert_failure("unrecognized message type %u", (unsigned int)type);
     }
     Assert_true(Message_getLength(msg) == 12 && CString_strcmp(msg->msgbytes, "hello world") == 0);
-    return Error(NONE);
+    return NULL;
 }
 
 static void pushRouteDataHeaders(struct Context* ctx, struct Message* message)

+ 2 - 1
util/events/libuv/FakeNetwork.c

@@ -20,6 +20,7 @@
 #include "util/events/EventBase.h"
 #include "util/log/Log.h"
 #include "interface/ASynchronizer.h"
+#include "wire/Error.h"
 
 #define Map_USE_HASH
 #define Map_USE_COMPARATOR
@@ -90,7 +91,7 @@ static Iface_DEFUN fromAsync(struct Message* msg, struct Iface* fnpFromAsync)
         char* srcAddr = Sockaddr_print(dp, Message_getAlloc(msg));
 
         Log_debug(fnp->log, "Message with unknown dest address [%s] from [%s]", destAddr, srcAddr);
-        return Error(INVALID);
+        return Error(msg, "INVALID");
     }
 
     struct FakeNetwork_UDPIface_pvt* fnip = Identity_check(fnp->map.values[idx]);

+ 2 - 2
util/events/libuv/Pipe.c

@@ -130,7 +130,7 @@ static Iface_DEFUN sendMessage(struct Message* m, struct Iface* iface)
     struct Pipe_pvt* pipe = Identity_check((struct Pipe_pvt*) iface);
 
     if (pipe->queueLen > 50000) {
-        return Error(OVERFLOW);
+        return Error(m, "OVERFLOW");
     }
 
     // This allocator will hold the message allocator in existance after it is freed.
@@ -164,7 +164,7 @@ static Iface_DEFUN sendMessage(struct Message* m, struct Iface* iface)
             pipe->bufferedRequest = req;
         }
     }
-    return Error(NONE);
+    return NULL;
 }
 
 /** Asynchronous allocator freeing. */

+ 1 - 1
util/events/libuv/PipeServer.c

@@ -79,7 +79,7 @@ static Iface_DEFUN sendMessage(struct Message* m, struct Iface* iface)
     int idx = Map_Clients_indexForHandle(handle, &psp->clients);
     if (idx < 0) {
         Log_warn(psp->log, "Attempted to send a message to client [0x%x] which is gone", handle);
-        return Error(UNHANDLED);
+        return Error(m, "UNHANDLED");
     }
     struct Client* cli = psp->clients.values[idx];
     return Iface_next(&cli->iface, m);

+ 4 - 4
util/events/libuv/UDPAddrIface.c

@@ -86,13 +86,13 @@ static Iface_DEFUN incomingFromIface(struct Message* m, struct Iface* iface)
     if (((struct Sockaddr*)m->msgbytes)->flags & Sockaddr_flags_BCAST) {
         Log_debug(context->logger, "Attempted bcast, bcast unsupported");
         // bcast not supported.
-        return Error(UNHANDLED);
+        return Error(m, "UNHANDLED");
     }
 
     if (context->queueLen > UDPAddrIface_MAX_QUEUE) {
         Log_warn(context->logger, "DROP msg length [%d] to [%s] maximum queue length reached",
             Message_getLength(m), Sockaddr_print(context->pub.generic.addr, Message_getAlloc(m)));
-        return Error(OVERFLOW);
+        return Error(m, "OVERFLOW");
     }
 
     // This allocator will hold the message allocator in existance after it is freed.
@@ -124,11 +124,11 @@ static Iface_DEFUN incomingFromIface(struct Message* m, struct Iface* iface)
         Log_info(context->logger, "DROP Failed writing to UDPAddrIface [%s]",
                  uv_strerror(ret));
         Allocator_free(req->alloc);
-        return Error(UNHANDLED);
+        return Error(m, "UNHANDLED");
     }
     context->queueLen += Message_getLength(m);
 
-    return Error(NONE);
+    return NULL;
 }
 
 #if UDPAddrIface_PADDING_AMOUNT < 8

+ 2 - 2
util/test/Process_test.c

@@ -74,7 +74,7 @@ static Iface_DEFUN receiveMessageParent(struct Message* msg, struct Iface* iface
     Assert_true(Message_getLength(msg) == (int)CString_strlen(MESSAGEB)+1);
     Assert_true(!Bits_memcmp(msg->msgbytes, MESSAGEB, CString_strlen(MESSAGEB)+1));
     Allocator_free(c->alloc);
-    return Error(NONE);
+    return NULL;
 }
 
 static void timeout(void* vNULL)
@@ -122,7 +122,7 @@ static Iface_DEFUN receiveMessageChild(struct Message* msg, struct Iface* iface)
     // shutdown
     Allocator_free(c->alloc);
 
-    return Error(NONE);
+    return NULL;
 }
 
 static void child(char* name, struct Context* ctx)

+ 1 - 1
util/test/Seccomp_test.c

@@ -102,7 +102,7 @@ static Iface_DEFUN receiveMessageParent(struct Message* msg, struct Iface* iface
     Assert_true(Message_getLength(msg) == 3);
     Assert_true(!Bits_memcmp(msg->msgbytes, "OK", 3));
     EventBase_endLoop(ctx->eventBase);
-    return Error(NONE);
+    return NULL;
 }
 
 int main(int argc, char** argv)

+ 9 - 26
wire/Error.h

@@ -15,6 +15,9 @@
 #ifndef Error_H
 #define Error_H
 
+#include "rust/cjdns_sys/Rffi.h"
+#include "wire/Message.h"
+
 enum Error_e {
     /** No error, everything is ok. */
     Error_NONE =                0,
@@ -59,31 +62,11 @@ enum Error_e {
     Error_INTERNAL =            13,
 };
 
-struct Error_s {
-    enum Error_e e;
-};
-
-#define Error(x) ((struct Error_s){ .e = Error_ ## x })
-
-static inline char* Error_strerror(int err)
-{
-    switch (err) {
-        case Error_NONE:                return "Error_NONE";
-        case Error_MALFORMED_ADDRESS:   return "Error_MALFORMED_ADDRESS";
-        case Error_FLOOD:               return "Error_FLOOD";
-        case Error_LINK_LIMIT_EXCEEDED: return "Error_LINK_LIMIT_EXCEEDED";
-        case Error_OVERSIZE_MESSAGE:    return "Error_OVERSIZE_MESSAGE";
-        case Error_RUNT:                return "Error_RUNT";
-        case Error_AUTHENTICATION:      return "Error_AUTHENTICATION";
-        case Error_INVALID:             return "Error_INVALID";
-        case Error_UNDELIVERABLE:       return "Error_UNDELIVERABLE";
-        case Error_LOOP_ROUTE:          return "Error_LOOP_ROUTE";
-        case Error_RETURN_PATH_INVALID: return "Error_RETURN_PATH_INVALID";
-        case Error_UNHANDLED:           return "Error_UNHANDLED";
-        case Error_INTERNAL:            return "Error_INTERNAL";
-        default: return "UNKNOWN";
-    }
-}
-
+#define Error(m, ...) \
+    Rffi_error_fl( \
+        String_printf(Message_getAlloc(m), __VA_ARGS__)->bytes, \
+        Gcc_SHORT_FILE, \
+        Gcc_LINE, \
+        Message_getAlloc(m))
 
 #endif