|
@@ -42,7 +42,7 @@ struct Ip6 {
|
|
|
struct SessionManager_pvt
|
|
|
{
|
|
|
struct SessionManager pub;
|
|
|
- struct Interface_Two eventIf;
|
|
|
+ struct Iface eventIf;
|
|
|
struct Allocator* alloc;
|
|
|
struct Map_BufferedMessages bufMap;
|
|
|
struct Log* log;
|
|
@@ -77,14 +77,37 @@ 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,
|
|
|
+ uint64_t path,
|
|
|
+ uint32_t destPf,
|
|
|
+ enum Event_Core ev,
|
|
|
+ struct Allocator* alloc)
|
|
|
+{
|
|
|
+ struct Event_Node session = {
|
|
|
+ .path_be = path,
|
|
|
+ .metric_be = 0xffffffff,
|
|
|
+ .version_be = Endian_hostToBigEndian32(sess->version)
|
|
|
+ };
|
|
|
+ Bits_memcpyConst(session.ip6, sess->ip6, 16);
|
|
|
+ uint8_t* publicKey = CryptoAuth_getHerPublicKey(sess->internal);
|
|
|
+ Bits_memcpyConst(session.publicKey, publicKey, 32);
|
|
|
+
|
|
|
+ struct Message* msg = Message_new(0, Event_Node_SIZE + 512, alloc);
|
|
|
+ Message_push(msg, &session, Event_Node_SIZE, NULL);
|
|
|
+ Message_push32(msg, destPf, NULL);
|
|
|
+ Message_push32(msg, ev, NULL);
|
|
|
+ Iface_send(&sm->eventIf, msg);
|
|
|
+}
|
|
|
+
|
|
|
static uint8_t incomingFromSwitchPostCryptoAuth(struct Message* msg, struct Interface* iface)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Identity_check((struct SessionManager_pvt*) iface->receiverContext);
|
|
|
+ struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) iface->receiverContext);
|
|
|
|
|
|
- struct SessionTable_Session* session = bw->currentSession;
|
|
|
- struct SwitchHeader* sh = bw->currentSwitchHeader;
|
|
|
- bw->currentSession = NULL;
|
|
|
- bw->currentSwitchHeader = NULL;
|
|
|
+ struct SessionTable_Session* session = sm->currentSession;
|
|
|
+ struct SwitchHeader* sh = sm->currentSwitchHeader;
|
|
|
+ sm->currentSession = NULL;
|
|
|
+ sm->currentSwitchHeader = NULL;
|
|
|
|
|
|
// CryptoAuth exports the nonce...
|
|
|
uint32_t nonce = ((uint32_t*)msg->bytes)[0];
|
|
@@ -100,14 +123,14 @@ static uint8_t incomingFromSwitchPostCryptoAuth(struct Message* msg, struct Inte
|
|
|
|
|
|
if (currentMessageSetup) {
|
|
|
Bits_memcpyConst(&header->sh, sh, SwitchHeader_SIZE);
|
|
|
- debugHandlesAndLabel0(bw->log,
|
|
|
+ debugHandlesAndLabel0(sm->log,
|
|
|
session,
|
|
|
Endian_bigEndianToHost64(sh->label_be),
|
|
|
"received start message");
|
|
|
} else {
|
|
|
// RouteHeader is laid out such that no copy of switch header should be needed.
|
|
|
Assert_true(&header->sh == sh);
|
|
|
- debugHandlesAndLabel0(bw->log,
|
|
|
+ debugHandlesAndLabel0(sm->log,
|
|
|
session,
|
|
|
Endian_bigEndianToHost64(sh->label_be),
|
|
|
"received run message");
|
|
@@ -123,31 +146,58 @@ static uint8_t incomingFromSwitchPostCryptoAuth(struct Message* msg, struct Inte
|
|
|
session->sendSwitchLabel = path;
|
|
|
}
|
|
|
if (path != session->recvSwitchLabel) {
|
|
|
- session->recvSwitchLabel = path;
|
|
|
- struct Message* eventMsg = Message_new(Event_Node_SIZE, 512, msg->alloc);
|
|
|
- struct Event_Node* node = (struct Event_Node*) eventMsg->bytes;
|
|
|
- Bits_memcpyConst(node->ip6, session->ip6, 16);
|
|
|
- Bits_memcpyConst(node->publicKey, pubKey, 32);
|
|
|
- node->path_be = sh->label_be;
|
|
|
- node->metric_be = 0xffffffff;
|
|
|
- node->version_be = header->version_be;
|
|
|
- Message_push32(eventMsg, Event_Core_SEARCH_REQ, NULL);
|
|
|
- Interface_send(&bw->eventIf, eventMsg);
|
|
|
+ sendSession(sm, session, path, 0xffffffff, Event_Core_DISCOVERED_PATH, msg->alloc);
|
|
|
}
|
|
|
|
|
|
- Interface_send(&bw->pub.insideIf, msg);
|
|
|
+ Iface_send(&sm->pub.insideIf, msg);
|
|
|
// Never return errors here because they can cause unencrypted stuff to be returned as an error.
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int incomingFromSwitchIf(struct Interface_Two* iface, struct Message* msg)
|
|
|
+
|
|
|
+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, Event_Core_SESSION_ENDED, alloc);
|
|
|
+ Allocator_free(alloc);
|
|
|
+ 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)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Identity_containerOf(iface, struct SessionManager_pvt, pub.switchIf);
|
|
|
+ struct SessionTable_Session* sess = SessionTable_sessionForIp6(ip6, sm->pub.sessionTable);
|
|
|
+ if (sess) {
|
|
|
+ sess->version = (sess->version) ? sess->version : version;
|
|
|
+ sess->sendSwitchLabel = (sess->sendSwitchLabel) ? sess->sendSwitchLabel : label;
|
|
|
+ } else {
|
|
|
+ sess = SessionTable_getSession(ip6, pubKey, sm->pub.sessionTable);
|
|
|
+ sess->version = version;
|
|
|
+ sess->sendSwitchLabel = label;
|
|
|
+ Allocator_onFree(sess->external.allocator, sessionCleanup, sess);
|
|
|
+ struct Allocator* alloc = Allocator_child(sm->alloc);
|
|
|
+ sendSession(sm, sess, label, 0xffffffff, Event_Core_SESSION, alloc);
|
|
|
+ Allocator_free(alloc);
|
|
|
+ }
|
|
|
+ return sess;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static Iface_DEFUN incomingFromSwitchIf(struct Iface* iface, struct Message* msg)
|
|
|
+{
|
|
|
+ struct SessionManager_pvt* sm =
|
|
|
+ Identity_containerOf(iface, struct SessionManager_pvt, pub.switchIf);
|
|
|
|
|
|
// SwitchHeader, handle, small cryptoAuth header
|
|
|
if (msg->length < SwitchHeader_SIZE + 4 + 20) {
|
|
|
- Log_debug(bw->log, "DROP runt");
|
|
|
- return 0;
|
|
|
+ Log_debug(sm->log, "DROP runt");
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
struct SwitchHeader* switchHeader = (struct SwitchHeader*) msg->bytes;
|
|
@@ -157,134 +207,131 @@ static int incomingFromSwitchIf(struct Interface_Two* iface, struct Message* msg
|
|
|
uint32_t nonceOrHandle = Endian_bigEndianToHost32(((uint32_t*)msg->bytes)[0]);
|
|
|
if (nonceOrHandle > 3) {
|
|
|
// > 3 it's a handle.
|
|
|
- session = SessionTable_sessionForHandle(nonceOrHandle, bw->pub.sessionTable);
|
|
|
+ session = SessionTable_sessionForHandle(nonceOrHandle, sm->pub.sessionTable);
|
|
|
if (!session) {
|
|
|
- Log_debug(bw->log, "DROP message with unrecognized handle");
|
|
|
- return 0;
|
|
|
+ Log_debug(sm->log, "DROP message with unrecognized handle");
|
|
|
+ return NULL;
|
|
|
}
|
|
|
Message_shift(msg, -4, NULL);
|
|
|
} else {
|
|
|
// handle + big cryptoauth header
|
|
|
if (msg->length < CryptoHeader_SIZE + 4) {
|
|
|
- Log_debug(bw->log, "DROP runt");
|
|
|
- return 0;
|
|
|
+ Log_debug(sm->log, "DROP runt");
|
|
|
+ return NULL;
|
|
|
}
|
|
|
union CryptoHeader* caHeader = (union CryptoHeader*) msg->bytes;
|
|
|
uint8_t* herKey = caHeader->handshake.publicKey;
|
|
|
uint8_t ip6[16];
|
|
|
// a packet which claims to be "from us" causes problems
|
|
|
if (!AddressCalc_addressForPublicKey(ip6, herKey)) {
|
|
|
- Log_debug(bw->log, "DROP Handshake with non-fc key");
|
|
|
- return 0;
|
|
|
+ Log_debug(sm->log, "DROP Handshake with non-fc key");
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- if (!Bits_memcmp(herKey, bw->ca->publicKey, 32)) {
|
|
|
- Log_debug(bw->log, "DROP Handshake from 'ourselves'");
|
|
|
- return 0;
|
|
|
+ if (!Bits_memcmp(herKey, sm->ca->publicKey, 32)) {
|
|
|
+ Log_debug(sm->log, "DROP Handshake from 'ourselves'");
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- session = SessionTable_getSession(ip6, herKey, bw->pub.sessionTable);
|
|
|
-
|
|
|
- debugHandlesAndLabel(bw->log, session,
|
|
|
- Endian_bigEndianToHost64(switchHeader->label_be),
|
|
|
- "new session nonce[%d]", nonceOrHandle);
|
|
|
+ uint64_t label = Endian_bigEndianToHost64(switchHeader->label_be);
|
|
|
+ session = getSession(sm, ip6, herKey, 0, label);
|
|
|
+ debugHandlesAndLabel(sm->log, session, label, "new session nonce[%d]", nonceOrHandle);
|
|
|
}
|
|
|
|
|
|
- Assert_true(NULL == bw->currentSession);
|
|
|
- Assert_true(NULL == bw->currentSwitchHeader);
|
|
|
- bw->currentSession = session;
|
|
|
- bw->currentSwitchHeader = switchHeader;
|
|
|
+ Assert_true(NULL == sm->currentSession);
|
|
|
+ Assert_true(NULL == sm->currentSwitchHeader);
|
|
|
+ sm->currentSession = session;
|
|
|
+ sm->currentSwitchHeader = switchHeader;
|
|
|
// --> incomingFromSwitchPostCryptoAuth
|
|
|
int ret = Interface_receiveMessage(&session->external, msg);
|
|
|
if (ret) {
|
|
|
- bw->currentSession = NULL;
|
|
|
- bw->currentSwitchHeader = NULL;
|
|
|
+ sm->currentSession = NULL;
|
|
|
+ sm->currentSwitchHeader = NULL;
|
|
|
|
|
|
- debugHandlesAndLabel(bw->log, session,
|
|
|
+ debugHandlesAndLabel(sm->log, session,
|
|
|
Endian_bigEndianToHost64(switchHeader->label_be),
|
|
|
"DROP Failed decrypting message NoH[%d] state[%s]",
|
|
|
nonceOrHandle,
|
|
|
CryptoAuth_stateString(CryptoAuth_getState(session->internal)));
|
|
|
- return Error_AUTHENTICATION;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
- Assert_true(NULL == bw->currentSession);
|
|
|
- Assert_true(NULL == bw->currentSwitchHeader);
|
|
|
+ Assert_true(NULL == sm->currentSession);
|
|
|
+ Assert_true(NULL == sm->currentSwitchHeader);
|
|
|
|
|
|
- return 0;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
static void checkTimedOutBuffers(void* vSessionManager)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Identity_check((struct SessionManager_pvt*) vSessionManager);
|
|
|
- for (int i = 0; i < (int)bw->bufMap.count; i++) {
|
|
|
- struct BufferedMessage* buffered = bw->bufMap.values[i];
|
|
|
- uint64_t lag = Time_currentTimeSeconds(bw->eventBase) - buffered->timeSent;
|
|
|
+ struct SessionManager_pvt* sm = Identity_check((struct SessionManager_pvt*) vSessionManager);
|
|
|
+ for (int i = 0; i < (int)sm->bufMap.count; i++) {
|
|
|
+ struct BufferedMessage* buffered = sm->bufMap.values[i];
|
|
|
+ uint64_t lag = Time_currentTimeSeconds(sm->eventBase) - buffered->timeSent;
|
|
|
if (lag < 10) { continue; }
|
|
|
- Map_BufferedMessages_remove(i, &bw->bufMap);
|
|
|
+ Map_BufferedMessages_remove(i, &sm->bufMap);
|
|
|
Allocator_free(buffered->alloc);
|
|
|
i--;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int needsLookup(struct SessionManager_pvt* bw, struct Message* msg)
|
|
|
+static void needsLookup(struct SessionManager_pvt* sm, struct Message* msg)
|
|
|
{
|
|
|
struct RouteHeader* header = (struct RouteHeader*) msg->bytes;
|
|
|
if (Defined(Log_DEBUG)) {
|
|
|
uint8_t ipStr[40];
|
|
|
AddrTools_printIp(ipStr, header->ip6);
|
|
|
- Log_debug(bw->log, "Buffering a packet to [%s] and beginning a search", ipStr);
|
|
|
+ Log_debug(sm->log, "Buffering a packet to [%s] and beginning a search", ipStr);
|
|
|
}
|
|
|
- int index = Map_BufferedMessages_indexForKey((struct Ip6*)header->ip6, &bw->bufMap);
|
|
|
+ int index = Map_BufferedMessages_indexForKey((struct Ip6*)header->ip6, &sm->bufMap);
|
|
|
if (index > -1) {
|
|
|
- struct BufferedMessage* buffered = bw->bufMap.values[index];
|
|
|
- Map_BufferedMessages_remove(index, &bw->bufMap);
|
|
|
+ struct BufferedMessage* buffered = sm->bufMap.values[index];
|
|
|
+ Map_BufferedMessages_remove(index, &sm->bufMap);
|
|
|
Allocator_free(buffered->alloc);
|
|
|
- Log_debug(bw->log, "DROP message which needs lookup because new one received");
|
|
|
+ Log_debug(sm->log, "DROP message which needs lookup because new one received");
|
|
|
}
|
|
|
- if ((int)bw->bufMap.count >= bw->pub.maxBufferedMessages) {
|
|
|
- checkTimedOutBuffers(bw);
|
|
|
- if ((int)bw->bufMap.count >= bw->pub.maxBufferedMessages) {
|
|
|
- Log_debug(bw->log, "DROP message needing lookup maxBufferedMessages ([%d]) is reached",
|
|
|
- bw->pub.maxBufferedMessages);
|
|
|
- return 0;
|
|
|
+ if ((int)sm->bufMap.count >= sm->pub.maxBufferedMessages) {
|
|
|
+ checkTimedOutBuffers(sm);
|
|
|
+ if ((int)sm->bufMap.count >= sm->pub.maxBufferedMessages) {
|
|
|
+ Log_debug(sm->log, "DROP message needing lookup maxBufferedMessages ([%d]) is reached",
|
|
|
+ sm->pub.maxBufferedMessages);
|
|
|
+ return;
|
|
|
}
|
|
|
}
|
|
|
- struct Allocator* lookupAlloc = Allocator_child(bw->alloc);
|
|
|
+ struct Allocator* lookupAlloc = Allocator_child(sm->alloc);
|
|
|
struct BufferedMessage* buffered =
|
|
|
Allocator_calloc(lookupAlloc, sizeof(struct BufferedMessage), 1);
|
|
|
buffered->msg = msg;
|
|
|
buffered->alloc = lookupAlloc;
|
|
|
- buffered->timeSent = Time_currentTimeSeconds(bw->eventBase);
|
|
|
+ buffered->timeSent = Time_currentTimeSeconds(sm->eventBase);
|
|
|
Allocator_adopt(lookupAlloc, msg->alloc);
|
|
|
- Assert_true(Map_BufferedMessages_put((struct Ip6*)header->ip6, &buffered, &bw->bufMap) > -1);
|
|
|
+ Assert_true(Map_BufferedMessages_put((struct Ip6*)header->ip6, &buffered, &sm->bufMap) > -1);
|
|
|
|
|
|
struct Allocator* eventAlloc = Allocator_child(lookupAlloc);
|
|
|
struct Message* eventMsg = Message_new(0, 512, eventAlloc);
|
|
|
Message_push(eventMsg, header->ip6, 16, NULL);
|
|
|
+ Message_push32(eventMsg, 0xffffffff, NULL);
|
|
|
Message_push32(eventMsg, Event_Core_SEARCH_REQ, NULL);
|
|
|
- Interface_send(&bw->eventIf, eventMsg);
|
|
|
+ Iface_send(&sm->eventIf, eventMsg);
|
|
|
Allocator_free(eventAlloc);
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
static uint8_t readyToSendPostCryptoAuth(struct Message* msg, struct Interface* iface)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Identity_check((struct SessionManager_pvt*) iface->senderContext);
|
|
|
- struct SwitchHeader* sh = bw->currentSwitchHeader;
|
|
|
- struct SessionTable_Session* sess = bw->currentSession;
|
|
|
- bw->currentSession = NULL;
|
|
|
- bw->currentSwitchHeader = NULL;
|
|
|
+ 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;
|
|
|
if (CryptoAuth_getState(sess->internal) >= CryptoAuth_HANDSHAKE3) {
|
|
|
//if (0) { // Noisy
|
|
|
- debugHandlesAndLabel0(bw->log,
|
|
|
+ debugHandlesAndLabel0(sm->log,
|
|
|
sess,
|
|
|
Endian_bigEndianToHost64(sh->label_be),
|
|
|
"sending run message");
|
|
|
//}
|
|
|
Message_push32(msg, sess->sendHandle, NULL);
|
|
|
} else {
|
|
|
- debugHandlesAndLabel0(bw->log,
|
|
|
+ debugHandlesAndLabel0(sm->log,
|
|
|
sess,
|
|
|
Endian_bigEndianToHost64(sh->label_be),
|
|
|
"sending start message");
|
|
@@ -294,18 +341,19 @@ static uint8_t readyToSendPostCryptoAuth(struct Message* msg, struct Interface*
|
|
|
Message_shift(msg, SwitchHeader_SIZE, NULL);
|
|
|
Assert_true((uint8_t*)sh == msg->bytes);
|
|
|
|
|
|
- return Interface_send(&bw->pub.switchIf, msg);
|
|
|
+ Iface_send(&sm->pub.switchIf, msg);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-static int readyToSend(struct SessionManager_pvt* bw,
|
|
|
- struct SessionTable_Session* sess,
|
|
|
- struct Message* msg)
|
|
|
+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(!bw->currentSession);
|
|
|
- Assert_true(!bw->currentSwitchHeader);
|
|
|
- bw->currentSession = sess;
|
|
|
+ Assert_true(!sm->currentSession);
|
|
|
+ Assert_true(!sm->currentSwitchHeader);
|
|
|
+ sm->currentSession = sess;
|
|
|
|
|
|
CryptoAuth_resetIfTimeout(sess->internal);
|
|
|
if (CryptoAuth_getState(sess->internal) < CryptoAuth_HANDSHAKE3) {
|
|
@@ -315,34 +363,40 @@ static int readyToSend(struct SessionManager_pvt* bw,
|
|
|
// 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);
|
|
|
- bw->currentSwitchHeader = (struct SwitchHeader*) msg->bytes;
|
|
|
+ sm->currentSwitchHeader = (struct SwitchHeader*) msg->bytes;
|
|
|
Message_shift(msg, -(CryptoHeader_SIZE + SwitchHeader_SIZE), NULL);
|
|
|
} else {
|
|
|
- bw->currentSwitchHeader = &header->sh;
|
|
|
+ sm->currentSwitchHeader = &header->sh;
|
|
|
}
|
|
|
|
|
|
// --> readyToSendPostCryptoAuth
|
|
|
- int ret = Interface_sendMessage(sess->internal, msg);
|
|
|
+ Interface_sendMessage(sess->internal, msg);
|
|
|
+
|
|
|
+ Assert_true(!sm->currentSession);
|
|
|
+ Assert_true(!sm->currentSwitchHeader);
|
|
|
|
|
|
- Assert_true(!bw->currentSession);
|
|
|
- Assert_true(!bw->currentSwitchHeader);
|
|
|
- return ret;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
-static int incomingFromInsideIf(struct Interface_Two* iface, struct Message* msg)
|
|
|
+static Iface_DEFUN incomingFromInsideIf(struct Iface* iface, struct Message* msg)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Identity_containerOf(iface, struct SessionManager_pvt, pub.insideIf);
|
|
|
+ struct SessionManager_pvt* sm =
|
|
|
+ Identity_containerOf(iface, struct SessionManager_pvt, pub.insideIf);
|
|
|
Assert_true(msg->length >= RouteHeader_SIZE);
|
|
|
struct RouteHeader* header = (struct RouteHeader*) msg->bytes;
|
|
|
|
|
|
struct SessionTable_Session* sess =
|
|
|
- SessionTable_sessionForIp6(header->ip6, bw->pub.sessionTable);
|
|
|
+ SessionTable_sessionForIp6(header->ip6, sm->pub.sessionTable);
|
|
|
if (!sess) {
|
|
|
if (!Bits_isZero(header->publicKey, 32)) {
|
|
|
- sess =
|
|
|
- SessionTable_getSession(header->ip6, header->publicKey, bw->pub.sessionTable);
|
|
|
+ sess = getSession(sm,
|
|
|
+ header->ip6,
|
|
|
+ header->publicKey,
|
|
|
+ Endian_bigEndianToHost32(header->version_be),
|
|
|
+ Endian_hostToBigEndian64(sess->sendSwitchLabel));
|
|
|
} else {
|
|
|
- return needsLookup(bw, msg);
|
|
|
+ needsLookup(sm, msg);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -353,10 +407,11 @@ static int incomingFromInsideIf(struct Interface_Two* iface, struct Message* msg
|
|
|
} else if (sess->sendSwitchLabel) {
|
|
|
header->sh.label_be = Endian_hostToBigEndian64(sess->sendSwitchLabel);
|
|
|
} else {
|
|
|
- return needsLookup(bw, msg);
|
|
|
+ needsLookup(sm, msg);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- return readyToSend(bw, sess, msg);
|
|
|
+ return readyToSend(msg, sm, sess);
|
|
|
}
|
|
|
|
|
|
/* too good to toss!
|
|
@@ -389,81 +444,96 @@ static uint32_t getEffectiveMetric(uint64_t nowMilliseconds,
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
-static Interface_Ret sessions(struct Interface_Two* iface, struct Message* msg)
|
|
|
+static Iface_DEFUN sessions(struct SessionManager_pvt* sm,
|
|
|
+ uint32_t sourcePf,
|
|
|
+ struct Allocator* tempAlloc)
|
|
|
{
|
|
|
-
|
|
|
+ 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 Allocator* alloc = Allocator_child(tempAlloc);
|
|
|
+ sendSession(sm, sess, sess->sendSwitchLabel, sourcePf, Event_Core_SESSION, alloc);
|
|
|
+ Allocator_free(alloc);
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
-static Interface_Ret incomingFromEventIf(struct Interface_Two* iface, struct Message* msg)
|
|
|
+static Iface_DEFUN incomingFromEventIf(struct Iface* iface, struct Message* msg)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Identity_containerOf(iface, struct SessionManager_pvt, eventIf);
|
|
|
+ struct SessionManager_pvt* sm = Identity_containerOf(iface, struct SessionManager_pvt, eventIf);
|
|
|
enum Event_Pathfinder ev = Message_pop32(msg, NULL);
|
|
|
uint32_t sourcePf = Message_pop32(msg, NULL);
|
|
|
if (ev == Event_Pathfinder_SESSIONS) {
|
|
|
Assert_true(!msg->length);
|
|
|
- return sessions(bw, sourcePf);
|
|
|
+ return sessions(sm, sourcePf, msg->alloc);
|
|
|
}
|
|
|
Assert_true(ev == Event_Pathfinder_NODE);
|
|
|
|
|
|
struct Event_Node node;
|
|
|
Message_pop(msg, &node, Event_Node_SIZE, NULL);
|
|
|
Assert_true(!msg->length);
|
|
|
- int index = Map_BufferedMessages_indexForKey((struct Ip6*)node.ip6, &bw->bufMap);
|
|
|
+ int index = Map_BufferedMessages_indexForKey((struct Ip6*)node.ip6, &sm->bufMap);
|
|
|
struct SessionTable_Session* sess;
|
|
|
if (index == -1) {
|
|
|
- sess = SessionTable_sessionForIp6(node.ip6, bw->pub.sessionTable);
|
|
|
+ sess = SessionTable_sessionForIp6(node.ip6, sm->pub.sessionTable);
|
|
|
// If we discovered a node we're not interested in ...
|
|
|
- if (!sess) { return Interface_RET; }
|
|
|
+ if (!sess) { return NULL; }
|
|
|
+ sess->sendSwitchLabel = Endian_bigEndianToHost64(node.path_be);
|
|
|
+ sess->version = Endian_bigEndianToHost32(node.version_be);
|
|
|
} else {
|
|
|
- sess = SessionTable_getSession(node.ip6, node.publicKey, bw->pub.sessionTable);
|
|
|
+ sess = getSession(sm,
|
|
|
+ node.ip6,
|
|
|
+ node.publicKey,
|
|
|
+ Endian_bigEndianToHost32(node.version_be),
|
|
|
+ Endian_bigEndianToHost64(node.path_be));
|
|
|
}
|
|
|
|
|
|
- sess->sendSwitchLabel = Endian_bigEndianToHost64(node.path_be);
|
|
|
- sess->version = Endian_bigEndianToHost64(node.version_be);
|
|
|
-
|
|
|
// Send what's on the buffer...
|
|
|
if (index > -1) {
|
|
|
- struct BufferedMessage* bm = bw->bufMap.values[index];
|
|
|
- readyToSend(bw, sess, bm->msg);
|
|
|
- Map_BufferedMessages_remove(index, &bw->bufMap);
|
|
|
+ struct BufferedMessage* bm = sm->bufMap.values[index];
|
|
|
+ Iface_CALL(readyToSend, bm->msg, sm, sess);
|
|
|
+ Map_BufferedMessages_remove(index, &sm->bufMap);
|
|
|
Allocator_free(bm->alloc);
|
|
|
}
|
|
|
- return Interface_RET;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
struct SessionManager* SessionManager_new(struct Allocator* alloc,
|
|
|
- struct EventBase* eventBase,
|
|
|
- struct CryptoAuth* cryptoAuth,
|
|
|
- struct Random* rand,
|
|
|
- struct Log* log,
|
|
|
- struct EventEmitter* ee)
|
|
|
+ struct EventBase* eventBase,
|
|
|
+ struct CryptoAuth* cryptoAuth,
|
|
|
+ struct Random* rand,
|
|
|
+ struct Log* log,
|
|
|
+ struct EventEmitter* ee)
|
|
|
{
|
|
|
- struct SessionManager_pvt* bw = Allocator_calloc(alloc, sizeof(struct SessionManager_pvt), 1);
|
|
|
- bw->alloc = alloc;
|
|
|
- bw->pub.switchIf.send = incomingFromSwitchIf;
|
|
|
- bw->pub.insideIf.send = incomingFromInsideIf;
|
|
|
- bw->bufMap.allocator = alloc;
|
|
|
- bw->log = log;
|
|
|
- bw->ca = cryptoAuth;
|
|
|
- bw->eventBase = eventBase;
|
|
|
-
|
|
|
- bw->pub.metricHalflifeMilliseconds = SessionManager_METRIC_HALFLIFE_MILLISECONDS_DEFAULT;
|
|
|
- bw->pub.maxBufferedMessages = SessionManager_MAX_BUFFERED_MESSAGES_DEFAULT;
|
|
|
-
|
|
|
- bw->eventIf.send = incomingFromEventIf;
|
|
|
- EventEmitter_regCore(ee, &bw->eventIf, Event_Pathfinder_NODE);
|
|
|
-
|
|
|
- bw->pub.sessionTable = SessionTable_new(incomingFromSwitchPostCryptoAuth,
|
|
|
+ struct SessionManager_pvt* sm = Allocator_calloc(alloc, sizeof(struct SessionManager_pvt), 1);
|
|
|
+ sm->alloc = alloc;
|
|
|
+ sm->pub.switchIf.send = incomingFromSwitchIf;
|
|
|
+ sm->pub.insideIf.send = incomingFromInsideIf;
|
|
|
+ sm->bufMap.allocator = alloc;
|
|
|
+ sm->log = log;
|
|
|
+ sm->ca = cryptoAuth;
|
|
|
+ sm->eventBase = eventBase;
|
|
|
+
|
|
|
+ sm->pub.metricHalflifeMilliseconds = SessionManager_METRIC_HALFLIFE_MILLISECONDS_DEFAULT;
|
|
|
+ sm->pub.maxBufferedMessages = SessionManager_MAX_BUFFERED_MESSAGES_DEFAULT;
|
|
|
+
|
|
|
+ sm->eventIf.send = incomingFromEventIf;
|
|
|
+ EventEmitter_regCore(ee, &sm->eventIf, Event_Pathfinder_NODE);
|
|
|
+ EventEmitter_regCore(ee, &sm->eventIf, Event_Pathfinder_SESSIONS);
|
|
|
+
|
|
|
+ sm->pub.sessionTable = SessionTable_new(incomingFromSwitchPostCryptoAuth,
|
|
|
readyToSendPostCryptoAuth,
|
|
|
- bw,
|
|
|
+ sm,
|
|
|
eventBase,
|
|
|
cryptoAuth,
|
|
|
rand,
|
|
|
alloc);
|
|
|
|
|
|
- Timeout_setInterval(checkTimedOutBuffers, bw, 10000, eventBase, alloc);
|
|
|
+ Timeout_setInterval(checkTimedOutBuffers, sm, 10000, eventBase, alloc);
|
|
|
|
|
|
- Identity_set(bw);
|
|
|
+ Identity_set(sm);
|
|
|
|
|
|
- return &bw->pub;
|
|
|
+ return &sm->pub;
|
|
|
}
|