int main(int argc, char** argv) { printf("init test"); struct Allocator* alloc = MallocAllocator_new(1<<20); struct Log* logger = FileWriterLog_new(stdout, alloc); struct EventBase* base = EventBase_new(alloc); char* ifName; struct Iface* iface = TAPInterface_new(NULL, &ifName, NULL, logger, base, alloc); struct NDPServer* ndp = NDPServer_new(iface, alloc); ndp->generic.receiveMessage = receiveMessage; ndp->generic.receiverContext = alloc; ndp->advertisePrefix[0] = 0xfd; ndp->prefixLen = AddressCalc_ADDRESS_PREFIX_BITS; struct Sockaddr_storage ss; Assert_true(!Sockaddr_parse("fd00::1", &ss)); NetDev_addAddress(ifName, &ss.addr, AddressCalc_ADDRESS_PREFIX_BITS, logger, NULL); Timeout_setTimeout(fail, alloc, 10000, base, alloc); EventBase_beginLoop(base); printf("Test ended\n"); return 0; }
struct Message* InterfaceWaiter_waitForData(struct Interface* iface, struct event_base* eventBase, struct Allocator* alloc, struct Except* eh) { struct Context ctx = { .eventBase = eventBase, .exceptionHandler = eh, .alloc = alloc }; struct Allocator* tempAlloc; BufferAllocator_STACK(tempAlloc, 512); iface->receiverContext = &ctx; iface->receiveMessage = receiveMessage; ctx.timeout = Timeout_setTimeout(timeout, &ctx, 2000, eventBase, tempAlloc); event_base_dispatch(eventBase); iface->receiveMessage = NULL; Assert_true(ctx.message); return ctx.message; }
struct Message* InterfaceWaiter_waitForData(struct Interface* iface, struct EventBase* eventBase, struct Allocator* alloc, struct Except* eh) { struct Context ctx = { .eventBase = eventBase, .alloc = alloc }; struct Allocator* tempAlloc = Allocator_child(alloc); iface->receiverContext = &ctx; iface->receiveMessage = receiveMessage; ctx.timeout = Timeout_setTimeout(timeout, &ctx, 2000, eventBase, tempAlloc); EventBase_beginLoop(eventBase); iface->receiveMessage = NULL; Allocator_free(tempAlloc); if (ctx.timedOut) { Except_raise(eh, InterfaceWaiter_waitForData_TIMEOUT, "InterfaceWaiter Timed out waiting for data."); } Assert_true(ctx.message); return ctx.message; }
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*) vcontext); Log_info(context->logger, "Got request to exit"); Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL); Admin_sendMessage(&d, txid, context->admin); Timeout_setTimeout(shutdown, context, 1, context->base, context->alloc); }
static void onAngelExitResponse(Dict* message, void* vcontext) { struct Context* context = vcontext; Log_info(context->logger, "Angel stopped"); Log_info(context->logger, "Exiting"); Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL); Admin_sendMessage(&d, context->exitTxid, context->admin); Timeout_setTimeout(shutdown, context, 1, context->base, context->allocator); }
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; }
static void traceStep(struct RouteTracer_Trace* trace, struct Node* next) { struct RouteTracer_pvt* ctx = Identity_cast((struct RouteTracer_pvt*)trace->tracer); if (!next) { // can't find a next node, stalled. Timeout_setTimeout(noPeers, trace, 0, trace->tracer->eventBase, trace->pub.alloc); return; } Assert_true(LabelSplicer_routesThrough(trace->target, next->address.path)); trace->lastNodeAsked = next->address.path; struct RouterModule_Promise* rp = RouterModule_newMessage(next, 0, ctx->router, trace->pub.alloc); Dict* message = Dict_new(rp->alloc); #ifdef Version_4_COMPAT if (next->version < 5) { // The node doesn't support the new API so try running a search for // the bitwise complement of their address to get some peers. Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_FN, rp->alloc); String* notAddr = String_newBinary((char*)next->address.ip6.bytes, 16, rp->alloc); for (int i = 0; i < 16; i++) { notAddr->bytes[i] ^= 0xff; } Dict_putString(message, CJDHTConstants_TARGET, notAddr, rp->alloc); log(ctx->logger, trace, "Sending legacy search method because getpeers is unavailable"); } else { #endif Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_GP, rp->alloc); uint64_t labelForThem = LabelSplicer_unsplice(trace->target, next->address.path); labelForThem = Endian_hostToBigEndian64(labelForThem); String* target = String_newBinary((char*)&labelForThem, 8, rp->alloc); Dict_putString(message, CJDHTConstants_TARGET, target, rp->alloc); log(ctx->logger, trace, "Sending getpeers request"); #ifdef Version_4_COMPAT } #endif rp->userData = trace; rp->callback = responseCallback; RouterModule_sendMessage(rp, message); }
static void beaconInterval(void* vInterfaceController) { struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) vInterfaceController); struct Allocator* alloc = Allocator_child(ic->alloc); for (int i = 0; i < ic->icis->length; i++) { struct InterfaceController_Iface_pvt* ici = ArrayList_OfIfaces_get(ic->icis, i); sendBeacon(ici, alloc); } Allocator_free(alloc); if (ic->beaconTimeoutAlloc) { Allocator_free(ic->beaconTimeoutAlloc); } ic->beaconTimeoutAlloc = Allocator_child(ic->alloc); Timeout_setTimeout( beaconInterval, ic, ic->beaconInterval, ic->eventBase, ic->beaconTimeoutAlloc); }
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* log = WriterLog_new(logWriter, alloc); struct Sockaddr* addrA = Sockaddr_fromBytes(testAddrA, Sockaddr_AF_INET6, alloc); char assignedIfName[TUNInterface_IFNAMSIZ]; struct Interface* tap = TUNInterface_new(NULL, assignedIfName, 1, base, log, NULL, alloc); struct TAPWrapper* tapWrapper = TAPWrapper_new(tap, log, alloc); // Now setup the NDP server so the tun will work correctly. struct NDPServer* ndp = NDPServer_new(&tapWrapper->generic, log, TAPWrapper_LOCAL_MAC, alloc); ndp->advertisePrefix[0] = 0xfd; ndp->prefixLen = 8; struct Interface* tun = &ndp->generic; NetDev_addAddress(assignedIfName, addrA, 126, log, NULL); struct Sockaddr_storage addr; Assert_true(!Sockaddr_parse("[::]", &addr)); struct AddrInterface* udp = TUNTools_setupUDP(base, &addr.addr, alloc, log); struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc); uint8_t* addrBytes; Assert_true(16 == Sockaddr_getAddress(dest, &addrBytes)); Bits_memcpy(addrBytes, testAddrB, 16); udp->generic.receiveMessage = receiveMessageUDP; udp->generic.receiverContext = alloc; tun->receiveMessage = receiveMessageTUN; TUNTools_sendHelloWorld(udp, dest, base, alloc); Timeout_setTimeout(fail, NULL, 10000000, 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; }
void TUNTools_echoTest(struct Sockaddr* udpBindTo, struct Sockaddr* tunDestAddr, TUNTools_Callback tunMessageHandler, struct Iface* tun, struct EventBase* base, struct Log* logger, struct Allocator* allocator) { struct Allocator* alloc = Allocator_child(allocator); struct AddrIface* udp = setupUDP(base, udpBindTo, alloc, logger); struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc); uint8_t* tunDestAddrBytes = NULL; uint8_t* udpDestPointer = NULL; int len = Sockaddr_getAddress(dest, &udpDestPointer); Assert_true(len && len == Sockaddr_getAddress(tunDestAddr, &tunDestAddrBytes)); Bits_memcpy(udpDestPointer, tunDestAddrBytes, len); struct TUNTools_pvt* ctx = Allocator_calloc(alloc, sizeof(struct TUNTools_pvt), 1); Identity_set(ctx); ctx->pub.udpIface.send = receiveMessageUDP; ctx->pub.tunIface.send = receiveMessageTUN; Iface_plumb(&ctx->pub.udpIface, &udp->iface); Iface_plumb(&ctx->pub.tunIface, tun); ctx->pub.cb = tunMessageHandler; ctx->pub.tunDestAddr = Sockaddr_clone(dest, alloc); ctx->pub.udpBindTo = Sockaddr_clone(udpBindTo, alloc); ctx->pub.alloc = alloc; ctx->pub.log = logger; ctx->pub.base = base; Timeout_setInterval(sendHello, ctx, 1000, base, alloc); Timeout_setTimeout(fail, NULL, 10000, base, alloc); EventBase_beginLoop(base); }
static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf) { struct Address addr; struct RouteHeader* hdr = (struct RouteHeader*) msg->bytes; Message_shift(msg, -(RouteHeader_SIZE + DataHeader_SIZE), NULL); Bits_memcpy(addr.ip6.bytes, hdr->ip6, 16); Bits_memcpy(addr.key, hdr->publicKey, 32); addr.protocolVersion = Endian_bigEndianToHost32(hdr->version_be); addr.padding = 0; addr.path = Endian_bigEndianToHost64(hdr->sh.label_be); //Log_debug(pf->log, "Incoming DHT"); struct DHTMessage dht = { .address = &addr, .binMessage = msg, .allocator = msg->alloc }; DHTModuleRegistry_handleIncoming(&dht, pf->registry); struct Message* nodeMsg = Message_new(0, 256, msg->alloc); Iface_CALL(sendNode, nodeMsg, &addr, 0xfffffff0u, pf); if (dht.pleaseRespond) { // what a beautiful hack, see incomingFromDHT return Iface_next(&pf->pub.eventIf, msg); } return NULL; } static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventIf) { struct Pathfinder_pvt* pf = Identity_containerOf(eventIf, struct Pathfinder_pvt, pub.eventIf); enum PFChan_Core ev = Message_pop32(msg, NULL); if (Pathfinder_pvt_state_INITIALIZING == pf->state) { Assert_true(ev == PFChan_Core_CONNECT); return connected(pf, msg); } // Let the PF send another 128 path changes again because it's basically a new tick. pf->bestPathChanges = 0; switch (ev) { case PFChan_Core_SWITCH_ERR: return switchErr(msg, pf); case PFChan_Core_SEARCH_REQ: return searchReq(msg, pf); case PFChan_Core_PEER: return peer(msg, pf); case PFChan_Core_PEER_GONE: return peerGone(msg, pf); case PFChan_Core_SESSION: return session(msg, pf); case PFChan_Core_SESSION_ENDED: return sessionEnded(msg, pf); case PFChan_Core_DISCOVERED_PATH: return discoveredPath(msg, pf); case PFChan_Core_MSG: return incomingMsg(msg, pf); case PFChan_Core_PING: return handlePing(msg, pf); case PFChan_Core_PONG: return handlePong(msg, pf); case PFChan_Core_UNSETUP_SESSION: case PFChan_Core_LINK_STATE: case PFChan_Core_CTRL_MSG: return NULL; default:; } Assert_failure("unexpected event [%d]", ev); } static void sendEvent(struct Pathfinder_pvt* pf, enum PFChan_Pathfinder ev, void* data, int size) { struct Allocator* alloc = Allocator_child(pf->alloc); struct Message* msg = Message_new(0, 512+size, alloc); Message_push(msg, data, size, NULL); Message_push32(msg, ev, NULL); Iface_send(&pf->pub.eventIf, msg); Allocator_free(alloc); } static void init(void* vpf) { struct Pathfinder_pvt* pf = Identity_check((struct Pathfinder_pvt*) vpf); struct PFChan_Pathfinder_Connect conn = { .superiority_be = Endian_hostToBigEndian32(1), .version_be = Endian_hostToBigEndian32(Version_CURRENT_PROTOCOL) }; CString_strncpy(conn.userAgent, "Cjdns internal pathfinder", 64); sendEvent(pf, PFChan_Pathfinder_CONNECT, &conn, PFChan_Pathfinder_Connect_SIZE); } struct Pathfinder* Pathfinder_register(struct Allocator* allocator, struct Log* log, struct EventBase* base, struct Random* rand, struct Admin* admin) { struct Allocator* alloc = Allocator_child(allocator); struct Pathfinder_pvt* pf = Allocator_calloc(alloc, sizeof(struct Pathfinder_pvt), 1); Identity_set(pf); pf->alloc = alloc; pf->log = log; pf->base = base; pf->rand = rand; pf->admin = admin; pf->pub.eventIf.send = incomingFromEventIf; pf->dhtModule.context = pf; pf->dhtModule.handleOutgoing = incomingFromDHT; // This needs to be done asynchronously so the pf can be plumbed to the core Timeout_setTimeout(init, pf, 0, base, alloc); return &pf->pub; }
static void sleep(int milliseconds, struct Context* ctx, struct Allocator* temp) { Timeout_setTimeout(awaken, ctx, milliseconds, ctx->base, temp); EventBase_beginLoop(ctx->base); }