Пример #1
0
int main(int argc, char** argv)
{
    struct AdminTestFramework* fw = AdminTestFramework_setUp(argc, argv, "UDPInterface_test");

    // mock interface controller.
    struct InterfaceController ifController = {
        .registerPeer = registerPeer
    };

    UDPInterface_admin_register(fw->eventBase,
                                fw->alloc,
                                fw->logger,
                                fw->admin,
                                &ifController);

    Dict* dict = Dict_new(fw->alloc);
    struct AdminClient_Promise* promise =
        AdminClient_rpcCall(String_CONST("UDPInterface_new"), dict, fw->client, fw->alloc);
    promise->callback = ifNewCallback;
    promise->userData = fw;

    EventBase_beginLoop(fw->eventBase);

    // bad key
    dict = Dict_new(fw->alloc);
    Dict_putString(dict, String_CONST("publicKey"), String_CONST("notAValidKey"), fw->alloc);
    Dict_putString(dict, String_CONST("address"), String_CONST("127.0.0.1:12345"), fw->alloc);
    promise = AdminClient_rpcCall(
        String_CONST("UDPInterface_beginConnection"), dict, fw->client, fw->alloc);
    promise->callback = badKeyCallback;
    promise->userData = fw;

    EventBase_beginLoop(fw->eventBase);


    dict = Dict_new(fw->alloc);
    Dict_putString(dict,
                   String_CONST("publicKey"),
                   String_CONST("c86pf0ngj3wlb569juqm10yzv29n9t4w5tmsyhx6xd3fbqjlcu50.k"),
                   fw->alloc);
    Dict_putString(dict, String_CONST("address"), String_CONST("127.0.0.1:12345"), fw->alloc);
    promise = AdminClient_rpcCall(
        String_CONST("UDPInterface_beginConnection"), dict, fw->client, fw->alloc);
    promise->callback = goodCallback;
    promise->userData = fw;

    EventBase_beginLoop(fw->eventBase);

    AdminTestFramework_tearDown(fw);
    return 0;
}
Пример #2
0
int main(int argc, char** argv)
{
printf("init test");
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Log* logger = FileWriterLog_new(stdout, alloc);
    struct EventBase* base = EventBase_new(alloc);

    char* ifName;
    struct Iface* iface = TAPInterface_new(NULL, &ifName, NULL, logger, base, alloc);
    struct NDPServer* ndp = NDPServer_new(iface, alloc);
    ndp->generic.receiveMessage = receiveMessage;
    ndp->generic.receiverContext = alloc;
    ndp->advertisePrefix[0] = 0xfd;
    ndp->prefixLen = AddressCalc_ADDRESS_PREFIX_BITS;

    struct Sockaddr_storage ss;
    Assert_true(!Sockaddr_parse("fd00::1", &ss));
    NetDev_addAddress(ifName, &ss.addr, AddressCalc_ADDRESS_PREFIX_BITS, logger, NULL);

    Timeout_setTimeout(fail, alloc, 10000, base, alloc);

    EventBase_beginLoop(base);
printf("Test ended\n");
    return 0;
}
Пример #3
0
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;
}
Пример #4
0
int main(int argc, char** argv)
{
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct EventBase* base = EventBase_new(alloc);
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(logWriter, alloc);

    struct Sockaddr* addrA = Sockaddr_fromBytes(testAddrA, Sockaddr_AF_INET6, alloc);

    char assignedIfName[TUNInterface_IFNAMSIZ];
    struct Interface* tun = TUNInterface_new(NULL, assignedIfName, base, logger, NULL, alloc);
    NetDev_addAddress(assignedIfName, addrA, 126, logger, NULL);

    struct Sockaddr_storage addr;
    Assert_always(!Sockaddr_parse("[fd00::1]", &addr));

    #ifdef freebsd
        // tun is not setup synchronously in bsd but it lets you bind to the tun's
        // address anyway.
        sleep(1);
    #endif

    // Mac OSX and BSD do not set up their TUN devices synchronously.
    // We'll just keep on trying until this works.
    struct AddrInterface* udp = NULL;
    for (int i = 0; i < 20; i++) {
        if ((udp = setupUDP(base, &addr.addr, alloc, logger))) {
            break;
        }
    }
    Assert_always(udp);

    struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc);
    uint8_t* addrBytes;
    Assert_always(16 == Sockaddr_getAddress(dest, &addrBytes));
    Bits_memcpy(addrBytes, testAddrB, 16);

    struct Message* msg;
    Message_STACK(msg, 0, 64);
    Message_push(msg, "Hello World", 12, NULL);
    Message_push(msg, dest, dest->addrLen, NULL);

    udp->generic.receiveMessage = receiveMessageUDP;
    udp->generic.receiverContext = alloc;
    tun->receiveMessage = receiveMessageTUN;

    udp->generic.sendMessage(msg, &udp->generic);

    Timeout_setTimeout(fail, NULL, 10000, base, alloc);

    EventBase_beginLoop(base);
    return 0;
}
Пример #5
0
/** Check if nodes A and C can communicate via B without A knowing that C exists. */
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1<<22);
    struct Writer* logwriter = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(logwriter, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);
    struct EventBase* base = EventBase_new(alloc);
    start(alloc, logger, base, rand, runTest);

    EventBase_beginLoop(base);
    Allocator_free(alloc);
    return 0;
}
Пример #6
0
static void standardClient(struct Context* ctx)
{
    ctx->called = false;
    struct AdminClient_Promise* promise =
        AdminClient_rpcCall(String_CONST("adminFunc"),
                            NULL,
                            ctx->framework->client,
                            ctx->framework->alloc);

    promise->callback = standardClientCallback;
    promise->userData = ctx;

    EventBase_beginLoop(ctx->framework->eventBase);
}
Пример #7
0
static int rpcCall0(String* function,
                    Dict* args,
                    struct Context* ctx,
                    struct Allocator* alloc,
                    Dict** resultP,
                    bool exitIfError)
{
    ctx->currentReqAlloc = Allocator_child(alloc);
    ctx->currentResult = NULL;
    struct AdminClient_Promise* promise = AdminClient_rpcCall(function, args, ctx->client, alloc);
    promise->callback = rpcCallback;
    promise->userData = ctx;

    EventBase_beginLoop(ctx->base);

    struct AdminClient_Result* res = ctx->currentResult;
    Assert_true(res);

    if (res->err) {
        Log_critical(ctx->logger,
                      "Failed to make function call [%s], error: [%s]",
                      AdminClient_errorString(res->err),
                      function->bytes);
        die(res, ctx, alloc);
    }
    String* error = Dict_getString(res->responseDict, String_CONST("error"));
    int ret = 0;
    if (error && !String_equals(error, String_CONST("none"))) {
        if (exitIfError) {
            Log_critical(ctx->logger,
                         "Got error [%s] calling [%s]",
                         error->bytes,
                         function->bytes);
            die(res, ctx, alloc);
        }
        Log_warn(ctx->logger, "Got error [%s] calling [%s], ignoring.",
                 error->bytes, function->bytes);
        ret = 1;
    }

    if (resultP) {
        *resultP = res->responseDict;
    } else {
        Allocator_free(ctx->currentReqAlloc);
    }
    ctx->currentReqAlloc = NULL;

    return ret;
}
Пример #8
0
int main(int argc, char** argv)
{
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct EventBase* base = EventBase_new(alloc);
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* log = WriterLog_new(logWriter, alloc);

    struct Sockaddr* addrA = Sockaddr_fromBytes(testAddrA, Sockaddr_AF_INET6, alloc);

    char assignedIfName[TUNInterface_IFNAMSIZ];
    struct Interface* tap = TUNInterface_new(NULL, assignedIfName, 1, base, log, NULL, alloc);
    struct TAPWrapper* tapWrapper = TAPWrapper_new(tap, log, alloc);

    // Now setup the NDP server so the tun will work correctly.
    struct NDPServer* ndp = NDPServer_new(&tapWrapper->generic, log, TAPWrapper_LOCAL_MAC, alloc);
    ndp->advertisePrefix[0] = 0xfd;
    ndp->prefixLen = 8;

    struct Interface* tun = &ndp->generic;

    NetDev_addAddress(assignedIfName, addrA, 126, log, NULL);

    struct Sockaddr_storage addr;
    Assert_true(!Sockaddr_parse("[::]", &addr));

    struct AddrInterface* udp = TUNTools_setupUDP(base, &addr.addr, alloc, log);

    struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc);
    uint8_t* addrBytes;
    Assert_true(16 == Sockaddr_getAddress(dest, &addrBytes));
    Bits_memcpy(addrBytes, testAddrB, 16);

    udp->generic.receiveMessage = receiveMessageUDP;
    udp->generic.receiverContext = alloc;
    tun->receiveMessage = receiveMessageTUN;

    TUNTools_sendHelloWorld(udp, dest, base, alloc);
    Timeout_setTimeout(fail, NULL, 10000000, base, alloc);

    EventBase_beginLoop(base);
    return 0;
}
Пример #9
0
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_throw(eh, "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_Promise* pingPromise =
        AdminClient_rpcCall(String_new("ping", alloc), pingArgs, adminClient, alloc);

    struct CheckRunningInstanceContext* ctx =
        Allocator_malloc(alloc, sizeof(struct CheckRunningInstanceContext));
    ctx->base = base;
    ctx->alloc = alloc;
    ctx->res = NULL;

    pingPromise->callback = checkRunningInstanceCallback;
    pingPromise->userData = ctx;

    EventBase_beginLoop(base);

    Assert_true(ctx->res);
    if (ctx->res->err != AdminClient_Error_TIMEOUT) {
        Except_throw(eh, "Startup failed: cjdroute is already running. [%d]", ctx->res->err);
    }

    Allocator_free(alloc);
}
Пример #10
0
int main(int argc, char** argv)
{
    // TODO: fix TUNConfigurator_addIp4Address() for Illumos, Darwin, BSD.
    #if defined(Illumos) || defined(Darwin) || defined(FreeBSD) || defined(OpenBSD)
        return 0;
    #endif

    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct EventBase* base = EventBase_new(alloc);
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(logWriter, alloc);

    struct Sockaddr* addrA = Sockaddr_fromBytes(testAddrA, Sockaddr_AF_INET, alloc);

    char assignedIfName[TUNInterface_IFNAMSIZ];
    struct Interface* tun = TUNInterface_new(NULL, assignedIfName, base, logger, NULL, alloc);
    NetDev_addAddress(assignedIfName, addrA, 30, logger, NULL);

    struct Sockaddr_storage ss;
    Assert_true(!Sockaddr_parse("0.0.0.0", &ss));
    struct AddrInterface* udp = UDPAddrInterface_new(base, &ss.addr, alloc, NULL, logger);

    struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc);
    uint8_t* addr;
    Assert_true(4 == Sockaddr_getAddress(dest, &addr));
    Bits_memcpy(addr, testAddrB, 4);

    struct Message* msg;
    Message_STACK(msg, 0, 64);
    Message_push(msg, "Hello World", 12);
    Message_push(msg, dest, dest->addrLen);

    udp->generic.receiveMessage = receiveMessageUDP;
    udp->generic.receiverContext = alloc;
    tun->receiveMessage = receiveMessageTUN;

    udp->generic.sendMessage(msg, &udp->generic);

    Timeout_setTimeout(fail, NULL, 1000, base, alloc);

    EventBase_beginLoop(base);
}
Пример #11
0
int main(int argc, char** argv)
{
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct EventBase* base = EventBase_new(alloc);
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(logWriter, alloc);

    // mock interface controller.
    struct InterfaceController ic = {
        .registerPeer = registerPeer
    };

    struct Sockaddr_storage addr;
    Assert_always(!Sockaddr_parse("127.0.0.1", &addr));

    struct UDPInterface* udpA = UDPInterface_new(base, &addr.addr, alloc, NULL, logger, &ic);
    struct UDPInterface* udpB = UDPInterface_new(base, &addr.addr, alloc, NULL, logger, &ic);

    struct Message* msg;
    Message_STACK(msg, 0, 128);

    Message_push(msg, "Hello World", 12, NULL);
    Message_push(msg, udpA->addr, udpA->addr->addrLen, NULL);

    struct Interface* ifA = &((struct UDPInterface_pvt*) udpA)->udpBase->generic;
    struct Interface* ifB = &((struct UDPInterface_pvt*) udpB)->udpBase->generic;

    ifA->receiveMessage = receiveMessageA;
    ifB->receiveMessage = receiveMessageB;
    ifB->receiverContext = alloc;

    struct Allocator* child = Allocator_child(alloc);
    msg = Message_clone(msg, child);
    ifB->sendMessage(msg, ifB);
    Allocator_free(child);

    Timeout_setTimeout(fail, NULL, 1000, base, alloc);

    EventBase_beginLoop(base);
    return 0;
}
Пример #12
0
static void die(struct AdminClient_Result* res, struct Context* ctx, struct Allocator* alloc)
{
    Log_keys(ctx->logger, "message bytes = [%s]", res->messageBytes);
    #ifndef Log_KEYS
        Log_critical(ctx->logger, "enable Log_LEVEL=KEYS to see message content.");
    #endif

    Dict d = NULL;
    struct AdminClient_Promise* exitPromise =
        AdminClient_rpcCall(String_CONST("Core_exit"), &d, ctx->client, alloc);
    exitPromise->callback = rpcCallback;
    exitPromise->userData = ctx;

    EventBase_beginLoop(ctx->base);

    if (ctx->currentResult->err) {
        Log_critical(ctx->logger, "Failed to stop the core.");
    }
    Log_critical(ctx->logger, "Aborting.");
    exit(1);
}
Пример #13
0
void TUNTools_echoTest(struct Sockaddr* udpBindTo,
                       struct Sockaddr* tunDestAddr,
                       TUNTools_Callback tunMessageHandler,
                       struct Iface* tun,
                       struct EventBase* base,
                       struct Log* logger,
                       struct Allocator* allocator)
{
    struct Allocator* alloc = Allocator_child(allocator);
    struct AddrIface* udp = setupUDP(base, udpBindTo, alloc, logger);

    struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc);
    uint8_t* tunDestAddrBytes = NULL;
    uint8_t* udpDestPointer = NULL;
    int len = Sockaddr_getAddress(dest, &udpDestPointer);
    Assert_true(len && len == Sockaddr_getAddress(tunDestAddr, &tunDestAddrBytes));
    Bits_memcpy(udpDestPointer, tunDestAddrBytes, len);

    struct TUNTools_pvt* ctx = Allocator_calloc(alloc, sizeof(struct TUNTools_pvt), 1);
    Identity_set(ctx);
    ctx->pub.udpIface.send = receiveMessageUDP;
    ctx->pub.tunIface.send = receiveMessageTUN;
    Iface_plumb(&ctx->pub.udpIface, &udp->iface);
    Iface_plumb(&ctx->pub.tunIface, tun);
    ctx->pub.cb = tunMessageHandler;
    ctx->pub.tunDestAddr = Sockaddr_clone(dest, alloc);
    ctx->pub.udpBindTo = Sockaddr_clone(udpBindTo, alloc);
    ctx->pub.alloc = alloc;
    ctx->pub.log = logger;
    ctx->pub.base = base;

    Timeout_setInterval(sendHello, ctx, 1000, base, alloc);
    Timeout_setTimeout(fail, NULL, 10000, base, alloc);

    EventBase_beginLoop(base);
}
Пример #14
0
static void sleep(int milliseconds, struct Context* ctx, struct Allocator* temp)
{
    Timeout_setTimeout(awaken, ctx, milliseconds, ctx->base, temp);
    EventBase_beginLoop(ctx->base);
}
Пример #15
0
int main(int argc, char** argv)
{
    #ifdef Log_KEYS
        fprintf(stderr, "Log_LEVEL = KEYS, EXPECT TO SEE PRIVATE KEYS IN YOUR LOGS!\n");
    #endif

    if (argc < 2) {
        // Fall through.
    } else if (!CString_strcmp("angel", argv[1])) {
        return AngelInit_main(argc, argv);
    } else if (!CString_strcmp("core", argv[1])) {
        return Core_main(argc, argv);
    }

    Assert_ifParanoid(argc > 0);
    struct Except* eh = NULL;

    // Allow it to allocate 8MB
    struct Allocator* allocator = MallocAllocator_new(1<<23);
    struct Random* rand = Random_new(allocator, NULL, eh);
    struct EventBase* eventBase = EventBase_new(allocator);

    if (argc == 2) {
        // one argument
        if ((CString_strcmp(argv[1], "--help") == 0) || (CString_strcmp(argv[1], "-h") == 0)) {
            return usage(allocator, argv[0]);
        } else if (CString_strcmp(argv[1], "--genconf") == 0) {
            return genconf(rand);
        } else if (CString_strcmp(argv[1], "--pidfile") == 0) {
            // deprecated
            fprintf(stderr, "'--pidfile' option is deprecated.\n");
            return 0;
        } else if (CString_strcmp(argv[1], "--reconf") == 0) {
            // Performed after reading the configuration
        } else if (CString_strcmp(argv[1], "--bench") == 0) {
            return benchmark();
        } else if ((CString_strcmp(argv[1], "--version") == 0)
            || (CString_strcmp(argv[1], "-v") == 0))
        {
            printf("Cjdns protocol version: %d\n", Version_CURRENT_PROTOCOL);
            return 0;
        } else if (CString_strcmp(argv[1], "--cleanconf") == 0) {
            // Performed after reading configuration
        } else if (CString_strcmp(argv[1], "--nobg") == 0) {
            // Performed while reading configuration
        } else {
            fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]);
            fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
            return -1;
        }
    } else if (argc > 2) {
        // more than one argument?
        fprintf(stderr, "%s: too many arguments [%s]\n", argv[0], argv[1]);
        fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
        // because of '--pidfile $filename'?
        if (CString_strcmp(argv[1], "--pidfile") == 0)
        {
            fprintf(stderr, "\n'--pidfile' option is deprecated.\n");
        }
        return -1;
    }

    if (isatty(STDIN_FILENO)) {
        // We were started from a terminal
        // The chances an user wants to type in a configuration
        // bij hand are pretty slim so we show him the usage
        return usage(allocator, argv[0]);
    } else {
        // We assume stdin is a configuration file and that we should
        // start routing
    }

    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;
    }

    if (argc == 2 && CString_strcmp(argv[1], "--cleanconf") == 0) {
        struct Writer* stdoutWriter = FileWriter_new(stdout, allocator);
        JsonBencSerializer_get()->serializeDictionary(stdoutWriter, &config);
        printf("\n");
        return 0;
    }

    int forceNoBackground = 0;
    if (argc == 2 && CString_strcmp(argv[1], "--nobg") == 0) {
        forceNoBackground = 1;
    }

    struct Writer* logWriter = FileWriter_new(stdout, allocator);
    struct Log* logger = WriterLog_new(logWriter, allocator);

    // --------------------- Get Admin  --------------------- //
    Dict* configAdmin = Dict_getDict(&config, String_CONST("admin"));
    String* adminPass = Dict_getString(configAdmin, String_CONST("password"));
    String* adminBind = Dict_getString(configAdmin, String_CONST("bind"));
    if (!adminPass) {
        adminPass = String_newBinary(NULL, 32, allocator);
        Random_base32(rand, (uint8_t*) adminPass->bytes, 32);
        adminPass->len = CString_strlen(adminPass->bytes);
    }
    if (!adminBind) {
        Except_throw(eh, "You must specify admin.bind in the cjdroute.conf file.");
    }

    // --------------------- Welcome to cjdns ---------------------- //
    char* archInfo = ArchInfo_describe(ArchInfo_detect(), allocator);
    char* sysInfo = SysInfo_describe(SysInfo_detect(), allocator);
    Log_info(logger, "Cjdns %s %s", archInfo, sysInfo);

    // --------------------- Check for running instance  --------------------- //

    Log_info(logger, "Checking for running instance...");
    checkRunningInstance(allocator, eventBase, adminBind, adminPass, logger, eh);

    // --------------------- Setup Pipes to Angel --------------------- //
    char angelPipeName[64] = "client-angel-";
    Random_base32(rand, (uint8_t*)angelPipeName+13, 31);
    Assert_ifParanoid(EventBase_eventCount(eventBase) == 0);
    struct Pipe* angelPipe = Pipe_named(angelPipeName, eventBase, eh, allocator);
    Assert_ifParanoid(EventBase_eventCount(eventBase) == 2);
    angelPipe->logger = logger;

    char* args[] = { "angel", angelPipeName, NULL };

    // --------------------- Spawn Angel --------------------- //
    String* privateKey = Dict_getString(&config, String_CONST("privateKey"));

    char* corePath = Process_getPath(allocator);

    if (!corePath) {
        Except_throw(eh, "Can't find a usable cjdns core executable, "
                         "make sure it is in the same directory as cjdroute");
    }

    if (!privateKey) {
        Except_throw(eh, "Need to specify privateKey.");
    }
    Log_info(logger, "Forking angel to background.");
    Process_spawn(corePath, args, eventBase, allocator);

    // --------------------- Get user for angel to setuid() ---------------------- //
    String* securityUser = NULL;
    List* securityConf = Dict_getList(&config, String_CONST("security"));
    for (int i = 0; securityConf && i < List_size(securityConf); i++) {
        securityUser = Dict_getString(List_getDict(securityConf, i), String_CONST("setuser"));
        if (securityUser) {
            int64_t* ea = Dict_getInt(List_getDict(securityConf, i), String_CONST("exemptAngel"));
            if (ea && *ea) {
                securityUser = NULL;
            }
            break;
        }
    }

    // --------------------- Pre-Configure Angel ------------------------- //
    Dict* preConf = Dict_new(allocator);
    Dict* adminPreConf = Dict_new(allocator);
    Dict_putDict(preConf, String_CONST("admin"), adminPreConf, allocator);
    Dict_putString(adminPreConf, String_CONST("core"), String_new(corePath, allocator), allocator);
    Dict_putString(preConf, String_CONST("privateKey"), privateKey, allocator);
    Dict_putString(adminPreConf, String_CONST("bind"), adminBind, allocator);
    Dict_putString(adminPreConf, String_CONST("pass"), adminPass, allocator);
    if (securityUser) {
        Dict_putString(adminPreConf, String_CONST("user"), securityUser, allocator);
    }
    Dict* logging = Dict_getDict(&config, String_CONST("logging"));
    if (logging) {
        Dict_putDict(preConf, String_CONST("logging"), logging, allocator);
    }

    struct Message* toAngelMsg = Message_new(0, 1024, allocator);
    BencMessageWriter_write(preConf, toAngelMsg, eh);
    Interface_sendMessage(&angelPipe->iface, toAngelMsg);

    Log_debug(logger, "Sent [%d] bytes to angel process", toAngelMsg->length);

    // --------------------- Get Response from Angel --------------------- //

    struct Message* fromAngelMsg =
        InterfaceWaiter_waitForData(&angelPipe->iface, eventBase, allocator, eh);
    Dict* responseFromAngel = BencMessageReader_read(fromAngelMsg, allocator, eh);

    // --------------------- Get Admin Addr/Port/Passwd --------------------- //
    Dict* responseFromAngelAdmin = Dict_getDict(responseFromAngel, String_CONST("admin"));
    adminBind = Dict_getString(responseFromAngelAdmin, String_CONST("bind"));

    if (!adminBind) {
        Except_throw(eh, "didn't get address and port back from angel");
    }
    struct Sockaddr_storage adminAddr;
    if (Sockaddr_parse(adminBind->bytes, &adminAddr)) {
        Except_throw(eh, "Unable to parse [%s] as an ip address port, eg: 127.0.0.1:11234",
                     adminBind->bytes);
    }

    // sanity check, Pipe_named() creates 2 events, see above.
    Assert_ifParanoid(EventBase_eventCount(eventBase) == 2);

    // --------------------- Configuration ------------------------- //
    Configurator_config(&config,
                        &adminAddr.addr,
                        adminPass,
                        eventBase,
                        logger,
                        allocator);

    // --------------------- noBackground ------------------------ //

    int64_t* noBackground = Dict_getInt(&config, String_CONST("noBackground"));
    if (forceNoBackground || (noBackground && *noBackground)) {
        EventBase_beginLoop(eventBase);
    }

    //Allocator_free(allocator);
    return 0;
}
Пример #16
0
int main(int argc, char** argv)
{
    if (argc > 1 && !strcmp("--genconf", argv[argc-1])) {
        genconf();
        return 0;
    }

    struct Allocator* alloc = MallocAllocator_new(1<<22);
    struct EventBase* base = EventBase_new(alloc);
    struct Writer* logWriter = FileWriter_new(stdout, alloc);
    struct Log* logger = WriterLog_new(logWriter, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);

    struct Reader* stdinReader = FileReader_new(stdin, alloc);
    Dict config;
    if (JsonBencSerializer_get()->parseDictionary(stdinReader, alloc, &config)) {
        Log_critical(logger, "Failed to parse configuration");
        return -1;
    }

    Dict* dns = Dict_getDict(&config, String_CONST("dns"));
    if (!dns) {
        Log_critical(logger, "No DNS in configuration");
        return -1;
    }

    struct Sockaddr_storage addr;
    Assert_true(!Sockaddr_parse("::", &addr));
    struct AddrInterface* ifaceB = UDPAddrInterface_new(base, &addr.addr, alloc, NULL, logger);
    struct RainflyClient* client = RainflyClient_new(ifaceB, base, rand, logger);

    String* bind = Dict_getString(dns, String_CONST("bind"));
    Assert_true(!Sockaddr_parse(bind ? bind->bytes : "[::]:5353", &addr));
    struct AddrInterface* iface = UDPAddrInterface_new(base, &addr.addr, alloc, NULL, logger);
    struct DNSServer* dnsServer = DNSServer_new(iface, logger, client);

    List* auth = Dict_getList(dns, String_CONST("authorities"));
    for (int i = 0; i < (int)List_size(auth); i++) {
        String* str = List_getString(auth, i);
        if (!str) {
            Log_warn(logger, "Element [%d] in [dns.authorities] list of wrong type", i);
            continue;
        }

        uint8_t key[32] = {0};
        if (str->len < 52 || Base32_decode(key, 32, str->bytes, 52) != 32) {
            Log_warn(logger, "Failed to parse key [%s]", str->bytes);
            continue;
        }

        if (RainflyClient_addKey(client, key)) {
            Log_warn(logger, "Failed to add key to RainflyClient [%s]", str->bytes);
        }
    }

    List* servers = Dict_getList(dns, String_CONST("servers"));
    for (int i = 0; i < (int)List_size(servers); i++) {
        String* str = List_getString(servers, i);
        if (!str) {
            Log_warn(logger, "Element [%d] in [dns.servers] list of wrong type", i);
            continue;
        }

        struct Sockaddr_storage node;
        if (Sockaddr_parse(str->bytes, &node)) {
            Log_warn(logger, "Failed to parse server name [%s]", str->bytes);
            continue;
        }

        if (RainflyClient_addServer(client, &node.addr)) {
            Log_warn(logger, "Failed to add server to RainflyClient [%s]", str->bytes);
        }
    }

    List* legacy = Dict_getList(dns, String_CONST("legacy"));
    for (int i = 0; i < (int)List_size(legacy); i++) {
        String* str = List_getString(legacy, i);
        if (!str) {
            Log_warn(logger, "Element [%d] in [dns.legacy] list of wrong type", i);
            continue;
        }

        struct Sockaddr_storage node;
        if (Sockaddr_parse(str->bytes, &node)) {
            Log_warn(logger, "Failed to parse legacy server name [%s]", str->bytes);
            continue;
        }

        if (DNSServer_addServer(dnsServer, &node.addr)) {
            Log_warn(logger, "Failed to add server to DNSServer [%s]", str->bytes);
        }
    }

    EventBase_beginLoop(base);
}