static inline uint8_t incomingDHT(struct Message* message, struct Address* addr, struct Ducttape_pvt* context) { struct DHTMessage dht = { .address = addr, .binMessage = message, .allocator = message->alloc }; DHTModuleRegistry_handleIncoming(&dht, context->registry); // TODO(cjd): return something meaningful. return Error_NONE; } /** Header must not be encrypted and must be aligned on the beginning of the ipv6 header. */ static inline uint8_t sendToRouter(struct Message* message, struct Ducttape_MessageHeader* dtHeader, struct SessionManager_Session* session, struct Ducttape_pvt* context) { int safeDistance = SwitchHeader_SIZE; CryptoAuth_resetIfTimeout(session->internal); if (CryptoAuth_getState(session->internal) < CryptoAuth_HANDSHAKE3) { // Put the handle into the message so that it's authenticated. // see: sendToSwitch() //Log_debug(context->logger, "Sending receive handle under CryptoAuth"); Message_push(message, &session->receiveHandle_be, 4, NULL); safeDistance += CryptoHeader_SIZE; } else { // 16 for the authenticator, 4 for the nonce and 4 for the handle safeDistance += 24; } Message_shift(message, safeDistance, NULL); if (dtHeader->switchHeader) { if (message->bytes != (uint8_t*)dtHeader->switchHeader) { Bits_memmoveConst(message->bytes, dtHeader->switchHeader, SwitchHeader_SIZE); dtHeader->switchHeader = (struct SwitchHeader*) message->bytes; } } else { dtHeader->switchHeader = (struct SwitchHeader*) message->bytes; Bits_memset(dtHeader->switchHeader, 0, SwitchHeader_SIZE); } Message_shift(message, -safeDistance, NULL); SwitchHeader_setVersion(dtHeader->switchHeader, SwitchHeader_CURRENT_VERSION); SwitchHeader_setLabelShift(dtHeader->switchHeader, 0); dtHeader->switchHeader->label_be = Endian_hostToBigEndian64(dtHeader->switchLabel); // This comes out in outgoingFromCryptoAuth() then sendToSwitch() dtHeader->receiveHandle = Endian_bigEndianToHost32(session->receiveHandle_be); dtHeader->layer = Ducttape_SessionLayer_OUTER; return Interface_sendMessage(session->internal, message); }
static uint8_t sendMessage(struct Message* message, struct Interface* interface) { struct CryptoAuth_Wrapper* wrapper = Identity_check((struct CryptoAuth_Wrapper*) interface->senderContext); // If there has been no incoming traffic for a while, reset the connection to state 0. // This will prevent "connection in bad state" situations from lasting forever. // this will reset the session if it has timed out. CryptoAuth_resetIfTimeout(interface); // If the nonce wraps, start over. if (wrapper->nextNonce >= 0xfffffff0) { reset(wrapper); } Assert_true(!((uintptr_t)message->bytes % 4) || !"alignment fault"); // nextNonce 0: sending hello, we are initiating connection. // nextNonce 1: sending another hello, nothing received yet. // nextNonce 2: sending key, hello received. // nextNonce 3: sending key again, no data packet recieved yet. // nextNonce >3: handshake complete // // if it's a blind handshake, every message will be empty and nextNonce will remain // zero until the first message is received back. if (wrapper->nextNonce < 5) { if (wrapper->nextNonce < 4) { return encryptHandshake(message, wrapper, 0); } else { cryptoAuthDebug0(wrapper, "Doing final step to send message. nonce=4"); Assert_ifParanoid(!Bits_isZero(wrapper->ourTempPrivKey, 32)); Assert_ifParanoid(!Bits_isZero(wrapper->herTempPubKey, 32)); getSharedSecret(wrapper->sharedSecret, wrapper->ourTempPrivKey, wrapper->herTempPubKey, NULL, wrapper->context->logger); } } Assert_true(message->length > 0 && "Empty packet during handshake"); return encryptMessage(message, wrapper); }
static Iface_DEFUN handleIncomingFromWire(struct Message* msg, struct Iface* addrIf) { struct InterfaceController_Iface_pvt* ici = Identity_containerOf(addrIf, struct InterfaceController_Iface_pvt, pub.addrIf); struct Sockaddr* lladdr = (struct Sockaddr*) msg->bytes; if (msg->length < Sockaddr_OVERHEAD || msg->length < lladdr->addrLen) { Log_debug(ici->ic->logger, "DROP runt"); return NULL; } Assert_true(!((uintptr_t)msg->bytes % 4) && "alignment fault"); Assert_true(!((uintptr_t)lladdr->addrLen % 4) && "alignment fault"); // noisy if (Defined(Log_DEBUG) && false) { char* printedAddr = Hex_print(&lladdr[1], lladdr->addrLen - Sockaddr_OVERHEAD, msg->alloc); Log_debug(ici->ic->logger, "Incoming message from [%s]", printedAddr); } if (lladdr->flags & Sockaddr_flags_BCAST) { return handleBeacon(msg, ici); } int epIndex = Map_EndpointsBySockaddr_indexForKey(&lladdr, &ici->peerMap); if (epIndex == -1) { return handleUnexpectedIncoming(msg, ici); } struct Peer* ep = Identity_check((struct Peer*) ici->peerMap.values[epIndex]); Message_shift(msg, -lladdr->addrLen, NULL); CryptoAuth_resetIfTimeout(ep->caSession); if (CryptoAuth_decrypt(ep->caSession, msg)) { return NULL; } PeerLink_recv(msg, ep->peerLink); return receivedPostCryptoAuth(msg, ep, ici->ic); }