static void H_store(mc_PIPELINE *pipeline, mc_PACKET *request, packet_info *response, lcb_error_t immerr) { lcb_t root = pipeline->parent->cqdata; lcb_RESPSTORE resp = { 0 }; lcb_U8 opcode; init_resp3(root, response, request, immerr, (lcb_RESPBASE*)&resp); if (!immerr) { opcode = PACKET_OPCODE(response); } else { protocol_binary_request_header hdr; mcreq_read_hdr(request, &hdr); opcode = hdr.request.opcode; } if (opcode == PROTOCOL_BINARY_CMD_ADD) { resp.op = LCB_ADD; } else if (opcode == PROTOCOL_BINARY_CMD_REPLACE) { resp.op = LCB_REPLACE; } else if (opcode == PROTOCOL_BINARY_CMD_APPEND) { resp.op = LCB_APPEND; } else if (opcode == PROTOCOL_BINARY_CMD_PREPEND) { resp.op = LCB_PREPEND; } else if (opcode == PROTOCOL_BINARY_CMD_SET) { resp.op = LCB_SET; } handle_synctoken(root, response, request, &resp.synctoken); TRACE_STORE_END(response, &resp); if (request->flags & MCREQ_F_REQEXT) { request->u_rdata.exdata->procs->handler(pipeline, request, immerr, &resp); } else { INVOKE_CALLBACK3(request, &resp, root, LCB_CALLBACK_STORE); } }
static void store_response_handler(lcb_server_t *server, packet_info *info) { lcb_t root = server->instance; lcb_storage_t op; char *packet; lcb_uint16_t nkey; lcb_error_t rc; lcb_uint16_t status = PACKET_STATUS(info); const char *key = get_key(server, &nkey, &packet); if (PACKET_STATUS(info) == PROTOCOL_BINARY_RESPONSE_SUCCESS) { rc = LCB_SUCCESS; } else { rc = map_error(root, status); } switch (PACKET_OPCODE(info)) { case PROTOCOL_BINARY_CMD_ADD: op = LCB_ADD; break; case PROTOCOL_BINARY_CMD_REPLACE: op = LCB_REPLACE; break; case PROTOCOL_BINARY_CMD_SET: op = LCB_SET; break; case PROTOCOL_BINARY_CMD_APPEND: op = LCB_APPEND; break; case PROTOCOL_BINARY_CMD_PREPEND: op = LCB_PREPEND; break; default: /* ** It is impossible to get here (since we're called from our ** lookup table... If we _DO_ get here, it must be a development ** version where the developer isn't done yet (and should be ** forced to think about what to do...) */ lcb_error_handler(root, LCB_EINTERNAL, "Internal error. Received an illegal command opcode"); abort(); } if (key == NULL) { lcb_error_handler(server->instance, LCB_EINTERNAL, NULL); } else { lcb_store_resp_t resp; setup_lcb_store_resp_t(&resp, key, nkey, PACKET_CAS(info)); PACKET_TRACE(TRACE_STORE_END, info, rc, &resp); root->callbacks.store(root, info->ct.cookie, op, rc, &resp); release_key(server, packet); } }
static void record_metrics(mc_PIPELINE *pipeline, mc_PACKET *req, packet_info *res) { lcb_t instance = pipeline->parent->cqdata; if (instance->histogram) { lcb_record_metrics( instance, gethrtime() - MCREQ_PKT_RDATA(req)->start, PACKET_OPCODE(res)); } }
static void H_subdoc(mc_PIPELINE *pipeline, mc_PACKET *request, packet_info *response, lcb_error_t immerr) { lcb_t o; respack_SUBDOC w = { { 0 } }; int cbtype; o = pipeline->parent->cqdata; init_resp3(o, response, request, immerr, (lcb_RESPBASE *)&w.resp); /* For mutations, add the mutation token */ switch (PACKET_OPCODE(response)) { case PROTOCOL_BINARY_CMD_SUBDOC_GET: case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS: case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP: cbtype = LCB_CALLBACK_SDLOOKUP; break; default: handle_mutation_token(o, response, request, &w.mt); w.resp.rflags |= LCB_RESP_F_EXTDATA; cbtype = LCB_CALLBACK_SDMUTATE; break; } if (PACKET_OPCODE(response) == PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP || PACKET_OPCODE(response) == PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION) { if (w.resp.rc == LCB_SUCCESS || w.resp.rc == LCB_SUBDOC_MULTI_FAILURE) { w.resp.responses = response; } } else { /* Single response */ w.resp.rflags |= LCB_RESP_F_SDSINGLE; if (w.resp.rc == LCB_SUCCESS) { w.resp.responses = response; } else if (LCB_EIFSUBDOC(w.resp.rc)) { w.resp.responses = response; w.resp.rc = LCB_SUBDOC_MULTI_FAILURE; } } INVOKE_CALLBACK3(request, &w.resp, o, cbtype); }
static void H_store(mc_PIPELINE *pipeline, mc_PACKET *request, packet_info *response, lcb_error_t immerr) { lcb_t root = pipeline->parent->instance; lcb_storage_t op; lcb_error_t rc; lcb_store_resp_t resp; MK_ERROR(root, rc, response, immerr); switch (PACKET_OPCODE(response)) { case PROTOCOL_BINARY_CMD_ADD: op = LCB_ADD; break; case PROTOCOL_BINARY_CMD_REPLACE: op = LCB_REPLACE; break; case PROTOCOL_BINARY_CMD_SET: op = LCB_SET; break; case PROTOCOL_BINARY_CMD_APPEND: op = LCB_APPEND; break; case PROTOCOL_BINARY_CMD_PREPEND: op = LCB_PREPEND; break; default: abort(); break; } resp.version = 0; MK_RESPKEY(&resp, 0, request); SET_RESP_CAS(&resp, 0, PACKET_CAS(response)); INVOKE_CALLBACK(request, root->callbacks.store, (root, MCREQ_PKT_COOKIE(request), op, rc, &resp)); }
LIBCOUCHBASE_API int lcb_sdresult_next(const lcb_RESPSUBDOC *resp, lcb_SDENTRY *ent, size_t *iter) { size_t iter_s = 0; const packet_info *response = (const packet_info*)resp->responses; if (!response) { return 0; } if (!iter) { /* Single response */ iter = &iter_s; } switch (PACKET_OPCODE(response)) { case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP: return sdlookup_next(response, ent, iter); case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION: return sdmutate_next(response, ent, iter); default: if (*iter) { return 0; } *iter = 1; if (resp->rc == LCB_SUCCESS || resp->rc == LCB_SUBDOC_MULTI_FAILURE) { ent->status = map_error(NULL, PACKET_STATUS(response)); ent->value = PACKET_VALUE(response); ent->nvalue = PACKET_NVALUE(response); ent->index = 0; return 1; } else { return 0; } } }
int mcreq_dispatch_response( mc_PIPELINE *pipeline, mc_PACKET *req, packet_info *res, lcb_error_t immerr) { record_metrics(pipeline, req, res); if (req->flags & MCREQ_F_UFWD) { dispatch_ufwd_error(pipeline, req, immerr); return 0; } #define INVOKE_OP(handler) \ handler(pipeline, req, res, immerr); \ return 0; \ break; switch (PACKET_OPCODE(res)) { case PROTOCOL_BINARY_CMD_GETQ: case PROTOCOL_BINARY_CMD_GATQ: case PROTOCOL_BINARY_CMD_GET: case PROTOCOL_BINARY_CMD_GAT: case PROTOCOL_BINARY_CMD_GET_LOCKED: INVOKE_OP(H_get); case PROTOCOL_BINARY_CMD_ADD: case PROTOCOL_BINARY_CMD_REPLACE: case PROTOCOL_BINARY_CMD_SET: case PROTOCOL_BINARY_CMD_APPEND: case PROTOCOL_BINARY_CMD_PREPEND: INVOKE_OP(H_store); case PROTOCOL_BINARY_CMD_INCREMENT: case PROTOCOL_BINARY_CMD_DECREMENT: INVOKE_OP(H_arithmetic); case PROTOCOL_BINARY_CMD_OBSERVE: INVOKE_OP(H_observe); case PROTOCOL_BINARY_CMD_GET_REPLICA: INVOKE_OP(H_getreplica); case PROTOCOL_BINARY_CMD_UNLOCK_KEY: INVOKE_OP(H_unlock); case PROTOCOL_BINARY_CMD_DELETE: INVOKE_OP(H_delete); case PROTOCOL_BINARY_CMD_TOUCH: INVOKE_OP(H_touch); case PROTOCOL_BINARY_CMD_OBSERVE_SEQNO: INVOKE_OP(H_observe_seqno); case PROTOCOL_BINARY_CMD_STAT: INVOKE_OP(H_stats); case PROTOCOL_BINARY_CMD_FLUSH: INVOKE_OP(H_flush); case PROTOCOL_BINARY_CMD_VERSION: INVOKE_OP(H_version); case PROTOCOL_BINARY_CMD_VERBOSITY: INVOKE_OP(H_verbosity); #if 0 case PROTOCOL_BINARY_CMD_NOOP: INVOKE_OP(H_noop); #endif case PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG: INVOKE_OP(H_config); default: return -1; } }
/** * It's assumed the server buffers will be reset upon close(), so we must make * sure to _not_ release the ringbuffer if that happens. */ static void handle_read(lcbio_CTX *ioctx, unsigned nb) { mc_pSESSREQ sreq = lcbio_ctx_data(ioctx); packet_info info; unsigned required; uint16_t status; sreq_STATE state = SREQ_S_WAIT; int rc; GT_NEXT_PACKET: memset(&info, 0, sizeof(info)); rc = lcb_pktinfo_ectx_get(&info, ioctx, &required); if (rc == 0) { LCBIO_CTX_RSCHEDULE(ioctx, required); return; } else if (rc < 0) { state = SREQ_S_ERROR; } status = PACKET_STATUS(&info); switch (PACKET_OPCODE(&info)) { case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS: { lcb_string str; int saslrc; const char *mechlist_data; unsigned int nmechlist_data; if (lcb_string_init(&str)) { set_error_ex(sreq, LCB_CLIENT_ENOMEM, NULL); state = SREQ_S_ERROR; break; } if (lcb_string_append(&str, info.payload, PACKET_NBODY(&info))) { lcb_string_release(&str); set_error_ex(sreq, LCB_CLIENT_ENOMEM, NULL); state = SREQ_S_ERROR; break; } saslrc = set_chosen_mech(sreq, &str, &mechlist_data, &nmechlist_data); if (saslrc == 0) { if (0 == send_sasl_auth(sreq, mechlist_data, nmechlist_data)) { state = SREQ_S_WAIT; } else { state = SREQ_S_ERROR; } } else if (saslrc < 0) { state = SREQ_S_ERROR; } else { state = SREQ_S_HELLODONE; } lcb_string_release(&str); break; } case PROTOCOL_BINARY_CMD_SASL_AUTH: { if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) { send_hello(sreq); state = SREQ_S_AUTHDONE; break; } if (status != PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE) { set_error_ex(sreq, LCB_AUTH_ERROR, "SASL AUTH failed"); state = SREQ_S_ERROR; break; } if (send_sasl_step(sreq, &info) == 0 && send_hello(sreq) == 0) { state = SREQ_S_WAIT; } else { state = SREQ_S_ERROR; } break; } case PROTOCOL_BINARY_CMD_SASL_STEP: { if (status != PROTOCOL_BINARY_RESPONSE_SUCCESS) { lcb_log(LOGARGS(sreq, WARN), SESSREQ_LOGFMT "SASL auth failed with STATUS=0x%x", SESSREQ_LOGID(sreq), status); set_error_ex(sreq, LCB_AUTH_ERROR, "SASL Step Failed"); state = SREQ_S_ERROR; } else { /* Wait for pipelined HELLO response */ state = SREQ_S_AUTHDONE; } break; } case PROTOCOL_BINARY_CMD_HELLO: { state = SREQ_S_HELLODONE; if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) { parse_hello(sreq, &info); } else if (status == PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND || status == PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED) { lcb_log(LOGARGS(sreq, DEBUG), SESSREQ_LOGFMT "Server does not support HELLO", SESSREQ_LOGID(sreq)); /* nothing */ } else { set_error_ex(sreq, LCB_PROTOCOL_ERROR, "Hello response unexpected"); state = SREQ_S_ERROR; } break; } default: { state = SREQ_S_ERROR; lcb_log(LOGARGS(sreq, ERROR), SESSREQ_LOGFMT "Received unknown response. OP=0x%x. RC=0x%x", SESSREQ_LOGID(sreq), PACKET_OPCODE(&info), PACKET_STATUS(&info)); set_error_ex(sreq, LCB_NOT_SUPPORTED, "Received unknown response"); break; } } lcb_pktinfo_ectx_done(&info, ioctx); if (sreq->err != LCB_SUCCESS) { bail_pending(sreq); } else if (state == SREQ_S_ERROR) { set_error_ex(sreq, LCB_ERROR, "FIXME: Error code set without description"); } else if (state == SREQ_S_HELLODONE) { negotiation_success(sreq); } else { goto GT_NEXT_PACKET; } (void)nb; }
/* This function is called within a loop to process a single packet. * * If a full packet is available, it will process the packet and return * PKT_READ_COMPLETE, resulting in the `on_read()` function calling this * function in a loop. * * When a complete packet is not available, PKT_READ_PARTIAL will be returned * and the `on_read()` loop will exit, scheduling any required pending I/O. */ static int try_read(lcbio_CTX *ctx, mc_SERVER *server, rdb_IOROPE *ior) { packet_info info_s, *info = &info_s; mc_PACKET *request; mc_PIPELINE *pl = &server->pipeline; unsigned pktsize = 24, is_last = 1; #define RETURN_NEED_MORE(n) \ if (mcserver_has_pending(server)) { \ lcbio_ctx_rwant(ctx, n); \ } \ return PKT_READ_PARTIAL; \ #define DO_ASSIGN_PAYLOAD() \ rdb_consumed(ior, sizeof(info->res.bytes)); \ if (PACKET_NBODY(info)) { \ info->payload = rdb_get_consolidated(ior, PACKET_NBODY(info)); \ } { #define DO_SWALLOW_PAYLOAD() \ } if (PACKET_NBODY(info)) { \ rdb_consumed(ior, PACKET_NBODY(info)); \ } if (rdb_get_nused(ior) < pktsize) { RETURN_NEED_MORE(pktsize) } /* copy bytes into the info structure */ rdb_copyread(ior, info->res.bytes, sizeof info->res.bytes); pktsize += PACKET_NBODY(info); if (rdb_get_nused(ior) < pktsize) { RETURN_NEED_MORE(pktsize); } /* Find the packet */ if (PACKET_OPCODE(info) == PROTOCOL_BINARY_CMD_STAT && PACKET_NKEY(info) != 0) { is_last = 0; request = mcreq_pipeline_find(pl, PACKET_OPAQUE(info)); } else { is_last = 1; request = mcreq_pipeline_remove(pl, PACKET_OPAQUE(info)); } if (!request) { lcb_log(LOGARGS(server, WARN), LOGFMT "Found stale packet (OP=0x%x, RC=0x%x, SEQ=%u)", LOGID(server), PACKET_OPCODE(info), PACKET_STATUS(info), PACKET_OPAQUE(info)); rdb_consumed(ior, pktsize); return PKT_READ_COMPLETE; } if (PACKET_STATUS(info) == PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET) { /* consume the header */ DO_ASSIGN_PAYLOAD() if (!handle_nmv(server, info, request)) { mcreq_dispatch_response(pl, request, info, LCB_NOT_MY_VBUCKET); } DO_SWALLOW_PAYLOAD() return PKT_READ_COMPLETE; }
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); } }
int lcb_proto_parse_single(lcb_server_t *c, hrtime_t stop) { int rv; packet_info info; protocol_binary_request_header req; lcb_size_t nr; lcb_connection_t conn = &c->connection; rv = lcb_packet_read_ringbuffer(&info, conn->input); if (rv == -1) { return -1; } else if (rv == 0) { return 0; } /* Is it already timed out? */ nr = ringbuffer_peek(&c->cmd_log, req.bytes, sizeof(req)); if (nr < sizeof(req) || /* the command log doesn't know about it */ (PACKET_OPAQUE(&info) < req.request.opaque && PACKET_OPAQUE(&info) > 0)) { /* sasl comes with zero opaque */ /* already processed. */ lcb_packet_release_ringbuffer(&info, conn->input); return 1; } nr = ringbuffer_peek(&c->output_cookies, &info.ct, sizeof(info.ct)); if (nr != sizeof(info.ct)) { lcb_error_handler(c->instance, LCB_EINTERNAL, NULL); lcb_packet_release_ringbuffer(&info, conn->input); return -1; } info.ct.vbucket = ntohs(req.request.vbucket); switch (info.res.response.magic) { case PROTOCOL_BINARY_REQ: /* * The only way to get request packets is if someone started * to send us TAP requests, and we don't support that anymore */ lcb_error_handler(c->instance, LCB_EINTERNAL, "Protocol error. someone sent us a command!"); return -1; case PROTOCOL_BINARY_RES: { int was_connected = c->connection_ready; rv = lcb_server_purge_implicit_responses(c, PACKET_OPAQUE(&info), stop, 0); if (rv != 0) { lcb_packet_release_ringbuffer(&info, conn->input); return -1; } if (c->instance->histogram) { lcb_record_metrics(c->instance, stop - info.ct.start, PACKET_OPCODE(&info)); } if (PACKET_STATUS(&info) != PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET || PACKET_OPCODE(&info) == CMD_GET_REPLICA || PACKET_OPCODE(&info) == CMD_OBSERVE) { rv = lcb_dispatch_response(c, &info); if (rv == -1) { lcb_error_handler(c->instance, LCB_EINTERNAL, "Received unknown command response"); abort(); return -1; } /* keep command and cookie until we get complete STAT response */ swallow_command(c, &info.res, was_connected); } else { rv = handle_not_my_vbucket(c, &info, &req, &info.ct); if (rv == -1) { return -1; } else if (rv == 0) { lcb_dispatch_response(c, &info); swallow_command(c, &info.res, was_connected); } } break; } default: lcb_error_handler(c->instance, LCB_PROTOCOL_ERROR, NULL); lcb_packet_release_ringbuffer(&info, conn->input); return -1; } lcb_packet_release_ringbuffer(&info, conn->input); return 1; }
int mcreq_dispatch_response( mc_PIPELINE *pipeline, mc_PACKET *req, packet_info *res, lcb_error_t immerr) { record_metrics(pipeline, req, res); if (req->flags & MCREQ_F_UFWD) { dispatch_ufwd_error(pipeline, req, immerr); return 0; } #define INVOKE_OP(handler) \ handler(pipeline, req, res, immerr); \ return 0; \ break; switch (PACKET_OPCODE(res)) { case PROTOCOL_BINARY_CMD_GETQ: case PROTOCOL_BINARY_CMD_GATQ: case PROTOCOL_BINARY_CMD_GET: case PROTOCOL_BINARY_CMD_GAT: case PROTOCOL_BINARY_CMD_GET_LOCKED: INVOKE_OP(H_get); case PROTOCOL_BINARY_CMD_ADD: case PROTOCOL_BINARY_CMD_REPLACE: case PROTOCOL_BINARY_CMD_SET: case PROTOCOL_BINARY_CMD_APPEND: case PROTOCOL_BINARY_CMD_PREPEND: INVOKE_OP(H_store); case PROTOCOL_BINARY_CMD_INCREMENT: case PROTOCOL_BINARY_CMD_DECREMENT: INVOKE_OP(H_arithmetic); case PROTOCOL_BINARY_CMD_SUBDOC_GET: case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS: case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_ADD_UNIQUE: case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_FIRST: case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_LAST: case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_INSERT: case PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD: case PROTOCOL_BINARY_CMD_SUBDOC_DICT_UPSERT: case PROTOCOL_BINARY_CMD_SUBDOC_REPLACE: case PROTOCOL_BINARY_CMD_SUBDOC_DELETE: case PROTOCOL_BINARY_CMD_SUBDOC_COUNTER: case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP: case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION: INVOKE_OP(H_subdoc); case PROTOCOL_BINARY_CMD_OBSERVE: INVOKE_OP(H_observe); case PROTOCOL_BINARY_CMD_GET_REPLICA: INVOKE_OP(H_getreplica); case PROTOCOL_BINARY_CMD_UNLOCK_KEY: INVOKE_OP(H_unlock); case PROTOCOL_BINARY_CMD_DELETE: INVOKE_OP(H_delete); case PROTOCOL_BINARY_CMD_TOUCH: INVOKE_OP(H_touch); case PROTOCOL_BINARY_CMD_OBSERVE_SEQNO: INVOKE_OP(H_observe_seqno); case PROTOCOL_BINARY_CMD_STAT: INVOKE_OP(H_stats); case PROTOCOL_BINARY_CMD_FLUSH: INVOKE_OP(H_flush); case PROTOCOL_BINARY_CMD_VERSION: INVOKE_OP(H_version); case PROTOCOL_BINARY_CMD_VERBOSITY: INVOKE_OP(H_verbosity); #if 0 case PROTOCOL_BINARY_CMD_NOOP: INVOKE_OP(H_noop); #endif case PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG: INVOKE_OP(H_config); default: fprintf(stderr, "COUCHBASE: Received unknown opcode=0x%x\n", PACKET_OPCODE(res)); return -1; } }