struct Allocator* Allocator__child(struct Allocator* allocator, const char* file, int line) { struct Allocator_pvt* parent = Identity_check((struct Allocator_pvt*) allocator); check(parent); struct Allocator_pvt stackChild = { .pub = { .fileName = file, .lineNum = line, }, .rootAlloc = parent->rootAlloc }; Identity_set(&stackChild); #ifdef Allocator_USE_CANARIES stackChild.nextCanary = stackChild.canary = parent->nextCanary; #endif struct Allocator_pvt* child = newAllocation(&stackChild, sizeof(struct Allocator_pvt), file, line); Bits_memcpy(child, &stackChild, sizeof(struct Allocator_pvt)); // Link the child into the parent's allocator list connect(parent, child, file, line); check(parent); return &child->pub; }
struct RandomSeed* RandomSeed_new(RandomSeed_Provider* providers, int providerCount, struct Log* logger, struct Allocator* alloc) { struct RandomSeed** rsList = Allocator_calloc(alloc, sizeof(struct RandomSeed), providerCount); int i = 0; for (int j = 0; j < providerCount; j++) { struct RandomSeed* rs = providers[j](alloc); if (rs) { rsList[i++] = rs; } } Assert_true(i > 0); struct RandomSeed_pvt* out = Allocator_malloc(alloc, sizeof(struct RandomSeed_pvt)); out->rsList = rsList; out->rsCount = i; out->logger = logger; out->pub.get = get; out->pub.name = "RandomSeed conglomeration of random seed providers"; Identity_set(out); return &out->pub; }
struct GlobalConfig* GlobalConfig_new(struct Allocator* alloc) { struct GlobalConfig_pvt* gcp = Allocator_calloc(alloc, sizeof(struct GlobalConfig_pvt), 1); Identity_set(gcp); gcp->alloc = alloc; return &gcp->pub; }
struct CryptoAuth* CryptoAuth_new(struct Allocator* allocator, const uint8_t* privateKey, struct EventBase* eventBase, struct Log* logger, struct Random* rand) { struct CryptoAuth_pvt* ca = Allocator_calloc(allocator, sizeof(struct CryptoAuth_pvt), 1); Identity_set(ca); ca->allocator = allocator; ca->eventBase = eventBase; ca->logger = logger; ca->pub.resetAfterInactivitySeconds = CryptoAuth_DEFAULT_RESET_AFTER_INACTIVITY_SECONDS; ca->rand = rand; if (privateKey != NULL) { Bits_memcpyConst(ca->privateKey, privateKey, 32); } else { Random_bytes(rand, ca->privateKey, 32); } crypto_scalarmult_curve25519_base(ca->pub.publicKey, ca->privateKey); if (Defined(Log_KEYS)) { uint8_t publicKeyHex[65]; printHexKey(publicKeyHex, ca->pub.publicKey); uint8_t privateKeyHex[65]; printHexKey(privateKeyHex, ca->privateKey); Log_keys(logger, "Initialized CryptoAuth:\n myPrivateKey=%s\n myPublicKey=%s\n", privateKeyHex, publicKeyHex); } return &ca->pub; }
void Core_init(struct Allocator* alloc, struct Log* logger, struct EventBase* eventBase, uint8_t privateKey[32], struct Admin* admin, struct Random* rand, struct Except* eh, struct FakeNetwork* fakeNet, bool noSec) { struct Security* sec = NULL; if (!noSec) { sec = Security_new(alloc, logger, eventBase); } struct NetCore* nc = NetCore_new(privateKey, alloc, eventBase, rand, logger); struct IpTunnel* ipTunnel = IpTunnel_new(logger, eventBase, alloc, rand); Iface_plumb(&nc->tunAdapt->ipTunnelIf, &ipTunnel->tunInterface); Iface_plumb(&nc->upper->ipTunnelIf, &ipTunnel->nodeInterface); // The link between the Pathfinder and the core needs to be asynchronous. struct Pathfinder* pf = Pathfinder_register(alloc, logger, eventBase, rand, admin); struct ASynchronizer* pfAsync = ASynchronizer_new(alloc, eventBase, logger); Iface_plumb(&pfAsync->ifA, &pf->eventIf); EventEmitter_regPathfinderIface(nc->ee, &pfAsync->ifB); // ------------------- Register RPC functions ----------------------- // InterfaceController_admin_register(nc->ifController, admin, alloc); SwitchPinger_admin_register(nc->sp, admin, alloc); UDPInterface_admin_register(eventBase, alloc, logger, admin, nc->ifController, fakeNet); #ifdef HAS_ETH_INTERFACE ETHInterface_admin_register(eventBase, alloc, logger, admin, nc->ifController); #endif AuthorizedPasswords_init(admin, nc->ca, alloc); Admin_registerFunction("ping", adminPing, admin, false, NULL, admin); if (!noSec) { Security_admin_register(alloc, logger, sec, admin); } IpTunnel_admin_register(ipTunnel, admin, alloc); SessionManager_admin_register(nc->sm, admin, alloc); Allocator_admin_register(alloc, admin); struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1); Identity_set(ctx); ctx->alloc = alloc; ctx->admin = admin; ctx->logger = logger; ctx->base = eventBase; ctx->ipTunnel = ipTunnel; ctx->nc = nc; Admin_registerFunction("Core_exit", adminExit, ctx, true, NULL, admin); Admin_registerFunction("Core_pid", adminPid, admin, false, NULL, admin); Admin_registerFunction("Core_initTunnel", initTunnel, ctx, true, ((struct Admin_FunctionArg[]) { { .name = "desiredTunName", .required = 0, .type = "String" } }), admin);
struct SupernodeHunter* SupernodeHunter_new(struct Allocator* allocator, struct Log* log, struct EventBase* base, struct AddrSet* peers, struct MsgCore* msgCore, struct Address* myAddress) { struct Allocator* alloc = Allocator_child(allocator); struct SupernodeHunter_pvt* out = Allocator_calloc(alloc, sizeof(struct SupernodeHunter_pvt), 1); out->authorizedSnodes = AddrSet_new(alloc); out->peers = peers; out->base = base; out->nodes = AddrSet_new(alloc); //out->timeSnodeCalled = Time_currentTimeMilliseconds(base); out->snodeCandidates = AddrSet_new(alloc); out->log = log; out->alloc = alloc; out->msgCore = msgCore; out->myAddress = myAddress; out->selfAddrStr = String_newBinary(myAddress->ip6.bytes, 16, alloc); Identity_set(out); Timeout_setInterval(pingCycle, out, CYCLE_MS, base, alloc); return &out->pub; }
struct CryptoAuth_Session* CryptoAuth_newSession(struct CryptoAuth* ca, struct Allocator* alloc, const uint8_t herPublicKey[32], const uint8_t herIp6[16], const bool requireAuth, char* displayName) { struct CryptoAuth_pvt* context = Identity_check((struct CryptoAuth_pvt*) ca); struct CryptoAuth_Session_pvt* session = Allocator_calloc(alloc, sizeof(struct CryptoAuth_Session_pvt), 1); Identity_set(session); session->context = context; session->requireAuth = requireAuth; session->pub.displayName = String_new(displayName, alloc); session->timeOfLastPacket = Time_currentTimeSeconds(context->eventBase); session->alloc = alloc; if (herPublicKey != NULL) { Bits_memcpyConst(session->pub.herPublicKey, herPublicKey, 32); uint8_t calculatedIp6[16]; AddressCalc_addressForPublicKey(calculatedIp6, herPublicKey); Bits_memcpyConst(session->pub.herIp6, calculatedIp6, 16); if (herIp6 != NULL) { Assert_true(!Bits_memcmp(calculatedIp6, herIp6, 16)); } } else if (herIp6) { Bits_memcpyConst(session->pub.herIp6, herIp6, 16); } return &session->pub; }
static void search(Dict* args, void* vctx, String* txid, struct Allocator* reqAlloc) { struct Context* ctx = Identity_check((struct Context*) vctx); String* addrStr = Dict_getStringC(args, "ipv6"); int maxRequests = -1; uint64_t* maxRequestsPtr = Dict_getIntC(args, "maxRequests"); if (maxRequestsPtr) { maxRequests = *maxRequestsPtr; } uint8_t addr[16]; if (AddrTools_parseIp(addr, (uint8_t*) addrStr->bytes)) { Dict* resp = Dict_new(reqAlloc); Dict_putStringCC(resp, "error", "ipv6 invalid", reqAlloc); Admin_sendMessage(resp, txid, ctx->admin); } else { struct Allocator* alloc = Allocator_child(ctx->allocator); struct Search* s = Allocator_calloc(alloc, sizeof(struct Search), 1); s->promise = SearchRunner_search(addr, maxRequests, maxRequests, ctx->runner, alloc); s->ctx = ctx; s->txid = String_clone(txid, alloc); s->alloc = alloc; Identity_set(s); if (!s->promise) { Dict* resp = Dict_new(reqAlloc); Dict_putStringCC(resp, "error", "creating search", reqAlloc); Admin_sendMessage(resp, txid, ctx->admin); Allocator_free(alloc); return; } s->promise->userData = s; s->promise->callback = searchResponse; } }
/** * Incoming message from someone we don't know, maybe someone responding to a beacon? * expects: [ struct LLAddress ][ content ] */ static Iface_DEFUN handleUnexpectedIncoming(struct Message* msg, struct InterfaceController_Iface_pvt* ici) { struct InterfaceController_pvt* ic = ici->ic; struct Sockaddr* lladdr = (struct Sockaddr*) msg->bytes; Message_shift(msg, -lladdr->addrLen, NULL); if (msg->length < CryptoHeader_SIZE) { return NULL; } struct Allocator* epAlloc = Allocator_child(ici->alloc); lladdr = Sockaddr_clone(lladdr, epAlloc); Assert_true(!((uintptr_t)msg->bytes % 4) && "alignment fault"); struct Peer* ep = Allocator_calloc(epAlloc, sizeof(struct Peer), 1); Identity_set(ep); ep->alloc = epAlloc; ep->ici = ici; ep->lladdr = lladdr; ep->alloc = epAlloc; ep->peerLink = PeerLink_new(ic->eventBase, epAlloc); struct CryptoHeader* ch = (struct CryptoHeader*) msg->bytes; ep->caSession = CryptoAuth_newSession(ic->ca, epAlloc, ch->publicKey, true, "outer"); if (CryptoAuth_decrypt(ep->caSession, msg)) { // If the first message is a dud, drop all state for this peer. // probably some random crap that wandered in the socket. Allocator_free(epAlloc); return NULL; } Assert_true(!Bits_isZero(ep->caSession->herPublicKey, 32)); Assert_true(Map_EndpointsBySockaddr_indexForKey(&lladdr, &ici->peerMap) == -1); int index = Map_EndpointsBySockaddr_put(&lladdr, &ep, &ici->peerMap); Assert_true(index >= 0); ep->handle = ici->peerMap.handles[index]; Allocator_onFree(epAlloc, closeInterface, ep); ep->state = InterfaceController_PeerState_UNAUTHENTICATED; ep->isIncomingConnection = true; ep->switchIf.send = sendFromSwitch; if (SwitchCore_addInterface(ic->switchCore, &ep->switchIf, epAlloc, &ep->addr.path)) { Log_debug(ic->logger, "handleUnexpectedIncoming() SwitchCore out of space"); Allocator_free(epAlloc); return NULL; } // We want the node to immedietly be pinged but we don't want it to appear unresponsive because // the pinger will only ping every (PING_INTERVAL * 8) so we set timeOfLastMessage to // (now - pingAfterMilliseconds - 1) so it will be considered a "lazy node". ep->timeOfLastMessage = Time_currentTimeMilliseconds(ic->eventBase) - ic->pingAfterMilliseconds - 1; Bits_memcpy(ep->addr.key, ep->caSession->herPublicKey, 32); Bits_memcpy(ep->addr.ip6.bytes, ep->caSession->herIp6, 16); Log_info(ic->logger, "Added peer [%s] from incoming message", Address_toString(&ep->addr, msg->alloc)->bytes); return receivedPostCryptoAuth(msg, ep, ic); }
struct Security* Security_new(struct Allocator* alloc, struct Log* log, struct EventBase* base) { struct Security_pvt* sec = Allocator_calloc(alloc, sizeof(struct Security_pvt), 1); Identity_set(sec); sec->setupAlloc = Allocator_child(alloc); Timeout_setInterval(fail, sec, 20000, base, sec->setupAlloc); sec->log = log; return &sec->pub; }
struct AddrSet* AddrSet_new(struct Allocator* allocator) { struct Allocator* alloc = Allocator_child(allocator); struct AddrSet_pvt* out = Allocator_calloc(alloc, sizeof(struct AddrSet_pvt), 1); out->alloc = alloc; out->addrList = ArrayList_OfAddrs_new(alloc); Identity_set(out); return &out->pub; }
struct PeerLink* PeerLink_new(struct EventBase* base, struct Allocator* allocator) { struct Allocator* alloc = Allocator_child(allocator); struct PeerLink_pvt* pl = Allocator_calloc(alloc, sizeof(struct PeerLink_pvt), 1); Identity_set(pl); pl->base = base; pl->alloc = alloc; pl->queue = ArrayList_Messages_new(alloc); return &pl->pub; }
struct TAPWrapper* TAPWrapper_new(struct Iface* external, struct Log* log, struct Allocator* alloc) { struct TAPWrapper_pvt* out = Allocator_calloc(alloc, sizeof(struct TAPWrapper_pvt), 1); Identity_set(out); out->log = log; out->external.send = receiveMessage; out->pub.internal.send = sendMessage; Iface_plumb(external, &out->external); return &out->pub; }
struct TUNAdapter* TUNAdapter_new(struct Allocator* allocator, struct Log* log, uint8_t myIp6[16]) { struct Allocator* alloc = Allocator_child(allocator); struct TUNAdapter_pvt* out = Allocator_calloc(alloc, sizeof(struct TUNAdapter_pvt), 1); out->pub.tunIf.send = incomingFromTunIf; out->pub.ipTunnelIf.send = incomingFromIpTunnelIf; out->pub.upperDistributorIf.send = incomingFromUpperDistributorIf; out->log = log; Identity_set(out); Bits_memcpy(out->myIp6, myIp6, 16); return &out->pub; }
struct EventBase* EventBase_new(struct Allocator* allocator) { struct Allocator* alloc = Allocator_child(allocator); struct EventBase_pvt* base = Allocator_calloc(alloc, sizeof(struct EventBase_pvt), 1); base->loop = uv_loop_new(); base->alloc = alloc; Identity_set(base); Allocator_onFree(alloc, onFree, base); calibrateTime(base); return &base->pub; }
/** Check if nodes A and C can communicate via B without A knowing that C exists. */ void Benchmark_runAll() { struct Allocator* alloc = MallocAllocator_new(1<<22); struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1); Identity_set(ctx); ctx->alloc = alloc; ctx->base = EventBase_new(alloc); struct Log* log = ctx->log = FileWriterLog_new(stdout, alloc); ctx->rand = Random_new(alloc, log, NULL); cryptoAuth(ctx); switching(ctx); }
int CryptoAuth_addUser_ipv6(String* password, String* login, uint8_t ipv6[16], struct CryptoAuth* cryptoAuth) { struct CryptoAuth_pvt* ca = Identity_check((struct CryptoAuth_pvt*) cryptoAuth); struct Allocator* alloc = Allocator_child(ca->allocator); struct CryptoAuth_User* user = Allocator_calloc(alloc, sizeof(struct CryptoAuth_User), 1); user->alloc = alloc; Identity_set(user); if (!login) { int i = 0; for (struct CryptoAuth_User* u = ca->users; u; u = u->next) { i++; } user->login = login = String_printf(alloc, "Anon #%d", i); } else { user->login = String_clone(login, alloc); } union CryptoHeader_Challenge ac; // Users specified with a login field might want to use authType 1 still. hashPassword(user->secret, &ac, login, password, 2); Bits_memcpyConst(user->userNameHash, ac.bytes, CryptoHeader_Challenge_KEYSIZE); hashPassword(user->secret, &ac, NULL, password, 1); Bits_memcpyConst(user->passwordHash, ac.bytes, CryptoHeader_Challenge_KEYSIZE); for (struct CryptoAuth_User* u = ca->users; u; u = u->next) { if (Bits_memcmp(user->secret, u->secret, 32)) { } else if (!login) { } else if (String_equals(login, u->login)) { Allocator_free(alloc); return CryptoAuth_addUser_DUPLICATE; } } if (ipv6) { Bits_memcpyConst(user->restrictedToip6, ipv6, 16); } // Add the user to the *end* of the list for (struct CryptoAuth_User** up = &ca->users; ; up = &(*up)->next) { if (!*up) { *up = user; break; } } return 0; }
struct EventEmitter* EventEmitter_new(struct Allocator* allocator, struct Log* log, uint8_t* publicKey) { struct Allocator* alloc = Allocator_child(allocator); struct EventEmitter_pvt* ee = Allocator_calloc(alloc, sizeof(struct EventEmitter_pvt), 1); ee->log = log; ee->alloc = alloc; ee->trickIf.send = incomingFromCore; ee->pathfinders = ArrayList_Pathfinders_new(ee->alloc); Bits_memcpy(ee->publicKey, publicKey, 32); Identity_set(ee); return &ee->pub; }
void AddrSet_add(struct AddrSet* as, struct Address* addr) { struct AddrSet_pvt* ap = Identity_check((struct AddrSet_pvt*) as); int idx = indexOf(ap, addr); if (idx != -1) { return; } struct Allocator* alloc = Allocator_child(ap->alloc); struct Elem* el = Allocator_calloc(alloc, sizeof(struct Elem), 1); el->alloc = alloc; Bits_memcpy(&el->addr, addr, sizeof(struct Address)); Identity_set(el); ArrayList_OfAddrs_add(ap->addrList, el); ArrayList_OfAddrs_sort(ap->addrList); ap->pub.length = ap->addrList->length; }
struct MsgCore_Handler* MsgCore_onQuery(struct MsgCore* core, char* queryType, struct Allocator* allocator) { struct MsgCore_pvt* mcp = Identity_check((struct MsgCore_pvt*) core); struct Allocator* alloc = Allocator_child(allocator); struct QueryHandler* qh = Allocator_calloc(alloc, sizeof(struct QueryHandler), 1); qh->queryType = String_new(queryType, alloc); qh->alloc = alloc; qh->mcp = mcp; Identity_set(qh); ArrayList_OfQueryHandlers_add(mcp->qh, qh); Allocator_onFree(alloc, qhOnFree, qh); return &qh->pub; }
static struct Ducttape_MessageHeader* getDtHeader(struct Message* message, bool init) { int padding = message->padding; Assert_true(padding > Ducttape_MessageHeader_SIZE); Message_shift(message, padding); struct Ducttape_MessageHeader* dtHeader = (struct Ducttape_MessageHeader*) message->bytes; Message_shift(message, -padding); if (init) { Bits_memset(dtHeader, 0, Ducttape_MessageHeader_SIZE); Identity_set(dtHeader); } else { Identity_check(dtHeader); } return dtHeader; }
void TestFramework_linkNodes(struct TestFramework* client, struct TestFramework* server, bool beacon) { // ifaceA is the client, ifaceB is the server struct TestFramework_Link* link = Allocator_calloc(client->alloc, sizeof(struct TestFramework_Link), 1); Identity_set(link); link->clientIf.send = sendClient; link->serverIf.send = sendServer; link->client = client; link->server = server; struct InterfaceController_Iface* clientIci = InterfaceController_newIface( client->nc->ifController, String_CONST("client"), client->alloc); link->clientIfNum = clientIci->ifNum; Iface_plumb(&link->clientIf, &clientIci->addrIf); struct InterfaceController_Iface* serverIci = InterfaceController_newIface( server->nc->ifController, String_CONST("server"), server->alloc); link->serverIfNum = serverIci->ifNum; Iface_plumb(&link->serverIf, &serverIci->addrIf); if (beacon) { int ret = InterfaceController_beaconState(client->nc->ifController, link->clientIfNum, InterfaceController_beaconState_newState_ACCEPT); Assert_true(!ret); ret = InterfaceController_beaconState(server->nc->ifController, link->serverIfNum, InterfaceController_beaconState_newState_SEND); Assert_true(!ret); } else { // Except that it has an authorizedPassword added. CryptoAuth_addUser(String_CONST("abcdefg123"), String_CONST("TEST"), server->nc->ca); // Client has pubKey and passwd for the server. InterfaceController_bootstrapPeer(client->nc->ifController, link->clientIfNum, server->publicKey, Sockaddr_LOOPBACK, String_CONST("abcdefg123"), NULL, NULL, client->alloc); } }
struct ControlHandler* ControlHandler_new(struct Allocator* allocator, struct Log* logger, struct EventEmitter* ee, uint8_t myPublicKey[32]) { struct Allocator* alloc = Allocator_child(allocator); struct ControlHandler_pvt* ch = Allocator_calloc(alloc, sizeof(struct ControlHandler_pvt), 1); ch->alloc = alloc; ch->log = logger; Bits_memcpy(ch->myPublicKey, myPublicKey, 32); ch->pub.coreIf.send = incomingFromCore; ch->pub.switchPingerIf.send = incomingFromSwitchPinger; EventEmitter_regCore(ee, &ch->eventIf, 0); Identity_set(ch); return &ch->pub; }
void EventEmitter_regPathfinderIface(struct EventEmitter* emitter, struct Iface* iface) { struct EventEmitter_pvt* ee = Identity_check((struct EventEmitter_pvt*) emitter); struct Allocator* alloc = Allocator_child(ee->alloc); struct Pathfinder* pf = Allocator_calloc(alloc, sizeof(struct Pathfinder), 1); pf->ee = ee; pf->iface.send = incomingFromPathfinder; pf->alloc = alloc; Iface_plumb(&pf->iface, iface); Identity_set(pf); int i = 0; for (; i < ee->pathfinders->length; i++) { struct Pathfinder* xpf = ArrayList_Pathfinders_get(ee->pathfinders, i); if (!xpf) { break; } } pf->pathfinderId = ArrayList_Pathfinders_put(ee->pathfinders, i, pf); }
struct TestFramework* TestFramework_setUp(char* privateKey, struct Allocator* allocator, struct EventBase* base, struct Random* rand, struct Log* logger) { if (!logger) { struct Writer* logwriter = FileWriter_new(stdout, allocator); logger = WriterLog_new(logwriter, allocator); } if (!rand) { rand = Random_new(allocator, logger, NULL); } if (!base) { base = EventBase_new(allocator); } uint64_t pks[4]; if (!privateKey) { Random_longs(rand, pks, 4); privateKey = (char*)pks; } struct NetCore* nc = NetCore_new(privateKey, allocator, base, rand, logger); struct Pathfinder* pf = Pathfinder_register(allocator, logger, base, rand, NULL); struct ASynchronizer* pfAsync = ASynchronizer_new(allocator, base, logger); Iface_plumb(&pfAsync->ifA, &pf->eventIf); EventEmitter_regPathfinderIface(nc->ee, &pfAsync->ifB); struct TestFramework* tf = Allocator_calloc(allocator, sizeof(struct TestFramework), 1); Identity_set(tf); tf->alloc = allocator; tf->rand = rand; tf->eventBase = base; tf->logger = logger; tf->nc = nc; tf->tunIf = &nc->tunAdapt->tunIf; tf->publicKey = nc->myAddress->key; tf->ip = nc->myAddress->ip6.bytes; tf->pathfinder = pf; return tf; }
struct UpperDistributor* UpperDistributor_new(struct Allocator* allocator, struct Log* log, struct EventEmitter* ee) { struct Allocator* alloc = Allocator_child(allocator); struct UpperDistributor_pvt* out = Allocator_calloc(alloc, sizeof(struct UpperDistributor_pvt), 1); out->eventIf.send = incomingFromEventIf; out->pub.tunAdapterIf.send = incomingFromTunAdapterIf; out->pub.ipTunnelIf.send = incomingFromIpTunnelIf; out->pub.sessionManagerIf.send = incomingFromSessionManagerIf; out->log = log; Identity_set(out); EventEmitter_regCore(ee, &out->eventIf, PFChan_Pathfinder_SENDMSG); return &out->pub; }
static void change0(struct ReachabilityCollector_pvt* rcp, struct Address* nodeAddr, struct Allocator* tempAlloc) { for (int i = 0; i < rcp->piList->length; i++) { struct PeerInfo_pvt* pi = ArrayList_OfPeerInfo_pvt_get(rcp->piList, i); if (Address_isSameIp(nodeAddr, &pi->pub.addr)) { if (nodeAddr->path == 0) { Log_debug(rcp->log, "Peer [%s] dropped", Address_toString(&pi->pub.addr, tempAlloc)->bytes); ArrayList_OfPeerInfo_pvt_remove(rcp->piList, i); Allocator_free(pi->alloc); } else if (nodeAddr->path != pi->pub.addr.path) { Log_debug(rcp->log, "Peer [%s] changed path", Address_toString(&pi->pub.addr, tempAlloc)->bytes); pi->pub.pathThemToUs = -1; pi->pathToCheck = 1; pi->pub.querying = true; pi->pub.addr.path = nodeAddr->path; } if (rcp->pub.onChange) { rcp->pub.onChange(&rcp->pub, nodeAddr->ip6.bytes, 0, 0, 0, 0xffff, 0xffff, 0xffff); } return; } } if (nodeAddr->path == 0) { Log_debug(rcp->log, "Nonexistant peer [%s] dropped", Address_toString(nodeAddr, tempAlloc)->bytes); return; } struct Allocator* piAlloc = Allocator_child(rcp->alloc); struct PeerInfo_pvt* pi = Allocator_calloc(piAlloc, sizeof(struct PeerInfo_pvt), 1); Identity_set(pi); Bits_memcpy(&pi->pub.addr, nodeAddr, Address_SIZE); pi->alloc = piAlloc; pi->pub.querying = true; pi->pathToCheck = 1; pi->pub.pathThemToUs = -1; pi->waitForResponse = false; ArrayList_OfPeerInfo_pvt_add(rcp->piList, pi); Log_debug(rcp->log, "Peer [%s] added", Address_toString(&pi->pub.addr, tempAlloc)->bytes); mkNextRequest(rcp); }
struct InterfaceController_Iface* InterfaceController_newIface(struct InterfaceController* ifc, String* name, struct Allocator* alloc) { struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) ifc); struct InterfaceController_Iface_pvt* ici = Allocator_calloc(alloc, sizeof(struct InterfaceController_Iface_pvt), 1); ici->name = String_clone(name, alloc); ici->peerMap.allocator = alloc; ici->ic = ic; ici->alloc = alloc; ici->pub.addrIf.send = handleIncomingFromWire; ici->pub.ifNum = ArrayList_OfIfaces_add(ic->icis, ici); Identity_set(ici); return &ici->pub; }
struct RumorMill* RumorMill_new(struct Allocator* allocator, struct Address* selfAddr, int capacity, struct Log* log, const char* name) { struct Allocator* alloc = Allocator_child(allocator); Address_getPrefix(selfAddr); struct RumorMill_pvt* rm = Allocator_calloc(alloc, sizeof(struct RumorMill_pvt), 1); rm->pub.addresses = Allocator_calloc(alloc, sizeof(struct Address), capacity); rm->capacity = capacity; rm->selfAddr = Allocator_clone(alloc, selfAddr); rm->log = log; rm->pub.name = name; Identity_set(rm); return &rm->pub; }
struct Ducttape* Ducttape_register(uint8_t privateKey[32], struct DHTModuleRegistry* registry, struct RouterModule* routerModule, struct SwitchCore* switchCore, struct EventBase* eventBase, struct Allocator* allocator, struct Log* logger, struct IpTunnel* ipTun, struct Random* rand) { struct Ducttape_pvt* context = Allocator_calloc(allocator, sizeof(struct Ducttape_pvt), 1); context->registry = registry; context->routerModule = routerModule; context->logger = logger; context->eventBase = eventBase; context->alloc = allocator; Identity_set(context); context->ipTunnel = ipTun; ipTun->nodeInterface.receiveMessage = sendToNode; ipTun->nodeInterface.receiverContext = context; ipTun->tunInterface.receiveMessage = sendToTun; ipTun->tunInterface.receiverContext = context; struct CryptoAuth* cryptoAuth = CryptoAuth_new(allocator, privateKey, eventBase, logger, rand); Bits_memcpyConst(context->myAddr.key, cryptoAuth->publicKey, 32); Address_getPrefix(&context->myAddr); context->sm = SessionManager_new(incomingFromCryptoAuth, outgoingFromCryptoAuth, context, eventBase, cryptoAuth, allocator); context->pub.sessionManager = context->sm; Bits_memcpyConst(&context->module, (&(struct DHTModule) { .name = "Ducttape", .context = context, .handleOutgoing = handleOutgoing }), sizeof(struct DHTModule));