Pārlūkot izejas kodu

checkin before sed run

Caleb James DeLisle 9 gadi atpakaļ
vecāks
revīzija
6e61b3959b
7 mainītis faili ar 308 papildinājumiem un 218 dzēšanām
  1. 8 7
      interface/DNSServer.c
  2. 15 20
      interface/FramingIface.c
  3. 144 95
      net/SessionManager.c
  4. 63 3
      net/SessionManager.h
  5. 10 13
      net/SessionManager_admin.c
  6. 34 48
      net/SessionTable.c
  7. 34 32
      net/SessionTable.h

+ 8 - 7
interface/DNSServer.c

@@ -390,11 +390,11 @@ struct DNSServer_RainflyRequest
     Identity
 };
 
-static Iface_DEFUN onRainflyReplyB(struct DNSServer_RainflyRequest* lookup,
-                                   struct DNSServer_pvt* ctx,
-                                   Dict* value,
-                                   enum RainflyClient_ResponseCode code,
-                                   struct Except* eh)
+static void onRainflyReplyB(struct DNSServer_RainflyRequest* lookup,
+                            struct DNSServer_pvt* ctx,
+                            Dict* value,
+                            enum RainflyClient_ResponseCode code,
+                            struct Except* eh)
 {
     struct DNSServer_Message* dmesg = lookup->dmesg;
     struct DNSServer_Question* q = dmesg->questions[0];
@@ -428,7 +428,8 @@ static Iface_DEFUN onRainflyReplyB(struct DNSServer_RainflyRequest* lookup,
         dmesg->additionals = NULL;
         Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
         dmesg->flags.responseCode = ResponseCode_NO_ERROR;
-        return sendResponse(lookup->msg, dmesg, lookup->addr, ctx, eh);
+        Iface_CALL(sendResponse, lookup->msg, dmesg, lookup->addr, ctx, eh);
+        return;
     }
 
     Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
@@ -436,7 +437,7 @@ static Iface_DEFUN onRainflyReplyB(struct DNSServer_RainflyRequest* lookup,
     dmesg->answers = NULL;
     dmesg->authorities = NULL;
     dmesg->additionals = NULL;
-    return sendResponse(lookup->msg, dmesg, lookup->addr, ctx, eh);
+    Iface_CALL(sendResponse, lookup->msg, dmesg, lookup->addr, ctx, eh);
 }
 
 

+ 15 - 20
interface/FramingIface.c

@@ -73,13 +73,13 @@ static struct Message* mergeMessage(struct FramingIface_pvt* fi, struct Message*
     return out;
 }
 
-static uint8_t receiveMessage(struct Message* msg, struct Iface* iface)
+static Iface_DEFUN receiveMessage(struct Iface* iface, struct Message* msg)
 {
-    struct FramingIface_pvt* fi =
-        Identity_check((struct FramingIface_pvt*)iface->receiverContext);
+    struct FramingIface_pvt* fi = Identity_containerOf(streamIf, struct FramingIface_pvt, streamIf);
 
     if (fi->bytesRemaining > fi->maxMessageSize) {
-        return Error_OVERSIZE_MESSAGE;
+        // Oversize message
+        return NULL;
     }
 
     if (fi->frameParts) {
@@ -152,29 +152,24 @@ static uint8_t receiveMessage(struct Message* msg, struct Iface* iface)
     }
 }
 
-static uint8_t sendMessage(struct Message* msg, struct Iface* iface)
+static Iface_DEFUN sendMessage(struct Iface* messageIf, struct Message* msg)
 {
-    struct FramingIface_pvt* fi = Identity_check((struct FramingIface_pvt*)iface);
-
-    int32_t length_be = Endian_hostToBigEndian32((uint32_t)msg->length);
-    Message_push(msg, &length_be, 4, NULL);
-
-    return Interface_sendMessage(fi->wrapped, msg);
+    struct FramingIface_pvt* fi =
+        Identity_containerOf(messageIf, struct FramingIface_pvt, messageIf);
+    Message_32(msg, msg->length, NULL);
+    return Iface_next(&fi->streamIf, msg);
 }
 
-struct Iface* FramingIface_new(uint32_t maxMessageSize,
-                                       struct Iface* toWrap,
-                                       struct Allocator* alloc)
+struct Iface* FramingIface_new(uint32_t maxMsgSize, struct Iface* toWrap, struct Allocator* alloc)
 {
     struct FramingIface_pvt* context =
         Allocator_clone(alloc, (&(struct FramingIface_pvt) {
-            .maxMessageSize = maxMessageSize,
+            .maxMessageSize = maxMsgSize,
             .alloc = alloc,
-            .wrapped = toWrap
+            .streamIf = { .send = receiveMessage },
+            .messageIf = { .send = sendMessage }
         }));
     Identity_set(context);
-
-    InterfaceWrapper_wrap(toWrap, sendMessage, receiveMessage, &context->generic);
-
-    return &context->generic;
+    Iface_plumb(toWrap, &context->streamIf);
+    return &context->messageIf;
 }

+ 144 - 95
net/SessionManager.c

@@ -23,6 +23,11 @@
 #include "wire/RouteHeader.h"
 #include "util/events/Timeout.h"
 
+/** Handle numbers 0-3 are reserved for CryptoAuth nonces. */
+#define MIN_FIRST_HANDLE 4
+
+#define MAX_FIRST_HANDLE 100000
+
 struct BufferedMessage
 {
     struct Message* msg;
@@ -38,6 +43,12 @@ struct Ip6 {
 #define Map_NAME BufferedMessages
 #include "util/Map.h"
 
+#define Map_KEY_TYPE struct Ip6
+#define Map_VALUE_TYPE struct SessionManager_Session_pvt*
+#define Map_NAME OfSessionsByIp6
+#define Map_ENABLE_HANDLES
+#include "util/Map.h"
+
 struct SessionManager_pvt
 {
     struct SessionManager pub;
@@ -47,6 +58,18 @@ struct SessionManager_pvt
     struct Log* log;
     struct CryptoAuth* ca;
     struct EventBase* eventBase;
+    uint32_t firstHandle;
+    Identity
+};
+
+struct SessionManager_Session_pvt
+{
+    struct SessionManager_Session pub;
+
+    struct SessionManager_pvt* sessionManager;
+
+    struct Allocator* alloc;
+
     Identity
 };
 
@@ -70,64 +93,115 @@ struct SessionManager_pvt
 #define debugHandlesAndLabel0(logger, session, label, message) \
     debugHandlesAndLabel(logger, session, label, "%s", message)
 
-static void sendSession(struct SessionManager_pvt* sm,
-                        struct SessionTable_Session* sess,
+static void sendSession(struct SessionManager_Session_pvt* sess,
                         uint64_t path,
                         uint32_t destPf,
-                        enum PFChan_Core ev,
-                        struct Allocator* alloc)
+                        enum PFChan_Core ev)
 {
     struct PFChan_Node session = {
         .path_be = Endian_hostToBigEndian64(path),
         .metric_be = 0xffffffff,
-        .version_be = Endian_hostToBigEndian32(sess->version)
+        .version_be = Endian_hostToBigEndian32(sess->pub.version)
     };
-    Bits_memcpyConst(session.ip6, sess->caSession->herIp6, 16);
-    Bits_memcpyConst(session.publicKey, sess->caSession->herPublicKey, 32);
+    Bits_memcpyConst(session.ip6, sess->pub.caSession->herIp6, 16);
+    Bits_memcpyConst(session.publicKey, sess->pub.caSession->herPublicKey, 32);
 
+    struct Allocator* alloc = Allocator_child(sess->alloc);
     struct Message* msg = Message_new(0, PFChan_Node_SIZE + 512, alloc);
     Message_push(msg, &session, PFChan_Node_SIZE, NULL);
     Message_push32(msg, destPf, NULL);
     Message_push32(msg, ev, NULL);
-    Iface_send(&sm->eventIf, msg);
+    Iface_send(&sess->sessionManager->eventIf, msg);
+    Allocator_free(alloc);
 }
 
 static int sessionCleanup(struct Allocator_OnFreeJob* job)
 {
-    struct SessionTable_Session* sess = job->userData;
-    void* vsm = SessionTable_getInterfaceContext(sess);
-    struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) vsm);
-    struct Allocator* alloc = Allocator_child(sm->alloc);
-    sendSession(sm, sess, sess->sendSwitchLabel, 0xffffffff, PFChan_Core_SESSION_ENDED, alloc);
-    Allocator_free(alloc);
+    struct SessionManager_Session_pvt* sess =
+        Identity_check((struct SessionManager_Session_pvt*) job->userData);
+    sendSession(sess, sess->pub.sendSwitchLabel, 0xffffffff, PFChan_Core_SESSION_ENDED);
     return 0;
 }
 
-static struct SessionTable_Session* getSession(struct SessionManager_pvt* sm,
-                                               uint8_t ip6[16],
-                                               uint8_t pubKey[32],
-                                               uint32_t version,
-                                               uint64_t label)
+static inline struct SessionManager_Session_pvt* sessionForHandle(uint32_t handle,
+                                                                  struct SessionManager_pvt* sm)
+{
+    int index = Map_OfSessionsByIp6_indexForHandle(handle - sm->firstHandle, &sm->ifaceMap);
+    if (index < 0) { return NULL; }
+    check(sm, index);
+    return Identity_check(sm->ifaceMap.values[index]);
+}
+
+struct SessionManager_Session* SessionManager_sessionForHandle(uint32_t handle,
+                                                               struct SessionManager* manager)
+{
+    struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) manager);
+    return sessionForHandle(handle, sm);
+}
+
+static inline struct SessionManager_Session* sessionForIp6(uint8_t ip6[16],
+                                                           struct SessionManager_pvt* sm)
+{
+    int ifaceIndex = Map_OfSessionsByIp6_indexForKey((struct Ip6*)ip6, &sm->ifaceMap);
+    if (ifaceIndex == -1) { return NULL; }
+    check(st, ifaceIndex);
+    return Identity_check(sm->ifaceMap.values[ifaceIndex]);
+}
+
+struct SessionManager_Session* SessionManager_sessionForIp6(uint8_t* ip6,
+                                                            struct SessionManager* sm)
+{
+    struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) manager);
+    return sessionForIp6(ip6, sm);
+}
+
+struct SessionManager_HandleList* SessionManager_getHandleList(struct SessionManager* st,
+                                                               struct Allocator* alloc)
+{
+    struct SessionManager_HandleList* out =
+        Allocator_calloc(alloc, sizeof(struct SessionManager_HandleList), 1);
+    uint32_t* buff = Allocator_calloc(alloc, 4, st->ifaceMap.count);
+    Bits_memcpy(buff, st->ifaceMap.handles, 4 * st->ifaceMap.count);
+    out->handles = buff;
+    out->count = st->ifaceMap.count;
+    for (int i = 0; i < out->length; i++) {
+        buff[i] += st->first;
+    }
+    return out;
+}
+
+
+static struct SessionManager_Session_pvt* getSession(struct SessionManager_pvt* sm,
+                                                     uint8_t ip6[16],
+                                                     uint8_t pubKey[32],
+                                                     uint32_t version,
+                                                     uint64_t label)
 {
-    struct SessionTable_Session* sess = SessionTable_sessionForIp6(ip6, sm->pub.sessionTable);
+    struct SessionManager_Session_pvt* sess = sessionForIp6(ip6, sm);
     if (sess) {
-        sess->version = (sess->version) ? sess->version : version;
-        sess->sendSwitchLabel = (sess->sendSwitchLabel) ? sess->sendSwitchLabel : label;
-    } else {
-        struct Allocator* alloc = Allocator_child(sm->alloc);
-        sess = SessionTable_newSession(ip6, pubKey, alloc, sm->pub.sessionTable);
-        sess->version = version;
-        sess->timeOfCreation = Time_currentTimeMilliseconds(sm->eventBase);
-        sess->sendSwitchLabel = label;
-        Allocator_onFree(sess->external.allocator, sessionCleanup, sess);
-        struct Allocator* alloc = Allocator_child(sm->alloc);
-        sendSession(sm, sess, label, 0xffffffff, PFChan_Core_SESSION, alloc);
-        Allocator_free(alloc);
+        sess->pub.version = (sess->pub.version) ? sess->pub.version : version;
+        sess->pub.sendSwitchLabel = (sess->pub.sendSwitchLabel) ? sess->pub.sendSwitchLabel : label;
+        return sess;
     }
+    struct Allocator* alloc = Allocator_child(sm->alloc);
+    sess = Allocator_calloc(alloc, sizeof(struct SessionManager_Session_pvt), 1);
+    Identity_set(sess);
+
+    sess->pub.caSession = CryptoAuth_newSession(pubKey, ip6, false, "inner", sm->cryptoAuth);
+    int ifaceIndex = Map_OfSessionsByIp6_put((struct Ip6*)ip6, &ss, &sm->ifaceMap);
+    sess->receiveHandle = sm->ifaceMap.handles[ifaceIndex] + sm->firstHandle;
+    check(sm, ifaceIndex);
+
+    sess->alloc = alloc;
+    sess->sessionManager = sm;
+    sess->pub.version = version;
+    sess->pub.timeOfCreation = Time_currentTimeMilliseconds(sm->eventBase);
+    sess->pub.sendSwitchLabel = label;
+    Allocator_onFree(alloc, sessionCleanup, sess);
+    sendSession(sess, label, 0xffffffff, PFChan_Core_SESSION);
     return sess;
 }
 
-
 static Iface_DEFUN incomingFromSwitchIf(struct Iface* iface, struct Message* msg)
 {
     struct SessionManager_pvt* sm =
@@ -142,11 +216,11 @@ static Iface_DEFUN incomingFromSwitchIf(struct Iface* iface, struct Message* msg
     struct SwitchHeader* switchHeader = (struct SwitchHeader*) msg->bytes;
     Message_shift(msg, -SwitchHeader_SIZE, NULL);
 
-    struct SessionTable_Session* session;
+    struct SessionManager_Session* session;
     uint32_t nonceOrHandle = Endian_bigEndianToHost32(((uint32_t*)msg->bytes)[0]);
     if (nonceOrHandle > 3) {
         // > 3 it's a handle.
-        session = SessionTable_sessionForHandle(nonceOrHandle, sm->pub.sessionTable);
+        session = sessionForHandle(nonceOrHandle, sm);
         if (!session) {
             Log_debug(sm->log, "DROP message with unrecognized handle");
             return NULL;
@@ -182,7 +256,7 @@ static Iface_DEFUN incomingFromSwitchIf(struct Iface* iface, struct Message* msg
                              Endian_bigEndianToHost64(switchHeader->label_be),
                              "DROP Failed decrypting message NoH[%d] state[%s]",
                              nonceOrHandle,
-                             CryptoAuth_stateString(CryptoAuth_getState(session->internal)));
+                             CryptoAuth_stateString(CryptoAuth_getState(session->caSession)));
         return NULL;
     }
 
@@ -211,9 +285,8 @@ static Iface_DEFUN incomingFromSwitchIf(struct Iface* iface, struct Message* msg
     }
 
     header->version_be = Endian_hostToBigEndian32(session->version);
-    Bits_memcpyConst(header->ip6, session->ip6, 16);
-    uint8_t* pubKey = CryptoAuth_getHerPublicKey(session->internal);
-    Bits_memcpyConst(header->publicKey, pubKey, 32);
+    Bits_memcpyConst(header->ip6, session->caSession->herIp6, 16);
+    Bits_memcpyConst(header->publicKey, session->caSession->herPublicKey, 32);
 
     uint64_t path = Endian_bigEndianToHost64(switchHeader->label_be);
     if (!session->sendSwitchLabel) {
@@ -221,7 +294,7 @@ static Iface_DEFUN incomingFromSwitchIf(struct Iface* iface, struct Message* msg
     }
     if (path != session->recvSwitchLabel) {
         session->recvSwitchLabel = path;
-        sendSession(sm, session, path, 0xffffffff, PFChan_Core_DISCOVERED_PATH, msg->alloc);
+        sendSession(sm, session, path, 0xffffffff, PFChan_Core_DISCOVERED_PATH);
     }
 
     return Iface_next(&sm->pub.insideIf, msg);
@@ -281,14 +354,29 @@ static void needsLookup(struct SessionManager_pvt* sm, struct Message* msg)
     Allocator_free(eventAlloc);
 }
 
-static uint8_t readyToSendPostCryptoAuth(struct Message* msg, struct Iface* iface)
+static Iface_DEFUN readyToSend(struct Message* msg,
+                               struct SessionManager_pvt* sm,
+                               struct SessionManager_Session* sess)
 {
-    struct SessionManager_pvt* sm =
-        Identity_check((struct SessionManager_pvt*) iface->senderContext);
-    struct SwitchHeader* sh = sm->currentSwitchHeader;
-    struct SessionTable_Session* sess = sm->currentSession;
-    sm->currentSession = NULL;
-    sm->currentSwitchHeader = NULL;
+    Message_shift(msg, -RouteHeader_SIZE, NULL);
+    struct SwitchHeader* sh;
+    CryptoAuth_resetIfTimeout(sess->internal);
+    if (CryptoAuth_getState(sess->internal) < CryptoAuth_HANDSHAKE3) {
+        // Put the handle into the message so that it's authenticated.
+        Message_push32(msg, sess->receiveHandle, NULL);
+
+        // Copy back the SwitchHeader so it is not clobbered.
+        Message_shift(msg, (CryptoHeader_SIZE + SwitchHeader_SIZE), NULL);
+        Bits_memcpyConst(msg->bytes, &header->sh, SwitchHeader_SIZE);
+        sh = (struct SwitchHeader*) msg->bytes;
+        Message_shift(msg, -(CryptoHeader_SIZE + SwitchHeader_SIZE), NULL);
+    } else {
+        struct RouteHeader* header = (struct RouteHeader*) &msg->bytes[-RouteHeader_SIZE];
+        sh = &header->sh;
+    }
+
+    Assert_true(!CryptoAuth_encrypt(sess->caSession, msg));
+
     if (CryptoAuth_getState(sess->internal) >= CryptoAuth_HANDSHAKE3) {
         //if (0) { // Noisy
             debugHandlesAndLabel0(sm->log,
@@ -308,41 +396,7 @@ static uint8_t readyToSendPostCryptoAuth(struct Message* msg, struct Iface* ifac
     Message_shift(msg, SwitchHeader_SIZE, NULL);
     Assert_true((uint8_t*)sh == msg->bytes);
 
-    Iface_send(&sm->pub.switchIf, msg);
-    return 0;
-}
-
-static Iface_DEFUN readyToSend(struct Message* msg,
-                               struct SessionManager_pvt* sm,
-                               struct SessionTable_Session* sess)
-{
-    struct RouteHeader* header = (struct RouteHeader*) msg->bytes;
-    Message_shift(msg, -RouteHeader_SIZE, NULL);
-    Assert_true(!sm->currentSession);
-    Assert_true(!sm->currentSwitchHeader);
-    sm->currentSession = sess;
-
-    CryptoAuth_resetIfTimeout(sess->internal);
-    if (CryptoAuth_getState(sess->internal) < CryptoAuth_HANDSHAKE3) {
-        // Put the handle into the message so that it's authenticated.
-        Message_push32(msg, sess->receiveHandle, NULL);
-
-        // Copy back the SwitchHeader so it is not clobbered.
-        Message_shift(msg, (CryptoHeader_SIZE + SwitchHeader_SIZE), NULL);
-        Bits_memcpyConst(msg->bytes, &header->sh, SwitchHeader_SIZE);
-        sm->currentSwitchHeader = (struct SwitchHeader*) msg->bytes;
-        Message_shift(msg, -(CryptoHeader_SIZE + SwitchHeader_SIZE), NULL);
-    } else {
-        sm->currentSwitchHeader = &header->sh;
-    }
-
-    // --> readyToSendPostCryptoAuth
-    Interface_sendMessage(sess->internal, msg);
-
-    Assert_true(!sm->currentSession);
-    Assert_true(!sm->currentSwitchHeader);
-
-    return NULL;
+    return Iface_next(&sm->pub.switchIf, msg);
 }
 
 static Iface_DEFUN incomingFromInsideIf(struct Iface* iface, struct Message* msg)
@@ -352,8 +406,7 @@ static Iface_DEFUN incomingFromInsideIf(struct Iface* iface, struct Message* msg
     Assert_true(msg->length >= RouteHeader_SIZE);
     struct RouteHeader* header = (struct RouteHeader*) msg->bytes;
 
-    struct SessionTable_Session* sess =
-        SessionTable_sessionForIp6(header->ip6, sm->pub.sessionTable);
+    struct SessionManager_Session* sess = sessionForIp6(header->ip6, sm);
     if (!sess) {
         if (!Bits_isZero(header->publicKey, 32)) {
             sess = getSession(sm,
@@ -418,8 +471,7 @@ static Iface_DEFUN sessions(struct SessionManager_pvt* sm,
     struct SessionTable_HandleList* handles =
         SessionTable_getHandleList(sm->pub.sessionTable, tempAlloc);
     for (int i = 0; i < (int)handles->count; i++) {
-        struct SessionTable_Session* sess =
-            SessionTable_sessionForHandle(handles->handles[i], sm->pub.sessionTable);
+        struct SessionManager_Session* sess = sessionForHandle(handles->handles[i], sm);
         struct Allocator* alloc = Allocator_child(tempAlloc);
         sendSession(sm, sess, sess->sendSwitchLabel, sourcePf, PFChan_Core_SESSION, alloc);
         Allocator_free(alloc);
@@ -442,9 +494,9 @@ static Iface_DEFUN incomingFromEventIf(struct Iface* iface, struct Message* msg)
     Message_pop(msg, &node, PFChan_Node_SIZE, NULL);
     Assert_true(!msg->length);
     int index = Map_BufferedMessages_indexForKey((struct Ip6*)node.ip6, &sm->bufMap);
-    struct SessionTable_Session* sess;
+    struct SessionManager_Session* sess;
     if (index == -1) {
-        sess = SessionTable_sessionForIp6(node.ip6, sm->pub.sessionTable);
+        sess = sessionForIp6(node.ip6, sm);
         // If we discovered a node we're not interested in ...
         if (!sess) { return NULL; }
         sess->sendSwitchLabel = Endian_bigEndianToHost64(node.path_be);
@@ -490,13 +542,10 @@ struct SessionManager* SessionManager_new(struct Allocator* alloc,
     EventEmitter_regCore(ee, &sm->eventIf, PFChan_Pathfinder_NODE);
     EventEmitter_regCore(ee, &sm->eventIf, PFChan_Pathfinder_SESSIONS);
 
-    sm->pub.sessionTable = SessionTable_new(incomingFromSwitchPostCryptoAuth,
-                                            readyToSendPostCryptoAuth,
-                                            sm,
-                                            eventBase,
-                                            cryptoAuth,
-                                            rand,
-                                            alloc);
+    sm->firstHandle =
+        (Random_uint32(rand) % (MAX_FIRST_HANDLE - MIN_FIRST_HANDLE)) + MIN_FIRST_HANDLE;
+
+    sm->pub.sessionTable = SessionTable_new(cryptoAuth, rand, alloc);
 
     Timeout_setInterval(checkTimedOutBuffers, sm, 10000, eventBase, alloc);
 

+ 63 - 3
net/SessionManager.h

@@ -15,7 +15,8 @@
 #ifndef SessionManager_H
 #define SessionManager_H
 
-#include "net/SessionTable.h"
+#include "crypto/random/Random.h"
+#include "crypto/CryptoAuth.h"
 #include "memory/Allocator.h"
 #include "wire/PFChan.h"
 #include "net/EventEmitter.h"
@@ -49,8 +50,6 @@ struct SessionManager
      */
     struct Iface insideIf;
 
-    struct SessionTable* sessionTable;
-
     /**
      * Maximum number of packets to hold in buffer before summarily dropping...
      */
@@ -66,6 +65,67 @@ struct SessionManager
     uint32_t metricHalflifeMilliseconds;
 };
 
+struct SessionManager_Session
+{
+    struct CryptoAuth_Session* caSession;
+
+    /** When the last message was received on this session (milliseconds since epoch). */
+    uint64_t timeOfLastIn;
+
+    /** When the last message was sent on this session (milliseconds since epoch). */
+    uint64_t timeOfLastOut;
+
+    uint64_t bytesOut;
+
+    uint64_t bytesIn;
+
+    /** When this session was created. */
+    //uint64_t timeOfCreation;
+
+    /** The CryptoAuth state as of the last message. See: CryptoAuth_getState() */
+    //int cryptoAuthState;
+
+    /** The handle which will be used to lookup this session on our side. */
+    uint32_t receiveHandle;
+
+    /** The handle which we are expected to send to identify ourselves */
+    uint32_t sendHandle;
+
+    /** The version of the other node. */
+    uint32_t version;
+
+    /** The best known switch label for reaching this node. */
+    uint64_t sendSwitchLabel;
+
+    /** The switch label which this node uses for reaching us. */
+    uint64_t recvSwitchLabel;
+};
+
+struct SessionManager_HandleList
+{
+    int length;
+    uint32_t* handles;
+};
+
+/**
+ * Get a session by its handle.
+ *
+ * @param handle an opaque handle associated with the session.
+ * @param sm the session manager.
+ * @return the sesssion if there is one by that handle or null.
+ */
+struct SessionManager_Session* SessionManager_sessionForHandle(uint32_t handle,
+                                                               struct SessionManager* sm);
+
+struct SessionManager_Session* SessionManager_sessionForIp6(uint8_t* lookupKey,
+                                                            struct SessionManager* sm);
+
+/**
+ * Get the list of all handles.
+ */
+struct SessionManager_HandleList* SessionManager_getHandleList(struct SessionManager* sm,
+                                                               struct Allocator* alloc);
+
 struct SessionManager* SessionManager_new(struct Allocator* alloc,
                                           struct EventBase* eventBase,
                                           struct CryptoAuth* cryptoAuth,

+ 10 - 13
net/SessionManager_admin.c

@@ -19,7 +19,7 @@
 #include "crypto/Key.h"
 #include "crypto/ReplayProtector.h"
 #include "dht/Address.h"
-#include "net/SessionTable.h"
+#include "net/SessionManager.h"
 #include "net/SessionManager_admin.h"
 #include "util/AddrTools.h"
 #include "util/Identity.h"
@@ -39,21 +39,20 @@ static void getHandles(Dict* args, void* vcontext, String* txid, struct Allocato
     struct Allocator* alloc = Allocator_child(context->alloc);
 
     int64_t* page = Dict_getInt(args, String_CONST("page"));
-    uint32_t i = (page) ? *page * ENTRIES_PER_PAGE : 0;
-    struct SessionTable_HandleList* hList =
-        SessionTable_getHandleList(context->sm->sessionTable, alloc);
+    int i = (page) ? *page * ENTRIES_PER_PAGE : 0;
+    struct SessionManager_HandleList* hList = SessionManager_getHandleList(context->sm, alloc);
 
     List* list = List_new(alloc);
-    for (int counter=0; i < hList->count && counter++ < ENTRIES_PER_PAGE; i++) {
+    for (int counter = 0; i > 0 && i < hList->length && counter++ < ENTRIES_PER_PAGE; i++) {
         List_addInt(list, hList->handles[i], alloc);
     }
 
     Dict* r = Dict_new(alloc);
     Dict_putList(r, String_CONST("handles"), list, alloc);
-    Dict_putInt(r, String_CONST("total"), hList->count, alloc);
+    Dict_putInt(r, String_CONST("total"), hList->length, alloc);
 
     String* more = String_CONST("more");
-    if (i < hList->count) {
+    if (i < hList->length) {
       Dict_putInt(r, more, 1, alloc);
     }
 
@@ -71,8 +70,7 @@ static void sessionStats(Dict* args,
     int64_t* handleP = Dict_getInt(args, String_CONST("handle"));
     uint32_t handle = *handleP;
 
-    struct SessionTable_Session* session =
-        SessionTable_sessionForHandle(handle, context->sm->sessionTable);
+    struct SessionManager_Session* session = SessionManager_sessionForHandle(handle, context->sm);
 
     Dict* r = Dict_new(alloc);
     if (!session) {
@@ -85,10 +83,9 @@ static void sessionStats(Dict* args,
     AddrTools_printIp(printedAddr, session->caSession->herIp6);
     Dict_putString(r, String_CONST("ip6"), String_new(printedAddr, alloc), alloc);
 
-    Dict_putString(r,
-                   String_CONST("state"),
-                   String_new(CryptoAuth_stateString(session->cryptoAuthState), alloc),
-                   alloc);
+    String* state =
+        String_new(CryptoAuth_stateString(CryptoAuth_getState(session->caSession)), alloc);
+    Dict_putString(r, String_CONST("state"), state, alloc);
 
     struct ReplayProtector* rp = &session->caSession->replayProtector;
     Dict_putInt(r, String_CONST("duplicates"), rp->duplicates, alloc);

+ 34 - 48
net/SessionTable.c

@@ -52,7 +52,7 @@ struct Ip6
 };
 #define Map_NAME OfSessionsByIp6
 #define Map_KEY_TYPE struct Ip6
-#define Map_VALUE_TYPE struct SessionTable_Session_pvt*
+#define Map_VALUE_TYPE struct SessionTable_Session*
 #define Map_ENABLE_HANDLES
 #include "util/Map.h"
 
@@ -99,24 +99,22 @@ static void cleanup(void* vsm)
 
 static int removeSession(struct Allocator_OnFreeJob* job)
 {
-    struct SessionTable_Session_pvt* s =
-        Identity_check((struct SessionTable_Session_pvt*) job->userData);
-    Assert_true(st == s->sm);
-    int index =
-        Map_OfSessionsByIp6_indexForHandle(sess->receiveHandle - s->sm.first, &s->sm.ifaceMap);
+    struct SessionTable_Session* s = (struct SessionTable_Session*) job->userData;
+    struct SessionTable* st = Identity_check((struct SessionTable*) s->sessionTable);
+    int index = Map_OfSessionsByIp6_indexForHandle(s->receiveHandle - st->first, &st->ifaceMap);
     Assert_true(index >= 0);
-    Map_OfSessionsByIp6_remove(index, &s->sm.ifaceMap);
+    Map_OfSessionsByIp6_remove(index, &st->ifaceMap);
     return 0;
 }
 
-static void check(struct SessionTable* sm, int mapIndex)
+static void check(struct SessionTable* st, int mapIndex)
 {
-    Assert_true(sm->ifaceMap.keys[mapIndex].bytes[0] == 0xfc);
-    uint8_t* herPubKey = CryptoAuth_getHerPublicKey(sm->ifaceMap.values[mapIndex]->pub.internal);
+    Assert_true(st->ifaceMap.keys[mapIndex].bytes[0] == 0xfc);
+    uint8_t* herPubKey = st->ifaceMap.values[mapIndex].caSession->herPublicKey;
     if (!Bits_isZero(herPubKey, 32)) {
         uint8_t ip6[16];
         AddressCalc_addressForPublicKey(ip6, herPubKey);
-        Assert_true(!Bits_memcmp(&sm->ifaceMap.keys[mapIndex], ip6, 16));
+        Assert_true(!Bits_memcmp(&st->ifaceMap.keys[mapIndex], ip6, 16));
     }
 }
 /*
@@ -163,62 +161,50 @@ static uint8_t receiveMessage(struct Message* msg, struct Iface* iface)
     return Iface_send(&ss->sm->iface, msg);
 }*/
 
-struct SessionTable_Session* SessionTable_sessionForIp6(uint8_t* lookupKey,
-                                                            struct SessionTable* sm)
+struct SessionTable_Session* SessionTable_sessionForIp6(uint8_t* ip6, struct SessionTable* st)
 {
-    int ifaceIndex = Map_OfSessionsByIp6_indexForKey((struct Ip6*)lookupKey, &sm->ifaceMap);
+    int ifaceIndex = Map_OfSessionsByIp6_indexForKey((struct Ip6*)ip6, &st->ifaceMap);
     if (ifaceIndex == -1) { return NULL; }
-    check(sm, ifaceIndex);
-    struct SessionTable_Session_pvt* sess = Identity_check(sm->ifaceMap.values[ifaceIndex]);
-    return &sess->pub;
+    check(st, ifaceIndex);
+    return st->ifaceMap.values[ifaceIndex];
 }
 
-struct SessionTable_Session* SessionTable_newSession(uint8_t* lookupKey,
-                                                     uint8_t cryptoKey[32],
-                                                     struct Allocator* alloc,
-                                                     struct SessionTable* sm)
+void SessionTable_regSession(uint8_t* ip6,
+                             uint8_t cryptoKey[32],
+                             struct SessionTable_Session* session,
+                             struct Allocator* alloc,
+                             struct SessionTable* st)
 {
     Assert_true(cryptoKey);
-    Assert_true(!SessionTable_sessionForIp6(lookupKey, sm));
-
-    struct SessionTable_Session_pvt* ss =
-        Allocator_calloc(alloc, sizeof(struct SessionTable_Session_pvt), 1);
-    Identity_set(ss);
-    ss->sm = sm;
-    ss->pub.alloc = alloc;
-
-    ss->pub.caSession = CryptoAuth_newSession(cryptoKey, lookupKey, false, "inner", sm->cryptoAuth);
-
-    int ifaceIndex = Map_OfSessionsByIp6_put((struct Ip6*)lookupKey, &ss, &sm->ifaceMap);
-
-    ss->pub.receiveHandle = sm->ifaceMap.handles[ifaceIndex] + sm->first;
-
-    check(sm, ifaceIndex);
-
-    Allocator_onFree(alloc, removeSession, ss);
-
+    Assert_true(!SessionTable_sessionForIp6(ip6, st));
+    session->sessionTable = st;
+    session->caSession = CryptoAuth_newSession(cryptoKey, ip6, false, "inner", st->cryptoAuth);
+    int ifaceIndex = Map_OfSessionsByIp6_put((struct Ip6*)ip6, &ss, &st->ifaceMap);
+    session->receiveHandle = st->ifaceMap.handles[ifaceIndex] + st->first;
+    check(st, ifaceIndex);
+    Allocator_onFree(alloc, removeSession, session);
     return &Identity_check(sm->ifaceMap.values[ifaceIndex])->pub;
 }
 
-struct SessionTable_Session* SessionTable_sessionForHandle(uint32_t handle, struct SessionTable* sm)
+struct SessionTable_Session* SessionTable_sessionForHandle(uint32_t handle, struct SessionTable* st)
 {
-    int index = Map_OfSessionsByIp6_indexForHandle(handle - sm->first, &sm->ifaceMap);
+    int index = Map_OfSessionsByIp6_indexForHandle(handle - st->first, &st->ifaceMap);
     if (index < 0) { return NULL; }
-    check(sm, index);
-    return &Identity_check(sm->ifaceMap.values[index])->pub;
+    check(st, index);
+    return st->ifaceMap.values[index];
 }
 
-struct SessionTable_HandleList* SessionTable_getHandleList(struct SessionTable* sm,
+struct SessionTable_HandleList* SessionTable_getHandleList(struct SessionTable* st,
                                                            struct Allocator* alloc)
 {
     struct SessionTable_HandleList* out =
         Allocator_malloc(alloc, sizeof(struct SessionTable_HandleList));
-    uint32_t* buff = Allocator_malloc(alloc, 4 * sm->ifaceMap.count);
-    Bits_memcpy(buff, sm->ifaceMap.handles, 4 * sm->ifaceMap.count);
+    uint32_t* buff = Allocator_malloc(alloc, 4 * st->ifaceMap.count);
+    Bits_memcpy(buff, st->ifaceMap.handles, 4 * st->ifaceMap.count);
     out->handles = buff;
-    out->count = sm->ifaceMap.count;
+    out->count = st->ifaceMap.count;
     for (int i = 0; i < (int)out->count; i++) {
-        buff[i] += sm->first;
+        buff[i] += st->first;
     }
     return out;
 }

+ 34 - 32
net/SessionTable.h

@@ -12,57 +12,60 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef SessionTable_H
-#define SessionTable_H
+#ifndef SessionManager_H
+#define SessionManager_H
+
+#error poisoned
 
 #include "crypto/CryptoAuth.h"
 #include "crypto/random/Random.h"
 #include "memory/Allocator.h"
 #include "util/events/EventBase.h"
 #include "util/Linker.h"
-Linker_require("net/SessionTable.c")
+Linker_require("net/SessionManager.c")
 
 #include <stdint.h>
 
-struct SessionTable;
+struct SessionManager;
 
-struct SessionTable_Session
+struct SessionManager_Session
 {
     struct CryptoAuth_Session* caSession;
 
-    struct Allocator* alloc;
+    /** The handle which will be used to lookup this session on our side. */
+    uint32_t receiveHandle;
+
+    //struct Allocator* alloc;
+
 
     /** When the last message was received on this session (milliseconds since epoch). */
-    uint64_t timeOfLastIn;
+    //uint64_t timeOfLastIn;
 
     /** When the last message was sent on this session (milliseconds since epoch). */
-    uint64_t timeOfLastOut;
+    //uint64_t timeOfLastOut;
 
     /** When this session was created. */
-    uint64_t timeOfCreation;
+    //uint64_t timeOfCreation;
 
     /** The CryptoAuth state as of the last message. See: CryptoAuth_getState() */
-    int cryptoAuthState;
-
-    /** The handle which will be used to lookup this session on our side. */
-    uint32_t receiveHandle;
+    //int cryptoAuthState;
 
     /** The handle which we are expected to send to identify ourselves */
-    uint32_t sendHandle;
+    //uint32_t sendHandle;
 
     /** The version of the other node. */
-    uint32_t version;
+    //uint32_t version;
 
     /** The best known switch label for reaching this node. */
-    uint64_t sendSwitchLabel;
+    //uint64_t sendSwitchLabel;
 
     /** The switch label which this node uses for reaching us. */
-    uint64_t recvSwitchLabel;
+    //uint64_t recvSwitchLabel;
 };
 
-struct SessionTable_HandleList
+struct SessionManager_HandleList
 {
-    uint32_t count;
+    int count;
     uint32_t* handles;
 };
 
@@ -77,14 +80,15 @@ struct SessionTable_HandleList
  * @param allocator means of getting memory.
  * @return a session manager.
  */
-struct SessionTable* SessionTable_new(struct CryptoAuth* cryptoAuth,
+struct SessionManager* SessionManager_new(struct CryptoAuth* cryptoAuth,
                                       struct Random* rand,
                                       struct Allocator* allocator);
 
-struct SessionTable_Session* SessionTable_newSession(uint8_t* lookupKey,
-                                                     uint8_t cryptoKey[32],
-                                                     struct Allocator* alloc,
-                                                     struct SessionTable* sm);
+void SessionManager_regSession(uint8_t* ip6,
+                             uint8_t cryptoKey[32],
+                             struct SessionManager_Session* session,
+                             struct Allocator* alloc,
+                             struct SessionManager* st);
 
 /**
  * Get a session by its handle.
@@ -93,18 +97,16 @@ struct SessionTable_Session* SessionTable_newSession(uint8_t* lookupKey,
  * @param sm the session manager.
  * @return the sesssion if there is one by that handle or null.
  */
-struct SessionTable_Session* SessionTable_sessionForHandle(uint32_t handle,
-                                                               struct SessionTable* sm);
+struct SessionManager_Session* SessionManager_sessionForHandle(uint32_t handle,
+                                                               struct SessionManager* sm);
 
-struct SessionTable_Session* SessionTable_sessionForIp6(uint8_t* lookupKey,
-                                                            struct SessionTable* sm);
+struct SessionManager_Session* SessionManager_sessionForIp6(uint8_t* lookupKey,
+                                                            struct SessionManager* sm);
 
 /**
  * Get the list of all handles.
  */
-struct SessionTable_HandleList* SessionTable_getHandleList(struct SessionTable* sm,
-                                                               struct Allocator* alloc);
-
-void SessionTable_remove(struct SessionTable* sessionTable, struct SessionTable_Session* session);
+struct SessionManager_HandleList* SessionManager_getHandleList(struct SessionManager* sm,
+                                                           struct Allocator* alloc);
 
 #endif