/** * Request all features from the server and dump the available ones * @param sock socket connected to the server * @param key the name of the stat to receive (NULL == ALL) */ static void request_hello(BIO *bio, const char *key) { protocol_binary_request_hello req; protocol_binary_response_hello res; char buffer[1024]; const char useragent[] = "mchello v1.0"; uint16_t nkey = (uint16_t)strlen(useragent); uint16_t features[MEMCACHED_TOTAL_HELLO_FEATURES]; uint32_t total = nkey + MEMCACHED_TOTAL_HELLO_FEATURES * 2; int ii; memset(&req, 0, sizeof(req)); req.message.header.request.magic = PROTOCOL_BINARY_REQ; req.message.header.request.opcode = PROTOCOL_BINARY_CMD_HELLO; req.message.header.request.bodylen = htonl(total); req.message.header.request.keylen = htons(nkey); req.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES; ensure_send(bio, &req, sizeof(req)); ensure_send(bio, useragent, nkey); for (ii = 0; ii < MEMCACHED_TOTAL_HELLO_FEATURES; ++ii) { features[ii] = htons(MEMCACHED_FIRST_HELLO_FEATURE + ii); } ensure_send(bio, &features, MEMCACHED_TOTAL_HELLO_FEATURES * 2); ensure_recv(bio, &res, sizeof(res.bytes)); total = ntohl(res.message.header.response.bodylen); ensure_recv(bio, buffer, total); if (res.message.header.response.status != 0) { fprintf(stderr, "Got return value: %d\n", ntohs(res.message.header.response.status)); return; } memcpy(features, buffer, total); total /= 2; fprintf(stdout, "Features:\n"); for (ii = 0; ii < total; ++ii) { fprintf(stderr, "\t- %s\n", protocol_feature_2_text(ntohs(features[ii]))); } }
static int parse_hello(mc_pSESSREQ sreq, packet_info *packet) { /* some caps */ const char *cur; const char *payload = PACKET_BODY(packet); const char *limit = payload + PACKET_NBODY(packet); for (cur = payload; cur < limit; cur += 2) { lcb_U16 tmp; memcpy(&tmp, cur, sizeof(tmp)); tmp = ntohs(tmp); lcb_log(LOGARGS(sreq, DEBUG), SESSREQ_LOGFMT "Found feature 0x%x (%s)", SESSREQ_LOGID(sreq), tmp, protocol_feature_2_text(tmp)); sreq->inner->features[tmp] = 1; } return 0; }