Ejemplo n.º 1
0
static void stat_response_handler(lcb_server_t *server, packet_info *info)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = PACKET_STATUS(info);
    lcb_error_t rc = map_error(root, status);
    lcb_server_stat_resp_t resp;
    struct lcb_command_data_st *command_data = &info->ct;

    if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
        if (!PACKET_NKEY(info)) {
            if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_STAT,
                                               PACKET_OPAQUE(info), server) < 0) {
                /* notify client that data is ready */
                setup_lcb_server_stat_resp_t(&resp, NULL, NULL, 0, NULL, 0);
                root->callbacks.stat(root, command_data->cookie, rc, &resp);
            }
            return;
        }
        setup_lcb_server_stat_resp_t(&resp, server->authority,
                                     PACKET_KEY(info), PACKET_NKEY(info),
                                     PACKET_VALUE(info), PACKET_NVALUE(info));
        root->callbacks.stat(root, command_data->cookie, rc, &resp);
    } else {
        setup_lcb_server_stat_resp_t(&resp, server->authority,
                                     NULL, 0, NULL, 0);
        root->callbacks.stat(root, command_data->cookie, rc, &resp);

        /* run callback with null-null-null to signal the end of transfer */
        if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_STAT,
                                           PACKET_OPAQUE(info), server) < 0) {
            setup_lcb_server_stat_resp_t(&resp, NULL, NULL, 0, NULL, 0);
            root->callbacks.stat(root, command_data->cookie, LCB_SUCCESS, &resp);
        }
    }
}
Ejemplo n.º 2
0
static void stat_response_handler(lcb_server_t *server,
                                  struct lcb_command_data_st *command_data,
                                  protocol_binary_response_header *res)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = ntohs(res->response.status);
    lcb_error_t rc = map_error(root, status);
    lcb_uint16_t nkey;
    lcb_uint32_t nvalue;
    const char *key, *value;
    lcb_server_stat_resp_t resp;

    if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
        nkey = ntohs(res->response.keylen);
        if (nkey == 0) {
            if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_STAT,
                                               res->response.opaque, server) < 0) {
                /* notify client that data is ready */
                setup_lcb_server_stat_resp_t(&resp, NULL, NULL, 0, NULL, 0);
                TRACE_STATS_END(res->response.opaque, command_data->vbucket,
                                res->response.opcode, rc);
                root->callbacks.stat(root, command_data->cookie, rc, &resp);
            }
            return;
        }
        key = (const char *)res + sizeof(res->bytes);
        nvalue = ntohl(res->response.bodylen) - nkey;
        value = key + nkey;

        setup_lcb_server_stat_resp_t(&resp, server->authority, key,
                                     nkey, value, nvalue);
        TRACE_STATS_PROGRESS(res->response.opaque, command_data->vbucket,
                             res->response.opcode, rc, &resp);
        root->callbacks.stat(root, command_data->cookie, rc, &resp);
    } else {
        setup_lcb_server_stat_resp_t(&resp, server->authority,
                                     NULL, 0, NULL, 0);
        TRACE_STATS_END(res->response.opaque, command_data->vbucket,
                        res->response.opcode, rc);
        root->callbacks.stat(root, command_data->cookie, rc, &resp);

        /* run callback with null-null-null to signal the end of transfer */
        if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_STAT,
                                           res->response.opaque, server) < 0) {
            setup_lcb_server_stat_resp_t(&resp, NULL, NULL, 0, NULL, 0);
            TRACE_STATS_END(res->response.opaque, command_data->vbucket,
                            res->response.opcode, LCB_SUCCESS);
            root->callbacks.stat(root, command_data->cookie, LCB_SUCCESS, &resp);
        }
    }
}
Ejemplo n.º 3
0
static void version_response_handler(lcb_server_t *server,
                                     packet_info *info)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = PACKET_STATUS(info);
    lcb_error_t rc = map_error(root, status);
    lcb_uint32_t nvstring = PACKET_NBODY(info);
    const char *vstring;
    lcb_server_version_resp_t resp;
    struct lcb_command_data_st *command_data = &info->ct;

    if (nvstring) {
        vstring = info->payload;
    } else {
        vstring = NULL;
    }

    setup_lcb_server_version_resp_t(&resp, server->authority, vstring, nvstring);
    PACKET_TRACE(TRACE_VERSIONS_PROGRESS, info, rc, &resp);
    root->callbacks.version(root, command_data->cookie, rc, &resp);

    if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_VERSION,
                                       PACKET_OPAQUE(info), server) < 0) {
        memset(&resp, 0, sizeof(resp));
        PACKET_TRACE_NORES(TRACE_VERSIONS_END, info, LCB_SUCCESS);
        root->callbacks.version(root, command_data->cookie, LCB_SUCCESS, &resp);
    }

}
Ejemplo n.º 4
0
static void version_response_handler(lcb_server_t *server,
                                     struct lcb_command_data_st *command_data,
                                     protocol_binary_response_header *res)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = ntohs(res->response.status);
    lcb_error_t rc = map_error(root, status);
    lcb_uint32_t nvstring = ntohl(res->response.bodylen);
    const char *vstring;
    lcb_server_version_resp_t resp;

    if (nvstring) {
        vstring = (const char *)res + sizeof(res->bytes);
    } else {
        vstring = NULL;
    }

    setup_lcb_server_version_resp_t(&resp, server->authority, vstring, nvstring);
    TRACE_VERSIONS_PROGRESS(res->response.opaque, command_data->vbucket,
                            res->response.opcode, rc, &resp);
    root->callbacks.version(root, command_data->cookie, rc, &resp);

    if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_VERSION,
                                       res->response.opaque, server) < 0) {
        memset(&resp, 0, sizeof(resp));
        TRACE_VERSIONS_END(res->response.opaque, command_data->vbucket,
                           res->response.opcode, LCB_SUCCESS);
        root->callbacks.version(root, command_data->cookie, LCB_SUCCESS, &resp);
    }

}
Ejemplo n.º 5
0
static void flush_response_handler(lcb_server_t *server,
                                   packet_info *info)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = PACKET_STATUS(info);
    lcb_error_t rc = map_error(root, status);
    lcb_flush_resp_t resp;
    struct lcb_command_data_st *command_data = &info->ct;

    setup_lcb_flush_resp_t(&resp, server->authority);


    root->callbacks.flush(root, command_data->cookie, rc, &resp);

    if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_FLUSH,
                                       PACKET_OPAQUE(info), server) < 0) {
        setup_lcb_flush_resp_t(&resp, NULL);
        root->callbacks.flush(root, command_data->cookie, LCB_SUCCESS, &resp);
    }
}
Ejemplo n.º 6
0
static void verbosity_response_handler(lcb_server_t *server,
                                       packet_info *info)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = PACKET_STATUS(info);
    lcb_error_t rc = map_error(root, status);
    lcb_verbosity_resp_t resp;
    struct lcb_command_data_st *command_data = &info->ct;

    setup_lcb_verbosity_resp_t(&resp, server->authority);

    root->callbacks.verbosity(root, command_data->cookie, rc, &resp);

    /* run callback with null-null-null to signal the end of transfer */
    if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_VERBOSITY,
                                       PACKET_OPAQUE(info), server) < 0) {
        setup_lcb_verbosity_resp_t(&resp, NULL);
        root->callbacks.verbosity(root, command_data->cookie, LCB_SUCCESS, &resp);
    }
}
Ejemplo n.º 7
0
void lcb_failout_observe_request(lcb_server_t *server,
                                 struct lcb_command_data_st *command_data,
                                 const char *packet,
                                 lcb_size_t npacket,
                                 lcb_error_t err)
{
    lcb_t instance = server->instance;
    protocol_binary_request_header *req = (void *)packet;
    const char *ptr = packet + sizeof(req->bytes);
    const char *end = packet + npacket;
    lcb_observe_resp_t resp;

    memset(&resp, 0, sizeof(resp));
    resp.v.v0.status = LCB_OBSERVE_MAX;
    while (ptr < end) {
        lcb_uint16_t nkey;

        /* ignore vbucket */
        ptr += sizeof(lcb_uint16_t);
        memcpy(&nkey, ptr, sizeof(nkey));
        nkey = ntohs(nkey);

        ptr += sizeof(lcb_uint16_t);
        resp.v.v0.key = ptr;
        resp.v.v0.nkey = nkey;

        TRACE_OBSERVE_PROGRESS(req->request.opaque, ntohs(req->request.vbucket),
                               req->request.opcode, err, &resp);
        lcb_observe_invoke_callback(instance, command_data, err, &resp);
        ptr += nkey;
    }
    if ((command_data->flags & LCB_CMD_F_OBS_BCAST) &&
            lcb_lookup_server_with_command(instance, CMD_OBSERVE,
                                           req->request.opaque, server) < 0) {
        TRACE_OBSERVE_END(req->request.opaque, ntohs(req->request.vbucket),
                          req->request.opcode, err);
        resp.v.v0.key = NULL;
        resp.v.v0.nkey = 0;
        lcb_observe_invoke_callback(instance, command_data, err, &resp);
    }
}
Ejemplo n.º 8
0
static void flush_response_handler(lcb_server_t *server,
                                   struct lcb_command_data_st *command_data,
                                   protocol_binary_response_header *res)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = ntohs(res->response.status);
    lcb_error_t rc = map_error(root, status);
    lcb_flush_resp_t resp;
    setup_lcb_flush_resp_t(&resp, server->authority);

    TRACE_FLUSH_PROGRESS(res->response.opaque, command_data->vbucket,
                         res->response.opcode, rc, &resp);
    root->callbacks.flush(root, command_data->cookie, rc, &resp);

    if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_FLUSH,
                                       res->response.opaque, server) < 0) {
        setup_lcb_flush_resp_t(&resp, NULL);
        TRACE_FLUSH_END(res->response.opaque, command_data->vbucket,
                        res->response.opcode, LCB_SUCCESS);
        root->callbacks.flush(root, command_data->cookie, LCB_SUCCESS, &resp);
    }
}
Ejemplo n.º 9
0
static void verbosity_response_handler(lcb_server_t *server,
                                       struct lcb_command_data_st *command_data,
                                       protocol_binary_response_header *res)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = ntohs(res->response.status);
    lcb_error_t rc = map_error(root, status);
    lcb_verbosity_resp_t resp;

    setup_lcb_verbosity_resp_t(&resp, server->authority);

    TRACE_VERBOSITY_END(res->response.opaque, command_data->vbucket,
                        res->response.opcode, rc, &resp);
    root->callbacks.verbosity(root, command_data->cookie, rc, &resp);

    /* run callback with null-null-null to signal the end of transfer */
    if (lcb_lookup_server_with_command(root, PROTOCOL_BINARY_CMD_VERBOSITY,
                                       res->response.opaque, server) < 0) {
        setup_lcb_verbosity_resp_t(&resp, NULL);
        TRACE_VERBOSITY_END(res->response.opaque, command_data->vbucket,
                            res->response.opcode, LCB_SUCCESS, &resp);
        root->callbacks.verbosity(root, command_data->cookie, LCB_SUCCESS, &resp);
    }
}
Ejemplo n.º 10
0
static void observe_response_handler(lcb_server_t *server,
                                     packet_info *info)
{
    lcb_t root = server->instance;
    lcb_error_t rc = map_error(root, PACKET_STATUS(info));
    lcb_uint32_t ttp;
    lcb_uint32_t ttr;
    lcb_size_t pos;

    VBUCKET_CONFIG_HANDLE config;
    const char *end, *ptr;

    /**
     * If we have an error we must decode the request instead
     */
    if (rc != LCB_SUCCESS) {
        protocol_binary_request_header req;
        lcb_size_t nr;

        nr = ringbuffer_peek(&server->cmd_log, req.bytes, sizeof(req.bytes));
        if (nr != sizeof(req.bytes)) {
            lcb_error_handler(server->instance, LCB_EINTERNAL, NULL);
            abort();
        }

        if (req.request.bodylen) {
            lcb_size_t npacket = sizeof(req.bytes) + ntohl(req.request.bodylen);
            char *packet = server->cmd_log.read_head;
            int allocated = 0;

            if (!ringbuffer_is_continous(&server->cmd_log, RINGBUFFER_READ, npacket)) {
                packet = malloc(npacket);
                if (packet == NULL) {
                    lcb_error_handler(root, LCB_CLIENT_ENOMEM, NULL);
                    abort();
                }
                nr = ringbuffer_peek(&server->cmd_log, packet, npacket);
                if (nr != npacket) {
                    lcb_error_handler(root, LCB_EINTERNAL, NULL);
                    free(packet);
                    abort();
                }
                allocated = 1;
            }
            lcb_failout_observe_request(server, &info->ct, packet, npacket, rc);
            if (allocated) {
                free(packet);
            }
        }
        return;
    }

    /** The CAS field is split into TTP/TTR values */
    ptr = (char *)&info->res.response.cas;
    memcpy(&ttp, ptr, sizeof(ttp));
    memcpy(&ttr, ptr + sizeof(ttp), sizeof(ttp));

    ttp = ntohl(ttp);
    ttr = ntohl(ttr);

    /** Actual payload sequence of (vb, nkey, key). Repeats multiple times */
    ptr = info->payload;
    end = (char *)ptr + PACKET_NBODY(info);
    config = root->vbucket_config;

    for (pos = 0; ptr < end; pos++) {
        lcb_cas_t cas;
        lcb_uint8_t obs;
        lcb_uint16_t nkey, vb;
        const char *key;
        lcb_observe_resp_t resp;

        memcpy(&vb, ptr, sizeof(vb));
        vb = ntohs(vb);
        ptr += sizeof(vb);
        memcpy(&nkey, ptr, sizeof(nkey));
        nkey = ntohs(nkey);
        ptr += sizeof(nkey);
        key = (const char *)ptr;
        ptr += nkey;
        obs = *((lcb_uint8_t *)ptr);
        ptr += sizeof(obs);
        memcpy(&cas, ptr, sizeof(cas));
        ptr += sizeof(cas);

        setup_lcb_observe_resp_t(&resp, key, nkey, cas, obs,
                                 server->index == vbucket_get_master(config, vb),
                                 ttp, ttr);
        PACKET_TRACE(TRACE_OBSERVE_PROGRESS, info, rc, &resp);
        lcb_observe_invoke_callback(root, &info->ct, rc, &resp);
    }

    /* run callback with null-null-null to signal the end of transfer */
    if ((info->ct.flags & LCB_CMD_F_OBS_BCAST) &&
            lcb_lookup_server_with_command(root, CMD_OBSERVE,
                                           PACKET_OPAQUE(info), server) < 0) {

        lcb_observe_resp_t resp;
        memset(&resp, 0, sizeof(resp));
        PACKET_TRACE_NORES(TRACE_OBSERVE_END, info, rc);
        lcb_observe_invoke_callback(root, &info->ct, LCB_SUCCESS, &resp);
    }
}
Ejemplo n.º 11
0
static void failout_single_request(lcb_server_t *server,
                                   protocol_binary_request_header *req,
                                   struct lcb_command_data_st *ct,
                                   lcb_error_t error,
                                   const void *keyptr,
                                   lcb_size_t nkey,
                                   const void *packet)
{
    lcb_t root = server->instance;
    union {
        lcb_get_resp_t get;
        lcb_store_resp_t store;
        lcb_remove_resp_t remove;
        lcb_touch_resp_t touch;
        lcb_unlock_resp_t unlock;
        lcb_arithmetic_resp_t arithmetic;
        lcb_observe_resp_t observe;
        lcb_server_stat_resp_t stats;
        lcb_server_version_resp_t versions;
        lcb_verbosity_resp_t verbosity;
        lcb_flush_resp_t flush;
    } resp;

    switch (req->request.opcode) {
    case PROTOCOL_BINARY_CMD_NOOP:
        break;
    case CMD_GET_LOCKED:
    case PROTOCOL_BINARY_CMD_GAT:
    case PROTOCOL_BINARY_CMD_GATQ:
    case PROTOCOL_BINARY_CMD_GET:
    case PROTOCOL_BINARY_CMD_GETQ:
        setup_lcb_get_resp_t(&resp.get, keyptr, nkey, NULL, 0, 0, 0, 0);
        TRACE_GET_END(req->request.opaque, ntohs(req->request.vbucket),
                      req->request.opcode, error, &resp.get);
        root->callbacks.get(root, ct->cookie, error, &resp.get);
        break;
    case CMD_UNLOCK_KEY:
        setup_lcb_unlock_resp_t(&resp.unlock, keyptr, nkey);
        TRACE_UNLOCK_END(req->request.opaque, ntohs(req->request.vbucket),
                         error, &resp.unlock);
        root->callbacks.unlock(root, ct->cookie, error, &resp.unlock);
        break;
    case PROTOCOL_BINARY_CMD_FLUSH:
        setup_lcb_flush_resp_t(&resp.flush, server->authority);
        TRACE_FLUSH_PROGRESS(req->request.opaque, ntohs(req->request.vbucket),
                             req->request.opcode, error, &resp.flush);
        root->callbacks.flush(root, ct->cookie, error, &resp.flush);
        if (lcb_lookup_server_with_command(root,
                                           PROTOCOL_BINARY_CMD_FLUSH,
                                           req->request.opaque,
                                           server) < 0) {
            setup_lcb_flush_resp_t(&resp.flush, NULL);
            TRACE_FLUSH_END(req->request.opaque, ntohs(req->request.vbucket),
                            req->request.opcode, error);
            root->callbacks.flush(root, ct->cookie, error, &resp.flush);
        }
        break;
    case PROTOCOL_BINARY_CMD_ADD:
        setup_lcb_store_resp_t(&resp.store, keyptr, nkey, 0);
        TRACE_STORE_END(req->request.opaque, ntohs(req->request.vbucket),
                        req->request.opcode, error, &resp.store);
        root->callbacks.store(root, ct->cookie, LCB_ADD, error, &resp.store);
        break;
    case PROTOCOL_BINARY_CMD_REPLACE:
        setup_lcb_store_resp_t(&resp.store, keyptr, nkey, 0);
        TRACE_STORE_END(req->request.opaque, ntohs(req->request.vbucket),
                        req->request.opcode, error, &resp.store);
        root->callbacks.store(root, ct->cookie, LCB_REPLACE, error,
                              &resp.store);
        break;
    case PROTOCOL_BINARY_CMD_SET:
        setup_lcb_store_resp_t(&resp.store, keyptr, nkey, 0);
        TRACE_STORE_END(req->request.opaque, ntohs(req->request.vbucket),
                        req->request.opcode, error, &resp.store);
        root->callbacks.store(root, ct->cookie, LCB_SET, error, &resp.store);
        break;
    case PROTOCOL_BINARY_CMD_APPEND:
        setup_lcb_store_resp_t(&resp.store, keyptr, nkey, 0);
        TRACE_STORE_END(req->request.opaque, ntohs(req->request.vbucket),
                        req->request.opcode, error, &resp.store);
        root->callbacks.store(root, ct->cookie, LCB_APPEND, error,
                              &resp.store);
        break;
    case PROTOCOL_BINARY_CMD_PREPEND:
        setup_lcb_store_resp_t(&resp.store, keyptr, nkey, 0);
        TRACE_STORE_END(req->request.opaque, ntohs(req->request.vbucket),
                        req->request.opcode, error, &resp.store);
        root->callbacks.store(root, ct->cookie, LCB_PREPEND, error,
                              &resp.store);
        break;
    case PROTOCOL_BINARY_CMD_DELETE:
        setup_lcb_remove_resp_t(&resp.remove, keyptr, nkey, 0);
        TRACE_REMOVE_END(req->request.opaque, ntohs(req->request.vbucket),
                         req->request.opcode, error, &resp.remove);
        root->callbacks.remove(root, ct->cookie, error, &resp.remove);
        break;

    case PROTOCOL_BINARY_CMD_INCREMENT:
    case PROTOCOL_BINARY_CMD_DECREMENT:
        setup_lcb_arithmetic_resp_t(&resp.arithmetic, keyptr, nkey, 0, 0);
        TRACE_ARITHMETIC_END(req->request.opaque, ntohs(req->request.vbucket),
                             req->request.opcode, error, &resp.arithmetic);
        root->callbacks.arithmetic(root, ct->cookie, error,
                                   &resp.arithmetic);
        break;
    case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS:
    case PROTOCOL_BINARY_CMD_SASL_AUTH:
    case PROTOCOL_BINARY_CMD_SASL_STEP:
        /* no need to notify user about these commands */
        break;

    case PROTOCOL_BINARY_CMD_TOUCH:
        setup_lcb_touch_resp_t(&resp.touch, keyptr, nkey, 0);
        TRACE_TOUCH_END(req->request.opaque, ntohs(req->request.vbucket),
                        req->request.opcode, error, &resp.touch);
        root->callbacks.touch(root, ct->cookie, error, &resp.touch);
        break;

    case PROTOCOL_BINARY_CMD_STAT:
        setup_lcb_server_stat_resp_t(&resp.stats, server->authority,
                                     NULL, 0, NULL, 0);
        TRACE_STATS_PROGRESS(req->request.opaque, ntohs(req->request.vbucket),
                             req->request.opcode, error, &resp.stats);
        root->callbacks.stat(root, ct->cookie, error, &resp.stats);

        if (lcb_lookup_server_with_command(root,
                                           PROTOCOL_BINARY_CMD_STAT,
                                           req->request.opaque,
                                           server) < 0) {
            setup_lcb_server_stat_resp_t(&resp.stats,
                                         NULL, NULL, 0, NULL, 0);
            TRACE_STATS_END(req->request.opaque, ntohs(req->request.vbucket),
                            req->request.opcode, error);
            root->callbacks.stat(root, ct->cookie, error, &resp.stats);
        }
        break;

    case PROTOCOL_BINARY_CMD_VERBOSITY:
        setup_lcb_verbosity_resp_t(&resp.verbosity, server->authority);
        TRACE_VERBOSITY_END(req->request.opaque, ntohs(req->request.vbucket),
                            req->request.opcode, error, &resp.verbosity);
        root->callbacks.verbosity(root, ct->cookie, error, &resp.verbosity);

        if (lcb_lookup_server_with_command(root,
                                           PROTOCOL_BINARY_CMD_VERBOSITY,
                                           req->request.opaque,
                                           server) < 0) {
            setup_lcb_verbosity_resp_t(&resp.verbosity, NULL);
            TRACE_VERBOSITY_END(req->request.opaque, ntohs(req->request.vbucket),
                                req->request.opcode, error, &resp.verbosity);
            root->callbacks.verbosity(root, ct->cookie, error, &resp.verbosity);
        }
        break;

    case PROTOCOL_BINARY_CMD_VERSION:
        setup_lcb_server_version_resp_t(&resp.versions, server->authority,
                                        NULL, 0);
        TRACE_VERSIONS_PROGRESS(req->request.opaque, ntohs(req->request.vbucket),
                                req->request.opcode, error, &resp.versions);
        root->callbacks.version(root, ct->cookie, error, &resp.versions);
        if (lcb_lookup_server_with_command(root,
                                           PROTOCOL_BINARY_CMD_VERSION,
                                           req->request.opaque,
                                           server) < 0) {
            TRACE_VERSIONS_END(req->request.opaque, ntohs(req->request.vbucket),
                               req->request.opcode, error);
            setup_lcb_server_version_resp_t(&resp.versions, NULL, NULL, 0);
            root->callbacks.version(root, ct->cookie, error, &resp.versions);
        }
        break;

    case CMD_OBSERVE:
        lcb_failout_observe_request(server, ct, packet,
                                    sizeof(req->bytes) + ntohl(req->request.bodylen),
                                    error);
        break;

    case CMD_GET_CLUSTER_CONFIG:
        lcb_cccp_update2(ct->cookie, error, NULL, 0, NULL);
        break;
    
    case PROTOCOL_BINARY_CMD_HELLO:
        lcb_cccp_update2(ct->cookie, error, NULL, 0, NULL);
        break;

    case PROTOCOL_BINARY_CMD_COMPACTDB:
        lcb_cccp_update2(ct->cookie, error, NULL, 0, NULL);
        break;
    
    default:
        lcb_assert("unexpected opcode while purging the server" && 0);
    }

}
Ejemplo n.º 12
0
static void observe_response_handler(lcb_server_t *server,
                                     struct lcb_command_data_st *command_data,
                                     protocol_binary_response_header *res)
{
    lcb_t root = server->instance;
    lcb_uint16_t status = ntohs(res->response.status);
    lcb_error_t rc = map_error(root, status);
    lcb_uint32_t ttp;
    lcb_uint32_t ttr;
    lcb_size_t pos;

    VBUCKET_CONFIG_HANDLE config;
    const char *end, *ptr = (const char *)&res->response.cas;

    /**
     * If we have an error we must decode the request instead
     */
    if (rc != LCB_SUCCESS) {
        protocol_binary_request_header req;
        lcb_size_t nr;

        nr = ringbuffer_peek(&server->cmd_log, req.bytes, sizeof(req.bytes));
        if (nr != sizeof(req.bytes)) {
            lcb_error_handler(server->instance, LCB_EINTERNAL, NULL);
            abort();
        }
        if (req.request.bodylen) {
            lcb_size_t npacket = sizeof(req.bytes) + ntohl(req.request.bodylen);
            char *packet = server->cmd_log.read_head;
            int allocated = 0;

            if (!ringbuffer_is_continous(&server->cmd_log, RINGBUFFER_READ, npacket)) {
                packet = malloc(npacket);
                if (packet == NULL) {
                    lcb_error_handler(root, LCB_CLIENT_ENOMEM, NULL);
                    abort();
                }
                nr = ringbuffer_peek(&server->cmd_log, packet, npacket);
                if (nr != npacket) {
                    lcb_error_handler(root, LCB_EINTERNAL, NULL);
                    free(packet);
                    abort();
                }
                allocated = 1;
            }
            lcb_failout_observe_request(server, command_data, packet, npacket, rc);
            if (allocated) {
                free(packet);
            }
        }
        return;
    }


    memcpy(&ttp, ptr, sizeof(ttp));
    ttp = ntohl(ttp);
    memcpy(&ttr, ptr + sizeof(ttp), sizeof(ttr));
    ttr = ntohl(ttr);


    ptr = (const char *)res + sizeof(res->bytes);
    end = ptr + ntohl(res->response.bodylen);
    config = root->vbucket_config;
    for (pos = 0; ptr < end; pos++) {
        lcb_cas_t cas;
        lcb_uint8_t obs;
        lcb_uint16_t nkey, vb;
        const char *key;
        lcb_observe_resp_t resp;

        memcpy(&vb, ptr, sizeof(vb));
        vb = ntohs(vb);
        ptr += sizeof(vb);
        memcpy(&nkey, ptr, sizeof(nkey));
        nkey = ntohs(nkey);
        ptr += sizeof(nkey);
        key = (const char *)ptr;
        ptr += nkey;
        obs = *((lcb_uint8_t *)ptr);
        ptr += sizeof(obs);
        memcpy(&cas, ptr, sizeof(cas));
        ptr += sizeof(cas);

        setup_lcb_observe_resp_t(&resp, key, nkey, cas, obs,
                                 server->index == vbucket_get_master(config, vb),
                                 ttp, ttr);
        TRACE_OBSERVE_PROGRESS(res->response.opaque, command_data->vbucket,
                               res->response.opcode, rc, &resp);
        lcb_observe_invoke_callback(root, command_data, rc, &resp);
    }

    /* run callback with null-null-null to signal the end of transfer */
    if ((command_data->flags & LCB_CMD_F_OBS_BCAST) &&
            lcb_lookup_server_with_command(root, CMD_OBSERVE,
                                           res->response.opaque, server) < 0) {

        lcb_observe_resp_t resp;
        memset(&resp, 0, sizeof(resp));
        TRACE_OBSERVE_END(res->response.opaque, command_data->vbucket,
                          res->response.opcode, rc);
        lcb_observe_invoke_callback(root, command_data, LCB_SUCCESS, &resp);
    }
}