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); }
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)); }
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; }
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; }
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); } }
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); } }
static void io_error_handler(lcb_connection_t conn) { mcio_error((cccp_provider *)conn->data, LCB_NETWORK_ERROR); }