/** * 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); }
static void waitUntilPong(struct Context* ctx) { for (int i = 0; i < 10; i++) { struct Allocator* temp = Allocator_child(ctx->alloc); if (tryPing(temp, ctx)) { Allocator_free(temp); return; } sleep(200, ctx, temp); Allocator_free(temp); } Assert_failure("Failed connecting to core (perhaps you have a firewall on loopback device?)"); }
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; } }
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); }
int main() { struct Allocator* alloc = MallocAllocator_new(1<<22); struct Random* rand = Random_new(alloc, NULL, NULL); struct Log* log = FileWriterLog_new(stdout, alloc); uint8_t ip[16]; uint8_t printedIp[40]; uint8_t printedShortIp[40]; uint8_t ipFromFull[16]; uint8_t ipFromShort[16]; for (int i = 0; i < 1024; ++i) { Random_bytes(rand, ip, 16); for (int j = 0; j < 16; j++) { // make the random result have lots of zeros since that's what we're looking for. ip[j] = (ip[j] % 2) ? 0 : ip[j]; } AddrTools_printIp(printedIp, ip); AddrTools_printShortIp(printedShortIp, ip); //printf("%s\n%s\n\n", printedIp, printedShortIp); AddrTools_parseIp(ipFromFull, printedIp); AddrTools_parseIp(ipFromShort, printedShortIp); Log_debug(log, "print/parse %s", printedIp); Assert_true(0 == Bits_memcmp(ip, ipFromFull, 16)); Assert_true(0 == Bits_memcmp(ipFromFull, ipFromShort, 16)); } Allocator_free(alloc); return 0; }
int main(int argc, char** argv) { struct Allocator* alloc = MallocAllocator_new(1<<20); struct EventBase* base = EventBase_new(alloc); struct Log* log = FileWriterLog_new(stdout, alloc); struct Sockaddr* addrA = Sockaddr_fromBytes(TUNTools_testIP6AddrA, Sockaddr_AF_INET6, alloc); struct Sockaddr* addrB = Sockaddr_fromBytes(TUNTools_testIP6AddrB, Sockaddr_AF_INET6, alloc); char assignedIfName[TUNInterface_IFNAMSIZ]; struct Iface* 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->internal, log, TAPWrapper_LOCAL_MAC, alloc); struct ARPServer* arp = ARPServer_new(&ndp->internal, log, TAPWrapper_LOCAL_MAC, alloc); addrA->flags |= Sockaddr_flags_PREFIX; addrA->prefix = 126; NetDev_addAddress(assignedIfName, addrA, log, NULL); TUNTools_echoTest(addrA, addrB, TUNTools_genericIP6Echo, &arp->internal, base, log, alloc); Allocator_free(alloc); return 0; }
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); }
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); }
/** * 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 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); }
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 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 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); }
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 timeout(void* vrequest) { struct Request* req = Identity_check((struct Request*) vrequest); Dict resp = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("timeout")), NULL); req->onResponse(&resp, req->onResponseContext); Allocator_free(req->alloc); }
static void repeatHello() { uint8_t* expectedOutput = "0000000101641c99f7719f5700000000a693a9fd3f0e27e81ab1100b57b37259" "4c2adca8671f1fdd050383c91e7d56ec2336c09739fa8e91d8dc5bec63e8fad0" "74bee22a90642a6ba8555be84c5e35970c5270e8f31f2a5978e0fbdee4542882" "97568f25a3fc2801aa707d954c78eccb970bcc8cb26867e9dbf0c9d6ef1b3f27" "24e7e550"; struct Allocator* alloc = MallocAllocator_new(1<<20); struct Context* ctx = setUp(NULL, HERPUBKEY, "password", alloc); struct Message* msg = Message_new(0, CryptoHeader_SIZE + HELLOWORLDLEN, alloc); Message_push(msg, HELLOWORLD, HELLOWORLDLEN, NULL); Assert_true(!CryptoAuth_encrypt(ctx->sess, msg)); Message_reset(msg); Message_push(msg, HELLOWORLD, HELLOWORLDLEN, NULL); Assert_true(!CryptoAuth_encrypt(ctx->sess, msg)); char* actual = Hex_print(msg->bytes, msg->length, alloc); if (CString_strcmp(actual, expectedOutput)) { Assert_failure("Test failed.\n" "Expected %s\n" " Got %s\n", expectedOutput, actual); } Allocator_free(alloc); }
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); }
int main(int argc, char** argv) { if (isatty(STDIN_FILENO)) { printf("Usage: %s < cjdroute.conf > compliant.json\n", argv[0]); printf("Cjdns accepts configuration which is not valid json but only outputs json\n" "which is valid. This tool deserialies and reserialized a conf file or other " "json file.\n"); printf("In honor of thefinn93, thanks for all of your hard work helping people.\n"); return 0; } struct Allocator* allocator = MallocAllocator_new(1<<20); struct Reader* stdinReader = FileReader_new(stdin, allocator); Dict config; if (JsonBencSerializer_get()->parseDictionary(stdinReader, allocator, &config)) { fprintf(stderr, "Failed to parse configuration.\n"); return -1; } struct Writer* stdoutWriter = FileWriter_new(stdout, allocator); JsonBencSerializer_get()->serializeDictionary(stdoutWriter, &config); printf("\n"); Allocator_free(allocator); }
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); }
int main() { struct Allocator* alloc = MallocAllocator_new(1<<20); struct TestFramework* tf = TestFramework_setUp("\xad\x7e\xa3\x26\xaa\x01\x94\x0a\x25\xbc\x9e\x01\x26\x22\xdb\x69" "\x4f\xd9\xb4\x17\x7c\xf3\xf8\x91\x16\xf3\xcf\xe8\x5c\x80\xe1\x4a", alloc, NULL, NULL, NULL); CryptoAuth_addUser(String_CONST("passwd"), 1, String_CONST("TEST"), tf->cryptoAuth); struct Message* message; struct Interface iface = { .sendMessage = messageFromInterface, .senderContext = &message, .allocator = alloc }; SwitchCore_setRouterInterface(&iface, tf->switchCore); //////////////////////// int ret = reconnectionNewEndpointTest(tf->ifController, tf->publicKey, &message, alloc, tf->eventBase, tf->logger, &iface, tf->rand); Allocator_free(alloc); return ret; }
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++; }
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; }
// 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; }
int main() { struct Allocator* alloc = MallocAllocator_new(1048576); struct Log* logger = FileWriterLog_new(stdout, alloc); struct Random* rand = Random_new(alloc, logger, NULL); uint8_t curve25519private[32]; Random_bytes(rand, curve25519private, 32); uint8_t curve25519public[32]; crypto_scalarmult_curve25519_base(curve25519public, curve25519private); uint8_t signingKeyPair[64]; Sign_signingKeyPairFromCurve25519(signingKeyPair, curve25519private); struct Message* msg = Message_new(0, 512, alloc); Message_push(msg, "hello world", 12, NULL); Sign_signMsg(signingKeyPair, msg, rand); uint8_t curve25519publicB[32]; Assert_true(!Sign_verifyMsg(&signingKeyPair[32], msg)); Assert_true(!Sign_publicSigningKeyToCurve25519(curve25519publicB, &signingKeyPair[32])); Assert_true(!Bits_memcmp(curve25519publicB, curve25519public, 32)); Allocator_free(alloc); return 0; }
int UDPInterface_beginConnection(const char* address, uint8_t cryptoKey[32], String* password, struct UDPInterface* udp) { struct UDPInterface_pvt* udpif = (struct UDPInterface_pvt*) udp; struct Sockaddr_storage addr; if (Sockaddr_parse(address, &addr)) { return UDPInterface_beginConnection_BAD_ADDRESS; } if (addr.addr.addrLen != udp->addr->addrLen) { return UDPInterface_beginConnection_ADDRESS_MISMATCH; } struct Interface* iface = MultiInterface_ifaceForKey(udpif->multiIface, &addr); int ret = InterfaceController_registerPeer(udpif->ic, cryptoKey, password, false, false, iface); if (ret) { Allocator_free(iface->allocator); switch(ret) { case InterfaceController_registerPeer_BAD_KEY: return UDPInterface_beginConnection_BAD_KEY; case InterfaceController_registerPeer_OUT_OF_SPACE: return UDPInterface_beginConnection_OUT_OF_SPACE; default: return UDPInterface_beginConnection_UNKNOWN_ERROR; } } return 0; }
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; }
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 fromName() { struct Allocator* alloc = MallocAllocator_new(20000); Sockaddr_fromName("localhost", alloc); // This will fail in some cases (eg dns hijacking) //Assert_always(!Sockaddr_fromName("hasjklgyolgbvlbiogi", 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); }
// 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); }