Example #1
0
void lcb_cccp_update2(const void *cookie, lcb_error_t err,
                      const void *bytes, lcb_size_t nbytes,
                      const lcb_host_t *origin)
{
    cccp_cookie *ck = (cccp_cookie *)cookie;
    cccp_provider *cccp = ck->parent;

    if (err == LCB_SUCCESS) {
        lcb_string ss;

        lcb_string_init(&ss);
        lcb_string_append(&ss, bytes, nbytes);
        err = lcb_cccp_update(&cccp->base, origin->host, &ss);
        lcb_string_release(&ss);

        if (err != LCB_SUCCESS && ck->ignore_errors == 0) {
            mcio_error(cccp, err);
        }


    } else if (!ck->ignore_errors) {
        mcio_error(cccp, err);
    }

    if (ck == cccp->cmdcookie) {
        cccp->cmdcookie = NULL;
    }

    free(ck);
}
Example #2
0
static void request_config(cccp_provider *cccp)
{
    protocol_binary_request_set_cluster_config req;
    lcb_connection_t conn = &cccp->connection;
    ringbuffer_t *buf = conn->output;

    memset(&req, 0, sizeof(req));
    req.message.header.request.magic = PROTOCOL_BINARY_REQ;
    req.message.header.request.opcode = CMD_GET_CLUSTER_CONFIG;
    req.message.header.request.opaque = 0xF00D;

    if (!buf) {
        if ((buf = calloc(1, sizeof(*buf))) == NULL) {
            mcio_error(cccp, LCB_CLIENT_ENOMEM);
            return;
        }
        conn->output = buf;
    }

    if (!ringbuffer_ensure_capacity(buf, sizeof(req.bytes))) {
        mcio_error(cccp, LCB_CLIENT_ENOMEM);
    }

    ringbuffer_write(buf, req.bytes, sizeof(req.bytes));
    lcb_sockrw_set_want(conn, LCB_WRITE_EVENT, 1);
    lcb_sockrw_apply_want(conn);
    lcb_timer_rearm(cccp->timer, PROVIDER_SETTING(&cccp->base,
                                                  config_node_timeout));
}
Example #3
0
static void socket_connected(connmgr_request *req)
{
    cccp_provider *cccp = req->data;
    lcb_connection_t conn = req->conn;
    struct lcb_nibufs_st nistrs;
    struct lcb_io_use_st use;
    struct negotiation_context *ctx;
    lcb_error_t err;

    free(req);
    cccp->cur_connreq = NULL;

    LOG(cccp, DEBUG, "CCCP Socket connected");

    if (!conn) {
        mcio_error(cccp, LCB_CONNECT_ERROR);
        return;
    }

    lcb_connuse_easy(&use, cccp, io_read_handler, io_error_handler);
    lcb_connection_transfer_socket(conn, &cccp->connection, &use);
    conn = NULL;


    if (cccp->connection.protoctx) {
        /** Already have SASL */
        if ((err = lcb_connection_reset_buffers(&cccp->connection)) != LCB_SUCCESS) {
            mcio_error(cccp, err);
            return;
        }

        request_config(cccp);
        return;
    }

    if (!lcb_get_nameinfo(&cccp->connection, &nistrs)) {
        mcio_error(cccp, LCB_EINTERNAL);
        return;
    }

    ctx = lcb_negotiation_create(&cccp->connection,
                                 cccp->base.parent->settings,
                                 PROVIDER_SETTING(&cccp->base,
                                         config_node_timeout),
                                 nistrs.remote,
                                 nistrs.local,
                                 &err);
    if (!ctx) {
        mcio_error(cccp, err);
    }

    ctx->complete = negotiation_done;
    ctx->data = cccp;
    cccp->connection.protoctx = ctx;
    cccp->connection.protoctx_dtor = (protoctx_dtor_t)lcb_negotiation_destroy;
}
Example #4
0
static void socket_timeout(lcb_timer_t tm, lcb_t instance, const void *cookie)
{
    cccp_provider *cccp = (cccp_provider *)cookie;
    mcio_error(cccp, LCB_ETIMEDOUT);

    (void)instance;
    (void)tm;
}
Example #5
0
static void negotiation_done(struct negotiation_context *ctx, lcb_error_t err)
{
    cccp_provider *cccp = ctx->data;
    struct lcb_io_use_st use;

    if (err != LCB_SUCCESS) {
        LOG(cccp, ERR, "CCCP SASL negotiation failed");
        mcio_error(cccp, err);

    } else {
        LOG(cccp, DEBUG, "CCCP SASL negotiation done");
        lcb_connuse_easy(&use, cccp, io_read_handler, io_error_handler);
        lcb_connection_use(&cccp->connection, &use);
        request_config(cccp);
    }
}
Example #6
0
static void io_read_handler(lcb_connection_t conn)
{
    packet_info pi;
    cccp_provider *cccp = conn->data;
    lcb_string jsonstr;
    lcb_error_t err;
    int rv;
    lcb_host_t curhost;

    memset(&pi, 0, sizeof(pi));

    rv = lcb_packet_read_ringbuffer(&pi, conn->input);

    if (rv < 0) {
        LOG(cccp, ERR, "Couldn't parse packet!?");
        mcio_error(cccp, LCB_EINTERNAL);
        return;

    } else if (rv == 0) {
        lcb_sockrw_set_want(conn, LCB_READ_EVENT, 1);
        lcb_sockrw_apply_want(conn);
        return;
    }

    if (PACKET_STATUS(&pi) != PROTOCOL_BINARY_RESPONSE_SUCCESS) {
        lcb_log(LOGARGS(cccp, ERR),
                "CCCP Packet responded with 0x%x; nkey=%d, nbytes=%lu, cmd=0x%x, seq=0x%x",
                PACKET_STATUS(&pi),
                PACKET_NKEY(&pi),
                PACKET_NBODY(&pi),
                PACKET_OPCODE(&pi),
                PACKET_OPAQUE(&pi));

        switch (PACKET_STATUS(&pi)) {
        case PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED:
        case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
            mcio_error(cccp, LCB_NOT_SUPPORTED);
            break;
        default:
            mcio_error(cccp, LCB_PROTOCOL_ERROR);
            break;
        }

        return;
    }

    if (!PACKET_NBODY(&pi)) {
        mcio_error(cccp, LCB_PROTOCOL_ERROR);
        return;
    }

    if (lcb_string_init(&jsonstr)) {
        mcio_error(cccp, LCB_CLIENT_ENOMEM);
        return;
    }

    if (lcb_string_append(&jsonstr, PACKET_BODY(&pi), PACKET_NBODY(&pi))) {
        mcio_error(cccp, LCB_CLIENT_ENOMEM);
        return;
    }

    curhost = *lcb_connection_get_host(&cccp->connection);
    lcb_packet_release_ringbuffer(&pi, conn->input);
    release_socket(cccp, 1);

    err = lcb_cccp_update(&cccp->base, curhost.host, &jsonstr);
    lcb_string_release(&jsonstr);
    if (err == LCB_SUCCESS) {
        lcb_timer_disarm(cccp->timer);
        cccp->server_active = 0;
    } else {
        schedule_next_request(cccp, LCB_PROTOCOL_ERROR, 0);
    }
}
Example #7
0
static void io_error_handler(lcb_connection_t conn)
{
    mcio_error((cccp_provider *)conn->data, LCB_NETWORK_ERROR);
}