Beispiel #1
0
static Iface_DEFUN receiveMessage(struct Message* msg, struct Iface* addrIface)
{
    struct Context* ctx = Identity_containerOf(addrIface, struct Context, addrIface);

    struct Sockaddr_storage source;
    Message_pop(msg, &source, ctx->targetAddr->addrLen, NULL);
    if (Bits_memcmp(&source, ctx->targetAddr, ctx->targetAddr->addrLen)) {
        Log_info(ctx->logger, "Got spurious message from [%s], expecting messages from [%s]",
                 Sockaddr_print(&source.addr, msg->alloc),
                 Sockaddr_print(ctx->targetAddr, msg->alloc));
        return NULL;
    }

    // we don't yet know with which message this data belongs,
    // the message alloc lives the length of the message reception.
    struct Allocator* alloc = Allocator_child(msg->alloc);

    int origLen = msg->length;
    Dict* d = NULL;
    char* err = BencMessageReader_readNoExcept(msg, alloc, &d);
    if (err) { return NULL; }
    Message_shift(msg, origLen, NULL);

    String* txid = Dict_getString(d, String_CONST("txid"));
    if (!txid || txid->len != 8) { return NULL; }

    // look up the result
    uint32_t handle = ~0u;
    Hex_decode((uint8_t*)&handle, 4, txid->bytes, 8);
    int idx = Map_OfRequestByHandle_indexForHandle(handle, &ctx->outstandingRequests);
    if (idx < 0) { return NULL; }

    struct Request* req = ctx->outstandingRequests.values[idx];

    // now this data will outlive the life of the message.
    Allocator_adopt(req->promise->alloc, alloc);

    req->res.responseDict = d;

    int len =
        (msg->length > AdminClient_MAX_MESSAGE_SIZE) ? AdminClient_MAX_MESSAGE_SIZE : msg->length;
    Bits_memset(req->res.messageBytes, 0, AdminClient_MAX_MESSAGE_SIZE);
    Bits_memcpy(req->res.messageBytes, msg->bytes, len);
    done(req, AdminClient_Error_NONE);
    return NULL;
}
Beispiel #2
0
static void receiveMessage2(struct Message* msg, struct Hermes* hermes, struct Allocator* tempAlloc)
{
    #ifdef Log_KEYS
        char lastChr = msg->bytes[msg->length - 1];
        msg->bytes[msg->length - 1] = '\0';
        Log_keys(hermes->logger, "Got message from angel [%s%c]", msg->bytes, lastChr);
        msg->bytes[msg->length - 1] = lastChr;
    #else
        Log_debug(hermes->logger, "Got message from angel");
    #endif

    Dict* d = NULL;
    char* err = BencMessageReader_readNoExcept(msg, tempAlloc, &d);
    if (err) {
        Log_warn(hermes->logger, "Failed to parse message from angel [%s]", err);
        return;
    }

    String* txid = Dict_getString(d, String_CONST("txid"));
    uint32_t handle;
    if (!txid || txid->len != 8 || 4 != Hex_decode((uint8_t*)&handle, 4, (uint8_t*)txid->bytes, 8))
    {
        Log_warn(hermes->logger, "Message from angel; txid missing or unrecognized");
        return;
    }

    int index = Map_RequestSet_indexForHandle(handle, &hermes->requestSet);
    if (index < 0) {
        Log_warn(hermes->logger, "Message from angel references nonexistant request");
        return;
    }

    struct Request* req = Identity_check((struct Request*) hermes->requestSet.values[index]);
    req->onResponse(d, req->onResponseContext);
    Allocator_free(req->alloc);
}
Beispiel #3
0
static Iface_DEFUN incoming(struct Message* msg, struct Iface* interRouterIf)
{
    struct MsgCore_pvt* mcp =
        Identity_containerOf(interRouterIf, struct MsgCore_pvt, pub.interRouterIf);

    struct Address addr = { .padding = 0 };
    struct RouteHeader* hdr = (struct RouteHeader*) msg->bytes;
    Message_shift(msg, -(RouteHeader_SIZE + DataHeader_SIZE), NULL);
    Bits_memcpy(addr.ip6.bytes, hdr->ip6, 16);
    Bits_memcpy(addr.key, hdr->publicKey, 32);
    addr.protocolVersion = Endian_bigEndianToHost32(hdr->version_be);
    addr.path = Endian_bigEndianToHost64(hdr->sh.label_be);

    Dict* content = NULL;
    uint8_t* msgBytes = msg->bytes;
    int length = msg->length;
    //Log_debug(mcp->log, "Receive msg [%s] from [%s]",
    //    Escape_getEscaped(msg->bytes, msg->length, msg->alloc),
    //    Address_toString(&addr, msg->alloc)->bytes);
    //
    BencMessageReader_readNoExcept(msg, msg->alloc, &content);
    if (!content) {
        char* esc = Escape_getEscaped(msgBytes, length, msg->alloc);
        Log_debug(mcp->log, "DROP Malformed message [%s]", esc);
        return NULL;
    }

    int64_t* verP = Dict_getIntC(content, "p");
    if (!verP) {
        Log_debug(mcp->log, "DROP Message without version");
        return NULL;
    }
    addr.protocolVersion = *verP;

    String* q = Dict_getStringC(content, "q");

    if (!Defined(SUBNODE)) {
        String* txid = Dict_getStringC(content, "txid");
        Assert_true(txid);
        if (q) {
            if (txid->bytes[0] == '0') {
                Log_debug(mcp->log, "DROP query which begins with 0 and is for old pathfinder");
                return NULL;
            }
        } else {
            if (txid->bytes[0] != '1') {
                Log_debug(mcp->log, "DROP reply which does not begin with 1");
                return NULL;
            }
            String* newTxid = String_newBinary(NULL, txid->len - 1, msg->alloc);
            Bits_memcpy(newTxid->bytes, &txid->bytes[1], txid->len - 1);
            Dict_putStringC(content, "txid", newTxid, msg->alloc);
            txid = newTxid;
        }
    }

    if (q) {
        return queryMsg(mcp, content, &addr, msg);
    } else {
        return replyMsg(mcp, content, &addr, msg);
    }
}

struct MsgCore* MsgCore_new(struct EventBase* base,
                            struct Random* rand,
                            struct Allocator* allocator,
                            struct Log* log,
                            struct EncodingScheme* scheme)
{
    struct Allocator* alloc = Allocator_child(allocator);
    struct MsgCore_pvt* mcp = Allocator_calloc(alloc, sizeof(struct MsgCore_pvt), 1);
    Identity_set(mcp);
    mcp->pub.interRouterIf.send = incoming;
    mcp->qh = ArrayList_OfQueryHandlers_new(alloc);
    mcp->pinger = Pinger_new(base, rand, log, alloc);
    mcp->log = log;

    mcp->scheme = scheme;
    mcp->schemeDefinition = EncodingScheme_serialize(scheme, alloc);

    return &mcp->pub;
}