static uint64_t getPath(int* hops) { int i; uint64_t out = 0; for (i = 0; hops[i] != 1; i++) ; for (; i >= 0; i--) { int bits = NumberCompress_bitsUsedForNumber(hops[i]); out <<= bits; out |= NumberCompress_getCompressed(hops[i], bits); } return out; }
/** * Get the label for a particular destination from a given source. * This needs to be called before handing out a label because if a source interface is * represented using more bits than the destination interface, the destination interface * must be padded out so that the switch will find the source and destination labels compatable. * * @param target_be the label for the location to send to in big endian. * @param whoIsAsking_be the label for the node which we are sending the target to in big endian. * @return the modified target for that node in big endian. */ uint64_t LabelSplicer_getLabelFor(uint64_t target_be, uint64_t whoIsAsking_be) { uint64_t target = Endian_bigEndianToHost64(target_be); uint64_t whoIsAsking = Endian_bigEndianToHost64(whoIsAsking_be); uint32_t targetBits = NumberCompress_bitsUsedForLabel(target); uint32_t whoIsAskingBits = NumberCompress_bitsUsedForLabel(whoIsAsking); if (targetBits >= whoIsAskingBits) { return target_be; } uint32_t targetIfaceNum = NumberCompress_getDecompressed(target, targetBits); uint64_t out = ((target & (UINT64_MAX << targetBits)) << (whoIsAskingBits - targetBits)) | NumberCompress_getCompressed(targetIfaceNum, whoIsAskingBits); return Endian_hostToBigEndian64(out); }
static int reconnectionNewEndpointTest(struct InterfaceController* ifController, uint8_t* pk, struct Message** fromSwitchPtr, struct Allocator* alloc, struct EventBase* eventBase, struct Log* logger, struct Interface* routerIf, struct Random* rand) { struct Message* message; struct Interface iface = { .sendMessage = messageFromInterface, .senderContext = &message, .allocator = alloc }; uint8_t* buffer = Allocator_malloc(alloc, 512); struct Message* outgoing = &(struct Message) { .length = 0, .padding = 512, .bytes = buffer + 512 }; struct CryptoAuth* externalCa = CryptoAuth_new(alloc, NULL, eventBase, logger, rand); struct Interface* wrapped = CryptoAuth_wrapInterface(&iface, pk, NULL, false, "", externalCa); CryptoAuth_setAuth(String_CONST("passwd"), 1, wrapped); struct Interface icIface = { .allocator = alloc, .sendMessage = messageFromInterface, .senderContext = &message }; InterfaceController_registerPeer(ifController, NULL, NULL, true, false, &icIface); uint8_t hexBuffer[1025]; for (int i = 0; i < 4; i++) { outgoing->length = 0; outgoing->padding = 512; outgoing->bytes = buffer + 512; Message_shift(outgoing, 12, NULL); Bits_memcpyConst(outgoing->bytes, "hello world", 12); Message_shift(outgoing, SwitchHeader_SIZE, NULL); Bits_memcpyConst(outgoing->bytes, (&(struct SwitchHeader) { .label_be = Endian_hostToBigEndian64(1), .lowBits_be = 0 }), SwitchHeader_SIZE); wrapped->sendMessage(outgoing, wrapped); *fromSwitchPtr = NULL; icIface.receiveMessage(outgoing, &icIface); message = *fromSwitchPtr; Assert_true(message); Assert_true(message->length == 24); Hex_encode(hexBuffer, 1025, message->bytes, message->length); printf("%s\n", hexBuffer); // Need to bounce the packets back when connecting after the first try. // This is needed to establish the CryptoAuth session and make the InterfaceController // merge the endpoints. if (i > 0) { // Reverse the bits to reverse the path: uint64_t path; Bits_memcpyConst(&path, message->bytes, 8); path = Bits_bitReverse64(path); Bits_memcpyConst(message->bytes, &path, 8); printf("sending back response.\n"); routerIf->receiveMessage(message, routerIf); printf("forwarding response to external cryptoAuth.\n"); iface.receiveMessage(message, &iface); printf("forwarded.\n"); } else { printf("not responding because we don't want to establish a connection yet.\n"); } } // check everything except the label Assert_true(!CString_strcmp((char*)hexBuffer+16, "0000000068656c6c6f20776f726c6400")); // check label: make sure the interface has been switched back into position 0. uint64_t label_be; Hex_decode((uint8_t*) &label_be, 8, hexBuffer, 16); uint64_t rev_label = Bits_bitReverse64(Endian_bigEndianToHost64(label_be)); // check label is decoded to 0 Assert_true(0 == NumberCompress_getDecompressed(rev_label, NumberCompress_bitsUsedForLabel(rev_label))); // check no other bits are set uint64_t out = NumberCompress_getCompressed(0, NumberCompress_bitsUsedForLabel(rev_label)); Assert_true(rev_label == out); return 0; }
static uint64_t routeToInterface(uint32_t number) { uint32_t bits = NumberCompress_bitsUsedForNumber(number); return (1 << bits) | NumberCompress_getCompressed(number, bits); }