Пример #1
0
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 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;
}
Пример #3
0
static void newInterface(Dict* args, void* vcontext, String* txid)
{
    struct Context* const ctx = vcontext;
    String* const bindAddress = Dict_getString(args, String_CONST("bindAddress"));
    struct Allocator* const alloc = ctx->allocator->child(ctx->allocator);

    struct UDPInterface* udpIf = NULL;
    struct Jmp jmp;
    Jmp_try(jmp) {
        char* const bindBytes = (bindAddress) ? bindAddress->bytes : NULL;
        udpIf = UDPInterface_new(
            ctx->eventBase, bindBytes, 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);

        if (jmp.code == UDPInterface_new_SOCKET_FAILED
            || jmp.code == UDPInterface_new_BIND_FAILED)
        {
            char* err = strerror(EVUTIL_SOCKET_ERROR());
            Dict out2 = Dict_CONST(String_CONST("cause"), String_OBJ(String_CONST(err)), out);
            Admin_sendMessage(&out2, txid, ctx->admin);
        } else {
            Admin_sendMessage(&out, txid, ctx->admin);
        }

        alloc->free(alloc);
        return;
    }

    // sizeof(struct UDPInterface*) the size of a pointer.
    ctx->ifaces = ctx->allocator->realloc(ctx->ifaces,
                                          sizeof(struct UDPInterface*) * (ctx->ifCount + 1),
                                          ctx->allocator);
    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++;
}
Пример #4
0
static void configureUDP(Dict* config, struct Context* ctx)
{
    String* bindStr = Dict_getString(config, BSTR("bind"));
    char* bindAddress = bindStr ? bindStr->bytes : NULL;

    struct UDPInterface* udpContext =
        UDPInterface_new(ctx->base, bindAddress, ctx->allocator, ctx->eHandler, ctx->logger);

    if (bindStr) {
        struct Interface* udpDefault = UDPInterface_getDefaultInterface(udpContext);
        struct Interface* authedDef =
            CryptoAuth_wrapInterface(udpDefault, NULL, true, true, ctx->ca);

        struct UDPInterfaceContext* uictx =
            ctx->allocator->malloc(sizeof(struct UDPInterfaceContext), ctx->allocator);
        uictx->context = ctx;
        uictx->udpContext = udpContext;
        authedDef->receiveMessage = serverFirstIncoming;
        authedDef->receiverContext = uictx;
    }

    Dict* connectTo = Dict_getDict(config, BSTR("connectTo"));
    if (connectTo) {
        struct Dict_Entry* entry = *connectTo;
        while (entry != NULL) {
            String* key = (String*) entry->key;
            if (entry->val->type != Object_DICT) {
                fprintf(stderr,
                        "interfaces.UDPInterface.connectTo: entry %s is not a dictionary type.\n",
                        key->bytes);
                abort();
            }
            Dict* value = entry->val->as.dictionary;

            udpConnectTo(key, value, udpContext, ctx);

            entry = entry->next;
        }
    }
}