示例#1
0
struct EncodingScheme* EncodingScheme_fromList(List* scheme, struct Allocator* alloc)
{
    struct EncodingScheme* list = Allocator_malloc(alloc, sizeof(struct EncodingScheme));
    list->count = List_size(scheme);
    list->forms = Allocator_malloc(alloc, sizeof(struct EncodingScheme_Form) * list->count);
    for (int i = 0; i < (int)list->count; i++) {
        Dict* form = List_getDict(scheme, i);
        uint64_t* prefixLen = Dict_getInt(form, String_CONST("prefixLen"));
        uint64_t* bitCount = Dict_getInt(form, String_CONST("bitCount"));
        String* prefixStr = Dict_getString(form, String_CONST("prefix"));
        if (!prefixLen || !bitCount || !prefixStr || prefixStr->len != 8) {
            return NULL;
        }
        uint32_t prefix_be;
        if (Hex_decode((uint8_t*)&prefix_be, 4, prefixStr->bytes, 8) != 4) {
            return NULL;
        }
        list->forms[i].prefixLen = *prefixLen;
        list->forms[i].bitCount = *bitCount;
        list->forms[i].prefix = Endian_bigEndianToHost32(prefix_be);
    }
    if (!EncodingScheme_isSane(list)) {
        return NULL;
    }
    return list;
}
示例#2
0
文件: TAPDevice.c 项目: cmotc/cjdns
struct TAPDevice* TAPDevice_find(const char* preferredName,
                                 struct Except* eh,
                                 struct Allocator* alloc)
{
    #define BUFF_SZ 0x100
    char guid[BUFF_SZ] = {0};
    char buff[BUFF_SZ] = {0};
    if (preferredName != NULL) {
        snprintf(buff, sizeof(buff), "%s", preferredName);
    }

    if (get_device_guid(guid, sizeof(guid), buff, sizeof(buff), eh)) {
        return NULL;
    }

    struct TAPDevice* out = Allocator_malloc(alloc, sizeof(struct TAPDevice));
    out->name = Allocator_malloc(alloc, CString_strlen(buff)+1);
    Bits_memcpy(out->name, buff, CString_strlen(buff)+1);

    snprintf(buff, sizeof(buff), USERMODEDEVICEDIR "%s" TAPSUFFIX, guid);

    out->path = Allocator_malloc(alloc, CString_strlen(buff)+1);
    Bits_memcpy(out->path, buff, CString_strlen(buff)+1);
    return out;
}
示例#3
0
static struct EncodingScheme* randomScheme(struct Random* rand, struct Allocator* alloc)
{
    struct EncodingScheme* out =
        Allocator_malloc(alloc, sizeof(struct EncodingScheme));
    do {
        out->count = Random_uint32(rand) % 32;
    } while (out->count < 2);
    out->forms = Allocator_malloc(alloc, sizeof(struct EncodingScheme_Form) * out->count);
    for (int i = 0; i < (int)out->count; i++) {
        randomForm(&out->forms[i], rand);
        for (int j = 0; j < i; j++) {
            if (out->forms[i].bitCount == out->forms[j].bitCount) {
                i--;
                break;
            }
            int minPfx = (out->forms[i].prefixLen < out->forms[j].prefixLen)
                ? out->forms[i].prefixLen : out->forms[j].prefixLen;
            if (((out->forms[j].prefix ^ out->forms[i].prefix) & ((1<<minPfx)-1)) == 0) {
                // collision, destroy both entries and try again.
                if (j != i-1) {
                    Bits_memcpyConst(&out->forms[j],
                                     &out->forms[i-1],
                                     sizeof(struct EncodingScheme_Form));
                }
                i -= 2;
                break;
            }
        }
    }
    Order_OfEncodingForms_qsort(out->forms, out->count);
    return out;
}
示例#4
0
/** @see BencSerializer.h */
static int32_t parseString(const struct Reader* reader,
                           const struct Allocator* allocator,
                           String** output)
{
    #define OUT_OF_CONTENT_TO_READ -2
    #define UNPARSABLE -3

    /* Strings longer than 1*10^21-1 represent numbers definitly larger than uint64. */
    #define NUMBER_MAXLENGTH 21
    char number[32];
    char nextChar;
    int ret;

    /* Parse the size of the string. */
    size_t i = 0;
    for (i = 0; ; i++) {
        ret = reader->read(&nextChar, 1, reader);
        if (ret != 0) {
            return OUT_OF_CONTENT_TO_READ;
        }
        if (nextChar == ':') {
            /* Found the separator. */
            break;
        }
        if (nextChar < '0' || nextChar > '9') {
            /* Invalid character. */
            return UNPARSABLE;
        }
        if (i >= NUMBER_MAXLENGTH) {
            /* Massive huge number. */
            return UNPARSABLE;
        }
        number[i] = nextChar;
    }
    number[i] = '\0';
    size_t length = strtoul(number, NULL, 10);

    char* bytes = Allocator_malloc(allocator, length + 1);
    String* string = Allocator_malloc(allocator, sizeof(String));

    /* Put a null terminator after the end so it can be treated as a normal string. */
    bytes[length] = '\0';

    if (reader->read(bytes, length, reader) != 0) {
        return OUT_OF_CONTENT_TO_READ;
    }
    string->bytes = bytes;
    string->len = length;

    *output = string;

    return 0;

    #undef OUT_OF_CONTENT_TO_READ
    #undef UNPARSABLE
    #undef NUMBER_MAXLENGTH
}
示例#5
0
文件: AdminLog.c 项目: CSRedRat/cjdns
static Dict* makeLogMessage(struct Subscription* subscription,
                            struct AdminLog* logger,
                            enum Log_Level logLevel,
                            const char* fullFilePath,
                            uint32_t line,
                            const char* format,
                            va_list vaArgs,
                            struct Allocator* alloc)
{
    time_t now;
    time(&now);

    Dict* out = Dict_new(alloc);
    char* buff = Allocator_malloc(alloc, 20);
    Hex_encode((uint8_t*)buff, 20, subscription->streamId, 8);
    Dict_putString(out, String_new("streamId", alloc), String_new(buff, alloc), alloc);
    Dict_putInt(out, String_new("time", alloc), now, alloc);
    Dict_putString(out,
                   String_new("level", alloc),
                   String_new(Log_nameForLevel(logLevel), alloc),
                   alloc);
    const char* shortName = getShortName(fullFilePath);
    Dict_putString(out, String_new("file", alloc), String_new((char*)shortName, alloc), alloc);
    Dict_putInt(out, String_new("line", alloc), line, alloc);
    String* message = String_vprintf(alloc, format, vaArgs);

    // Strip all of the annoying \n marks in the log entries.
    if (message->len > 0 && message->bytes[message->len - 1] == '\n') {
        message->len--;
    }
    Dict_putString(out, String_new("message", alloc), message, alloc);

    return out;
}
示例#6
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));
示例#7
0
struct RandomSeed* RandomSeed_new(RandomSeed_Provider* providers,
                                  int providerCount,
                                  struct Log* logger,
                                  struct Allocator* alloc)
{
    struct RandomSeed** rsList = Allocator_calloc(alloc, sizeof(struct RandomSeed), providerCount);
    int i = 0;
    for (int j = 0; j < providerCount; j++) {
        struct RandomSeed* rs = providers[j](alloc);
        if (rs) {
            rsList[i++] = rs;
        }
    }

    Assert_true(i > 0);

    struct RandomSeed_pvt* out = Allocator_malloc(alloc, sizeof(struct RandomSeed_pvt));

    out->rsList = rsList;
    out->rsCount = i;
    out->logger = logger;
    out->pub.get = get;
    out->pub.name = "RandomSeed conglomeration of random seed providers";
    Identity_set(out);

    return &out->pub;
}
示例#8
0
/** @see BencSerializer.h */
static int32_t parseDictionary(struct Reader* reader,
                               struct Allocator* allocator,
                               Dict* output)
{
    uint8_t nextChar;
    readUntil('{', reader);

    String* key;
    Object* value;
    struct Dict_Entry* entryPointer;
    struct Dict_Entry* lastEntryPointer = NULL;
    int ret = 0;

    for (;;) {
        while (!ret) {
            ret = Reader_read(reader, &nextChar, 0);
            switch (nextChar) {
                case '"':
                    break;

                case '}':
                    Reader_skip(reader, 1);
                    *output = lastEntryPointer;
                    return 0;

                case '/':
                    parseComment(reader);
                    continue;

                default:
                    Reader_skip(reader, 1);
                    continue;
            }
            break;
        }
        if (ret) {
            printf("Unterminated dictionary\n");
            return OUT_OF_CONTENT_TO_READ;
        }

        // Get key and value.
        if ((ret = parseString(reader, allocator, &key)) != 0) {
            return ret;
        }

        readUntil(':', reader);

        if ((ret = parseGeneric(reader, allocator, &value)) != 0) {
            return ret;
        }

        /* Allocate the entry. */
        entryPointer = Allocator_malloc(allocator, sizeof(struct Dict_Entry));

        entryPointer->next = lastEntryPointer;
        entryPointer->key = key;
        entryPointer->val = value;
        lastEntryPointer = entryPointer;
    }
}
示例#9
0
static inline int parseString(struct Reader* reader,
                              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 = Allocator_malloc(localAllocator, curSize);
    if (readUntil('"', reader) || Reader_read(reader, buffer, 1)) {
        printf("Unterminated string\n");
        Allocator_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(reader, 1);
            uint8_t hex[2];
            if (Reader_read(reader, (char*)hex, 2)) {
                printf("Unexpected end of input parsing escape sequence\n");
                Allocator_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);
                Allocator_free(localAllocator);
                return UNPARSABLE;
            }
            buffer[i] = (uint8_t) byte;
        } else if (buffer[i] == '"') {
            *output = String_newBinary((char*)buffer, i, allocator);
            Allocator_free(localAllocator);
            return 0;
        }
        if (i == curSize - 1) {
            curSize <<= 1;
            buffer = Allocator_realloc(localAllocator, buffer, curSize);
        }
        if (Reader_read(reader, buffer + i + 1, 1)) {
            if (i+1 <= 20) {
                printf("Unterminated string \"%.*s\"\n", i+1, buffer);
            } else {
                printf("Unterminated string starting with \"%.*s...\"\n", 20, buffer);
            }
            Allocator_free(localAllocator);
            return OUT_OF_CONTENT_TO_READ;
        }
    }

    printf("Maximum string length of %d bytes exceeded.\n",BUFF_SZ);
    Allocator_free(localAllocator);
    return UNPARSABLE;

    #undef BUFF_SZ
    #undef BUFF_MAX
}
示例#10
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    // mock interface controller.
    struct Context ctx = {
        .ic = {
            .registerPeer = registerPeer,
            .getPeerState = getPeerState
        }
    };

    struct Interface externalIf = {
        .sendMessage = sendMessage,
        .allocator = alloc,
        .senderContext = &ctx
    };

    /*struct MultiInterface* mif = */MultiInterface_new(KEY_SIZE, &externalIf, &ctx.ic);

    struct Entry* entries = Allocator_malloc(alloc, sizeof(struct Entry) * ENTRY_COUNT);
    Random_bytes(rand, (uint8_t*)entries, ENTRY_COUNT * sizeof(struct Entry));

    struct Interface** ifaces = Allocator_calloc(alloc, sizeof(char*), ENTRY_COUNT);

    // seed the list with some near collisions.
    for (int i = 0; i < 10; i++) {
        int rnd = (((uint32_t*)entries)[i] >> 1) % ENTRY_COUNT;
        ((uint32_t*) (&entries[rnd]))[0] = ((uint32_t*) (&entries[i]))[0];
    }

    for (int i = 0; i < CYCLES; i++) {
        int rnd = ((uint32_t*)entries)[i] % ENTRY_COUNT;
        struct Entry* entry = &entries[rnd];
        struct Interface* iface = ifaces[rnd];

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

        Message_push(msg, "hello world", 12);
        Message_push(msg, entry, 16);

        externalIf.receiveMessage(msg, &externalIf);

        //printf("Received message for iface [%u] from [%p]\n", rnd, (void*)ctx.receivedOn);
        if (iface) {
            Assert_always(ctx.receivedOn == iface);
        } else {
            ifaces[rnd] = ctx.receivedOn;
        }
    }

    Allocator_free(alloc);
}
示例#11
0
/** @see BencSerializer.h */
static int32_t parseList(const struct Reader* reader,
                         const struct Allocator* allocator,
                         List* output)
{
    #define OUT_OF_CONTENT_TO_READ -2
    #define UNPARSABLE -3

    char nextChar;
    if (reader->read(&nextChar, 1, reader) != 0) {
        return OUT_OF_CONTENT_TO_READ;
    }
    if (nextChar != 'l') {
        return UNPARSABLE;
    }

    Object* element;
    struct List_Item* thisEntry = NULL;
    struct List_Item** lastEntryPointer = output;
    int ret;

    if (reader->read(&nextChar, 0, reader) != 0) {
        return OUT_OF_CONTENT_TO_READ;
    }
    *lastEntryPointer = NULL;

    while (nextChar != 'e') {
        ret = parseGeneric(reader, allocator, &element);
        if (ret != 0) {
            return ret;
        }
        thisEntry = Allocator_malloc(allocator, sizeof(struct List_Item));
        thisEntry->elem = element;

        /* Read backwards so that the list reads out forward. */
        *lastEntryPointer = thisEntry;
        lastEntryPointer = &(thisEntry->next);

        if (reader->read(&nextChar, 0, reader) != 0) {
            return OUT_OF_CONTENT_TO_READ;
        }
    }

    if (thisEntry) {
        thisEntry->next = NULL;
    }

    /* move the pointer to after the 'e' at the end of the list. */
    reader->skip(1, reader);

    return 0;

    #undef OUT_OF_CONTENT_TO_READ
    #undef UNPARSABLE
}
示例#12
0
static void handleEvent(void* vcontext)
{
    struct UDPAddrInterface_pvt* context = (struct UDPAddrInterface_pvt*) vcontext;

    struct Message message = {
        .bytes = context->messageBuff.content,
        .padding = UDPAddrInterface_PADDING,
        .length = UDPAddrInterface_MAX_PACKET_SIZE
    };

    struct Sockaddr_storage addrStore;

    int rc = Socket_recvfrom(context->socket,
                             message.bytes,
                             message.length,
                             0,
                             &addrStore);

    if (rc < 0) {
        return;
    }
    if (addrStore.addr.addrLen != context->pub.addr->addrLen) {
        return;
    }
    message.length = rc;

    Message_push(&message, &addrStore, addrStore.addr.addrLen);

    if (context->pub.generic.receiveMessage) {
        context->pub.generic.receiveMessage(&message, &context->pub.generic);
    }
}

struct AddrInterface* UDPAddrInterface_new(struct EventBase* base,
                                           struct Sockaddr* addr,
                                           struct Allocator* allocator,
                                           struct Except* exHandler,
                                           struct Log* logger)
{
    struct UDPAddrInterface_pvt* context =
        Allocator_malloc(allocator, sizeof(struct UDPAddrInterface_pvt));

    Bits_memcpyConst(context, (&(struct UDPAddrInterface_pvt) {
        .pub = {
            .generic = {
                .sendMessage = sendMessage,
                .senderContext = context,
                .allocator = allocator
            },
        },
        .logger = logger,
        .socket = -1
    }), sizeof(struct UDPAddrInterface_pvt));
示例#13
0
void AuthorizedPasswords_init(struct Admin* admin,
                              struct CryptoAuth* ca,
                              struct Allocator* allocator)
{
    struct Context* context = Allocator_malloc(allocator, sizeof(struct Context));
    context->admin = admin;
    context->allocator = allocator;
    context->ca = ca;

    Admin_registerFunction("AuthorizedPasswords_add", add, context, true,
        ((struct Admin_FunctionArg[]){
            { .name = "password", .required = 1, .type = "String" },
            { .name = "user", .required = 1, .type = "String" },
            { .name = "ipv6", .required = 0, .type = "String" },
示例#14
0
文件: Sign.c 项目: benhylau/cjdns
int Sign_verifyMsg(uint8_t publicSigningKey[32], struct Message* msg)
{
    if (msg->length < 64) { return -1; }
    struct Allocator* alloc = Allocator_child(msg->alloc);
    uint8_t* buff = Allocator_malloc(alloc, msg->length);
    unsigned long long ml = msg->length;
    int ret = crypto_sign_ed25519_open(buff, &ml, msg->bytes, msg->length, publicSigningKey);
    Allocator_free(alloc);
    if (ret) {
        return -1;
    }
    Message_pop(msg, NULL, 64, NULL);
    return 0;
}
示例#15
0
struct AddrInterface* AddrInterfaceAdapter_new(struct Interface* toWrap, struct Allocator* alloc)
{
    struct AddrInterfaceAdapter_pvt* context =
        Allocator_malloc(alloc, sizeof(struct AddrInterfaceAdapter_pvt));

    Bits_memcpyConst(context, (&(struct AddrInterfaceAdapter_pvt) {
        .pub = {
            .generic = {
                .sendMessage = sendMessage,
                .senderContext = context,
                .allocator = alloc
            }
        },
        .wrapped = toWrap
    }), sizeof(struct AddrInterfaceAdapter_pvt));
示例#16
0
文件: Seccomp.c 项目: cmotc/cjdns
static struct sock_fprog* compile(struct Filter* input, int inputLen, struct Allocator* alloc)
{
    // compute gotos
    int totalOut = 0;
    for (int i = inputLen-1; i >= 0; i--) {
        struct Filter* a = &input[i];
        if (a->label == 0) {
            // check for unresolved gotos...
            Assert_true(a->jt == 0 && a->jf == 0);
            totalOut++;
            continue;
        }
        int diff = 0;
        for (int j = i-1; j >= 0; j--) {
            struct Filter* b = &input[j];
            if (b->label != 0) { continue; }
            if (b->jt == a->label) {
                b->sf.jt = diff;
                b->jt = 0;
            }
            if (b->jf == a->label) {
                b->sf.jf = diff;
                b->jf = 0;
            }
            diff++;
        }
    }

    // copy into output filter array...
    struct sock_filter* sf = Allocator_calloc(alloc, sizeof(struct sock_filter), totalOut);
    int outI = 0;
    for (int i = 0; i < inputLen; i++) {
        if (input[i].label == 0) {
            Bits_memcpyConst(&sf[outI++], &input[i].sf, sizeof(struct sock_filter));
        }
        Assert_true(outI <= totalOut);
        Assert_true(i != inputLen-1 || outI == totalOut);
    }

    struct sock_fprog* out = Allocator_malloc(alloc, sizeof(struct sock_fprog));
    out->len = (unsigned short) totalOut;
    out->filter = sf;

    return out;
}
示例#17
0
struct UDPInterface* UDPInterface_new(struct EventBase* base,
                                      struct Sockaddr* bindAddr,
                                      struct Allocator* allocator,
                                      struct Except* exHandler,
                                      struct Log* logger,
                                      struct InterfaceController* ic)
{
    struct AddrInterface* udpBase =
        UDPAddrInterface_new(base, bindAddr, allocator, exHandler, logger);

    struct UDPInterface_pvt* context = Allocator_malloc(allocator, sizeof(struct UDPInterface_pvt));
    Bits_memcpyConst(context, (&(struct UDPInterface_pvt) {
        .pub = {
            .addr = udpBase->addr
        },
        .udpBase = udpBase,
        .logger = logger,
        .ic = ic
    }), sizeof(struct UDPInterface_pvt));
示例#18
0
static int init(const uint8_t* privateKey,
                uint8_t* publicKey,
                const uint8_t* password)
{
    printf("\nSetting up:\n");
    struct Allocator* allocator = MallocAllocator_new(1048576);
    textBuff = Allocator_malloc(allocator, BUFFER_SIZE);
    struct Writer* logwriter = FileWriter_new(stdout, allocator);
    struct Log* logger = WriterLog_new(logwriter, allocator);
    struct Random* rand = Random_new(allocator, logger, NULL);

    struct EventBase* base = EventBase_new(allocator);

    ca1 = CryptoAuth_new(allocator, NULL, base, logger, rand);
    if1 = Allocator_clone(allocator, (&(struct Interface) {
        .sendMessage = sendMessageToIf2,
        .receiveMessage = recvMessageOnIf2,
        .allocator = allocator
    }));
示例#19
0
文件: ArchInfo.c 项目: antinet/cjdns
char* ArchInfo_describe(enum ArchInfo ai, struct Allocator* alloc)
{
    uint8_t flagBuff[archFlags_BUFF_SZ];
    archFlags(ai, flagBuff);

    uint8_t buff[1024];
    snprintf(buff, 1024, "%s %d-bit %sEndian %s",
        archStr(ai),
        ArchInfo_getBits(ai),
        ArchInfo_isBigEndian(ai) ? "Big" : "Little",
        flagBuff);

    int len = CString_strlen(buff);
    Assert_true(len < 1024);
    if (buff[len-1] == ' ') { buff[--len] = '\0'; }
    char* out = Allocator_malloc(alloc, len+1);
    Bits_memcpy(out, buff, len+1);
    return out;
}
示例#20
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);
}
示例#21
0
文件: Core.c 项目: AdUser/cjdns
void Core_admin_register(struct Sockaddr* ipAddr,
                         struct Ducttape* dt,
                         struct Log* logger,
                         struct IpTunnel* ipTunnel,
                         struct Allocator* alloc,
                         struct Admin* admin,
                         struct EventBase* eventBase)
{
    struct Core_Context* ctx = Allocator_malloc(alloc, sizeof(struct Core_Context));
    ctx->ipAddr = ipAddr;
    ctx->ducttape = dt;
    ctx->logger = logger;
    ctx->alloc = alloc;
    ctx->admin = admin;
    ctx->eventBase = eventBase;
    ctx->ipTunnel = ipTunnel;

    struct Admin_FunctionArg args[] = {
        { .name = "desiredTunName", .required = 0, .type = "String" }
    };
static int reconnectionNewEndpointTest(struct InterfaceController* ifController,
                                       uint8_t* pk,
                                       struct Message** fromSwitchPtr,
                                       struct Allocator* alloc,
                                       struct EventBase* eventBase,
                                       struct Log* logger,
                                       struct Interface* routerIf,
                                       struct Random* rand)
{
    struct Message* message;
    struct Interface iface = {
        .sendMessage = messageFromInterface,
        .senderContext = &message,
        .allocator = alloc
    };

    uint8_t* buffer = Allocator_malloc(alloc, 512);

    struct Message* outgoing =
        &(struct Message) { .length = 0, .padding = 512, .bytes = buffer + 512 };

    struct CryptoAuth* externalCa = CryptoAuth_new(alloc, NULL, eventBase, logger, rand);
    struct Interface* wrapped = CryptoAuth_wrapInterface(&iface, pk, NULL, false, "", externalCa);
    CryptoAuth_setAuth(String_CONST("passwd"), 1, wrapped);

    struct Interface icIface = {
        .allocator = alloc,
        .sendMessage = messageFromInterface,
        .senderContext = &message
    };

    InterfaceController_registerPeer(ifController, NULL, NULL, true, false, &icIface);

    uint8_t hexBuffer[1025];

    for (int i = 0; i < 4; i++) {

        outgoing->length = 0;
        outgoing->padding = 512;
        outgoing->bytes = buffer + 512;
        Message_shift(outgoing, 12, NULL);
        Bits_memcpyConst(outgoing->bytes, "hello world", 12);

        Message_shift(outgoing, SwitchHeader_SIZE, NULL);
        Bits_memcpyConst(outgoing->bytes, (&(struct SwitchHeader) {
            .label_be = Endian_hostToBigEndian64(1),
            .lowBits_be = 0
        }), SwitchHeader_SIZE);

        wrapped->sendMessage(outgoing, wrapped);

        *fromSwitchPtr = NULL;

        icIface.receiveMessage(outgoing, &icIface);

        message = *fromSwitchPtr;
        Assert_true(message);
        Assert_true(message->length == 24);

        Hex_encode(hexBuffer, 1025, message->bytes, message->length);
        printf("%s\n", hexBuffer);

        // Need to bounce the packets back when connecting after the first try.
        // This is needed to establish the CryptoAuth session and make the InterfaceController
        // merge the endpoints.
        if (i > 0) {
            // Reverse the bits to reverse the path:
            uint64_t path;
            Bits_memcpyConst(&path, message->bytes, 8);
            path = Bits_bitReverse64(path);
            Bits_memcpyConst(message->bytes, &path, 8);

            printf("sending back response.\n");
            routerIf->receiveMessage(message, routerIf);
            printf("forwarding response to external cryptoAuth.\n");
            iface.receiveMessage(message, &iface);
            printf("forwarded.\n");
        } else {
            printf("not responding because we don't want to establish a connection yet.\n");
        }
    }

    // check everything except the label
    Assert_true(!CString_strcmp((char*)hexBuffer+16, "0000000068656c6c6f20776f726c6400"));
    // check label: make sure the interface has been switched back into position 0.
    uint64_t label_be;
    Hex_decode((uint8_t*) &label_be, 8, hexBuffer, 16);
    uint64_t rev_label = Bits_bitReverse64(Endian_bigEndianToHost64(label_be));
    // check label is decoded to 0
    Assert_true(0 == NumberCompress_getDecompressed(rev_label,
                                                      NumberCompress_bitsUsedForLabel(rev_label)));
    // check no other bits are set
    uint64_t out = NumberCompress_getCompressed(0, NumberCompress_bitsUsedForLabel(rev_label));
    Assert_true(rev_label == out);
    return 0;
}
示例#23
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
    }));
示例#24
0
int main()
{
    struct Allocator* mainAlloc = MallocAllocator_new(1<<20);
    struct Log* log = FileWriterLog_new(stdout, mainAlloc);
    struct Random* rand = Random_new(mainAlloc, log, NULL);
    struct Context* ctx = Allocator_malloc(mainAlloc, sizeof(struct Context));
    Identity_set(ctx);

    struct Interface iface = { .sendMessage = NULL };
    struct Interface* fi = FramingInterface_new(4096, &iface, mainAlloc);
    fi->receiveMessage = messageOut;
    fi->receiverContext = ctx;

    for (int i = 0; i < CYCLES; i++) {
        struct Allocator* alloc = Allocator_child(mainAlloc);
        // max frame size must be at least 5 so that at least 1 byte of data is sent.
        int maxFrameSize = ( Random_uint32(rand) % (MAX_FRAME_SZ - 1) ) + 1;
        int maxMessageSize = ( Random_uint32(rand) % (MAX_MSG_SZ - MIN_MSG_SZ) ) + MIN_MSG_SZ;
        Log_debug(log, "maxFrameSize[%d] maxMessageSize[%d]", maxFrameSize, maxMessageSize);
        ctx->alloc = alloc;
        ctx->messages = NULL;
        ctx->messageCount = 0;
        ctx->currentMessage = 0;

        // Create one huge message, then create lots of little frames inside of it
        // then split it up in random places and send the sections to the framing
        // interface.
        struct Message* msg = Message_new(WORK_BUFF_SZ, 0, alloc);

        Assert_true(WORK_BUFF_SZ == msg->length);
        Random_bytes(rand, msg->bytes, msg->length);
        Message_shift(msg, -WORK_BUFF_SZ, NULL);

        for (;;) {
            int len = Random_uint32(rand) % maxFrameSize;
            if (!len) {
                len++;
            }
            if (msg->padding < len + 4) {
                break;
            }
            Message_shift(msg, len, NULL);

            ctx->messageCount++;
            ctx->messages =
                Allocator_realloc(alloc, ctx->messages, ctx->messageCount * sizeof(char*));
            struct Message* om = ctx->messages[ctx->messageCount-1] = Message_new(len, 0, alloc);
            Bits_memcpy(om->bytes, msg->bytes, len);

            Message_push32(msg, len, NULL);
        }

        do {
            int nextMessageSize = Random_uint32(rand) % maxMessageSize;
            if (!nextMessageSize) {
                nextMessageSize++;
            }
            if (nextMessageSize > msg->length) {
                nextMessageSize = msg->length;
            }
            struct Allocator* msgAlloc = Allocator_child(alloc);
            struct Message* m = Message_new(nextMessageSize, 0, msgAlloc);
            Message_pop(msg, m->bytes, nextMessageSize, NULL);
            Interface_receiveMessage(&iface, m);
            Allocator_free(msgAlloc);
        } while (msg->length);

        Assert_true(ctx->messageCount == ctx->currentMessage);

        Allocator_free(alloc);
    }

    return 0;
}
示例#25
0
/**
 * Parse an unknown data type.
 * This is not exposed to the world because it is expected that one would
 * know what type they are parsing to begin with. This is used by parseDictionary
 * and parseList to grab pieces of data which are of unknown type and parse them.
 *
 * @param reader the reader to get the stream of data from.
 * @param allocator the means of storing the parsed data.
 * @param output a pointer which will be pointed to the output.
 */
static int32_t parseGeneric(const struct Reader* reader,
                            const struct Allocator* allocator,
                            Object** output)
{
    #define OUT_OF_CONTENT_TO_READ -2
    #define UNPARSABLE -3

    int ret;
    char firstChar;
    ret = reader->read(&firstChar, 0, reader);
    if (ret != 0) {
        return OUT_OF_CONTENT_TO_READ;
    }

    Object* out = Allocator_malloc(allocator, sizeof(Object));

    if (firstChar <= '9' && firstChar >= '0') {
        /* It's a string! */
        String* string = NULL;
        ret = parseString(reader, allocator, &string);
        out->type = Object_STRING;
        out->as.string = string;
    } else {
        switch (firstChar) {
            case 'i':;
                /* int64_t. Int is special because it is not a pointer but a int64_t. */
                int64_t bint = 0;
                ret = parseint64_t(reader, &bint);
                out->type = Object_INTEGER;
                out->as.number = bint;
                break;
            case 'l':;
                /* List. */
                List* list = Allocator_calloc(allocator, sizeof(List), 1);
                ret = parseList(reader, allocator, list);
                out->type = Object_LIST;
                out->as.list = list;
                break;
            case 'd':;
                /* Dictionary. */
                Dict* dict = Allocator_calloc(allocator, sizeof(Dict), 1);
                ret = parseDictionary(reader, allocator, dict);
                out->type = Object_DICT;
                out->as.dictionary = dict;
                break;
            default:
                return UNPARSABLE;
        }
    }

    if (ret != 0) {
        /* Something went wrong while parsing. */
        return ret;
    }

    *output = out;
    return 0;

    #undef OUT_OF_CONTENT_TO_READ
    #undef UNPARSABLE
}
示例#26
0
/** @see BencSerializer.h */
static int32_t parseDictionary(const struct Reader* reader,
                               const struct Allocator* allocator,
                               Dict* output)
{
    #define OUT_OF_CONTENT_TO_READ -2
    #define UNPARSABLE -3

    char nextChar;
    if (reader->read(&nextChar, 1, reader) < 0) {
        return OUT_OF_CONTENT_TO_READ;
    }
    if (nextChar != 'd') {
        /* Not a dictionary. */
        return UNPARSABLE;
    }

    String* key;
    Object* value;
    struct Dict_Entry* entryPointer;
    struct Dict_Entry* lastEntryPointer = NULL;
    int ret;

    for (;;) {
        /* Peek at the next char. */
        if (reader->read(&nextChar, 0, reader) < 0) {
            /* Ran over read buffer. */
            return OUT_OF_CONTENT_TO_READ;
        }
        if (nextChar == 'e') {
            /* Got to the end. */
            break;
        }

        /* Get key and value. */
        ret = parseString(reader, allocator, &key);
        if (ret != 0) {
            return ret;
        }
        ret = parseGeneric(reader, allocator, &value);
        if (ret != 0) {
            return ret;
        }

        /* Allocate the entry. */
        entryPointer = Allocator_malloc(allocator, sizeof(struct Dict_Entry));

        entryPointer->next = lastEntryPointer;
        entryPointer->key = key;
        entryPointer->val = value;
        lastEntryPointer = entryPointer;
    }

    /* We got an 'e', leave the pointer on the next char after it. */
    reader->skip(1, reader);

    *output = lastEntryPointer;

    return 0;

    #undef OUT_OF_CONTENT_TO_READ
    #undef UNPARSABLE
}
示例#27
0
/** @return a string representing the address and port to connect to. */
static void initAngel(struct Pipe* asClientPipe,
                      struct Interface* asCoreIface,
                      char* asCorePipeName,
                      struct EventBase* eventBase,
                      struct Log* logger,
                      struct Allocator* alloc,
                      struct Random* rand)
{
    Dict admin = Dict_CONST(
        String_CONST("bind"), String_OBJ(String_CONST("127.0.0.1")), Dict_CONST(
        String_CONST("corePipeName"), String_OBJ(String_CONST(asCorePipeName)), Dict_CONST(
        String_CONST("pass"), String_OBJ(String_CONST("abcd")), NULL
    )));
    Dict message = Dict_CONST(
        String_CONST("admin"), Dict_OBJ(&admin), NULL
    );

    struct Allocator* tempAlloc = Allocator_child(alloc);

    #define BUFFER_SZ 1023
    uint8_t buff[BUFFER_SZ + 1] = {0};
    struct Writer* w = ArrayWriter_new(buff, BUFFER_SZ, tempAlloc);
    StandardBencSerializer_get()->serializeDictionary(w, &message);

    struct Message* toAngel = Allocator_malloc(tempAlloc, sizeof(struct Message) + w->bytesWritten);
    toAngel->bytes = (uint8_t*) (&toAngel[1]);
    toAngel->length = toAngel->capacity = w->bytesWritten;
    toAngel->padding = 0;
    toAngel->alloc = tempAlloc;
    Bits_memcpy(toAngel->bytes, buff, toAngel->length);

    Log_info(logger, "Writing intial configuration to angel on [%s] config: [%s]",
             asClientPipe->name, buff);
    Interface_sendMessage(&asClientPipe->iface, toAngel);

    // This is client->angel->core data, we can throw this away.
    //struct Message* angelToCore =
    InterfaceWaiter_waitForData(asCoreIface, eventBase, tempAlloc, NULL);

    // unterminated string
    //Log_info(logger, "Init message from angel to core: [%s]", angelToCore->bytes);

    // Send response on behalf of core.
    char* coreToAngelResponse = "        PADDING         "
        "d"
          "5:error" "4:none"
        "e";

    struct Message* m = &(struct Message) {
        .bytes = (uint8_t*) coreToAngelResponse,
        .length = strlen(coreToAngelResponse),
        .padding = 0,
        .capacity = strlen(coreToAngelResponse)
    };
    Message_shift(m, -24, NULL);
    m = Message_clone(m, tempAlloc);

    Interface_sendMessage(asCoreIface, m);

    // This is angel->client data, it will tell us which port was bound.
    struct Message* angelToClient =
        InterfaceWaiter_waitForData(&asClientPipe->iface, eventBase, tempAlloc, NULL);

    printf("Response from angel to client: [%s]\n", angelToClient->bytes);

    Allocator_free(tempAlloc);

    return;
}
示例#28
0
static int32_t parseGeneric(struct Reader* reader,
                            struct Allocator* allocator,
                            Object** output)
{
    int ret = 0;
    char firstChar;

    for (;;) {
        ret = Reader_read(reader, &firstChar, 0);
        switch (firstChar) {
            case ' ':
            case '\r':
            case '\n':
            case '\t':
                Reader_skip(reader, 1);
                continue;

            case '/':;
                if ((ret = parseComment(reader)) != 0) {
                    return ret;
                }
                continue;

            default:
                break;
        }
        if (ret) {
            printf("Unexpected end of input\n");
            return OUT_OF_CONTENT_TO_READ;
        }
        break;
    }

    Object* out = Allocator_malloc(allocator, sizeof(Object));

    switch (firstChar) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':;
            // int64_t. Int is special because it is not a pointer but a int64_t.
            int64_t bint;
            if ((ret = parseint64_t(reader, &bint)) == UNPARSABLE) {
                break;
            }
            out->type = Object_INTEGER;
            out->as.number = bint;
            break;

        case '[':;
            // List.
            List* list = Allocator_calloc(allocator, sizeof(List), 1);
            ret = parseList(reader, allocator, list);
            out->type = Object_LIST;
            out->as.list = list;
            break;

        case '{':;
            // Dictionary
            Dict* dict = Allocator_calloc(allocator, sizeof(Dict), 1);
            ret = parseDictionary(reader, allocator, dict);
            out->type = Object_DICT;
            out->as.dictionary = dict;
            break;

        case '"':;
            // String
            String* string = NULL;
            ret = parseString(reader, allocator, &string);
            out->type = Object_STRING;
            out->as.string = string;
            break;

        default:
            printf("While looking for something to parse: "
                   "expected one of 0 1 2 3 4 5 6 7 8 9 [ { \", found '%c'\n", firstChar);
            return UNPARSABLE;
    }

    if (ret != 0) {
        // Something went wrong while parsing.
        return ret;
    }

    *output = out;
    return 0;
}
示例#29
0
static uint8_t receiveMessage(struct Message* msg, struct Iface* iface)
{
    struct Allocator* alloc = iface->receiverContext;
    if (msg->length < 20) {
        printf("runt\n");
        return 0;
    }
    // ethernet padding.
    Message_shift(msg, -2, NULL);

    uint8_t from[13];
    uint8_t to[13];
    Hex_encode(from, 13, msg->bytes, 6);
    Message_shift(msg, -6, NULL);
    Hex_encode(to, 13, msg->bytes, 6);
    Message_shift(msg, -6, NULL);

    uint8_t type[5];
    Hex_encode(type, 5, msg->bytes, 2);
    Message_shift(msg, -2, NULL);

    int subsubtype = -1;
    int subtype = -1;
//    int typeCode = -1;
    if (!Bits_memcmp(type, "86dd", 4)) {
        Bits_memcpy(type, "ipv6", 5);
        subtype = msg->bytes[6];
//        typeCode = 6;
        if (subtype == 58) {
          subsubtype = msg->bytes[40];
        }
    } else if (!Bits_memcmp(type, "0800", 4)) {
return 0;
        Bits_memcpy(type, "ipv4", 5);
        subtype = msg->bytes[9];
//        typeCode = 4;
    } else {
return 0;
    }
//       6000000000183aff0000000000000000000000000000000fff0200000000000000000001ff000018 870
//6000000000201101fd000000000000000000000000000001ff020000000000000000000000010003 eee914...
//6000000000083aff00000000000000000000000000000000ff020000000000000000000000000002 85007b
//6000000000203aff fd000000000000000000000000000001 ff0200000000000000000001ff000002 8700.

    int len = msg->length * 2 + 1;
    uint8_t* buff = Allocator_malloc(alloc, len + 2);
    Hex_encode(buff, len, msg->bytes, msg->length);
/*    if (typeCode == 6 && len > 86) {
        Bits_memmove(&buff[82], &buff[81], len - 81);
        Bits_memmove(&buff[49], &buff[48], len - 48);
        Bits_memmove(&buff[17], &buff[16], len - 16);
        buff[80] = buff[48] = buff[16] = ' ';
    }*/

    if (msg->length > 45) {
        Bits_memcpy(buff+86, "...", 4);
    }

    printf("[%s] [%s] [%s] [%02d] [%03d] [%s]\n", to, from, type, subtype, subsubtype, buff);
    return 0;
}
static uint8_t sendMessage(struct Message* message, struct Interface* iface)
{
    struct PacketHeaderToUDPAddrInterface_pvt* context =
        Identity_check((struct PacketHeaderToUDPAddrInterface_pvt*) iface);

    struct Sockaddr_storage ss;
    Message_pop(message, &ss, context->pub.addr->addrLen, NULL);
    struct Sockaddr* addr = &ss.addr;

    struct Headers_UDPHeader udp;
    udp.srcPort_be = Endian_hostToBigEndian16(Sockaddr_getPort(context->pub.addr));
    udp.destPort_be = Endian_hostToBigEndian16(Sockaddr_getPort(addr));
    udp.length_be = Endian_hostToBigEndian16(message->length + Headers_UDPHeader_SIZE);
    udp.checksum_be = 0;
    Message_push(message, &udp, sizeof(struct Headers_UDPHeader), NULL);

    struct Headers_IP6Header ip = {
        .nextHeader = 17,
        .hopLimit = 255,
    };
    ip.payloadLength_be = Endian_hostToBigEndian16(message->length);
    Headers_setIpVersion(&ip);
    uint8_t* addrPtr = NULL;
    Assert_true(Sockaddr_getAddress(addr, &addrPtr) == 16);
    Bits_memcpyConst(ip.destinationAddr, addrPtr, 16);
    Assert_true(Sockaddr_getAddress(context->pub.addr, &addrPtr) == 16);
    Bits_memcpyConst(ip.sourceAddr, addrPtr, 16);

    uint16_t checksum = Checksum_udpIp6(ip.sourceAddr, message->bytes, message->length);
    ((struct Headers_UDPHeader*)message->bytes)->checksum_be = checksum;

    Message_push(message, &ip, sizeof(struct Headers_IP6Header), NULL);

    return Interface_sendMessage(context->wrapped, message);
}

static uint8_t receiveMessage(struct Message* message, struct Interface* iface)
{
    struct PacketHeaderToUDPAddrInterface_pvt* context =
        Identity_check((struct PacketHeaderToUDPAddrInterface_pvt*) iface->receiverContext);

    if (message->length < Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE) {
        // runt
        return Error_NONE;
    }

    struct Headers_IP6Header* ip = (struct Headers_IP6Header*) message->bytes;

    // udp
    if (ip->nextHeader != 17) {
        return Error_NONE;
    }

    struct Allocator* alloc = Allocator_child(message->alloc);
    struct Sockaddr* addr = Sockaddr_clone(context->pub.addr, alloc);
    uint8_t* addrPtr = NULL;
    Assert_true(Sockaddr_getAddress(addr, &addrPtr) == 16);
    Bits_memcpyConst(addrPtr, ip->sourceAddr, 16);

    struct Headers_UDPHeader* udp = (struct Headers_UDPHeader*) (&ip[1]);
    Sockaddr_setPort(addr, Endian_bigEndianToHost16(udp->srcPort_be));

    if (Sockaddr_getPort(context->pub.addr) != Endian_bigEndianToHost16(udp->destPort_be)) {
        // not the right port
        return Error_NONE;
    }

    Message_shift(message, -(Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE), NULL);
    Message_push(message, addr, addr->addrLen, NULL);

    return Interface_receiveMessage(&context->pub.generic, message);
}

struct AddrInterface* PacketHeaderToUDPAddrInterface_new(struct Interface* toWrap,
                                                         struct Allocator* alloc,
                                                         struct Sockaddr* addr)
{
    struct PacketHeaderToUDPAddrInterface_pvt* context =
        Allocator_malloc(alloc, sizeof(struct PacketHeaderToUDPAddrInterface_pvt));

    Bits_memcpyConst(context, (&(struct PacketHeaderToUDPAddrInterface_pvt) {
        .pub = {
            .generic = {
                .sendMessage = sendMessage,
                .senderContext = context,
                .allocator = alloc
            }
        },
        .wrapped = toWrap
    }), sizeof(struct PacketHeaderToUDPAddrInterface_pvt));