static void searchResponse(struct RouterModule_Promise* promise, uint32_t lag, struct Address* from, Dict* responseDict) { struct Search* search = Identity_check((struct Search*) promise->userData); struct Allocator* alloc = Allocator_child(search->alloc); Dict* resp = Dict_new(alloc); if (!from) { Dict_putStringCC(resp, "error", "none", alloc); Dict_putIntC(resp, "complete", 1, alloc); Admin_sendMessage(resp, search->txid, search->ctx->admin); Allocator_free(alloc); return; } String* fromStr = Address_toString(from, alloc); Dict_putStringC(resp, "from", fromStr, alloc); Dict_putIntC(resp, "ms", lag, alloc); struct Address_List* addrs = ReplySerializer_parse(from, responseDict, NULL, true, alloc); List* nodes = List_new(alloc); for (int i = 0; addrs && i < addrs->length; i++) { String* addr = Address_toString(&addrs->elems[i], alloc); List_addString(nodes, addr, alloc); } Dict_putListC(resp, "nodes", nodes, alloc); Admin_sendMessage(resp, search->txid, search->ctx->admin); }
static void newInterface2(struct Context* ctx, struct Sockaddr* addr, String* txid, struct Allocator* requestAlloc) { struct Allocator* const alloc = Allocator_child(ctx->alloc); struct UDPAddrIface* udpIf = NULL; struct Jmp jmp; Jmp_try(jmp) { udpIf = UDPAddrIface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger); } Jmp_catch { String* errStr = String_CONST(jmp.message); Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL); Admin_sendMessage(&out, txid, ctx->admin); Allocator_free(alloc); return; } struct AddrIface* ai = ctx->udpIf = &udpIf->generic; struct InterfaceController_Iface* ici = InterfaceController_newIface(ctx->ic, String_CONST("UDP"), alloc); Iface_plumb(&ici->addrIf, &ai->iface); Dict* out = Dict_new(requestAlloc); Dict_putString(out, String_CONST("error"), String_CONST("none"), requestAlloc); Dict_putInt(out, String_CONST("interfaceNumber"), ici->ifNum, requestAlloc); char* printedAddr = Sockaddr_print(ai->addr, requestAlloc); Dict_putString(out, String_CONST("bindAddress"), String_CONST(printedAddr), requestAlloc); Admin_sendMessage(out, txid, ctx->admin); }
// This is directly called from SwitchCore, message is not encrypted. static uint8_t sendFromSwitch(struct Message* msg, struct Interface* switchIf) { struct InterfaceController_Peer* ep = Identity_check((struct InterfaceController_Peer*) switchIf); ep->bytesOut += msg->length; struct InterfaceController_pvt* ic = ifcontrollerForPeer(ep); uint8_t ret; uint64_t now = Time_currentTimeMilliseconds(ic->eventBase); if (now - ep->timeOfLastMessage > ic->unresponsiveAfterMilliseconds) { // TODO(cjd): This is a hack because if the time of last message exceeds the // unresponsive time, we need to send back an error and that means // mangling the message which would otherwise be in the queue. struct Allocator* tempAlloc = Allocator_child(ic->allocator); struct Message* toSend = Message_clone(msg, tempAlloc); ret = Interface_sendMessage(ep->cryptoAuthIf, toSend); Allocator_free(tempAlloc); } else { ret = Interface_sendMessage(ep->cryptoAuthIf, msg); } // If this node is unresponsive then return an error. if (ret || now - ep->timeOfLastMessage > ic->unresponsiveAfterMilliseconds) { return ret ? ret : Error_UNDELIVERABLE; } else { /* Way way way too much noise Log_debug(ic->logger, "Sending to neighbor, last message from this node was [%u] ms ago.", (now - ep->timeOfLastMessage)); */ } return Error_NONE; }
static void checkRunningInstance(struct Allocator* allocator, struct EventBase* base, String* addr, String* password, struct Log* logger, struct Except* eh) { struct Allocator* alloc = Allocator_child(allocator); struct Sockaddr_storage pingAddrStorage; if (Sockaddr_parse(addr->bytes, &pingAddrStorage)) { Except_raise(eh, -1, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234", addr->bytes); } struct AdminClient* adminClient = AdminClient_new(&pingAddrStorage.addr, password, base, logger, alloc); // 100 milliseconds is plenty to wait for a process to respond on the same machine. adminClient->millisecondsToWait = 100; Dict* pingArgs = Dict_new(alloc); struct AdminClient_Result* pingResult = AdminClient_rpcCall(String_new("ping", alloc), pingArgs, adminClient, alloc); if (pingResult->err == AdminClient_Error_NONE) { Except_raise(eh, -1, "Startup failed: cjdroute is already running."); } Allocator_free(alloc); }
static void newInterface2(struct Context* ctx, struct Sockaddr* addr, String* txid) { struct Allocator* const alloc = Allocator_child(ctx->allocator); struct UDPInterface* udpIf = NULL; struct Jmp jmp; Jmp_try(jmp) { udpIf = UDPInterface_new(ctx->eventBase, addr, alloc, &jmp.handler, ctx->logger, ctx->ic); } Jmp_catch { String* errStr = String_CONST(jmp.message); Dict out = Dict_CONST(String_CONST("error"), String_OBJ(errStr), NULL); Admin_sendMessage(&out, txid, ctx->admin); Allocator_free(alloc); } // sizeof(struct UDPInterface*) the size of a pointer. ctx->ifaces = Allocator_realloc(ctx->allocator, ctx->ifaces, sizeof(struct UDPInterface*) * (ctx->ifCount + 1)); ctx->ifaces[ctx->ifCount] = udpIf; Dict out = Dict_CONST( String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST( String_CONST("interfaceNumber"), Int_OBJ(ctx->ifCount), NULL )); Admin_sendMessage(&out, txid, ctx->admin); ctx->ifCount++; }
static void getHandles(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = Identity_check((struct Context*) vcontext); struct Allocator* alloc = Allocator_child(context->alloc); int64_t* page = Dict_getInt(args, String_CONST("page")); int i = (page) ? *page * ENTRIES_PER_PAGE : 0; struct SessionManager_HandleList* hList = SessionManager_getHandleList(context->sm, alloc); List* list = List_new(alloc); for (int counter = 0; i < hList->length && counter++ < ENTRIES_PER_PAGE; i++) { List_addInt(list, hList->handles[i], alloc); } Dict* r = Dict_new(alloc); Dict_putList(r, String_CONST("handles"), list, alloc); Dict_putInt(r, String_CONST("total"), hList->length, alloc); String* more = String_CONST("more"); if (i < hList->length) { Dict_putInt(r, more, 1, alloc); } Admin_sendMessage(r, txid, context->admin); Allocator_free(alloc); }
static void search(uint8_t target[16], struct Janitor* janitor) { if (janitor->searches >= MAX_SEARCHES) { Log_debug(janitor->logger, "Skipping search because 20 are in progress"); return; } #ifdef Log_DEBUG uint8_t targetStr[40]; AddrTools_printIp(targetStr, target); Log_debug(janitor->logger, "Beginning search for [%s]", targetStr); #endif struct Allocator* searchAlloc = Allocator_child(janitor->allocator); struct RouterModule_Promise* rp = SearchRunner_search(target, janitor->searchRunner, searchAlloc); if (!rp) { Log_debug(janitor->logger, "SearchRunner_search() returned NULL, probably full."); Allocator_free(searchAlloc); return; } janitor->searches++; struct Janitor_Search* search = Allocator_clone(rp->alloc, (&(struct Janitor_Search) { .janitor = janitor, .alloc = searchAlloc, }));
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; } }
void ReachabilityCollector_change(struct ReachabilityCollector* rc, struct Address* nodeAddr) { struct ReachabilityCollector_pvt* rcp = Identity_check((struct ReachabilityCollector_pvt*) rc); struct Allocator* tempAlloc = Allocator_child(rcp->alloc); change0(rcp, nodeAddr, tempAlloc); Allocator_free(tempAlloc); }
static void sendFirstMessageToCore(void* vcontext) { struct NodeContext* ctx = Identity_check((struct NodeContext*) vcontext); struct Allocator* alloc = Allocator_child(ctx->alloc); struct Message* msg = Message_new(0, 512, alloc); Dict* d = Dict_new(alloc); Dict_putString(d, String_CONST("privateKey"), String_new(ctx->privateKeyHex, alloc), alloc); Dict* logging = Dict_new(alloc); { Dict_putString(logging, String_CONST("logTo"), String_CONST("stdout"), alloc); } Dict_putDict(d, String_CONST("logging"), logging, alloc); Dict* admin = Dict_new(alloc); { Dict_putString(admin, String_CONST("bind"), ctx->bind, alloc); Dict_putString(admin, String_CONST("pass"), ctx->pass, alloc); } Dict_putDict(d, String_CONST("admin"), admin, alloc); BencMessageWriter_write(d, msg, NULL); Iface_send(&ctx->angelIface, msg); Allocator_free(alloc); }
static void addKey(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = vcontext; struct Allocator* alloc = Allocator_child(context->alloc); String* identStr = Dict_getString(args, String_CONST("ident")); int ret; uint8_t key[32]; char* err = "none"; if (identStr->len < 52) { err = "too short"; } else if (Base32_decode(key, 32, identStr->bytes, 52) != 32) { err = "failed to parse"; } else if ((ret = RainflyClient_addKey(context->rainfly, key))) { if (ret == RainflyClient_addKey_TOO_MANY_KEYS) { err = "RainflyClient_addKey_TOO_MANY_KEYS"; } else { err = "unknown error"; } } Dict* response = Dict_new(alloc); Dict_putString(response, String_CONST("error"), String_CONST(err), alloc); Admin_sendMessage(response, txid, context->admin); Allocator_free(alloc); }
static void addServer(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Context* context = vcontext; struct Allocator* alloc = Allocator_child(context->alloc); String* addrStr = Dict_getString(args, String_CONST("addr")); int ret; struct Sockaddr_storage ss; char* err = "none"; if (Sockaddr_parse(addrStr->bytes, &ss)) { err = "could not parse address"; } else if ((ret = RainflyClient_addServer(context->rainfly, &ss.addr))) { if (ret == RainflyClient_addServer_WRONG_ADDRESS_TYPE) { err = "RainflyClient_addServer_WRONG_ADDRESS_TYPE"; } else { err = "unknown error"; } } Dict* response = Dict_new(alloc); Dict_putString(response, String_CONST("error"), String_CONST(err), alloc); Admin_sendMessage(response, txid, context->admin); Allocator_free(alloc); }
int InterfaceController_beaconState(struct InterfaceController* ifc, int interfaceNumber, int newState) { struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) ifc); struct InterfaceController_Iface_pvt* ici = ArrayList_OfIfaces_get(ic->icis, interfaceNumber); if (!ici) { return InterfaceController_beaconState_NO_SUCH_IFACE; } char* val = NULL; switch (newState) { default: return InterfaceController_beaconState_INVALID_STATE; case InterfaceController_beaconState_newState_OFF: val = "OFF"; break; case InterfaceController_beaconState_newState_ACCEPT: val = "ACCEPT"; break; case InterfaceController_beaconState_newState_SEND: val = "SEND"; break; } Log_debug(ic->logger, "InterfaceController_beaconState(%s, %s)", ici->name->bytes, val); ici->beaconState = newState; if (newState == InterfaceController_beaconState_newState_SEND) { // Send out a beacon right away so we don't have to wait. struct Allocator* alloc = Allocator_child(ici->alloc); sendBeacon(ici, alloc); Allocator_free(alloc); } return 0; }
struct InterfaceController* InterfaceController_new(struct CryptoAuth* ca, struct SwitchCore* switchCore, struct Log* logger, struct EventBase* eventBase, struct SwitchPinger* switchPinger, struct Random* rand, struct Allocator* allocator, struct EventEmitter* ee) { struct Allocator* alloc = Allocator_child(allocator); struct InterfaceController_pvt* out = Allocator_malloc(alloc, sizeof(struct InterfaceController_pvt)); Bits_memcpy(out, (&(struct InterfaceController_pvt) { .alloc = alloc, .ca = ca, .rand = rand, .switchCore = switchCore, .logger = logger, .eventBase = eventBase, .switchPinger = switchPinger, .unresponsiveAfterMilliseconds = UNRESPONSIVE_AFTER_MILLISECONDS, .pingAfterMilliseconds = PING_AFTER_MILLISECONDS, .timeoutMilliseconds = TIMEOUT_MILLISECONDS, .forgetAfterMilliseconds = FORGET_AFTER_MILLISECONDS, .beaconInterval = BEACON_INTERVAL, .pingInterval = (switchPinger) ? Timeout_setInterval(pingCallback, out, PING_INTERVAL_MILLISECONDS, eventBase, alloc) : NULL }), sizeof(struct InterfaceController_pvt));
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 cryptoAuth(struct Context* ctx) { Log_info(ctx->log, "Setting up salsa20/poly1305 benchmark (encryption and decryption only)"); struct Allocator* alloc = Allocator_child(ctx->alloc); struct CryptoAuth* ca1 = CryptoAuth_new(alloc, NULL, ctx->base, ctx->log, ctx->rand); struct CryptoAuth* ca2 = CryptoAuth_new(alloc, NULL, ctx->base, ctx->log, ctx->rand); struct CryptoAuth_Session* sess1 = CryptoAuth_newSession(ca1, alloc, ca2->publicKey, NULL, false, "bench"); struct CryptoAuth_Session* sess2 = CryptoAuth_newSession(ca2, alloc, ca1->publicKey, NULL, false, "bench"); int size = 1500; int count = 100000; struct Message* msg = Message_new(size, 256, alloc); Random_bytes(ctx->rand, msg->bytes, msg->length); // setup session for (int i = 0; i < 2; i++) { Assert_true(!CryptoAuth_encrypt(sess1, msg)); Assert_true(!CryptoAuth_decrypt(sess2, msg)); Assert_true(!CryptoAuth_encrypt(sess2, msg)); Assert_true(!CryptoAuth_decrypt(sess1, msg)); } begin(ctx, "salsa20/poly1305", (count * size * 8) / 1024, "kilobits"); for (int i = 0; i < count; i++) { Assert_true(!CryptoAuth_encrypt(sess1, msg)); Assert_true(!CryptoAuth_decrypt(sess2, msg)); } done(ctx); Allocator_free(alloc); }
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; }
static String* getExpectedResponse(struct Sockaddr* sa4, int prefix4, int alloc4, struct Sockaddr* sa6, int prefix6, int alloc6, struct Allocator* allocator) { Assert_true(alloc6 >= prefix6); Assert_true(alloc4 >= prefix4); struct Allocator* alloc = Allocator_child(allocator); Dict* addresses = Dict_new(alloc); if (sa4) { uint8_t* addr = NULL; Assert_true(Sockaddr_getAddress(sa4, &addr) == 4); String* addrStr = String_newBinary(addr, 4, alloc); Dict_putString(addresses, String_new("ip4", alloc), addrStr, alloc); Dict_putInt(addresses, String_new("ip4Prefix", alloc), prefix4, alloc); Dict_putInt(addresses, String_new("ip4Alloc", alloc), alloc4, alloc); } if (sa6) { uint8_t* addr = NULL; Assert_true(Sockaddr_getAddress(sa6, &addr) == 16); String* addrStr = String_newBinary(addr, 16, alloc); Dict_putString(addresses, String_new("ip6", alloc), addrStr, alloc); Dict_putInt(addresses, String_new("ip6Prefix", alloc), prefix6, alloc); Dict_putInt(addresses, String_new("ip6Alloc", alloc), alloc6, alloc); } Dict* output = Dict_new(alloc); Dict_putDict(output, String_new("addresses", alloc), addresses, alloc); Dict_putString(output, String_new("txid", alloc), String_new("abcd", alloc), alloc); struct Message* msg = Message_new(0, 512, alloc); BencMessageWriter_write(output, msg, NULL); String* outStr = String_newBinary(msg->bytes, msg->length, allocator); Allocator_free(alloc); return outStr; }
/** * If we don't know her key, the handshake has to be done backwards. * Reverse handshake requests are signaled by sending a non-obfuscated zero nonce. */ static uint8_t genReverseHandshake(struct Message* message, struct CryptoAuth_Wrapper* wrapper, union Headers_CryptoAuth* header) { reset(wrapper); Message_shift(message, -Headers_CryptoAuth_SIZE, NULL); // Buffer the packet so it can be sent ASAP if (wrapper->bufferedMessage != NULL) { // Not exactly a drop but a message is not going to reach the destination. cryptoAuthDebug0(wrapper, "DROP Expelled a message because a session has not yet been setup"); Allocator_free(wrapper->bufferedMessage->alloc); } cryptoAuthDebug0(wrapper, "Buffered a message"); struct Allocator* bmalloc = Allocator_child(wrapper->externalInterface.allocator); wrapper->bufferedMessage = Message_clone(message, bmalloc); Assert_ifParanoid(wrapper->nextNonce == 0); Message_shift(message, Headers_CryptoAuth_SIZE, NULL); header = (union Headers_CryptoAuth*) message->bytes; header->nonce = UINT32_MAX; message->length = Headers_CryptoAuth_SIZE; // sessionState must be 0, auth and 24 byte nonce are garbaged and public key is set // now garbage the authenticator and the encrypted key which are not used. Random_bytes(wrapper->context->rand, (uint8_t*) &header->handshake.authenticator, 48); // This is a special packet which the user should never see. Headers_setSetupPacket(&header->handshake.auth, 1); return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface); }
static inline int parseString(const struct Reader* reader, const struct Allocator* allocator, String** output) { #define BUFF_SZ (1<<8) #define BUFF_MAX (1<<20) int curSize = BUFF_SZ; struct Allocator* localAllocator = Allocator_child(allocator); uint8_t* buffer = localAllocator->malloc(curSize, localAllocator); if (readUntil('"', reader) || reader->read(buffer, 1, reader)) { printf("Unterminated string\n"); localAllocator->free(localAllocator); return OUT_OF_CONTENT_TO_READ; } for (int i = 0; i < BUFF_MAX - 1; i++) { if (buffer[i] == '\\') { // \x01 (skip the x) reader->skip(1, reader); uint8_t hex[2]; if (reader->read((char*)hex, 2, reader)) { printf("Unexpected end of input parsing escape sequence\n"); localAllocator->free(localAllocator); return OUT_OF_CONTENT_TO_READ; } int byte = Hex_decodeByte(hex[0], hex[1]); if (byte == -1) { printf("Invalid escape \"%c%c\" after \"%.*s\"\n",hex[0],hex[1],i+1,buffer); localAllocator->free(localAllocator); return UNPARSABLE; } buffer[i] = (uint8_t) byte; } else if (buffer[i] == '"') { *output = String_newBinary((char*)buffer, i, allocator); localAllocator->free(localAllocator); return 0; } if (i == curSize - 1) { curSize <<= 1; buffer = localAllocator->realloc(buffer, curSize, localAllocator); } if (reader->read(buffer + i + 1, 1, reader)) { if (i+1 <= 20) { printf("Unterminated string \"%.*s\"\n", i+1, buffer); } else { printf("Unterminated string starting with \"%.*s...\"\n", 20, buffer); } localAllocator->free(localAllocator); return OUT_OF_CONTENT_TO_READ; } } printf("Maximum string length of %d bytes exceeded.\n",BUFF_SZ); localAllocator->free(localAllocator); return UNPARSABLE; #undef BUFF_SZ #undef BUFF_MAX }
/** * 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); }
// Just make sure random crap doesn't crash it. static void fuzzTest(struct Allocator* parent, struct Random* rand) { struct Allocator* alloc = Allocator_child(parent); String* data = String_newBinary(NULL, Random_uint32(rand) % 1024, alloc); Random_bytes(rand, (uint8_t*)data->bytes, data->len); EncodingScheme_deserialize(data, alloc); Allocator_free(alloc); }
static void onBestPathChange(void* vPathfinder, struct Node_Two* node) { struct Pathfinder_pvt* pf = Identity_check((struct Pathfinder_pvt*) vPathfinder); struct Allocator* alloc = Allocator_child(pf->alloc); struct Message* msg = Message_new(0, 256, alloc); Iface_CALL(sendNode, msg, &node->address, 0xffffffffu - Node_getReach(node), pf); Allocator_free(alloc); }
static uint8_t receiveMessage(struct Message* msg, struct Interface* iface) { struct Hermes* hermes = Identity_check((struct Hermes*) iface->receiverContext); struct Allocator* alloc = Allocator_child(hermes->alloc); receiveMessage2(msg, hermes, alloc); Allocator_free(alloc); return 0; }
static void sendMsg(struct MsgCore_pvt* mcp, Dict* msgDict, struct Address* addr, struct Allocator* allocator) { struct Allocator* alloc = Allocator_child(allocator); // Send the encoding scheme definition Dict_putString(msgDict, CJDHTConstants_ENC_SCHEME, mcp->schemeDefinition, allocator); // And tell the asker which interface the message came from int encIdx = EncodingScheme_getFormNum(mcp->scheme, addr->path); Assert_true(encIdx != EncodingScheme_getFormNum_INVALID); Dict_putInt(msgDict, CJDHTConstants_ENC_INDEX, encIdx, allocator); // send the protocol version Dict_putInt(msgDict, CJDHTConstants_PROTOCOL, Version_CURRENT_PROTOCOL, allocator); if (!Defined(SUBNODE)) { String* q = Dict_getStringC(msgDict, "q"); String* sq = Dict_getStringC(msgDict, "sq"); if (q || sq) { Log_debug(mcp->log, "Send query [%s] to [%s]", ((q) ? q->bytes : sq->bytes), Address_toString(addr, alloc)->bytes); String* txid = Dict_getStringC(msgDict, "txid"); Assert_true(txid); String* newTxid = String_newBinary(NULL, txid->len + 1, alloc); Bits_memcpy(&newTxid->bytes[1], txid->bytes, txid->len); newTxid->bytes[0] = '1'; Dict_putStringC(msgDict, "txid", newTxid, alloc); } } struct Message* msg = Message_new(0, 2048, alloc); BencMessageWriter_write(msgDict, msg, NULL); //Log_debug(mcp->log, "Sending msg [%s]", Escape_getEscaped(msg->bytes, msg->length, alloc)); // Sanity check (make sure the addr was actually calculated) Assert_true(addr->ip6.bytes[0] == 0xfc); struct DataHeader data; Bits_memset(&data, 0, sizeof(struct DataHeader)); DataHeader_setVersion(&data, DataHeader_CURRENT_VERSION); DataHeader_setContentType(&data, ContentType_CJDHT); Message_push(msg, &data, sizeof(struct DataHeader), NULL); struct RouteHeader route; Bits_memset(&route, 0, sizeof(struct RouteHeader)); Bits_memcpy(route.ip6, addr->ip6.bytes, 16); route.version_be = Endian_hostToBigEndian32(addr->protocolVersion); route.sh.label_be = Endian_hostToBigEndian64(addr->path); Bits_memcpy(route.publicKey, addr->key, 32); Message_push(msg, &route, sizeof(struct RouteHeader), NULL); Iface_send(&mcp->pub.interRouterIf, msg); }
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; }
static void randomTest(struct Allocator* parent, struct Random* rand) { struct Allocator* alloc = Allocator_child(parent); struct EncodingScheme* control = randomScheme(rand, alloc); String* data = EncodingScheme_serialize(control, alloc); struct EncodingScheme* test = EncodingScheme_deserialize(data, alloc); assertEqual(control, test); Allocator_free(alloc); }
void InterfaceController_admin_register(struct InterfaceController* ic, struct Admin* admin, struct Allocator* allocator) { struct Allocator* alloc = Allocator_child(allocator); struct Context* ctx = Allocator_clone(alloc, (&(struct Context) { .alloc = alloc, .ic = ic, .admin = admin }));
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); }