static void sendHello(void* vctx) { struct TUNTools_pvt* ctx = Identity_check((struct TUNTools_pvt*) vctx); struct Message* msg; Message_STACK(msg, 0, 64); Message_push(msg, "Hello World", 12, NULL); Message_push(msg, ctx->dest, ctx->dest->addrLen, NULL); Interface_sendMessage(&ctx->iface->generic, msg); }
int main() { struct Allocator* alloc = MallocAllocator_new(1<<20); struct Random* rand = Random_new(alloc, NULL, NULL); // mock interface controller. struct Context ctx = { .ic = { .registerPeer = registerPeer, .getPeerState = getPeerState } }; struct Interface externalIf = { .sendMessage = sendMessage, .allocator = alloc, .senderContext = &ctx }; /*struct MultiInterface* mif = */MultiInterface_new(KEY_SIZE, &externalIf, &ctx.ic); struct Entry* entries = Allocator_malloc(alloc, sizeof(struct Entry) * ENTRY_COUNT); Random_bytes(rand, (uint8_t*)entries, ENTRY_COUNT * sizeof(struct Entry)); struct Interface** ifaces = Allocator_calloc(alloc, sizeof(char*), ENTRY_COUNT); // seed the list with some near collisions. for (int i = 0; i < 10; i++) { int rnd = (((uint32_t*)entries)[i] >> 1) % ENTRY_COUNT; ((uint32_t*) (&entries[rnd]))[0] = ((uint32_t*) (&entries[i]))[0]; } for (int i = 0; i < CYCLES; i++) { int rnd = ((uint32_t*)entries)[i] % ENTRY_COUNT; struct Entry* entry = &entries[rnd]; struct Interface* iface = ifaces[rnd]; struct Message* msg; Message_STACK(msg, 0, 128); Message_push(msg, "hello world", 12); Message_push(msg, entry, 16); externalIf.receiveMessage(msg, &externalIf); //printf("Received message for iface [%u] from [%p]\n", rnd, (void*)ctx.receivedOn); if (iface) { Assert_always(ctx.receivedOn == iface); } else { ifaces[rnd] = ctx.receivedOn; } } Allocator_free(alloc); }
int main(int argc, char** argv) { struct Allocator* alloc = MallocAllocator_new(1<<20); struct EventBase* base = EventBase_new(alloc); struct Writer* logWriter = FileWriter_new(stdout, alloc); struct Log* logger = WriterLog_new(logWriter, alloc); struct Sockaddr* addrA = Sockaddr_fromBytes(testAddrA, Sockaddr_AF_INET6, alloc); char assignedIfName[TUNInterface_IFNAMSIZ]; struct Interface* tun = TUNInterface_new(NULL, assignedIfName, base, logger, NULL, alloc); NetDev_addAddress(assignedIfName, addrA, 126, logger, NULL); struct Sockaddr_storage addr; Assert_always(!Sockaddr_parse("[fd00::1]", &addr)); #ifdef freebsd // tun is not setup synchronously in bsd but it lets you bind to the tun's // address anyway. sleep(1); #endif // Mac OSX and BSD do not set up their TUN devices synchronously. // We'll just keep on trying until this works. struct AddrInterface* udp = NULL; for (int i = 0; i < 20; i++) { if ((udp = setupUDP(base, &addr.addr, alloc, logger))) { break; } } Assert_always(udp); struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc); uint8_t* addrBytes; Assert_always(16 == Sockaddr_getAddress(dest, &addrBytes)); Bits_memcpy(addrBytes, testAddrB, 16); struct Message* msg; Message_STACK(msg, 0, 64); Message_push(msg, "Hello World", 12, NULL); Message_push(msg, dest, dest->addrLen, NULL); udp->generic.receiveMessage = receiveMessageUDP; udp->generic.receiverContext = alloc; tun->receiveMessage = receiveMessageTUN; udp->generic.sendMessage(msg, &udp->generic); Timeout_setTimeout(fail, NULL, 10000, base, alloc); EventBase_beginLoop(base); return 0; }
int main(int argc, char** argv) { // TODO: fix TUNConfigurator_addIp4Address() for Illumos, Darwin, BSD. #if defined(Illumos) || defined(Darwin) || defined(FreeBSD) || defined(OpenBSD) return 0; #endif struct Allocator* alloc = MallocAllocator_new(1<<20); struct EventBase* base = EventBase_new(alloc); struct Writer* logWriter = FileWriter_new(stdout, alloc); struct Log* logger = WriterLog_new(logWriter, alloc); struct Sockaddr* addrA = Sockaddr_fromBytes(testAddrA, Sockaddr_AF_INET, alloc); char assignedIfName[TUNInterface_IFNAMSIZ]; struct Interface* tun = TUNInterface_new(NULL, assignedIfName, base, logger, NULL, alloc); NetDev_addAddress(assignedIfName, addrA, 30, logger, NULL); struct Sockaddr_storage ss; Assert_true(!Sockaddr_parse("0.0.0.0", &ss)); struct AddrInterface* udp = UDPAddrInterface_new(base, &ss.addr, alloc, NULL, logger); struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc); uint8_t* addr; Assert_true(4 == Sockaddr_getAddress(dest, &addr)); Bits_memcpy(addr, testAddrB, 4); struct Message* msg; Message_STACK(msg, 0, 64); Message_push(msg, "Hello World", 12); Message_push(msg, dest, dest->addrLen); udp->generic.receiveMessage = receiveMessageUDP; udp->generic.receiverContext = alloc; tun->receiveMessage = receiveMessageTUN; udp->generic.sendMessage(msg, &udp->generic); Timeout_setTimeout(fail, NULL, 1000, base, alloc); EventBase_beginLoop(base); }
int main(int argc, char** argv) { struct Allocator* alloc = MallocAllocator_new(1<<20); struct EventBase* base = EventBase_new(alloc); struct Writer* logWriter = FileWriter_new(stdout, alloc); struct Log* logger = WriterLog_new(logWriter, alloc); // mock interface controller. struct InterfaceController ic = { .registerPeer = registerPeer }; struct Sockaddr_storage addr; Assert_always(!Sockaddr_parse("127.0.0.1", &addr)); struct UDPInterface* udpA = UDPInterface_new(base, &addr.addr, alloc, NULL, logger, &ic); struct UDPInterface* udpB = UDPInterface_new(base, &addr.addr, alloc, NULL, logger, &ic); struct Message* msg; Message_STACK(msg, 0, 128); Message_push(msg, "Hello World", 12, NULL); Message_push(msg, udpA->addr, udpA->addr->addrLen, NULL); struct Interface* ifA = &((struct UDPInterface_pvt*) udpA)->udpBase->generic; struct Interface* ifB = &((struct UDPInterface_pvt*) udpB)->udpBase->generic; ifA->receiveMessage = receiveMessageA; ifB->receiveMessage = receiveMessageB; ifB->receiverContext = alloc; struct Allocator* child = Allocator_child(alloc); msg = Message_clone(msg, child); ifB->sendMessage(msg, ifB); Allocator_free(child); Timeout_setTimeout(fail, NULL, 1000, base, alloc); EventBase_beginLoop(base); return 0; }
static void sendMessage(struct TwoNodes* tn, char* message, struct TestFramework* from, struct TestFramework* to) { struct Message* msg; Message_STACK(msg, 64, 512); Bits_memcpy(msg->bytes, message, CString_strlen(message) + 1); msg->length = CString_strlen(message) + 1; TestFramework_craftIPHeader(msg, from->ip, to->ip); msg = Message_clone(msg, from->alloc); struct Iface* fromIf; if (from == tn->nodeA) { fromIf = &tn->tunA; } else if (from == tn->nodeB) { fromIf = &tn->tunB; } else { Assert_true(false); } TUNMessageType_push(msg, Ethernet_TYPE_IP6, NULL); Iface_send(fromIf, msg); if (to == tn->nodeA) { Assert_true(tn->messageFrom == TUNA); } else if (to == tn->nodeB) { Assert_true(tn->messageFrom == TUNB); } else { Assert_true(false); } TestFramework_assertLastMessageUnaltered(tn->nodeA); TestFramework_assertLastMessageUnaltered(tn->nodeB); tn->messageFrom = 0; }
int main() { AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey); struct Allocator* alloc = MallocAllocator_new(1<<20); struct Writer* w = FileWriter_new(stdout, alloc); struct Log* logger = WriterLog_new(w, alloc); struct Random* rand = Random_new(alloc, logger, NULL); struct EventBase* eb = EventBase_new(alloc); struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand, NULL); struct Sockaddr_storage ip6ToGive; Sockaddr_parse("fd01:0101:0101:0101:0101:0101:0101:0101", &ip6ToGive); IpTunnel_allowConnection(fakePubKey, &ip6ToGive.addr, NULL, ipTun); struct Message* message; Message_STACK(message, 64, 512); message->alloc = alloc; const char* requestForAddresses = "d" "1:q" "21:IpTunnel_getAddresses" "4:txid" "4:abcd" "e"; CString_strcpy((char*)message->bytes, requestForAddresses); message->length = CString_strlen(requestForAddresses); Message_shift(message, Headers_UDPHeader_SIZE, NULL); struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes; uh->srcPort_be = 0; uh->destPort_be = 0; uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE); uint16_t* checksum = &uh->checksum_be; *checksum = 0; uint32_t length = message->length; Message_shift(message, Headers_IP6Header_SIZE, NULL); struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes; ip->versionClassAndFlowLabel = 0; ip->flowLabelLow_be = 0; ip->payloadLength_be = Endian_hostToBigEndian16(length); ip->nextHeader = 17; ip->hopLimit = 255; Bits_memset(ip->sourceAddr, 0, 32); Headers_setIpVersion(ip); Message_shift(message, IpTunnel_PacketInfoHeader_SIZE, NULL); struct IpTunnel_PacketInfoHeader* pi = (struct IpTunnel_PacketInfoHeader*) message->bytes; Bits_memcpyConst(pi->nodeIp6Addr, nodeCjdnsIp6, 16); Bits_memcpyConst(pi->nodeKey, fakePubKey, 32); *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length); ipTun->nodeInterface.receiveMessage = responseWithIpCallback; ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface); Assert_true(called); called = 0; // Now create a message for someone else. Message_shift(message, Headers_UDPHeader_SIZE + Headers_IP6Header_SIZE + IpTunnel_PacketInfoHeader_SIZE, NULL); Bits_memcpyConst(ip->sourceAddr, fakeIp6ToGive, 16); // This can't be zero. Bits_memset(ip->destinationAddr, 1, 16); ipTun->tunInterface.receiveMessage = messageToTun; ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface); Assert_true(called); Allocator_free(alloc); return 0; }
int main() { AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey); struct Allocator* alloc = MallocAllocator_new(1<<20); struct Log* logger = FileWriterLog_new(stdout, alloc); struct Random* rand = Random_new(alloc, logger, NULL); struct EventBase* eb = EventBase_new(alloc); struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand); struct Sockaddr_storage ip6ToGive; Sockaddr_parse("fd01:0101:0101:0101:0101:0101:0101:0101", &ip6ToGive); IpTunnel_allowConnection(fakePubKey, &ip6ToGive.addr, 0, NULL, 0, ipTun); struct Message* message; Message_STACK(message, 64, 512); message->alloc = alloc; const char* requestForAddresses = "d" "1:q" "21:IpTunnel_getAddresses" "4:txid" "4:abcd" "e"; CString_strcpy((char*)message->bytes, requestForAddresses); message->length = CString_strlen(requestForAddresses); Message_shift(message, Headers_UDPHeader_SIZE, NULL); struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes; uh->srcPort_be = 0; uh->destPort_be = 0; uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE); uint16_t* checksum = &uh->checksum_be; *checksum = 0; uint32_t length = message->length; Message_shift(message, Headers_IP6Header_SIZE, NULL); struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes; ip->versionClassAndFlowLabel = 0; ip->flowLabelLow_be = 0; ip->payloadLength_be = Endian_hostToBigEndian16(length); ip->nextHeader = 17; ip->hopLimit = 255; Bits_memset(ip->sourceAddr, 0, 32); Headers_setIpVersion(ip); Message_shift(message, RouteHeader_SIZE + DataHeader_SIZE, NULL); struct RouteHeader* rh = (struct RouteHeader*) message->bytes; struct DataHeader* dh = (struct DataHeader*) &rh[1]; Bits_memset(rh, 0, RouteHeader_SIZE + DataHeader_SIZE); Bits_memcpy(rh->ip6, nodeCjdnsIp6, 16); Bits_memcpy(rh->publicKey, fakePubKey, 32); DataHeader_setContentType(dh, ContentType_IPTUN); *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length); int origCap = message->capacity; int origLen = message->length; struct Iface nodeIface = { .send = responseWithIpCallback }; Iface_plumb(&nodeIface, &ipTun->nodeInterface); struct Iface tunIface = { .send = messageToTun }; Iface_plumb(&tunIface, &ipTun->tunInterface); Iface_send(&nodeIface, message); Assert_true(called == 2); called = 0; // This is a hack, reusing the message will cause breakage if IpTunnel is refactored. Message_reset(message); Message_shift(message, origCap, NULL); message->length = origLen; Bits_memcpy(ip->sourceAddr, fakeIp6ToGive, 16); // This can't be zero. Bits_memset(ip->destinationAddr, 1, 16); Iface_send(&nodeIface, message); Assert_true(called == 1); Allocator_free(alloc); return 0; }