Пример #1
0
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);
Пример #2
0
/*
 * This process is started with 2 parameters, they must all be numeric in base 10.
 * toAngel the pipe which is used to send data back to the angel process.
 * fromAngel the pipe which is used to read incoming data from the angel.
 *
 * Upon initialization, this process will wait for an initial configuration to be sent to
 * it and then it will send an initial response.
 */
int Core_main(int argc, char** argv)
{
    struct Except* eh = NULL;
    int toAngel;
    int fromAngel;
    if (argc != 4
        || !(toAngel = atoi(argv[2]))
        || !(fromAngel = atoi(argv[3])))
    {
        Except_raise(eh, -1, "This is internal to cjdns and shouldn't started manually.");
    }

    struct Allocator* alloc = MallocAllocator_new(ALLOCATOR_FAILSAFE);
    struct EventBase* eventBase = EventBase_new(alloc);
    struct Random* rand = Random_new(alloc, eh);

    // -------------------- Setup the Pre-Logger ---------------------- //
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* preLogger = WriterLog_new(logWriter, alloc);
    struct IndirectLog* indirectLogger = IndirectLog_new(alloc);
    indirectLogger->wrappedLog = preLogger;
    struct Log* logger = &indirectLogger->pub;

    // The first read inside of getInitialConfig() will begin it waiting.
    struct PipeInterface* pi =
        PipeInterface_new(fromAngel, toAngel, eventBase, logger, alloc, rand);

    Dict* config = getInitialConfig(&pi->generic, eventBase, alloc, eh);
    String* privateKeyHex = Dict_getString(config, String_CONST("privateKey"));
    Dict* adminConf = Dict_getDict(config, String_CONST("admin"));
    String* pass = Dict_getString(adminConf, String_CONST("pass"));
    if (!pass || !privateKeyHex) {
        Except_raise(eh, -1, "Expected 'pass' and 'privateKey' in configuration.");
    }
    Log_keys(logger, "Starting core with admin password [%s]", pass->bytes);
    uint8_t privateKey[32];
    if (privateKeyHex->len != 64
        || Hex_decode(privateKey, 32, (uint8_t*) privateKeyHex->bytes, 64) != 32)
    {
        Except_raise(eh, -1, "privateKey must be 64 bytes of hex.");
    }

    struct Admin* admin = Admin_new(&pi->generic, alloc, logger, eventBase, pass);

    Dict adminResponse = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL);
    Admin_sendMessageToAngel(&adminResponse, admin);

    // --------------------- Setup the Logger --------------------- //
    // the prelogger will nolonger be used.
    struct Log* adminLogger = AdminLog_registerNew(admin, alloc, rand);
    indirectLogger->wrappedLog = adminLogger;
    logger = adminLogger;


    // CryptoAuth
    struct Address addr;
    parsePrivateKey(privateKey, &addr, eh);
    struct CryptoAuth* cryptoAuth = CryptoAuth_new(alloc, privateKey, eventBase, logger, rand);

    struct SwitchCore* switchCore = SwitchCore_new(logger, alloc);
    struct DHTModuleRegistry* registry = DHTModuleRegistry_new(alloc);
    ReplyModule_register(registry, alloc);

    // Router
    struct RouterModule* router = RouterModule_register(registry,
                                                        alloc,
                                                        addr.key,
                                                        eventBase,
                                                        logger,
                                                        admin,
                                                        rand);

    SerializationModule_register(registry, logger, alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eventBase, alloc, rand);

    struct Ducttape* dt = Ducttape_register(privateKey,
                                            registry,
                                            router,
                                            switchCore,
                                            eventBase,
                                            alloc,
                                            logger,
                                            admin,
                                            ipTun,
                                            rand);

    struct SwitchPinger* sp =
        SwitchPinger_new(&dt->switchPingerIf, eventBase, logger, alloc);

    // Interfaces.
    struct InterfaceController* ifController =
        DefaultInterfaceController_new(cryptoAuth,
                                       switchCore,
                                       router,
                                       logger,
                                       eventBase,
                                       sp,
                                       alloc);

    // ------------------- Register RPC functions ----------------------- //
    SwitchPinger_admin_register(sp, admin, alloc);
    UDPInterface_admin_register(eventBase, alloc, logger, admin, ifController);
#ifdef HAS_ETH_INTERFACE
    ETHInterface_admin_register(eventBase, alloc, logger, admin, ifController);
#endif
    RouterModule_admin_register(router, admin, alloc);
    AuthorizedPasswords_init(admin, cryptoAuth, alloc);
    Admin_registerFunction("ping", adminPing, admin, false, NULL, admin);
    Admin_registerFunction("Core_exit", adminExit, logger, true, NULL, admin);
    Core_admin_register(addr.ip6.bytes, dt, logger, alloc, admin, eventBase);
    Security_admin_register(alloc, logger, admin);
    IpTunnel_admin_register(ipTun, admin, alloc);

    struct MemoryContext* mc =
        alloc->clone(sizeof(struct MemoryContext), alloc,
            &(struct MemoryContext) {
                .allocator = alloc,
                .admin = admin
            });
Пример #3
0
int main()
{
    AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey);
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Writer* w = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(w, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);
    struct EventBase* eb = EventBase_new(alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand, NULL);
    struct Sockaddr_storage ip6ToGive;
    Sockaddr_parse("fd01:0101:0101:0101:0101:0101:0101:0101", &ip6ToGive);
    IpTunnel_allowConnection(fakePubKey, &ip6ToGive.addr, NULL, ipTun);

    struct Message* message;
    Message_STACK(message, 64, 512);
    message->alloc = alloc;

    const char* requestForAddresses =
        "d"
          "1:q" "21:IpTunnel_getAddresses"
          "4:txid" "4:abcd"
        "e";
    CString_strcpy((char*)message->bytes, requestForAddresses);
    message->length = CString_strlen(requestForAddresses);

    Message_shift(message, Headers_UDPHeader_SIZE, NULL);
    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes;

    uh->srcPort_be = 0;
    uh->destPort_be = 0;
    uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE);
    uint16_t* checksum = &uh->checksum_be;
    *checksum = 0;
    uint32_t length = message->length;

    Message_shift(message, Headers_IP6Header_SIZE, NULL);
    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;

    ip->versionClassAndFlowLabel = 0;
    ip->flowLabelLow_be = 0;
    ip->payloadLength_be = Endian_hostToBigEndian16(length);
    ip->nextHeader = 17;
    ip->hopLimit = 255;
    Bits_memset(ip->sourceAddr, 0, 32);
    Headers_setIpVersion(ip);

    Message_shift(message, IpTunnel_PacketInfoHeader_SIZE, NULL);
    struct IpTunnel_PacketInfoHeader* pi = (struct IpTunnel_PacketInfoHeader*) message->bytes;

    Bits_memcpyConst(pi->nodeIp6Addr, nodeCjdnsIp6, 16);
    Bits_memcpyConst(pi->nodeKey, fakePubKey, 32);

    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);

    ipTun->nodeInterface.receiveMessage = responseWithIpCallback;
    ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface);
    Assert_true(called);
    called = 0;

    // Now create a message for someone else.
    Message_shift(message,
        Headers_UDPHeader_SIZE
        + Headers_IP6Header_SIZE
        + IpTunnel_PacketInfoHeader_SIZE,
        NULL);
    Bits_memcpyConst(ip->sourceAddr, fakeIp6ToGive, 16);
    // This can't be zero.
    Bits_memset(ip->destinationAddr, 1, 16);

    ipTun->tunInterface.receiveMessage = messageToTun;
    ipTun->nodeInterface.sendMessage(message, &ipTun->nodeInterface);
    Assert_true(called);

    Allocator_free(alloc);
    return 0;
}
Пример #4
0
static void testAddr(struct Context* ctx,
                     char* addr4, int prefix4, int alloc4,
                     char* addr6, int prefix6, int alloc6)
{
    struct Allocator* alloc = Allocator_child(ctx->alloc);
    struct IpTunnel* ipTun = IpTunnel_new(ctx->log, ctx->base, alloc, ctx->rand, NULL);

    struct Sockaddr* sa4 = NULL;
    struct Sockaddr_storage ip6ToGive;
    struct Sockaddr_storage ip4ToGive;
    if (addr4) {
        Assert_true(!Sockaddr_parse(addr4, &ip4ToGive));
        sa4 = &ip4ToGive.addr;
        Assert_true(Sockaddr_getFamily(sa4) == Sockaddr_AF_INET);
    }
    struct Sockaddr* sa6 = NULL;
    if (addr6) {
        Assert_true(!Sockaddr_parse(addr6, &ip6ToGive));
        sa6 = &ip6ToGive.addr;
        Assert_true(Sockaddr_getFamily(sa6) == Sockaddr_AF_INET6);
    }

    IpTunnel_allowConnection(ctx->pubKey,
                             sa6, prefix6, alloc6,
                             sa4, prefix4, alloc4,
                             ipTun);

    struct Message* msg = Message_new(64, 512, alloc);
    const char* requestForAddresses =
        "d"
          "1:q" "21:IpTunnel_getAddresses"
          "4:txid" "4:abcd"
        "e";
    CString_strcpy(msg->bytes, requestForAddresses);
    msg->length = CString_strlen(requestForAddresses);

    Message_push(msg, NULL, Headers_UDPHeader_SIZE, NULL);
    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) msg->bytes;
    uh->length_be = Endian_hostToBigEndian16(msg->length - Headers_UDPHeader_SIZE);

    uint16_t* checksum = &((struct Headers_UDPHeader*) msg->bytes)->checksum_be;
    *checksum = 0;
    uint32_t length = msg->length;

    // Because of old reasons, we need to have at least an empty IPv6 header
    Message_push(msg, NULL, Headers_IP6Header_SIZE, NULL);
    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) msg->bytes;
    Headers_setIpVersion(ip);
    ip->payloadLength_be = Endian_hostToBigEndian16(msg->length - Headers_IP6Header_SIZE);
    ip->nextHeader = 17;

    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);

    pushRouteDataHeaders(ctx, msg);

    struct IfaceContext* nodeIf = Allocator_calloc(alloc, sizeof(struct IfaceContext), 1);
    nodeIf->ctx = ctx;
    nodeIf->iface.send = responseWithIpCallback;
    struct IfaceContext* tunIf = Allocator_calloc(alloc, sizeof(struct IfaceContext), 1);
    tunIf->ctx = ctx;
    tunIf->iface.send = messageToTun;
    Iface_plumb(&nodeIf->iface, &ipTun->nodeInterface);
    Iface_plumb(&tunIf->iface, &ipTun->tunInterface);
    ctx->expectedResponse =
        getExpectedResponse(sa4, prefix4, alloc4, sa6, prefix6, alloc6, alloc);
    Iface_send(&nodeIf->iface, msg);
    Assert_true(ctx->called == 2);
    ctx->called = 0;

    if (sa4) {
        uint8_t* addrBytes = NULL;
        Assert_true(Sockaddr_getAddress(sa4, &addrBytes) == 4);
        uint32_t addr;
        Bits_memcpy(&addr, addrBytes, 4);
        addr = Endian_bigEndianToHost32(addr);
        // Send from the address specified
        Assert_true(trySend4(alloc, addr, &nodeIf->iface, ctx));

        if (alloc4 < 32) {
            // Send from another (random) address in the prefix
            uint32_t flip = Random_uint32(ctx->rand) >> alloc4;
            if (prefix4 != 32) {
                Assert_true(trySend4(alloc, addr ^ flip, &nodeIf->iface, ctx));
            } else {
                // If netSize is not specified, we do not allow multi-address
                Assert_true(!trySend4(alloc, addr ^ flip, &nodeIf->iface, ctx));
            }
        } else {
Пример #5
0
/*
 * This process is started with 2 parameters, they must all be numeric in base 10.
 * toAngel the pipe which is used to send data back to the angel process.
 * fromAngel the pipe which is used to read incoming data from the angel.
 *
 * Upon initialization, this process will wait for an initial configuration to be sent to
 * it and then it will send an initial response.
 */
int Core_main(int argc, char** argv)
{
    struct Except* eh = NULL;

    if (argc != 3) {
        Except_raise(eh, -1, "This is internal to cjdns and shouldn't started manually.");
    }

    struct Allocator* alloc = MallocAllocator_new(ALLOCATOR_FAILSAFE);
    struct Log* preLogger = FileWriterLog_new(stderr, alloc);
    struct EventBase* eventBase = EventBase_new(alloc);

    // -------------------- Setup the Pre-Logger ---------------------- //
    struct Log* logger = IndirectLog_new(alloc);
    IndirectLog_set(logger, preLogger);

    // -------------------- Setup the PRNG ---------------------- //
    struct Random* rand = LibuvEntropyProvider_newDefaultRandom(eventBase, logger, eh, alloc);

    // -------------------- Change Canary Value ---------------------- //
    MallocAllocator_setCanary(alloc, (long)Random_int64(rand));
    struct Allocator* tempAlloc = Allocator_child(alloc);


    // The first read inside of getInitialConfig() will begin it waiting.
    struct Pipe* angelPipe = Pipe_named(argv[2], eventBase, eh, alloc);
    angelPipe->logger = logger;
    angelPipe->onClose = angelDied;

    struct Interface* angelIface = FramingInterface_new(65535, &angelPipe->iface, alloc);

    Dict* config = getInitialConfig(angelIface, eventBase, tempAlloc, eh);

    struct Hermes* hermes = Hermes_new(angelIface, eventBase, logger, alloc);

    String* privateKeyHex = Dict_getString(config, String_CONST("privateKey"));
    Dict* adminConf = Dict_getDict(config, String_CONST("admin"));
    String* pass = Dict_getString(adminConf, String_CONST("pass"));
    String* bind = Dict_getString(adminConf, String_CONST("bind"));
    if (!(pass && privateKeyHex && bind)) {
        if (!pass) {
            Except_raise(eh, -1, "Expected 'pass'");
        }
        if (!bind) {
            Except_raise(eh, -1, "Expected 'bind'");
        }
        if (!privateKeyHex) {
            Except_raise(eh, -1, "Expected 'privateKey'");
        }
        Except_raise(eh, -1, "Expected 'pass', 'privateKey' and 'bind' in configuration.");
    }
    Log_keys(logger, "Starting core with admin password [%s]", pass->bytes);
    uint8_t privateKey[32];
    if (privateKeyHex->len != 64
        || Hex_decode(privateKey, 32, (uint8_t*) privateKeyHex->bytes, 64) != 32)
    {
        Except_raise(eh, -1, "privateKey must be 64 bytes of hex.");
    }

    struct Sockaddr_storage bindAddr;
    if (Sockaddr_parse(bind->bytes, &bindAddr)) {
        Except_raise(eh, -1, "bind address [%s] unparsable", bind->bytes);
    }

    struct AddrInterface* udpAdmin =
        UDPAddrInterface_new(eventBase, &bindAddr.addr, alloc, eh, logger);

    struct Admin* admin = Admin_new(udpAdmin, alloc, logger, eventBase, pass);

    char* boundAddr = Sockaddr_print(udpAdmin->addr, tempAlloc);
    Dict adminResponse = Dict_CONST(
        String_CONST("bind"), String_OBJ(String_CONST(boundAddr)), NULL
    );
    Dict response = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
        String_CONST("admin"), Dict_OBJ(&adminResponse), NULL
    ));
    // This always times out because the angel doesn't respond.
    Hermes_callAngel(&response, angelResponse, NULL, alloc, eh, hermes);

    // --------------------- Setup the Logger --------------------- //
    Dict* logging = Dict_getDict(config, String_CONST("logging"));
    String* logTo = Dict_getString(logging, String_CONST("logTo"));
    if (logTo && String_equals(logTo, String_CONST("stdout"))) {
        // do nothing, continue logging to stdout.
    } else {
        struct Log* adminLogger = AdminLog_registerNew(admin, alloc, rand);
        IndirectLog_set(logger, adminLogger);
        logger = adminLogger;
    }

    // CryptoAuth
    struct Address addr;
    parsePrivateKey(privateKey, &addr, eh);
    struct CryptoAuth* cryptoAuth = CryptoAuth_new(alloc, privateKey, eventBase, logger, rand);

    struct Sockaddr* myAddr = Sockaddr_fromBytes(addr.ip6.bytes, Sockaddr_AF_INET6, alloc);

    struct SwitchCore* switchCore = SwitchCore_new(logger, alloc);
    struct DHTModuleRegistry* registry = DHTModuleRegistry_new(alloc);
    ReplyModule_register(registry, alloc);

    // Router
    struct RouterModule* router = RouterModule_register(registry,
                                                        alloc,
                                                        addr.key,
                                                        eventBase,
                                                        logger,
                                                        admin,
                                                        rand);

    SerializationModule_register(registry, logger, alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eventBase, alloc, rand, hermes);

    struct Ducttape* dt = Ducttape_register(privateKey,
                                            registry,
                                            router,
                                            switchCore,
                                            eventBase,
                                            alloc,
                                            logger,
                                            admin,
                                            ipTun,
                                            rand);

    struct SwitchPinger* sp =
        SwitchPinger_new(&dt->switchPingerIf, eventBase, logger, alloc);

    // Interfaces.
    struct InterfaceController* ifController =
        DefaultInterfaceController_new(cryptoAuth,
                                       switchCore,
                                       router,
                                       logger,
                                       eventBase,
                                       sp,
                                       rand,
                                       alloc);

    // ------------------- Register RPC functions ----------------------- //
    SwitchPinger_admin_register(sp, admin, alloc);
    UDPInterface_admin_register(eventBase, alloc, logger, admin, ifController);
#ifdef HAS_ETH_INTERFACE
    ETHInterface_admin_register(eventBase, alloc, logger, admin, ifController);
#endif
    RouterModule_admin_register(router, admin, alloc);
    AuthorizedPasswords_init(admin, cryptoAuth, alloc);
    Admin_registerFunction("ping", adminPing, admin, false, NULL, admin);
    Core_admin_register(myAddr, dt, logger, ipTun, alloc, admin, eventBase);
    Security_admin_register(alloc, logger, admin);
    IpTunnel_admin_register(ipTun, admin, alloc);

    struct Context* ctx = Allocator_clone(alloc, (&(struct Context) {
        .allocator = alloc,
        .admin = admin,
        .logger = logger,
        .hermes = hermes
    }));
Пример #6
0
struct TestFramework* TestFramework_setUp(char* privateKey,
        struct Allocator* allocator,
        struct Log* logger)
{
    if (!logger) {
        struct Writer* logwriter = FileWriter_new(stdout, allocator);
        logger = WriterLog_new(logwriter, allocator);
    }

    struct Random* rand = Random_new(allocator, logger, NULL);
    struct EventBase* base = EventBase_new(allocator);

    uint64_t pks[4];
    if (!privateKey) {
        Random_longs(rand, pks, 4);
        privateKey = (char*)pks;
    }

    uint8_t* publicKey = Allocator_malloc(allocator, 32);
    crypto_scalarmult_curve25519_base(publicKey, (uint8_t*)privateKey);

    struct Address* myAddress = Allocator_calloc(allocator, sizeof(struct Address), 1);
    Bits_memcpyConst(myAddress->key, publicKey, 32);
    AddressCalc_addressForPublicKey(myAddress->ip6.bytes, publicKey);

    struct SwitchCore* switchCore = SwitchCore_new(logger, allocator);
    struct CryptoAuth* ca = CryptoAuth_new(allocator, (uint8_t*)privateKey, base, logger, rand);

    struct DHTModuleRegistry* registry = DHTModuleRegistry_new(allocator);
    ReplyModule_register(registry, allocator);

    struct NodeStore* nodeStore = NodeStore_new(myAddress, 128, allocator, logger, rand);

    struct RouterModule* routerModule =
        RouterModule_register(registry, allocator, publicKey, base, logger, rand, nodeStore);

    struct SearchRunner* searchRunner =
        SearchRunner_new(nodeStore, logger, base, routerModule, myAddress->ip6.bytes, allocator);

    SerializationModule_register(registry, logger, allocator);

    struct IpTunnel* ipTun = IpTunnel_new(logger, base, allocator, rand, NULL);

    struct Ducttape* dt =
        Ducttape_register((uint8_t*)privateKey, registry, routerModule, searchRunner,
                          switchCore, base, allocator, logger, ipTun, rand);

    struct SwitchPinger* sp = SwitchPinger_new(&dt->switchPingerIf, base, rand, logger, allocator);

    // Interfaces.
    struct InterfaceController* ifController =
        DefaultInterfaceController_new(ca,
                                       switchCore,
                                       routerModule,
                                       logger,
                                       base,
                                       sp,
                                       rand,
                                       allocator);

    struct TestFramework* tf = Allocator_clone(allocator, (&(struct TestFramework) {
        .alloc = allocator,
         .rand = rand,
          .eventBase = base,
           .logger = logger,
            .switchCore = switchCore,
             .ducttape = dt,
              .cryptoAuth = ca,
               .router = routerModule,
                .switchPinger = sp,
                 .ifController = ifController,
                  .publicKey = publicKey,
                   .ip = myAddress->ip6.bytes
    }));
Пример #7
0
int main()
{
    AddressCalc_addressForPublicKey(nodeCjdnsIp6, fakePubKey);
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Log* logger = FileWriterLog_new(stdout, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);
    struct EventBase* eb = EventBase_new(alloc);

    struct IpTunnel* ipTun = IpTunnel_new(logger, eb, alloc, rand);
    struct Sockaddr_storage ip6ToGive;
    Sockaddr_parse("fd01:0101:0101:0101:0101:0101:0101:0101", &ip6ToGive);
    IpTunnel_allowConnection(fakePubKey, &ip6ToGive.addr, 0, NULL, 0, ipTun);

    struct Message* message;
    Message_STACK(message, 64, 512);
    message->alloc = alloc;

    const char* requestForAddresses =
        "d"
          "1:q" "21:IpTunnel_getAddresses"
          "4:txid" "4:abcd"
        "e";
    CString_strcpy((char*)message->bytes, requestForAddresses);
    message->length = CString_strlen(requestForAddresses);

    Message_shift(message, Headers_UDPHeader_SIZE, NULL);
    struct Headers_UDPHeader* uh = (struct Headers_UDPHeader*) message->bytes;

    uh->srcPort_be = 0;
    uh->destPort_be = 0;
    uh->length_be = Endian_hostToBigEndian16(message->length - Headers_UDPHeader_SIZE);
    uint16_t* checksum = &uh->checksum_be;
    *checksum = 0;
    uint32_t length = message->length;

    Message_shift(message, Headers_IP6Header_SIZE, NULL);
    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;

    ip->versionClassAndFlowLabel = 0;
    ip->flowLabelLow_be = 0;
    ip->payloadLength_be = Endian_hostToBigEndian16(length);
    ip->nextHeader = 17;
    ip->hopLimit = 255;
    Bits_memset(ip->sourceAddr, 0, 32);
    Headers_setIpVersion(ip);

    Message_shift(message, RouteHeader_SIZE + DataHeader_SIZE, NULL);
    struct RouteHeader* rh = (struct RouteHeader*) message->bytes;
    struct DataHeader* dh = (struct DataHeader*) &rh[1];

    Bits_memset(rh, 0, RouteHeader_SIZE + DataHeader_SIZE);
    Bits_memcpy(rh->ip6, nodeCjdnsIp6, 16);
    Bits_memcpy(rh->publicKey, fakePubKey, 32);
    DataHeader_setContentType(dh, ContentType_IPTUN);

    *checksum = Checksum_udpIp6(ip->sourceAddr, (uint8_t*) uh, length);

    int origCap = message->capacity;
    int origLen = message->length;

    struct Iface nodeIface = { .send = responseWithIpCallback };
    Iface_plumb(&nodeIface, &ipTun->nodeInterface);
    struct Iface tunIface = { .send = messageToTun };
    Iface_plumb(&tunIface, &ipTun->tunInterface);

    Iface_send(&nodeIface, message);
    Assert_true(called == 2);
    called = 0;

    // This is a hack, reusing the message will cause breakage if IpTunnel is refactored.
    Message_reset(message);
    Message_shift(message, origCap, NULL);
    message->length = origLen;

    Bits_memcpy(ip->sourceAddr, fakeIp6ToGive, 16);
    // This can't be zero.
    Bits_memset(ip->destinationAddr, 1, 16);

    Iface_send(&nodeIface, message);
    Assert_true(called == 1);

    Allocator_free(alloc);
    return 0;
}