1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2/* 3 * Copyright (c) <2008>, Sun Microsystems, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * * Neither the name of the nor the 14 * names of its contributors may be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY SUN MICROSYSTEMS, INC. ``AS IS'' AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28/* 29 * Summary: Constants used by to implement the binary protocol. 30 * 31 * Copy: See Copyright for the status of this software. 32 * 33 * Author: Trond Norbye <trond.norbye@sun.com> 34 */ 35#pragma once 36 37#include "config.h" 38 39#include <memcached/vbucket.h> 40 41#include <cstdint> 42#include <gsl/gsl> 43#include <sstream> 44#include <stdexcept> 45#include <string> 46 47/** 48 * \addtogroup Protocol 49 * @{ 50 */ 51 52/** 53 * This file contains definitions of the constants and packet formats 54 * defined in the binary specification. Please note that you _MUST_ remember 55 * to convert each multibyte field to / from network byte order to / from 56 * host order. 57 */ 58 59#include <mcbp/protocol/datatype.h> 60#include <mcbp/protocol/feature.h> 61#include <mcbp/protocol/magic.h> 62#include <mcbp/protocol/opcode.h> 63#include <mcbp/protocol/request.h> 64#include <mcbp/protocol/response.h> 65#include <mcbp/protocol/status.h> 66 67// For backward compatibility with old sources 68 69// Magic 70const uint8_t PROTOCOL_BINARY_REQ = uint8_t(cb::mcbp::Magic::ClientRequest); 71const uint8_t PROTOCOL_BINARY_RES = uint8_t(cb::mcbp::Magic::ClientResponse); 72 73// Status codes 74using protocol_binary_response_status = uint16_t; 75 76const uint16_t PROTOCOL_BINARY_RESPONSE_SUCCESS = 77 uint16_t(cb::mcbp::Status::Success); 78const uint16_t PROTOCOL_BINARY_RESPONSE_KEY_ENOENT = 79 uint16_t(cb::mcbp::Status::KeyEnoent); 80const uint16_t PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS = 81 uint16_t(cb::mcbp::Status::KeyEexists); 82const uint16_t PROTOCOL_BINARY_RESPONSE_E2BIG = uint16_t(cb::mcbp::Status::E2big); 83const uint16_t PROTOCOL_BINARY_RESPONSE_EINVAL = 84 uint16_t(cb::mcbp::Status::Einval); 85const uint16_t PROTOCOL_BINARY_RESPONSE_NOT_STORED = 86 uint16_t(cb::mcbp::Status::NotStored); 87const uint16_t PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL = 88 uint16_t(cb::mcbp::Status::DeltaBadval); 89const uint16_t PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET = 90 uint16_t(cb::mcbp::Status::NotMyVbucket); 91const uint16_t PROTOCOL_BINARY_RESPONSE_NO_BUCKET = 92 uint16_t(cb::mcbp::Status::NoBucket); 93const uint16_t PROTOCOL_BINARY_RESPONSE_LOCKED = 94 uint16_t(cb::mcbp::Status::Locked); 95const uint16_t PROTOCOL_BINARY_RESPONSE_AUTH_STALE = 96 uint16_t(cb::mcbp::Status::AuthStale); 97const uint16_t PROTOCOL_BINARY_RESPONSE_AUTH_ERROR = 98 uint16_t(cb::mcbp::Status::AuthError); 99const uint16_t PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE = 100 uint16_t(cb::mcbp::Status::AuthContinue); 101const uint16_t PROTOCOL_BINARY_RESPONSE_ERANGE = 102 uint16_t(cb::mcbp::Status::Erange); 103const uint16_t PROTOCOL_BINARY_RESPONSE_ROLLBACK = 104 uint16_t(cb::mcbp::Status::Rollback); 105const uint16_t PROTOCOL_BINARY_RESPONSE_EACCESS = 106 uint16_t(cb::mcbp::Status::Eaccess); 107const uint16_t PROTOCOL_BINARY_RESPONSE_NOT_INITIALIZED = 108 uint16_t(cb::mcbp::Status::NotInitialized); 109const uint16_t PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND = 110 uint16_t(cb::mcbp::Status::UnknownCommand); 111const uint16_t PROTOCOL_BINARY_RESPONSE_ENOMEM = 112 uint16_t(cb::mcbp::Status::Enomem); 113const uint16_t PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED = 114 uint16_t(cb::mcbp::Status::NotSupported); 115const uint16_t PROTOCOL_BINARY_RESPONSE_EINTERNAL = 116 uint16_t(cb::mcbp::Status::Einternal); 117const uint16_t PROTOCOL_BINARY_RESPONSE_EBUSY = uint16_t(cb::mcbp::Status::Ebusy); 118const uint16_t PROTOCOL_BINARY_RESPONSE_ETMPFAIL = 119 uint16_t(cb::mcbp::Status::Etmpfail); 120const uint16_t PROTOCOL_BINARY_RESPONSE_XATTR_EINVAL = 121 uint16_t(cb::mcbp::Status::XattrEinval); 122const uint16_t PROTOCOL_BINARY_RESPONSE_UNKNOWN_COLLECTION = 123 uint16_t(cb::mcbp::Status::UnknownCollection); 124const uint16_t PROTOCOL_BINARY_RESPONSE_NO_COLLECTIONS_MANIFEST = 125 uint16_t(cb::mcbp::Status::NoCollectionsManifest); 126const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_PATH_ENOENT = 127 uint16_t(cb::mcbp::Status::SubdocPathEnoent); 128const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_PATH_MISMATCH = 129 uint16_t(cb::mcbp::Status::SubdocPathMismatch); 130const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_PATH_EINVAL = 131 uint16_t(cb::mcbp::Status::SubdocPathEinval); 132const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_PATH_E2BIG = 133 uint16_t(cb::mcbp::Status::SubdocPathE2big); 134const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_DOC_E2DEEP = 135 uint16_t(cb::mcbp::Status::SubdocDocE2deep); 136const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_VALUE_CANTINSERT = 137 uint16_t(cb::mcbp::Status::SubdocValueCantinsert); 138const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_DOC_NOTJSON = 139 uint16_t(cb::mcbp::Status::SubdocDocNotJson); 140const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_NUM_ERANGE = 141 uint16_t(cb::mcbp::Status::SubdocNumErange); 142const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_DELTA_EINVAL = 143 uint16_t(cb::mcbp::Status::SubdocDeltaEinval); 144const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_PATH_EEXISTS = 145 uint16_t(cb::mcbp::Status::SubdocPathEexists); 146const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_VALUE_ETOODEEP = 147 uint16_t(cb::mcbp::Status::SubdocValueEtoodeep); 148const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_INVALID_COMBO = 149 uint16_t(cb::mcbp::Status::SubdocInvalidCombo); 150const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_MULTI_PATH_FAILURE = 151 uint16_t(cb::mcbp::Status::SubdocMultiPathFailure); 152const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_SUCCESS_DELETED = 153 uint16_t(cb::mcbp::Status::SubdocSuccessDeleted); 154const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_INVALID_FLAG_COMBO = 155 uint16_t(cb::mcbp::Status::SubdocXattrInvalidFlagCombo); 156const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_INVALID_KEY_COMBO = 157 uint16_t(cb::mcbp::Status::SubdocXattrInvalidKeyCombo); 158const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_UNKNOWN_MACRO = 159 uint16_t(cb::mcbp::Status::SubdocXattrUnknownMacro); 160const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_UNKNOWN_VATTR = 161 uint16_t(cb::mcbp::Status::SubdocXattrUnknownVattr); 162const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_XATTR_CANT_MODIFY_VATTR = 163 uint16_t(cb::mcbp::Status::SubdocXattrCantModifyVattr); 164const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_MULTI_PATH_FAILURE_DELETED = 165 uint16_t(cb::mcbp::Status::SubdocMultiPathFailureDeleted); 166const uint16_t PROTOCOL_BINARY_RESPONSE_SUBDOC_INVALID_XATTR_ORDER = 167 uint16_t(cb::mcbp::Status::SubdocInvalidXattrOrder); 168 169using protocol_binary_command = uint8_t; 170 171const uint8_t PROTOCOL_BINARY_CMD_GET = uint8_t(cb::mcbp::ClientOpcode::Get); 172const uint8_t PROTOCOL_BINARY_CMD_SET = uint8_t(cb::mcbp::ClientOpcode::Set); 173const uint8_t PROTOCOL_BINARY_CMD_ADD = uint8_t(cb::mcbp::ClientOpcode::Add); 174const uint8_t PROTOCOL_BINARY_CMD_REPLACE = 175 uint8_t(cb::mcbp::ClientOpcode::Replace); 176const uint8_t PROTOCOL_BINARY_CMD_DELETE = 177 uint8_t(cb::mcbp::ClientOpcode::Delete); 178const uint8_t PROTOCOL_BINARY_CMD_INCREMENT = 179 uint8_t(cb::mcbp::ClientOpcode::Increment); 180const uint8_t PROTOCOL_BINARY_CMD_DECREMENT = 181 uint8_t(cb::mcbp::ClientOpcode::Decrement); 182const uint8_t PROTOCOL_BINARY_CMD_QUIT = uint8_t(cb::mcbp::ClientOpcode::Quit); 183const uint8_t PROTOCOL_BINARY_CMD_FLUSH = 184 uint8_t(cb::mcbp::ClientOpcode::Flush); 185const uint8_t PROTOCOL_BINARY_CMD_GETQ = uint8_t(cb::mcbp::ClientOpcode::Getq); 186const uint8_t PROTOCOL_BINARY_CMD_NOOP = uint8_t(cb::mcbp::ClientOpcode::Noop); 187const uint8_t PROTOCOL_BINARY_CMD_VERSION = 188 uint8_t(cb::mcbp::ClientOpcode::Version); 189const uint8_t PROTOCOL_BINARY_CMD_GETK = uint8_t(cb::mcbp::ClientOpcode::Getk); 190const uint8_t PROTOCOL_BINARY_CMD_GETKQ = 191 uint8_t(cb::mcbp::ClientOpcode::Getkq); 192const uint8_t PROTOCOL_BINARY_CMD_APPEND = 193 uint8_t(cb::mcbp::ClientOpcode::Append); 194const uint8_t PROTOCOL_BINARY_CMD_PREPEND = 195 uint8_t(cb::mcbp::ClientOpcode::Prepend); 196const uint8_t PROTOCOL_BINARY_CMD_STAT = uint8_t(cb::mcbp::ClientOpcode::Stat); 197const uint8_t PROTOCOL_BINARY_CMD_SETQ = uint8_t(cb::mcbp::ClientOpcode::Setq); 198const uint8_t PROTOCOL_BINARY_CMD_ADDQ = uint8_t(cb::mcbp::ClientOpcode::Addq); 199const uint8_t PROTOCOL_BINARY_CMD_REPLACEQ = 200 uint8_t(cb::mcbp::ClientOpcode::Replaceq); 201const uint8_t PROTOCOL_BINARY_CMD_DELETEQ = 202 uint8_t(cb::mcbp::ClientOpcode::Deleteq); 203const uint8_t PROTOCOL_BINARY_CMD_INCREMENTQ = 204 uint8_t(cb::mcbp::ClientOpcode::Incrementq); 205const uint8_t PROTOCOL_BINARY_CMD_DECREMENTQ = 206 uint8_t(cb::mcbp::ClientOpcode::Decrementq); 207const uint8_t PROTOCOL_BINARY_CMD_QUITQ = 208 uint8_t(cb::mcbp::ClientOpcode::Quitq); 209const uint8_t PROTOCOL_BINARY_CMD_FLUSHQ = 210 uint8_t(cb::mcbp::ClientOpcode::Flushq); 211const uint8_t PROTOCOL_BINARY_CMD_APPENDQ = 212 uint8_t(cb::mcbp::ClientOpcode::Appendq); 213const uint8_t PROTOCOL_BINARY_CMD_PREPENDQ = 214 uint8_t(cb::mcbp::ClientOpcode::Prependq); 215const uint8_t PROTOCOL_BINARY_CMD_VERBOSITY = 216 uint8_t(cb::mcbp::ClientOpcode::Verbosity); 217const uint8_t PROTOCOL_BINARY_CMD_TOUCH = 218 uint8_t(cb::mcbp::ClientOpcode::Touch); 219const uint8_t PROTOCOL_BINARY_CMD_GAT = uint8_t(cb::mcbp::ClientOpcode::Gat); 220const uint8_t PROTOCOL_BINARY_CMD_GATQ = uint8_t(cb::mcbp::ClientOpcode::Gatq); 221const uint8_t PROTOCOL_BINARY_CMD_HELLO = 222 uint8_t(cb::mcbp::ClientOpcode::Hello); 223const uint8_t PROTOCOL_BINARY_CMD_SASL_LIST_MECHS = 224 uint8_t(cb::mcbp::ClientOpcode::SaslListMechs); 225const uint8_t PROTOCOL_BINARY_CMD_SASL_AUTH = 226 uint8_t(cb::mcbp::ClientOpcode::SaslAuth); 227const uint8_t PROTOCOL_BINARY_CMD_SASL_STEP = 228 uint8_t(cb::mcbp::ClientOpcode::SaslStep); 229const uint8_t PROTOCOL_BINARY_CMD_IOCTL_GET = 230 uint8_t(cb::mcbp::ClientOpcode::IoctlGet); 231const uint8_t PROTOCOL_BINARY_CMD_IOCTL_SET = 232 uint8_t(cb::mcbp::ClientOpcode::IoctlSet); 233const uint8_t PROTOCOL_BINARY_CMD_CONFIG_VALIDATE = 234 uint8_t(cb::mcbp::ClientOpcode::ConfigValidate); 235const uint8_t PROTOCOL_BINARY_CMD_CONFIG_RELOAD = 236 uint8_t(cb::mcbp::ClientOpcode::ConfigReload); 237const uint8_t PROTOCOL_BINARY_CMD_AUDIT_PUT = 238 uint8_t(cb::mcbp::ClientOpcode::AuditPut); 239const uint8_t PROTOCOL_BINARY_CMD_AUDIT_CONFIG_RELOAD = 240 uint8_t(cb::mcbp::ClientOpcode::AuditConfigReload); 241const uint8_t PROTOCOL_BINARY_CMD_SHUTDOWN = 242 uint8_t(cb::mcbp::ClientOpcode::Shutdown); 243const uint8_t PROTOCOL_BINARY_CMD_RGET = uint8_t(cb::mcbp::ClientOpcode::Rget); 244const uint8_t PROTOCOL_BINARY_CMD_RSET = uint8_t(cb::mcbp::ClientOpcode::Rset); 245const uint8_t PROTOCOL_BINARY_CMD_RSETQ = 246 uint8_t(cb::mcbp::ClientOpcode::Rsetq); 247const uint8_t PROTOCOL_BINARY_CMD_RAPPEND = 248 uint8_t(cb::mcbp::ClientOpcode::Rappend); 249const uint8_t PROTOCOL_BINARY_CMD_RAPPENDQ = 250 uint8_t(cb::mcbp::ClientOpcode::Rappendq); 251const uint8_t PROTOCOL_BINARY_CMD_RPREPEND = 252 uint8_t(cb::mcbp::ClientOpcode::Rprepend); 253const uint8_t PROTOCOL_BINARY_CMD_RPREPENDQ = 254 uint8_t(cb::mcbp::ClientOpcode::Rprependq); 255const uint8_t PROTOCOL_BINARY_CMD_RDELETE = 256 uint8_t(cb::mcbp::ClientOpcode::Rdelete); 257const uint8_t PROTOCOL_BINARY_CMD_RDELETEQ = 258 uint8_t(cb::mcbp::ClientOpcode::Rdeleteq); 259const uint8_t PROTOCOL_BINARY_CMD_RINCR = 260 uint8_t(cb::mcbp::ClientOpcode::Rincr); 261const uint8_t PROTOCOL_BINARY_CMD_RINCRQ = 262 uint8_t(cb::mcbp::ClientOpcode::Rincrq); 263const uint8_t PROTOCOL_BINARY_CMD_RDECR = 264 uint8_t(cb::mcbp::ClientOpcode::Rdecr); 265const uint8_t PROTOCOL_BINARY_CMD_RDECRQ = 266 uint8_t(cb::mcbp::ClientOpcode::Rdecrq); 267const uint8_t PROTOCOL_BINARY_CMD_SET_VBUCKET = 268 uint8_t(cb::mcbp::ClientOpcode::SetVbucket); 269const uint8_t PROTOCOL_BINARY_CMD_GET_VBUCKET = 270 uint8_t(cb::mcbp::ClientOpcode::GetVbucket); 271const uint8_t PROTOCOL_BINARY_CMD_DEL_VBUCKET = 272 uint8_t(cb::mcbp::ClientOpcode::DelVbucket); 273const uint8_t PROTOCOL_BINARY_CMD_TAP_CONNECT = 274 uint8_t(cb::mcbp::ClientOpcode::TapConnect); 275const uint8_t PROTOCOL_BINARY_CMD_TAP_MUTATION = 276 uint8_t(cb::mcbp::ClientOpcode::TapMutation); 277const uint8_t PROTOCOL_BINARY_CMD_TAP_DELETE = 278 uint8_t(cb::mcbp::ClientOpcode::TapDelete); 279const uint8_t PROTOCOL_BINARY_CMD_TAP_FLUSH = 280 uint8_t(cb::mcbp::ClientOpcode::TapFlush); 281const uint8_t PROTOCOL_BINARY_CMD_TAP_OPAQUE = 282 uint8_t(cb::mcbp::ClientOpcode::TapOpaque); 283const uint8_t PROTOCOL_BINARY_CMD_TAP_VBUCKET_SET = 284 uint8_t(cb::mcbp::ClientOpcode::TapVbucketSet); 285const uint8_t PROTOCOL_BINARY_CMD_TAP_CHECKPOINT_START = 286 uint8_t(cb::mcbp::ClientOpcode::TapCheckpointStart); 287const uint8_t PROTOCOL_BINARY_CMD_TAP_CHECKPOINT_END = 288 uint8_t(cb::mcbp::ClientOpcode::TapCheckpointEnd); 289const uint8_t PROTOCOL_BINARY_CMD_GET_ALL_VB_SEQNOS = 290 uint8_t(cb::mcbp::ClientOpcode::GetAllVbSeqnos); 291const uint8_t PROTOCOL_BINARY_CMD_DCP_OPEN = 292 uint8_t(cb::mcbp::ClientOpcode::DcpOpen); 293const uint8_t PROTOCOL_BINARY_CMD_DCP_ADD_STREAM = 294 uint8_t(cb::mcbp::ClientOpcode::DcpAddStream); 295const uint8_t PROTOCOL_BINARY_CMD_DCP_CLOSE_STREAM = 296 uint8_t(cb::mcbp::ClientOpcode::DcpCloseStream); 297const uint8_t PROTOCOL_BINARY_CMD_DCP_STREAM_REQ = 298 uint8_t(cb::mcbp::ClientOpcode::DcpStreamReq); 299const uint8_t PROTOCOL_BINARY_CMD_DCP_GET_FAILOVER_LOG = 300 uint8_t(cb::mcbp::ClientOpcode::DcpGetFailoverLog); 301const uint8_t PROTOCOL_BINARY_CMD_DCP_STREAM_END = 302 uint8_t(cb::mcbp::ClientOpcode::DcpStreamEnd); 303const uint8_t PROTOCOL_BINARY_CMD_DCP_SNAPSHOT_MARKER = 304 uint8_t(cb::mcbp::ClientOpcode::DcpSnapshotMarker); 305const uint8_t PROTOCOL_BINARY_CMD_DCP_MUTATION = 306 uint8_t(cb::mcbp::ClientOpcode::DcpMutation); 307const uint8_t PROTOCOL_BINARY_CMD_DCP_DELETION = 308 uint8_t(cb::mcbp::ClientOpcode::DcpDeletion); 309const uint8_t PROTOCOL_BINARY_CMD_DCP_EXPIRATION = 310 uint8_t(cb::mcbp::ClientOpcode::DcpExpiration); 311const uint8_t PROTOCOL_BINARY_CMD_DCP_FLUSH = 312 uint8_t(cb::mcbp::ClientOpcode::DcpFlush); 313const uint8_t PROTOCOL_BINARY_CMD_DCP_SET_VBUCKET_STATE = 314 uint8_t(cb::mcbp::ClientOpcode::DcpSetVbucketState); 315const uint8_t PROTOCOL_BINARY_CMD_DCP_NOOP = 316 uint8_t(cb::mcbp::ClientOpcode::DcpNoop); 317const uint8_t PROTOCOL_BINARY_CMD_DCP_BUFFER_ACKNOWLEDGEMENT = 318 uint8_t(cb::mcbp::ClientOpcode::DcpBufferAcknowledgement); 319const uint8_t PROTOCOL_BINARY_CMD_DCP_CONTROL = 320 uint8_t(cb::mcbp::ClientOpcode::DcpControl); 321const uint8_t PROTOCOL_BINARY_CMD_DCP_SYSTEM_EVENT = 322 uint8_t(cb::mcbp::ClientOpcode::DcpSystemEvent); 323const uint8_t PROTOCOL_BINARY_CMD_STOP_PERSISTENCE = 324 uint8_t(cb::mcbp::ClientOpcode::StopPersistence); 325const uint8_t PROTOCOL_BINARY_CMD_START_PERSISTENCE = 326 uint8_t(cb::mcbp::ClientOpcode::StartPersistence); 327const uint8_t PROTOCOL_BINARY_CMD_SET_PARAM = 328 uint8_t(cb::mcbp::ClientOpcode::SetParam); 329const uint8_t PROTOCOL_BINARY_CMD_GET_REPLICA = 330 uint8_t(cb::mcbp::ClientOpcode::GetReplica); 331const uint8_t PROTOCOL_BINARY_CMD_CREATE_BUCKET = 332 uint8_t(cb::mcbp::ClientOpcode::CreateBucket); 333const uint8_t PROTOCOL_BINARY_CMD_DELETE_BUCKET = 334 uint8_t(cb::mcbp::ClientOpcode::DeleteBucket); 335const uint8_t PROTOCOL_BINARY_CMD_LIST_BUCKETS = 336 uint8_t(cb::mcbp::ClientOpcode::ListBuckets); 337const uint8_t PROTOCOL_BINARY_CMD_SELECT_BUCKET = 338 uint8_t(cb::mcbp::ClientOpcode::SelectBucket); 339const uint8_t PROTOCOL_BINARY_CMD_OBSERVE_SEQNO = 340 uint8_t(cb::mcbp::ClientOpcode::ObserveSeqno); 341const uint8_t PROTOCOL_BINARY_CMD_OBSERVE = 342 uint8_t(cb::mcbp::ClientOpcode::Observe); 343const uint8_t PROTOCOL_BINARY_CMD_EVICT_KEY = 344 uint8_t(cb::mcbp::ClientOpcode::EvictKey); 345const uint8_t PROTOCOL_BINARY_CMD_GET_LOCKED = 346 uint8_t(cb::mcbp::ClientOpcode::GetLocked); 347const uint8_t PROTOCOL_BINARY_CMD_UNLOCK_KEY = 348 uint8_t(cb::mcbp::ClientOpcode::UnlockKey); 349const uint8_t PROTOCOL_BINARY_CMD_GET_FAILOVER_LOG = 350 uint8_t(cb::mcbp::ClientOpcode::GetFailoverLog); 351const uint8_t PROTOCOL_BINARY_CMD_LAST_CLOSED_CHECKPOINT = 352 uint8_t(cb::mcbp::ClientOpcode::LastClosedCheckpoint); 353const uint8_t PROTOCOL_BINARY_CMD_GET_META = 354 uint8_t(cb::mcbp::ClientOpcode::GetMeta); 355const uint8_t PROTOCOL_BINARY_CMD_GETQ_META = 356 uint8_t(cb::mcbp::ClientOpcode::GetqMeta); 357const uint8_t PROTOCOL_BINARY_CMD_SET_WITH_META = 358 uint8_t(cb::mcbp::ClientOpcode::SetWithMeta); 359const uint8_t PROTOCOL_BINARY_CMD_SETQ_WITH_META = 360 uint8_t(cb::mcbp::ClientOpcode::SetqWithMeta); 361const uint8_t PROTOCOL_BINARY_CMD_ADD_WITH_META = 362 uint8_t(cb::mcbp::ClientOpcode::AddWithMeta); 363const uint8_t PROTOCOL_BINARY_CMD_ADDQ_WITH_META = 364 uint8_t(cb::mcbp::ClientOpcode::AddqWithMeta); 365const uint8_t PROTOCOL_BINARY_CMD_SNAPSHOT_VB_STATES = 366 uint8_t(cb::mcbp::ClientOpcode::SnapshotVbStates); 367const uint8_t PROTOCOL_BINARY_CMD_VBUCKET_BATCH_COUNT = 368 uint8_t(cb::mcbp::ClientOpcode::VbucketBatchCount); 369const uint8_t PROTOCOL_BINARY_CMD_DEL_WITH_META = 370 uint8_t(cb::mcbp::ClientOpcode::DelWithMeta); 371const uint8_t PROTOCOL_BINARY_CMD_DELQ_WITH_META = 372 uint8_t(cb::mcbp::ClientOpcode::DelqWithMeta); 373const uint8_t PROTOCOL_BINARY_CMD_CREATE_CHECKPOINT = 374 uint8_t(cb::mcbp::ClientOpcode::CreateCheckpoint); 375const uint8_t PROTOCOL_BINARY_CMD_NOTIFY_VBUCKET_UPDATE = 376 uint8_t(cb::mcbp::ClientOpcode::NotifyVbucketUpdate); 377const uint8_t PROTOCOL_BINARY_CMD_ENABLE_TRAFFIC = 378 uint8_t(cb::mcbp::ClientOpcode::EnableTraffic); 379const uint8_t PROTOCOL_BINARY_CMD_DISABLE_TRAFFIC = 380 uint8_t(cb::mcbp::ClientOpcode::DisableTraffic); 381const uint8_t PROTOCOL_BINARY_CMD_CHECKPOINT_PERSISTENCE = 382 uint8_t(cb::mcbp::ClientOpcode::CheckpointPersistence); 383const uint8_t PROTOCOL_BINARY_CMD_RETURN_META = 384 uint8_t(cb::mcbp::ClientOpcode::ReturnMeta); 385const uint8_t PROTOCOL_BINARY_CMD_COMPACT_DB = 386 uint8_t(cb::mcbp::ClientOpcode::CompactDb); 387const uint8_t PROTOCOL_BINARY_CMD_SET_CLUSTER_CONFIG = 388 uint8_t(cb::mcbp::ClientOpcode::SetClusterConfig); 389const uint8_t PROTOCOL_BINARY_CMD_GET_CLUSTER_CONFIG = 390 uint8_t(cb::mcbp::ClientOpcode::GetClusterConfig); 391const uint8_t PROTOCOL_BINARY_CMD_GET_RANDOM_KEY = 392 uint8_t(cb::mcbp::ClientOpcode::GetRandomKey); 393const uint8_t PROTOCOL_BINARY_CMD_SEQNO_PERSISTENCE = 394 uint8_t(cb::mcbp::ClientOpcode::SeqnoPersistence); 395const uint8_t PROTOCOL_BINARY_CMD_GET_KEYS = 396 uint8_t(cb::mcbp::ClientOpcode::GetKeys); 397const uint8_t PROTOCOL_BINARY_CMD_COLLECTIONS_SET_MANIFEST = 398 uint8_t(cb::mcbp::ClientOpcode::CollectionsSetManifest); 399const uint8_t PROTOCOL_BINARY_CMD_COLLECTIONS_GET_MANIFEST = 400 uint8_t(cb::mcbp::ClientOpcode::CollectionsGetManifest); 401const uint8_t PROTOCOL_BINARY_CMD_SET_DRIFT_COUNTER_STATE = 402 uint8_t(cb::mcbp::ClientOpcode::SetDriftCounterState); 403const uint8_t PROTOCOL_BINARY_CMD_GET_ADJUSTED_TIME = 404 uint8_t(cb::mcbp::ClientOpcode::GetAdjustedTime); 405const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_GET = 406 uint8_t(cb::mcbp::ClientOpcode::SubdocGet); 407const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_EXISTS = 408 uint8_t(cb::mcbp::ClientOpcode::SubdocExists); 409const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD = 410 uint8_t(cb::mcbp::ClientOpcode::SubdocDictAdd); 411const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_DICT_UPSERT = 412 uint8_t(cb::mcbp::ClientOpcode::SubdocDictUpsert); 413const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_DELETE = 414 uint8_t(cb::mcbp::ClientOpcode::SubdocDelete); 415const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_REPLACE = 416 uint8_t(cb::mcbp::ClientOpcode::SubdocReplace); 417const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_LAST = 418 uint8_t(cb::mcbp::ClientOpcode::SubdocArrayPushLast); 419const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_FIRST = 420 uint8_t(cb::mcbp::ClientOpcode::SubdocArrayPushFirst); 421const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_INSERT = 422 uint8_t(cb::mcbp::ClientOpcode::SubdocArrayInsert); 423const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_ADD_UNIQUE = 424 uint8_t(cb::mcbp::ClientOpcode::SubdocArrayAddUnique); 425const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_COUNTER = 426 uint8_t(cb::mcbp::ClientOpcode::SubdocCounter); 427const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP = 428 uint8_t(cb::mcbp::ClientOpcode::SubdocMultiLookup); 429const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION = 430 uint8_t(cb::mcbp::ClientOpcode::SubdocMultiMutation); 431const uint8_t PROTOCOL_BINARY_CMD_SUBDOC_GET_COUNT = 432 uint8_t(cb::mcbp::ClientOpcode::SubdocGetCount); 433const uint8_t PROTOCOL_BINARY_CMD_SCRUB = 434 uint8_t(cb::mcbp::ClientOpcode::Scrub); 435const uint8_t PROTOCOL_BINARY_CMD_ISASL_REFRESH = 436 uint8_t(cb::mcbp::ClientOpcode::IsaslRefresh); 437const uint8_t PROTOCOL_BINARY_CMD_SSL_CERTS_REFRESH = 438 uint8_t(cb::mcbp::ClientOpcode::SslCertsRefresh); 439const uint8_t PROTOCOL_BINARY_CMD_GET_CMD_TIMER = 440 uint8_t(cb::mcbp::ClientOpcode::GetCmdTimer); 441const uint8_t PROTOCOL_BINARY_CMD_SET_CTRL_TOKEN = 442 uint8_t(cb::mcbp::ClientOpcode::SetCtrlToken); 443const uint8_t PROTOCOL_BINARY_CMD_GET_CTRL_TOKEN = 444 uint8_t(cb::mcbp::ClientOpcode::GetCtrlToken); 445const uint8_t PROTOCOL_BINARY_CMD_RBAC_REFRESH = 446 uint8_t(cb::mcbp::ClientOpcode::RbacRefresh); 447const uint8_t PROTOCOL_BINARY_CMD_ADJUST_TIMEOFDAY = 448 uint8_t(cb::mcbp::ClientOpcode::AdjustTimeofday); 449const uint8_t PROTOCOL_BINARY_CMD_EWOULDBLOCK_CTL = 450 uint8_t(cb::mcbp::ClientOpcode::EwouldblockCtl); 451const uint8_t PROTOCOL_BINARY_CMD_GET_ERROR_MAP = 452 uint8_t(cb::mcbp::ClientOpcode::GetErrorMap); 453const uint8_t PROTOCOL_BINARY_CMD_DROP_PRIVILEGE = 454 uint8_t(cb::mcbp::ClientOpcode::DropPrivilege); 455const uint8_t PROTOCOL_BINARY_CMD_INVALID = 456 uint8_t(cb::mcbp::ClientOpcode::Invalid); 457 458using protocol_binary_datatype_t = uint8_t; 459#define PROTOCOL_BINARY_RAW_BYTES uint8_t(cb::mcbp::Datatype::Raw) 460#define PROTOCOL_BINARY_DATATYPE_JSON uint8_t(cb::mcbp::Datatype::JSON) 461#define PROTOCOL_BINARY_DATATYPE_SNAPPY uint8_t(cb::mcbp::Datatype::Snappy) 462#define PROTOCOL_BINARY_DATATYPE_XATTR uint8_t(cb::mcbp::Datatype::Xattr) 463 464/* 465 * Bitmask that defines datatypes that can only be valid when a document body 466 * exists. i.e. When the document is not soft-deleted 467 */ 468#define BODY_ONLY_DATATYPE_MASK \ 469 uint8_t(PROTOCOL_BINARY_DATATYPE_JSON | PROTOCOL_BINARY_DATATYPE_SNAPPY); 470 471/* 472 * Bitmask that defines the datatypes that can be resident in memory. For 473 * example, DATATYPE_COMPRESSED is excluded as resident items are not 474 * compressed. 475 * This is useful for efficiently storing statistics about datatypes. 476 */ 477#define RESIDENT_DATATYPE_MASK uint8_t(5); 478 479 480/** 481 * Definition of the header structure for a request packet. 482 * See section 2 483 */ 484typedef union { 485 cb::mcbp::Request request; 486 uint8_t bytes[24]; 487} protocol_binary_request_header; 488 489/** 490 * Definition of the header structure for a response packet. 491 * See section 2 492 */ 493typedef union { 494 cb::mcbp::Response response; 495 uint8_t bytes[24]; 496} protocol_binary_response_header; 497 498/** 499 * Definition of a request-packet containing no extras 500 */ 501typedef union { 502 struct { 503 protocol_binary_request_header header; 504 } message; 505 uint8_t bytes[sizeof(protocol_binary_request_header)]; 506} protocol_binary_request_no_extras; 507 508/** 509 * Definition of a response-packet containing no extras 510 */ 511typedef union { 512 struct { 513 protocol_binary_response_header header; 514 } message; 515 uint8_t bytes[sizeof(protocol_binary_response_header)]; 516} protocol_binary_response_no_extras; 517 518/** 519 * Definition of the packet used by the get, getq, getk and getkq command. 520 * See section 4 521 */ 522typedef protocol_binary_request_no_extras protocol_binary_request_get; 523typedef protocol_binary_request_no_extras protocol_binary_request_getq; 524typedef protocol_binary_request_no_extras protocol_binary_request_getk; 525typedef protocol_binary_request_no_extras protocol_binary_request_getkq; 526 527/** 528 * Definition of the packet returned from a successful get, getq, getk and 529 * getkq. 530 * See section 4 531 */ 532typedef union { 533 struct { 534 protocol_binary_response_header header; 535 struct { 536 uint32_t flags; 537 } body; 538 } message; 539 uint8_t bytes[sizeof(protocol_binary_response_header) + 4]; 540} protocol_binary_response_get; 541 542typedef protocol_binary_response_get protocol_binary_response_getq; 543typedef protocol_binary_response_get protocol_binary_response_getk; 544typedef protocol_binary_response_get protocol_binary_response_getkq; 545 546/** 547 * Definition of the packet used by the delete command 548 * See section 4 549 */ 550typedef protocol_binary_request_no_extras protocol_binary_request_delete; 551 552/** 553 * Definition of the packet returned by the delete command 554 * See section 4 555 * 556 * extlen should be either zero, or 16 if the client has enabled the 557 * MUTATION_SEQNO feature, with the following format: 558 * 559 * Header: (0-23): <protocol_binary_response_header> 560 * Extras: 561 * Vbucket UUID (24-31): 0x0000000000003039 562 * Seqno (32-39): 0x000000000000002D 563 */ 564typedef protocol_binary_response_no_extras protocol_binary_response_delete; 565 566/** 567 * Definition of the packet used by the flush command 568 * See section 4 569 * Please note that the expiration field is optional, so remember to see 570 * check the header.bodysize to see if it is present. 571 */ 572typedef union { 573 struct { 574 protocol_binary_request_header header; 575 struct { 576 /* 577 * Specifying a non-null expiration time is no longer 578 * supported 579 */ 580 uint32_t expiration; 581 } body; 582 } message; 583 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 584} protocol_binary_request_flush; 585 586/** 587 * Definition of the packet returned by the flush command 588 * See section 4 589 */ 590typedef protocol_binary_response_no_extras protocol_binary_response_flush; 591 592/** 593 * Definition of the packet used by set, add and replace 594 * See section 4 595 */ 596typedef union { 597 struct { 598 protocol_binary_request_header header; 599 struct { 600 uint32_t flags; 601 uint32_t expiration; 602 } body; 603 } message; 604 uint8_t bytes[sizeof(protocol_binary_request_header) + 8]; 605} protocol_binary_request_set; 606typedef protocol_binary_request_set protocol_binary_request_add; 607typedef protocol_binary_request_set protocol_binary_request_replace; 608 609/** 610 * Definition of the packet returned by set, add and replace 611 * See section 4 612 */ 613typedef protocol_binary_response_no_extras protocol_binary_response_set; 614typedef protocol_binary_response_no_extras protocol_binary_response_add; 615typedef protocol_binary_response_no_extras protocol_binary_response_replace; 616 617/** 618 * Definition of the noop packet 619 * See section 4 620 */ 621typedef protocol_binary_request_no_extras protocol_binary_request_noop; 622 623/** 624 * Definition of the packet returned by the noop command 625 * See section 4 626 */ 627typedef protocol_binary_response_no_extras protocol_binary_response_noop; 628 629/** 630 * Definition of the structure used by the increment and decrement 631 * command. 632 * See section 4 633 */ 634typedef union { 635 struct { 636 protocol_binary_request_header header; 637 struct { 638 uint64_t delta; 639 uint64_t initial; 640 uint32_t expiration; 641 } body; 642 } message; 643 uint8_t bytes[sizeof(protocol_binary_request_header) + 20]; 644} protocol_binary_request_incr; 645typedef protocol_binary_request_incr protocol_binary_request_decr; 646 647/** 648 * Definition of the response from an incr or decr command 649 * command. 650 * 651 * The result of the incr/decr is a uint64_t placed at header + extlen. 652 * 653 * extlen should be either zero, or 16 if the client has enabled the 654 * MUTATION_SEQNO feature, with the following format: 655 * 656 * Header: (0-23): <protocol_binary_response_header> 657 * Extras: 658 * Vbucket UUID (24-31): 0x0000000000003039 659 * Seqno (32-39): 0x000000000000002D 660 * Value: (40-47): .... 661 * 662 */ 663typedef protocol_binary_response_no_extras protocol_binary_response_incr; 664typedef protocol_binary_response_no_extras protocol_binary_response_decr; 665 666/** 667 * Definition of the quit 668 * See section 4 669 */ 670typedef protocol_binary_request_no_extras protocol_binary_request_quit; 671 672/** 673 * Definition of the packet returned by the quit command 674 * See section 4 675 */ 676typedef protocol_binary_response_no_extras protocol_binary_response_quit; 677 678/** 679 * Definition of the packet used by append and prepend command 680 * See section 4 681 */ 682typedef protocol_binary_request_no_extras protocol_binary_request_append; 683typedef protocol_binary_request_no_extras protocol_binary_request_prepend; 684 685/** 686 * Definition of the packet returned from a successful append or prepend 687 * See section 4 688 */ 689typedef protocol_binary_response_no_extras protocol_binary_response_append; 690typedef protocol_binary_response_no_extras protocol_binary_response_prepend; 691 692/** 693 * Definition of the packet used by the version command 694 * See section 4 695 */ 696typedef protocol_binary_request_no_extras protocol_binary_request_version; 697 698/** 699 * Definition of the packet returned from a successful version command 700 * See section 4 701 */ 702typedef protocol_binary_response_no_extras protocol_binary_response_version; 703 704/** 705 * Definition of the packet used by the stats command. 706 * See section 4 707 */ 708typedef protocol_binary_request_no_extras protocol_binary_request_stats; 709 710/** 711 * Definition of the packet returned from a successful stats command 712 * See section 4 713 */ 714typedef protocol_binary_response_no_extras protocol_binary_response_stats; 715 716/** 717 * Definition of the packet used by the verbosity command 718 */ 719typedef union { 720 struct { 721 protocol_binary_request_header header; 722 struct { 723 uint32_t level; 724 } body; 725 } message; 726 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 727} protocol_binary_request_verbosity; 728 729/** 730 * Definition of the packet returned from the verbosity command 731 */ 732typedef protocol_binary_response_no_extras protocol_binary_response_verbosity; 733 734/** 735 * Definition of the packet used by the touch command. 736 */ 737typedef union { 738 struct { 739 protocol_binary_request_header header; 740 struct { 741 uint32_t expiration; 742 } body; 743 } message; 744 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 745} protocol_binary_request_touch; 746 747/** 748 * Definition of the packet returned from the touch command 749 */ 750typedef protocol_binary_response_no_extras protocol_binary_response_touch; 751 752/** 753 * Definition of the packet used by the GAT(Q) command. 754 */ 755typedef union { 756 struct { 757 protocol_binary_request_header header; 758 struct { 759 uint32_t expiration; 760 } body; 761 } message; 762 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 763} protocol_binary_request_gat; 764 765typedef protocol_binary_request_gat protocol_binary_request_gatq; 766 767/** 768 * Definition of the packet returned from the GAT(Q) 769 */ 770typedef protocol_binary_response_get protocol_binary_response_gat; 771typedef protocol_binary_response_get protocol_binary_response_gatq; 772 773 774/** 775 * Definitions for extended (flexible) metadata 776 * 777 * @1: Flex Code to identify the number of extended metadata fields 778 * @2: Size of the Flex Code, set to 1 byte 779 * @3: Current size of extended metadata 780 */ 781typedef enum { 782 FLEX_META_CODE = 0x01, 783 FLEX_DATA_OFFSET = 1, 784 EXT_META_LEN = 1 785} protocol_binary_flexmeta; 786 787/** 788 * Definitions of sub-document path flags (this is a bitmap) 789 */ 790typedef enum : uint8_t { 791 /** No flags set */ 792 SUBDOC_FLAG_NONE = 0x0, 793 794 /** (Mutation) Should non-existent intermediate paths be created? */ 795 SUBDOC_FLAG_MKDIR_P = 0x01, 796 797 /** 798 * 0x02 is unused 799 */ 800 801 /** 802 * If set, the path refers to an Extended Attribute (XATTR). 803 * If clear, the path refers to a path inside the document body. 804 */ 805 SUBDOC_FLAG_XATTR_PATH = 0x04, 806 807 /** 808 * 0x08 is unused 809 */ 810 811 /** 812 * Expand macro values inside extended attributes. The request is 813 * invalid if this flag is set without SUBDOC_FLAG_XATTR_PATH being 814 * set. 815 */ 816 SUBDOC_FLAG_EXPAND_MACROS = 0x10, 817 818} protocol_binary_subdoc_flag; 819 820namespace mcbp { 821namespace subdoc { 822/** 823 * Definitions of sub-document doc flags (this is a bitmap). 824 */ 825 826enum class doc_flag : uint8_t { 827 None = 0x0, 828 829 /** 830 * (Mutation) Create the document if it does not exist. Implies 831 * SUBDOC_FLAG_MKDIR_P and Set (upsert) mutation semantics. Not valid 832 * with Add. 833 */ 834 Mkdoc = 0x1, 835 836 /** 837 * (Mutation) Add the document only if it does not exist. Implies 838 * SUBDOC_FLAG_MKDIR_P. Not valid with Mkdoc. 839 */ 840 Add = 0x02, 841 842 /** 843 * Allow access to XATTRs for deleted documents (instead of 844 * returning KEY_ENOENT). 845 */ 846 AccessDeleted = 0x04, 847 848}; 849} // namespace subdoc 850} // namespace mcbp 851 852 853 854 855/** 856 * Definition of the packet used by SUBDOCUMENT single-path commands. 857 * 858 * The path, which is always required, is in the Body, after the Key. 859 * 860 * Header: 24 @0: <protocol_binary_request_header> 861 * Extras: 862 * Sub-document pathlen 2 @24: <variable> 863 * Sub-document flags 1 @26: <protocol_binary_subdoc_flag> 864 * Expiry 4 @27: (Optional) Mutations only. The 865 * ttl 866 * Sub-document doc flags 1 @27: (Optional) @31 if expiry is 867 * set. Note these are the 868 * subdocument doc flags not the 869 * flag section in the document. 870 * Body: 871 * Key keylen @27: <variable> 872 * Path pathlen @27+keylen: <variable> 873 * Value to insert/replace 874 * vallen-keylen-pathlen @27+keylen+pathlen: [variable] 875 */ 876typedef union { 877 struct { 878 protocol_binary_request_header header; 879 struct { 880 uint16_t pathlen; // Length in bytes of the sub-doc path. 881 uint8_t subdoc_flags; // See protocol_binary_subdoc_flag 882 /* uint32_t expiry (optional for mutations only - present 883 if extlen == 7 or extlen == 8) */ 884 /* uint8_t doc_flags (optional - present if extlen == 4 or 885 extlen == 8) Note these are the 886 subdocument doc flags not the flag 887 \section in the document. */ 888 } extras; 889 } message; 890 uint8_t bytes[sizeof(protocol_binary_request_header) + 3]; 891} protocol_binary_request_subdocument; 892 893/** Definition of the packet used by SUBDOCUMENT responses. 894 */ 895typedef union { 896 struct { 897 protocol_binary_response_header header; 898 } message; 899 uint8_t bytes[sizeof(protocol_binary_response_header)]; 900} protocol_binary_response_subdocument; 901 902/** 903 * Definition of the request packets used by SUBDOCUMENT multi-path commands. 904 * 905 * Multi-path sub-document commands differ from single-path in that they 906 * encode a series of multiple paths to operate on (from a single key). 907 * There are two multi-path commands - MULTI_LOOKUP and MULTI_MUTATION. 908 * - MULTI_LOOKUP consists of variable number of subdoc lookup commands 909 * (SUBDOC_GET or SUBDOC_EXISTS). 910 * - MULTI_MUTATION consists of a variable number of subdoc mutation 911 * commands (i.e. all subdoc commands apart from 912 * SUBDOC_{GET,EXISTS}). 913 * 914 * Each path to be operated on is specified by an Operation Spec, which are 915 * contained in the body. This defines the opcode, path, and value 916 * (for mutations). 917 * 918 * A maximum of MULTI_MAX_PATHS paths (operations) can be encoded in a 919 * single multi-path command. 920 * 921 * SUBDOC_MULTI_LOOKUP: 922 * Header: 24 @0: <protocol_binary_request_header> 923 * Extras: 0 or 1 @24: (optional) doc_flags. Note these are 924 * the subdocument doc flags not the flag 925 * section in the document. 926 * Body: <variable> @24: 927 * Key keylen @24: <variable> 928 * 1..MULTI_MAX_PATHS [Lookup Operation Spec] 929 * 930 * Lookup Operation Spec: 931 * 1 @0 : Opcode 932 * 1 @1 : Flags 933 * 2 @2 : Path Length 934 * pathlen @4 : Path 935 */ 936static const int PROTOCOL_BINARY_SUBDOC_MULTI_MAX_PATHS = 16; 937 938typedef struct { 939 uint8_t opcode; 940 uint8_t flags; 941 uint16_t pathlen; 942 /* uint8_t path[pathlen] */ 943} protocol_binary_subdoc_multi_lookup_spec; 944 945typedef protocol_binary_request_no_extras 946 protocol_binary_request_subdocument_multi_lookup; 947 948/* 949 * 950 * SUBDOC_MULTI_MUTATION 951 * Header: 24 @0: <protocol_binary_request_header> 952 * Extras: 0 OR 4 @24: (optional) expiration 953 * 0 OR 1 @24: (optional) doc_flags. Note these are 954 * the subdocument doc flags not the 955 * flag section in the document. 956 * Body: variable @24 + extlen: 957 * Key keylen @24: <variable> 958 * 1..MULTI_MAX_PATHS [Mutation Operation Spec] 959 * 960 * Mutation Operation Spec: 961 * 1 @0 : Opcode 962 * 1 @1 : Flags 963 * 2 @2 : Path Length 964 * 4 @4 : Value Length 965 * pathlen @8 : Path 966 * vallen @8+pathlen : Value 967 */ 968typedef struct { 969 uint8_t opcode; 970 uint8_t flags; 971 uint16_t pathlen; 972 uint32_t valuelen; 973 /* uint8_t path[pathlen] */ 974 /* uint8_t value[valuelen] */ 975} protocol_binary_subdoc_multi_mutation_spec; 976 977typedef protocol_binary_request_no_extras 978 protocol_binary_request_subdocument_multi_mutation; 979 980/** 981 * Definition of the response packets used by SUBDOCUMENT multi-path 982 * commands. 983 * 984 * SUBDOC_MULTI_LOOKUP - Body consists of a series of lookup_result structs, 985 * one per lookup_spec in the request. 986 * 987 * Lookup Result: 988 * 2 @0 : status 989 * 4 @2 : resultlen 990 * resultlen @6 : result 991 */ 992typedef struct { 993 protocol_binary_request_header header; 994 /* Variable-length 1..PROTOCOL_BINARY_SUBDOC_MULTI_MAX_PATHS */ 995 protocol_binary_subdoc_multi_lookup_spec body[1]; 996} protocol_binary_response_subdoc_multi_lookup; 997 998/** 999 * SUBDOC_MULTI_MUTATION response 1000 * 1001 * Extras is either 0 or 16 if MUTATION_SEQNO is enabled. 1002 * 1003 * Body consists of a variable number of subdoc_multi_mutation_result_spec 1004 * structs: 1005 * 1006 * On success (header.status == SUCCESS), zero or more result specs, one for 1007 * each multi_mutation_spec which wishes to return a value. 1008 * 1009 * Mutation Result (success): 1010 * [0..N] of: 1011 * 1 @0 : index - Index of multi_mutation spec this result 1012 * corresponds to. 1013 * 2 @1 : status - Status of the mutation (should always 1014 * be SUCCESS for successful multi-mutation 1015 * requests). 1016 * 4 @3 : resultlen - Result value length 1017 * resultlen @7 : Value payload 1018 * 1019 1020 * On one of more of the mutation specs failing, there is exactly one 1021 * result spec, specifying the index and status code of the first failing 1022 * mutation spec. 1023 * 1024 * Mutation Result (failure): 1025 * 1 of: 1026 * 1 @0 : index - Index of multi_mutation spec this result 1027 * corresponds to. 1028 * 2 @1 : status - Status of the mutation (should always be 1029 * !SUCCESS for failures). 1030 * 1031 * (Note: On failure the multi_mutation_result_spec only includes the 1032 * first two fields). 1033 */ 1034typedef union { 1035 struct { 1036 protocol_binary_response_header header; 1037 } message; 1038 uint8_t bytes[sizeof(protocol_binary_response_header)]; 1039} protocol_binary_response_subdoc_multi_mutation; 1040 1041/** 1042 * Definition of a request for a range operation. 1043 * See http://code.google.com/p/memcached/wiki/RangeOps 1044 * 1045 * These types are used for range operations and exist within 1046 * this header for use in other projects. Range operations are 1047 * not expected to be implemented in the memcached server itself. 1048 */ 1049typedef union { 1050 struct { 1051 protocol_binary_response_header header; 1052 struct { 1053 uint16_t size; 1054 uint8_t reserved; 1055 uint8_t flags; 1056 uint32_t max_results; 1057 } body; 1058 } message; 1059 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 1060} protocol_binary_request_rangeop; 1061 1062typedef protocol_binary_request_rangeop protocol_binary_request_rget; 1063typedef protocol_binary_request_rangeop protocol_binary_request_rset; 1064typedef protocol_binary_request_rangeop protocol_binary_request_rsetq; 1065typedef protocol_binary_request_rangeop protocol_binary_request_rappend; 1066typedef protocol_binary_request_rangeop protocol_binary_request_rappendq; 1067typedef protocol_binary_request_rangeop protocol_binary_request_rprepend; 1068typedef protocol_binary_request_rangeop protocol_binary_request_rprependq; 1069typedef protocol_binary_request_rangeop protocol_binary_request_rdelete; 1070typedef protocol_binary_request_rangeop protocol_binary_request_rdeleteq; 1071typedef protocol_binary_request_rangeop protocol_binary_request_rincr; 1072typedef protocol_binary_request_rangeop protocol_binary_request_rincrq; 1073typedef protocol_binary_request_rangeop protocol_binary_request_rdecr; 1074typedef protocol_binary_request_rangeop protocol_binary_request_rdecrq; 1075 1076/** 1077 * Definition of tap commands 1078 * See To be written 1079 * 1080 */ 1081 1082typedef union { 1083 struct { 1084 protocol_binary_request_header header; 1085 struct { 1086 /** 1087 * flags is a bitmask used to set properties for the 1088 * the connection. Please In order to be forward compatible 1089 * you should set all undefined bits to 0. 1090 * 1091 * If the bit require extra userdata, it will be stored 1092 * in the user-data field of the body (passed to the engine 1093 * as enginespeciffic). That means that when you parse the 1094 * flags and the engine-specific data, you have to work your 1095 * way from bit 0 and upwards to find the correct offset for 1096 * the data. 1097 * 1098 */ 1099 uint32_t flags; 1100 1101/** 1102 * Backfill age 1103 * 1104 * By using this flag you can limit the amount of data being 1105 * transmitted. If you don't specify a backfill age, the 1106 * server will transmit everything it contains. 1107 * 1108 * The first 8 bytes in the engine specific data contains 1109 * the oldest entry (from epoc) you're interested in. 1110 * Specifying a time in the future (for the server you are 1111 * connecting to), will cause it to start streaming current 1112 * changes. 1113 */ 1114#define TAP_CONNECT_FLAG_BACKFILL 0x01 1115/** 1116 * Dump will cause the server to send the data stored on the 1117 * server, but disconnect when the keys stored in the server 1118 * are transmitted. 1119 */ 1120#define TAP_CONNECT_FLAG_DUMP 0x02 1121/** 1122 * The body contains a list of 16 bits words in network byte 1123 * order specifying the vbucket ids to monitor. The first 16 1124 * bit word contains the number of buckets. The number of 0 1125 * means "all buckets" 1126 */ 1127#define TAP_CONNECT_FLAG_LIST_VBUCKETS 0x04 1128/** 1129 * The responsibility of the vbuckets is to be transferred 1130 * over to the caller when all items are transferred. 1131 */ 1132#define TAP_CONNECT_FLAG_TAKEOVER_VBUCKETS 0x08 1133/** 1134 * The tap consumer supports ack'ing of tap messages 1135 */ 1136#define TAP_CONNECT_SUPPORT_ACK 0x10 1137/** 1138 * The tap consumer would prefer to just get the keys 1139 * back. If the engine supports this it will set 1140 * the TAP_FLAG_NO_VALUE flag in each of the 1141 * tap packets returned. 1142 */ 1143#define TAP_CONNECT_REQUEST_KEYS_ONLY 0x20 1144/** 1145 * The body contains a list of (vbucket_id, last_checkpoint_id) 1146 * pairs. This provides the checkpoint support in TAP streams. 1147 * The last checkpoint id represents the last checkpoint that 1148 * was successfully persisted. 1149 */ 1150#define TAP_CONNECT_CHECKPOINT 0x40 1151/** 1152 * The tap consumer is a registered tap client, which means that 1153 * the tap server will maintain its checkpoint cursor permanently. 1154 */ 1155#define TAP_CONNECT_REGISTERED_CLIENT 0x80 1156 1157/** 1158 * The initial TAP implementation convert flags to/from network 1159 * byte order, but the values isn't stored in host local order 1160 * causing them to change if you mix platforms.. 1161 */ 1162#define TAP_CONNECT_TAP_FIX_FLAG_BYTEORDER 0x100 1163 1164 } body; 1165 } message; 1166 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 1167} protocol_binary_request_tap_connect; 1168 1169typedef union { 1170 struct { 1171 protocol_binary_request_header header; 1172 struct { 1173 struct { 1174 uint16_t enginespecific_length; 1175/* 1176 * The flag section support the following flags 1177 */ 1178/** 1179 * Request that the consumer send a response packet 1180 * for this packet. The opaque field must be preserved 1181 * in the response. 1182 */ 1183#define TAP_FLAG_ACK 0x01 1184/** 1185 * The value for the key is not included in the packet 1186 */ 1187#define TAP_FLAG_NO_VALUE 0x02 1188/** 1189 * The flags are in network byte order 1190 */ 1191#define TAP_FLAG_NETWORK_BYTE_ORDER 0x04 1192 1193 uint16_t flags; 1194 uint8_t ttl; 1195 uint8_t res1; 1196 uint8_t res2; 1197 uint8_t res3; 1198 } tap; 1199 struct { 1200 uint32_t flags; 1201 uint32_t expiration; 1202 } item; 1203 } body; 1204 } message; 1205 uint8_t bytes[sizeof(protocol_binary_request_header) + 16]; 1206} protocol_binary_request_tap_mutation; 1207 1208typedef union { 1209 struct { 1210 protocol_binary_request_header header; 1211 struct { 1212 struct { 1213 uint16_t enginespecific_length; 1214 /** 1215 * See the definition of the flags for 1216 * protocol_binary_request_tap_mutation for a description 1217 * of the available flags. 1218 */ 1219 uint16_t flags; 1220 uint8_t ttl; 1221 uint8_t res1; 1222 uint8_t res2; 1223 uint8_t res3; 1224 } tap; 1225 } body; 1226 } message; 1227 uint8_t bytes[sizeof(protocol_binary_request_header) + 8]; 1228} protocol_binary_request_tap_no_extras; 1229 1230typedef protocol_binary_request_tap_no_extras 1231 protocol_binary_request_tap_delete; 1232typedef protocol_binary_request_tap_no_extras protocol_binary_request_tap_flush; 1233 1234/** 1235 * TAP OPAQUE command list 1236 */ 1237#define TAP_OPAQUE_ENABLE_AUTO_NACK 0 1238#define TAP_OPAQUE_INITIAL_VBUCKET_STREAM 1 1239#define TAP_OPAQUE_ENABLE_CHECKPOINT_SYNC 2 1240#define TAP_OPAQUE_OPEN_CHECKPOINT 3 1241#define TAP_OPAQUE_COMPLETE_VB_FILTER_CHANGE 4 1242#define TAP_OPAQUE_CLOSE_TAP_STREAM 7 1243#define TAP_OPAQUE_CLOSE_BACKFILL 8 1244 1245typedef protocol_binary_request_tap_no_extras 1246 protocol_binary_request_tap_opaque; 1247typedef protocol_binary_request_tap_no_extras 1248 protocol_binary_request_tap_vbucket_set; 1249 1250/** 1251 * Definition of the packet used by the scrub. 1252 */ 1253typedef protocol_binary_request_no_extras protocol_binary_request_scrub; 1254 1255/** 1256 * Definition of the packet returned from scrub. 1257 */ 1258typedef protocol_binary_response_no_extras protocol_binary_response_scrub; 1259 1260/** 1261 * Definition of the packet used by set vbucket 1262 */ 1263typedef union { 1264 struct { 1265 protocol_binary_request_header header; 1266 struct { 1267 vbucket_state_t state; 1268 } body; 1269 } message; 1270 uint8_t bytes[sizeof(protocol_binary_request_header) + 1271 sizeof(vbucket_state_t)]; 1272} protocol_binary_request_set_vbucket; 1273/** 1274 * Definition of the packet returned from set vbucket 1275 */ 1276typedef protocol_binary_response_no_extras protocol_binary_response_set_vbucket; 1277/** 1278 * Definition of the packet used by del vbucket 1279 */ 1280typedef protocol_binary_request_no_extras protocol_binary_request_del_vbucket; 1281/** 1282 * Definition of the packet returned from del vbucket 1283 */ 1284typedef protocol_binary_response_no_extras protocol_binary_response_del_vbucket; 1285 1286/** 1287 * Definition of the packet used by get vbucket 1288 */ 1289typedef protocol_binary_request_no_extras protocol_binary_request_get_vbucket; 1290 1291/** 1292 * Definition of the packet returned from get vbucket 1293 */ 1294typedef union { 1295 struct { 1296 protocol_binary_response_header header; 1297 struct { 1298 vbucket_state_t state; 1299 } body; 1300 } message; 1301 uint8_t bytes[sizeof(protocol_binary_response_header) + 1302 sizeof(vbucket_state_t)]; 1303} protocol_binary_response_get_vbucket; 1304 1305/** 1306 * The HELLO command is used by the client and the server to agree 1307 * upon the set of features the other end supports. It is initiated 1308 * by the client by sending its agent string and the list of features 1309 * it would like to use. The server will then reply with the list 1310 * of the requested features it supports. 1311 * 1312 * ex: 1313 * Client -> HELLO [myclient 2.0] datatype, tls 1314 * Server -> HELLO SUCCESS datatype 1315 * 1316 * In this example the server responds that it allows the client to 1317 * use the datatype extension, but not the tls extension. 1318 */ 1319 1320/** 1321 * Definition of the packet requested by hello cmd. 1322 * Key: This is a client-specific identifier (not really used by 1323 * the server, except for logging the HELLO and may therefore 1324 * be used to identify the client at a later time) 1325 * Body: Contains all features supported by client. Each feature is 1326 * specified as an uint16_t in network byte order. 1327 */ 1328typedef protocol_binary_request_no_extras protocol_binary_request_hello; 1329 1330/** 1331 * Definition of the packet returned by hello cmd. 1332 * Body: Contains all features requested by the client that the 1333 * server agrees to ssupport. Each feature is 1334 * specified as an uint16_t in network byte order. 1335 */ 1336typedef protocol_binary_response_no_extras protocol_binary_response_hello; 1337 1338/** 1339 * The SET_CTRL_TOKEN command will be used by ns_server and ns_server alone 1340 * to set the session cas token in memcached which will be used to 1341 * recognize the particular instance on ns_server. The previous token will 1342 * be passed in the cas section of the request header for the CAS operation, 1343 * and the new token will be part of ext (8B). 1344 * 1345 * The response to this request will include the cas as it were set, 1346 * and a SUCCESS as status, or a KEY_EEXISTS with the existing token in 1347 * memcached if the CAS operation were to fail. 1348 */ 1349 1350/** 1351 * Definition of the request packet for SET_CTRL_TOKEN. 1352 * Body: new session_cas_token of uint64_t type. 1353 */ 1354typedef union { 1355 struct { 1356 protocol_binary_request_header header; 1357 struct { 1358 uint64_t new_cas; 1359 } body; 1360 } message; 1361 uint8_t bytes[sizeof(protocol_binary_request_header) + 8]; 1362} protocol_binary_request_set_ctrl_token; 1363 1364/** 1365 * Definition of the response packet for SET_CTRL_TOKEN 1366 */ 1367typedef protocol_binary_response_no_extras 1368 protocol_binary_response_set_ctrl_token; 1369 1370/** 1371 * The GET_CTRL_TOKEN command will be used by ns_server to fetch the current 1372 * session cas token held in memcached. 1373 * 1374 * The response to this request will include the token currently held in 1375 * memcached in the cas field of the header. 1376 */ 1377 1378/** 1379 * Definition of the request packet for GET_CTRL_TOKEN. 1380 */ 1381typedef protocol_binary_request_no_extras 1382 protocol_binary_request_get_ctrl_token; 1383 1384/** 1385 * Definition of the response packet for GET_CTRL_TOKEN 1386 */ 1387typedef protocol_binary_response_no_extras 1388 protocol_binary_response_get_ctrl_token; 1389 1390/* DCP related stuff */ 1391typedef union { 1392 struct { 1393 protocol_binary_request_header header; 1394 struct { 1395 uint32_t seqno; 1396/* 1397 * The following flags are defined 1398 */ 1399#define DCP_OPEN_PRODUCER 1 1400#define DCP_OPEN_NOTIFIER 2 1401 1402/** 1403 * Indicate that the server include the documents' XATTRs 1404 * within mutation and deletion bodies. 1405 */ 1406#define DCP_OPEN_INCLUDE_XATTRS 4 1407 1408/** 1409 * Indicate that the server should strip off the values (note, 1410 * if you add INCLUDE_XATTR those will be present) 1411 */ 1412#define DCP_OPEN_NO_VALUE 8 1413 1414/** 1415 * Indicate that the server should send collection data 1416 * and this request can also optionally include a collection 1417 * filter in the body (no filter = all data) 1418 */ 1419#define DCP_OPEN_COLLECTIONS 16 1420 1421/** 1422 * Request that DCP delete message include the time the a delete was persisted. 1423 * This only applies to deletes being backfilled from storage, in-memory deletes 1424 * will have a delete time of 0 1425 */ 1426#define DCP_OPEN_INCLUDE_DELETE_TIMES 32 1427 1428/** 1429 * Indicates that the server should strip off the values, but return the 1430 * datatype of the underlying document (note, if you add 1431 * INCLUDE_XATTR those will be present). 1432 * Note this differs from DCP_OPEN_NO_VALUE in that the datatype field will 1433 * contain the underlying datatype of the document; not the datatype of the 1434 * transmitted payload. 1435 * This flag can be used to obtain the full, original datatype for a document 1436 * without the user's value. 1437 * Not valid to specify with DCP_OPEN_NO_VALUE. 1438 */ 1439#define DCP_OPEN_NO_VALUE_WITH_UNDERLYING_DATATYPE 64 1440 1441 uint32_t flags; 1442 } body; 1443 } message; 1444 uint8_t bytes[sizeof(protocol_binary_request_header) + 8]; 1445} protocol_binary_request_dcp_open; 1446 1447typedef protocol_binary_response_no_extras protocol_binary_response_dcp_open; 1448 1449typedef union { 1450 struct { 1451 protocol_binary_request_header header; 1452 struct { 1453/* 1454 * The following flags are defined 1455 */ 1456#define DCP_ADD_STREAM_FLAG_TAKEOVER 1 1457#define DCP_ADD_STREAM_FLAG_DISKONLY 2 1458#define DCP_ADD_STREAM_FLAG_LATEST 4 1459/** 1460 * This flag is not used anymore, and should NOT be 1461 * set. It is replaced by DCP_OPEN_NO_VALUE. 1462 */ 1463#define DCP_ADD_STREAM_FLAG_NO_VALUE 8 1464/** 1465 * Indicate the server to add stream only if the vbucket 1466 * is active. 1467 * If the vbucket is not active, the stream request fails with 1468 * error ENGINE_NOT_MY_VBUCKET 1469 */ 1470#define DCP_ADD_STREAM_ACTIVE_VB_ONLY 16 1471/** 1472 * Indicate the server to check for vb_uuid match even at start_seqno 0 before 1473 * adding the stream successfully. 1474 * If the flag is set and there is a vb_uuid mismatch at start_seqno 0, then 1475 * the server returns ENGINE_ROLLBACK error. 1476 */ 1477#define DCP_ADD_STREAM_STRICT_VBUUID 32 1478 uint32_t flags; 1479 } body; 1480 } message; 1481 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 1482} protocol_binary_request_dcp_add_stream; 1483 1484typedef union { 1485 struct { 1486 protocol_binary_response_header header; 1487 struct { 1488 uint32_t opaque; 1489 } body; 1490 } message; 1491 uint8_t bytes[sizeof(protocol_binary_response_header) + 4]; 1492} protocol_binary_response_dcp_add_stream; 1493 1494typedef protocol_binary_request_no_extras 1495 protocol_binary_request_dcp_close_stream; 1496typedef protocol_binary_response_no_extras 1497 protocol_binary_response_dcp_close_stream; 1498 1499typedef union { 1500 struct { 1501 protocol_binary_request_header header; 1502 struct { 1503 uint32_t flags; 1504 uint32_t reserved; 1505 uint64_t start_seqno; 1506 uint64_t end_seqno; 1507 uint64_t vbucket_uuid; 1508 uint64_t snap_start_seqno; 1509 uint64_t snap_end_seqno; 1510 } body; 1511 /* Group ID is specified in the key */ 1512 } message; 1513 uint8_t bytes[sizeof(protocol_binary_request_header) + 48]; 1514} protocol_binary_request_dcp_stream_req; 1515 1516typedef union { 1517 struct { 1518 protocol_binary_response_header header; 1519 } message; 1520 /* 1521 ** In case of PROTOCOL_BINARY_RESPONSE_ROLLBACK the body contains 1522 ** the rollback sequence number (uint64_t) 1523 */ 1524 uint8_t bytes[sizeof(protocol_binary_request_header)]; 1525} protocol_binary_response_dcp_stream_req; 1526 1527typedef protocol_binary_request_no_extras 1528 protocol_binary_request_dcp_get_failover_log; 1529 1530/* The body of the message contains UUID/SEQNO pairs */ 1531typedef protocol_binary_response_no_extras 1532 protocol_binary_response_dcp_get_failover_log; 1533 1534typedef union { 1535 struct { 1536 protocol_binary_request_header header; 1537 struct { 1538 /** 1539 * All flags set to 0 == OK, 1540 * 1: state changed 1541 */ 1542 uint32_t flags; 1543 } body; 1544 } message; 1545 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 1546} protocol_binary_request_dcp_stream_end; 1547typedef protocol_binary_response_no_extras 1548 protocol_binary_response_dcp_stream_end; 1549 1550typedef union { 1551 struct { 1552 protocol_binary_request_header header; 1553 struct { 1554 uint64_t start_seqno; 1555 uint64_t end_seqno; 1556 uint32_t flags; 1557 } body; 1558 } message; 1559 uint8_t bytes[sizeof(protocol_binary_request_header) + 20]; 1560} protocol_binary_request_dcp_snapshot_marker; 1561 1562typedef protocol_binary_response_no_extras 1563 protocol_binary_response_dcp_snapshot_marker; 1564 1565union protocol_binary_request_dcp_mutation { 1566 protocol_binary_request_dcp_mutation(bool collectionsAware, 1567 uint32_t opaque, 1568 uint16_t vbucket, 1569 uint64_t cas, 1570 uint16_t keyLen, 1571 uint32_t valueLen, 1572 protocol_binary_datatype_t datatype, 1573 uint64_t bySeqno, 1574 uint64_t revSeqno, 1575 uint32_t flags, 1576 uint32_t expiration, 1577 uint32_t lockTime, 1578 uint16_t nmeta, 1579 uint8_t nru, 1580 uint8_t collectionLen) { 1581 auto& req = message.header.request; 1582 req.magic = (uint8_t)PROTOCOL_BINARY_REQ; 1583 req.opcode = (uint8_t)PROTOCOL_BINARY_CMD_DCP_MUTATION; 1584 req.opaque = opaque; 1585 req.vbucket = htons(vbucket); 1586 req.cas = htonll(cas); 1587 req.keylen = htons(keyLen); 1588 req.extlen = gsl::narrow<uint8_t>(getExtrasLength(collectionsAware)); 1589 req.bodylen = ntohl(req.extlen + keyLen + nmeta + valueLen); 1590 req.datatype = datatype; 1591 1592 auto& body = message.body; 1593 body.by_seqno = htonll(bySeqno); 1594 body.rev_seqno = htonll(revSeqno); 1595 body.flags = flags; 1596 body.expiration = htonl(expiration); 1597 body.lock_time = htonl(lockTime); 1598 body.nmeta = htons(nmeta); 1599 body.nru = nru; 1600 body.collection_len = collectionLen; 1601 } 1602 1603 struct { 1604 protocol_binary_request_header header; 1605 struct { 1606 uint64_t by_seqno; 1607 uint64_t rev_seqno; 1608 uint32_t flags; 1609 uint32_t expiration; 1610 uint32_t lock_time; 1611 uint16_t nmeta; 1612 uint8_t nru; 1613 uint8_t collection_len; 1614 } body; 1615 } message; 1616 uint8_t bytes[sizeof(protocol_binary_request_header) + 32]; 1617 1618 static uint8_t getExtrasLength(bool collectionAware) { 1619 if (collectionAware) { 1620 return (2 * sizeof(uint64_t)) + (3 * sizeof(uint32_t)) + 1621 sizeof(uint16_t) + (2 * sizeof(uint8_t)); 1622 } else { 1623 return (2 * sizeof(uint64_t)) + (3 * sizeof(uint32_t)) + 1624 sizeof(uint16_t) + sizeof(uint8_t); 1625 } 1626 } 1627 1628 static size_t getHeaderLength(bool collectionAware) { 1629 return sizeof(protocol_binary_request_header) + 1630 getExtrasLength(collectionAware); 1631 } 1632}; 1633 1634union protocol_binary_request_dcp_deletion { 1635 static constexpr size_t extlen = 18; 1636 protocol_binary_request_dcp_deletion(uint32_t opaque, 1637 uint16_t vbucket, 1638 uint64_t cas, 1639 uint16_t keyLen, 1640 uint32_t valueLen, 1641 protocol_binary_datatype_t datatype, 1642 uint64_t bySeqno, 1643 uint64_t revSeqno, 1644 uint16_t nmeta) { 1645 auto& req = message.header.request; 1646 req.magic = (uint8_t)PROTOCOL_BINARY_REQ; 1647 req.opcode = (uint8_t)PROTOCOL_BINARY_CMD_DCP_DELETION; 1648 req.opaque = opaque; 1649 req.vbucket = htons(vbucket); 1650 req.cas = htonll(cas); 1651 req.keylen = htons(keyLen); 1652 req.extlen = extlen; 1653 req.bodylen = ntohl(req.extlen + keyLen + nmeta + valueLen); 1654 req.datatype = datatype; 1655 1656 auto& body = message.body; 1657 body.by_seqno = htonll(bySeqno); 1658 body.rev_seqno = htonll(revSeqno); 1659 body.nmeta = htons(nmeta); 1660 } 1661 struct { 1662 protocol_binary_request_header header; 1663 struct { 1664 uint64_t by_seqno; 1665 uint64_t rev_seqno; 1666 uint16_t nmeta; 1667 } body; 1668 } message; 1669 uint8_t bytes[sizeof(protocol_binary_request_header) + extlen]; 1670}; 1671 1672union protocol_binary_request_dcp_deletion_v2 { 1673 static constexpr size_t extlen = 21; 1674 protocol_binary_request_dcp_deletion_v2(uint32_t opaque, 1675 uint16_t vbucket, 1676 uint64_t cas, 1677 uint16_t keyLen, 1678 uint32_t valueLen, 1679 protocol_binary_datatype_t datatype, 1680 uint64_t bySeqno, 1681 uint64_t revSeqno, 1682 uint32_t deleteTime, 1683 uint8_t collectionLen) { 1684 auto& req = message.header.request; 1685 req.magic = (uint8_t)PROTOCOL_BINARY_REQ; 1686 req.opcode = (uint8_t)PROTOCOL_BINARY_CMD_DCP_DELETION; 1687 req.opaque = opaque; 1688 req.vbucket = htons(vbucket); 1689 req.cas = htonll(cas); 1690 req.keylen = htons(keyLen); 1691 req.extlen = extlen; 1692 req.bodylen = ntohl(req.extlen + keyLen + valueLen); 1693 req.datatype = datatype; 1694 1695 auto& body = message.body; 1696 body.by_seqno = htonll(bySeqno); 1697 body.rev_seqno = htonll(revSeqno); 1698 body.delete_time = htonl(deleteTime); 1699 body.collection_len = collectionLen; 1700 } 1701 1702 struct { 1703 protocol_binary_request_header header; 1704 struct { 1705 uint64_t by_seqno; 1706 uint64_t rev_seqno; 1707 uint32_t delete_time; 1708 uint8_t collection_len; 1709 } body; 1710 } message; 1711 uint8_t bytes[sizeof(protocol_binary_request_header) + extlen]; 1712}; 1713 1714union protocol_binary_request_dcp_expiration { 1715 protocol_binary_request_dcp_expiration(bool collectionsAware, 1716 uint32_t opaque, 1717 uint16_t vbucket, 1718 uint64_t cas, 1719 uint16_t keyLen, 1720 uint32_t valueLen, 1721 protocol_binary_datatype_t datatype, 1722 uint64_t bySeqno, 1723 uint64_t revSeqno, 1724 uint16_t nmeta, 1725 uint8_t collectionLen) { 1726 auto& req = message.header.request; 1727 req.magic = (uint8_t)PROTOCOL_BINARY_REQ; 1728 req.opcode = (uint8_t)PROTOCOL_BINARY_CMD_DCP_EXPIRATION; 1729 req.opaque = opaque; 1730 req.vbucket = htons(vbucket); 1731 req.cas = htonll(cas); 1732 req.keylen = htons(keyLen); 1733 req.extlen = gsl::narrow<uint8_t>(getExtrasLength(collectionsAware)); 1734 req.bodylen = ntohl(req.extlen + keyLen + nmeta + valueLen); 1735 req.datatype = datatype; 1736 1737 auto& body = message.body; 1738 body.by_seqno = htonll(bySeqno); 1739 body.rev_seqno = htonll(revSeqno); 1740 body.nmeta = htons(nmeta); 1741 body.collection_len = collectionLen; 1742 } 1743 1744 struct { 1745 protocol_binary_request_header header; 1746 struct { 1747 uint64_t by_seqno; 1748 uint64_t rev_seqno; 1749 uint16_t nmeta; 1750 uint8_t collection_len; 1751 } body; 1752 } message; 1753 uint8_t bytes[sizeof(protocol_binary_request_header) + 19]; 1754 1755 static size_t getExtrasLength(bool collectionsAware) { 1756 if (collectionsAware) { 1757 return (2 * sizeof(uint64_t)) + sizeof(uint16_t) + 1758 (1 * sizeof(uint8_t)); 1759 } else { 1760 return (2 * sizeof(uint64_t)) + sizeof(uint16_t); 1761 } 1762 } 1763 1764 /** 1765 * Retrieve the size of a DCP expiration header - all the non variable 1766 * data of the packet. The size of a collectionAware DCP stream expiration 1767 * differs to that of legacy DCP streams. 1768 */ 1769 static size_t getHeaderLength(bool collectionsAware) { 1770 return sizeof(protocol_binary_request_header) + 1771 getExtrasLength(collectionsAware); 1772 } 1773}; 1774 1775typedef protocol_binary_request_no_extras protocol_binary_request_dcp_flush; 1776 1777typedef union { 1778 struct { 1779 protocol_binary_request_header header; 1780 struct { 1781 /** 1782 * 0x01 - Active 1783 * 0x02 - Replica 1784 * 0x03 - Pending 1785 * 0x04 - Dead 1786 */ 1787 uint8_t state; 1788 } body; 1789 } message; 1790 uint8_t bytes[sizeof(protocol_binary_request_header) + 1]; 1791} protocol_binary_request_dcp_set_vbucket_state; 1792typedef protocol_binary_response_no_extras 1793 protocol_binary_response_dcp_set_vbucket_state; 1794 1795typedef protocol_binary_request_no_extras protocol_binary_request_dcp_noop; 1796typedef protocol_binary_response_no_extras protocol_binary_response_dcp_noop; 1797 1798typedef union { 1799 struct { 1800 protocol_binary_request_header header; 1801 struct { 1802 uint32_t buffer_bytes; 1803 } body; 1804 } message; 1805 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 1806} protocol_binary_request_dcp_buffer_acknowledgement; 1807typedef protocol_binary_response_no_extras 1808 protocol_binary_response_dcp_buffer_acknowledgement; 1809 1810typedef protocol_binary_request_no_extras protocol_binary_request_dcp_control; 1811typedef protocol_binary_response_no_extras protocol_binary_response_dcp_control; 1812 1813/** 1814 * Events that the system may send 1815 */ 1816namespace mcbp { 1817namespace systemevent { 1818 1819enum class id : uint32_t { 1820 CreateCollection = 0, 1821 DeleteCollection = 1, 1822 CollectionsSeparatorChanged = 2 1823}; 1824 1825/** 1826 * Validate that the uint32_t represents a valid systemevent::id 1827 */ 1828static inline bool validate(uint32_t event) { 1829 switch (id(event)) { 1830 case id::CreateCollection: 1831 case id::DeleteCollection: 1832 case id::CollectionsSeparatorChanged: 1833 return true; 1834 } 1835 return false; 1836} 1837 1838} 1839} 1840 1841/** 1842 * Format for a DCP_SYSTEM_EVENT packet. Encodes a sequence number for the 1843 * event and the event's identifier. 1844 */ 1845union protocol_binary_request_dcp_system_event { 1846 protocol_binary_request_dcp_system_event(uint32_t opaque, 1847 uint16_t vbucket, 1848 uint16_t keyLen, 1849 size_t valueLen, 1850 mcbp::systemevent::id event, 1851 uint64_t bySeqno) { 1852 auto& req = message.header.request; 1853 req.magic = (uint8_t)PROTOCOL_BINARY_REQ; 1854 req.opcode = (uint8_t)PROTOCOL_BINARY_CMD_DCP_SYSTEM_EVENT; 1855 req.opaque = opaque; 1856 req.vbucket = htons(vbucket); 1857 req.keylen = htons(keyLen); 1858 req.extlen = getExtrasLength(); 1859 req.bodylen = 1860 htonl(gsl::narrow<uint32_t>(req.extlen + valueLen + keyLen)); 1861 req.datatype = PROTOCOL_BINARY_RAW_BYTES; 1862 message.body.event = htonl(uint32_t(event)); 1863 message.body.by_seqno = htonll(bySeqno); 1864 } 1865 struct { 1866 protocol_binary_request_header header; 1867 struct { 1868 uint64_t by_seqno; 1869 uint32_t event; 1870 } body; 1871 } message; 1872 uint8_t bytes[sizeof(protocol_binary_request_header) + 12]; 1873 1874 /** 1875 * @returns the extlen value that a system_event packet should encode. 1876 */ 1877 static inline uint8_t getExtrasLength() { 1878 return sizeof(uint64_t) + sizeof(uint32_t); 1879 } 1880}; 1881 1882/** 1883 * IOCTL_GET command message to get/set control parameters. 1884 */ 1885typedef protocol_binary_request_no_extras protocol_binary_request_ioctl_get; 1886typedef protocol_binary_request_no_extras protocol_binary_request_ioctl_set; 1887 1888typedef protocol_binary_request_no_extras 1889 protocol_binary_request_config_validate; 1890typedef protocol_binary_request_no_extras protocol_binary_request_config_reload; 1891 1892typedef protocol_binary_request_no_extras protocol_binary_request_ssl_refresh; 1893typedef protocol_binary_response_no_extras protocol_binary_response_ssl_refresh; 1894 1895/** 1896 * Request command timings for a bucket from memcached. Privileged 1897 * connections may specify the name of the bucket in the "key" field, 1898 * or the aggregated timings for the entire server by using the 1899 * special name <code>/all/</code>. 1900 * 1901 * The returned payload is a json document of the following format: 1902 * { "us" : [ x, x, x, x, ... ], 1903 * "ms" : [ y, y, y, ...], 1904 * "500ms" : [ z, z, z, ...], 1905 * "wayout" : nnn 1906 * } 1907 */ 1908typedef union { 1909 struct { 1910 protocol_binary_request_header header; 1911 struct { 1912 uint8_t opcode; 1913 } body; 1914 } message; 1915 uint8_t bytes[sizeof(protocol_binary_request_header) + 1]; 1916} protocol_binary_request_get_cmd_timer; 1917 1918typedef protocol_binary_response_no_extras 1919 protocol_binary_response_get_cmd_timer; 1920 1921typedef protocol_binary_request_no_extras protocol_binary_request_create_bucket; 1922typedef protocol_binary_request_no_extras protocol_binary_request_delete_bucket; 1923typedef protocol_binary_request_no_extras protocol_binary_request_list_buckets; 1924typedef protocol_binary_request_no_extras protocol_binary_request_select_bucket; 1925 1926/* 1927 * Parameter types of CMD_SET_PARAM command. 1928 */ 1929typedef enum : int { 1930 protocol_binary_engine_param_flush = 1, /* flusher-related param type */ 1931 protocol_binary_engine_param_replication, /* replication param type */ 1932 protocol_binary_engine_param_checkpoint, /* checkpoint-related param type */ 1933 protocol_binary_engine_param_dcp, /* dcp param type */ 1934 protocol_binary_engine_param_vbucket /* vbucket param type */ 1935} protocol_binary_engine_param_t; 1936 1937/** 1938 * CMD_SET_PARAM command message to set engine parameters. 1939 * flush, tap, checkpoint, dcp and vbucket parameter types are currently 1940 * supported. 1941 */ 1942typedef union { 1943 struct { 1944 protocol_binary_request_header header; 1945 struct { 1946 protocol_binary_engine_param_t param_type; 1947 } body; 1948 } message; 1949 uint8_t bytes[sizeof(protocol_binary_request_header) + 1950 sizeof(protocol_binary_engine_param_t)]; 1951} protocol_binary_request_set_param; 1952 1953typedef union { 1954 struct { 1955 protocol_binary_request_header header; 1956 struct { 1957 uint32_t size; 1958 } body; 1959 } message; 1960 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 1961} protocol_binary_request_set_batch_count; 1962 1963/** 1964 * This flag is used by the setWithMeta/addWithMeta/deleteWithMeta packets 1965 * to specify that the operation should be forced. The update will not 1966 * be subject to conflict resolution and the target vb can be active/pending or 1967 * replica. 1968 */ 1969#define FORCE_WITH_META_OP 0x01 1970 1971/** 1972 * This flag is used to indicate that the *_with_meta should be accepted 1973 * regardless of the bucket config. LWW buckets require this flag. 1974 */ 1975#define FORCE_ACCEPT_WITH_META_OPS 0x02 1976 1977/** 1978 * This flag asks that the server regenerates the CAS. The server requires 1979 * that SKIP_CONFLICT_RESOLUTION_FLAG is set along with this option. 1980 */ 1981#define REGENERATE_CAS 0x04 1982 1983/** 1984 * This flag is used by the setWithMeta/addWithMeta/deleteWithMeta packets 1985 * to specify that the conflict resolution mechanism should be skipped for 1986 * this operation. 1987 */ 1988#define SKIP_CONFLICT_RESOLUTION_FLAG 0x08 1989 1990#define SET_RET_META 1 1991#define ADD_RET_META 2 1992#define DEL_RET_META 3 1993 1994/** 1995 * This flag is used with the get meta response packet. If set it 1996 * specifies that the item recieved has been deleted, but that the 1997 * items meta data is still contained in ep-engine. Eg. the item 1998 * has been soft deleted. 1999 */ 2000#define GET_META_ITEM_DELETED_FLAG 0x01 2001 2002/** 2003 * The physical layout for the CMD_SET_WITH_META looks like the the normal 2004 * set request with the addition of a bulk of extra meta data stored 2005 * at the <b>end</b> of the package. 2006 */ 2007typedef union { 2008 struct { 2009 protocol_binary_request_header header; 2010 struct { 2011 uint32_t flags; 2012 uint32_t expiration; 2013 uint64_t seqno; 2014 uint64_t cas; 2015 } body; 2016 } message; 2017 uint8_t bytes[sizeof(protocol_binary_request_header) + 24]; 2018} protocol_binary_request_set_with_meta; 2019 2020typedef union { 2021 struct { 2022 protocol_binary_request_header header; 2023 struct { 2024 uint32_t flags; 2025 uint32_t delete_time; 2026 uint64_t seqno; 2027 uint64_t cas; 2028 } body; 2029 } message; 2030 uint8_t bytes[sizeof(protocol_binary_request_header) + 24]; 2031} protocol_binary_request_delete_with_meta; 2032 2033/** 2034 * The message format for getLocked engine API 2035 */ 2036typedef protocol_binary_request_gat protocol_binary_request_getl; 2037 2038/** 2039 * The physical layout for a CMD_GET_META command returns the meta-data 2040 * section for an item: 2041 */ 2042typedef protocol_binary_request_no_extras protocol_binary_request_get_meta; 2043 2044/** 2045 * Structure holding getMeta command response fields 2046 */ 2047#pragma pack(1) 2048 2049struct GetMetaResponse { 2050 uint32_t deleted; 2051 uint32_t flags; 2052 uint32_t expiry; 2053 uint64_t seqno; 2054 uint8_t datatype; 2055 2056 GetMetaResponse() : deleted(0), flags(0), expiry(0), seqno(0), datatype(0) { 2057 } 2058 2059 GetMetaResponse(uint32_t deleted, 2060 uint32_t flags, 2061 uint32_t expiry, 2062 uint64_t seqno, 2063 uint8_t datatype) 2064 : deleted(deleted), 2065 flags(flags), 2066 expiry(expiry), 2067 seqno(seqno), 2068 datatype(datatype) { 2069 } 2070}; 2071 2072#pragma pack() 2073 2074static_assert(sizeof(GetMetaResponse) == 21, "Incorrect compiler padding"); 2075 2076/* Meta data versions for GET_META */ 2077enum class GetMetaVersion : uint8_t { 2078 V1 = 1, // returns deleted, flags, expiry and seqno 2079 V2 = 2, // The 'spock' version returns V1 + the datatype 2080}; 2081 2082/** 2083 * The response for CMD_SET_WITH_META does not carry any user-data and the 2084 * status of the operation is signalled in the status bits. 2085 */ 2086typedef protocol_binary_response_no_extras 2087 protocol_binary_response_set_with_meta; 2088 2089typedef union { 2090 struct { 2091 protocol_binary_request_header header; 2092 struct { 2093 uint64_t file_version; 2094 uint64_t header_offset; 2095 uint32_t vbucket_state_updated; 2096 uint32_t state; 2097 uint64_t checkpoint; 2098 } body; 2099 } message; 2100 uint8_t bytes[sizeof(protocol_binary_request_header) + 32]; 2101} protocol_binary_request_notify_vbucket_update; 2102typedef protocol_binary_response_no_extras 2103 protocol_binary_response_notify_vbucket_update; 2104 2105/** 2106 * The physical layout for the CMD_RETURN_META 2107 */ 2108typedef union { 2109 struct { 2110 protocol_binary_request_header header; 2111 struct { 2112 uint32_t mutation_type; 2113 uint32_t flags; 2114 uint32_t expiration; 2115 } body; 2116 } message; 2117 uint8_t bytes[sizeof(protocol_binary_request_header) + 12]; 2118} protocol_binary_request_return_meta; 2119 2120/** 2121 * Message format for CMD_SET_CONFIG 2122 */ 2123typedef protocol_binary_request_no_extras 2124 protocol_binary_request_set_cluster_config; 2125 2126/** 2127 * Message format for CMD_GET_CONFIG 2128 */ 2129typedef protocol_binary_request_no_extras 2130 protocol_binary_request_get_cluster_config; 2131 2132/** 2133 * Message format for CMD_GET_ADJUSTED_TIME 2134 * 2135 * The PROTOCOL_BINARY_CMD_GET_ADJUSTED_TIME command will be 2136 * used by XDCR to retrieve the vbucket's latest adjusted_time 2137 * which is calculated based on the driftCounter if timeSync 2138 * has been enabled. 2139 * 2140 * Request:- 2141 * 2142 * Header: Contains a vbucket id. 2143 * 2144 * Response:- 2145 * 2146 * The response will contain the adjusted_time (type: int64_t) 2147 * as part of the body if in case of a SUCCESS, or else a NOTSUP 2148 * in case of timeSync not being enabled. 2149 * 2150 * The request packet's header will contain the vbucket_id. 2151 */ 2152typedef protocol_binary_request_no_extras 2153 protocol_binary_request_get_adjusted_time; 2154 2155/** 2156 * Message format for CMD_SET_DRIFT_COUNTER_STATE 2157 * 2158 * The PROTOCOL_BINARY_CMD_SET_DRIFT_COUNTER_STATE command will be 2159 * used by GO-XDCR to set the initial drift counter and enable/disable 2160 * the time synchronization for the vbucket. 2161 * 2162 * Request:- 2163 * 2164 * Header: Contains a vbucket id. 2165 * Extras: Contains the initial drift value which is of type int64_t and 2166 * the time sync state (0x00 for disable, 0x01 for enable), 2167 * 2168 * Response:- 2169 * 2170 * The response will return a SUCCESS after saving the settings, the 2171 * body will contain the vbucket uuid (type: uint64_t) and the vbucket 2172 * high seqno (type: int64_t). 2173 * A NOT_MY_VBUCKET (along with cluster config) is returned if the 2174 * vbucket isn't found. 2175 */ 2176typedef union { 2177 struct { 2178 protocol_binary_request_header header; 2179 struct { 2180 int64_t initial_drift; 2181 uint8_t time_sync; 2182 } body; 2183 } message; 2184 uint8_t bytes[sizeof(protocol_binary_request_header) + 9]; 2185} protocol_binary_request_set_drift_counter_state; 2186 2187/** 2188 * Message format for CMD_COMPACT_DB 2189 * 2190 * The PROTOCOL_BINARY_CMD_COMPACT_DB is used by ns_server to 2191 * issue a compaction request to ep-engine to compact the 2192 * underlying store's database files 2193 * 2194 * Request: 2195 * 2196 * Header: Contains the vbucket id. The vbucket id will be used 2197 * to identify the database file if the backend is 2198 * couchstore. If the vbucket id is set to 0xFFFF, then 2199 * the db_file_id field will be used for compaction. 2200 * Body: 2201 * - purge_before_ts: Deleted items whose expiry timestamp is less 2202 * than purge_before_ts will be purged. 2203 * - purge_before_seq: Deleted items whose sequence number is less 2204 * than purge_before_seq will be purged. 2205 * - drop_deletes: whether to purge deleted items or not. 2206 * - db_file_id : Database file id for the underlying store. 2207 * 2208 * Response: 2209 * 2210 * The response will return a SUCCESS after compaction is done 2211 * successfully and a NOT_MY_VBUCKET (along with cluster config) 2212 * if the vbucket isn't found. 2213 */ 2214typedef union { 2215 struct { 2216 protocol_binary_request_header header; 2217 struct { 2218 uint64_t purge_before_ts; 2219 uint64_t purge_before_seq; 2220 uint8_t drop_deletes; 2221 uint8_t align_pad1; 2222 uint16_t db_file_id; 2223 uint32_t align_pad3; 2224 } body; 2225 } message; 2226 uint8_t bytes[sizeof(protocol_binary_request_header) + 24]; 2227} protocol_binary_request_compact_db; 2228 2229typedef protocol_binary_request_get protocol_binary_request_get_random; 2230 2231#define OBS_STATE_NOT_PERSISTED 0x00 2232#define OBS_STATE_PERSISTED 0x01 2233#define OBS_STATE_NOT_FOUND 0x80 2234#define OBS_STATE_LOGICAL_DEL 0x81 2235 2236/** 2237 * The physical layout for the PROTOCOL_BINARY_CMD_AUDIT_PUT 2238 */ 2239typedef union { 2240 struct { 2241 protocol_binary_request_header header; 2242 struct { 2243 uint32_t id; 2244 } body; 2245 } message; 2246 uint8_t bytes[sizeof(protocol_binary_request_header) + 4]; 2247} protocol_binary_request_audit_put; 2248 2249typedef protocol_binary_response_no_extras protocol_binary_response_audit_put; 2250 2251/** 2252 * The shutdown message is sent from ns_server to memcached to tell 2253 * memcached to initiate a clean shutdown. This is a privileged 2254 * command and carries no payload, but the CAS field needs to be 2255 * set to the current session token (see GET/SET_CTRL_TOKEN) 2256 */ 2257typedef protocol_binary_request_no_extras protocol_binary_request_shutdown; 2258typedef protocol_binary_response_no_extras protocol_binary_response_shutdown; 2259 2260/** 2261 * The rbac_refresh message is sent from ns_server to memcached to tell 2262 * memcached to reload the RBAC configuration file. This is a privileged 2263 * command and carries no payload. 2264 */ 2265typedef protocol_binary_request_no_extras protocol_binary_request_rbac_refresh; 2266typedef protocol_binary_response_no_extras 2267 protocol_binary_response_rbac_refresh; 2268 2269/** 2270 * The PROTOCOL_BINARY_CMD_OBSERVE_SEQNO command is used by the 2271 * client to retrieve information about the vbucket in order to 2272 * find out if a particular mutation has been persisted or 2273 * replicated at the server side. In order to do so, the client 2274 * would pass the vbucket uuid of the vbucket that it wishes to 2275 * observe to the serve. The response would contain the last 2276 * persisted sequence number and the latest sequence number in the 2277 * vbucket. For example, if a client sends a request to observe 2278 * the vbucket 0 with uuid 12345 and if the response contains the 2279 * values <58, 65> and then the client can infer that sequence 2280 * number 56 has been persisted, 60 has only been replicated and 2281 * not been persisted yet and 68 has not been replicated yet. 2282 */ 2283 2284/** 2285 * Definition of the request packet for the observe_seqno command. 2286 * 2287 * Header: Contains the vbucket id of the vbucket that the client 2288 * wants to observe. 2289 * 2290 * Body: Contains the vbucket uuid of the vbucket that the client 2291 * wants to observe. The vbucket uuid is of type uint64_t. 2292 * 2293 */ 2294typedef union { 2295 struct { 2296 protocol_binary_request_header header; 2297 struct { 2298 uint64_t uuid; 2299 } body; 2300 } message; 2301 uint8_t bytes[sizeof(protocol_binary_request_header) + 8]; 2302} protocol_binary_request_observe_seqno; 2303 2304/** 2305 * Definition of the response packet for the observe_seqno command. 2306 * Body: Contains a tuple of the form 2307 * <format_type, vbucket id, vbucket uuid, last_persisted_seqno, 2308 * current_seqno> 2309 * 2310 * - format_type is of type uint8_t and it describes whether 2311 * the vbucket has failed over or not. 1 indicates a hard 2312 * failover, 0 indicates otherwise. 2313 * - vbucket id is of type uint16_t and it is the identifier for 2314 * the vbucket. 2315 * - vbucket uuid is of type uint64_t and it represents a UUID for 2316 * the vbucket. 2317 * - last_persisted_seqno is of type uint64_t and it is the 2318 * last sequence number that was persisted for this 2319 * vbucket. 2320 * - current_seqno is of the type uint64_t and it is the 2321 * sequence number of the latest mutation in the vbucket. 2322 * 2323 * In the case of a hard failover, the tuple is of the form 2324 * <format_type, vbucket id, vbucket uuid, last_persisted_seqno, 2325 * current_seqno, old vbucket uuid, last_received_seqno> 2326 * 2327 * - old vbucket uuid is of type uint64_t and it is the 2328 * vbucket UUID of the vbucket prior to the hard failover. 2329 * 2330 * - last_received_seqno is of type uint64_t and it is the 2331 * last received sequence number in the old vbucket uuid. 2332 * 2333 * The other fields are the same as that mentioned in the normal case. 2334 */ 2335typedef protocol_binary_response_no_extras 2336 protocol_binary_response_observe_seqno; 2337 2338/** 2339 * Definition of the request packet for the command 2340 * PROTOCOL_BINARY_CMD_GET_ALL_VB_SEQNOS 2341 * 2342 * Header: Only opcode field is used. 2343 * 2344 * Body: Contains the vbucket state for which the vb sequence numbers are 2345 * requested. 2346 * Please note that this field is optional, header.request.extlen is 2347 * checked to see if it is present. If not present, it implies request 2348 * is for all vbucket states. 2349 */ 2350typedef union { 2351 struct { 2352 protocol_binary_request_header header; 2353 struct { 2354 vbucket_state_t state; 2355 } body; 2356 } message; 2357 uint8_t bytes[sizeof(protocol_binary_request_header) + 2358 sizeof(vbucket_state_t)]; 2359} protocol_binary_request_get_all_vb_seqnos; 2360 2361/** 2362 * Definition of the payload in the PROTOCOL_BINARY_CMD_GET_ALL_VB_SEQNOS 2363 * response. 2364 * 2365 * The body contains a "list" of "vbucket id - seqno pairs" for all 2366 * active and replica buckets on the node in network byte order. 2367 * 2368 * 2369 * Byte/ 0 | 1 | 2 | 3 | 2370 * / | | | | 2371 * |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| 2372 * +---------------+---------------+---------------+---------------+ 2373 * 0| VBID | VBID | SEQNO | SEQNO | 2374 * +---------------+---------------+---------------+---------------+ 2375 * 4| SEQNO | SEQNO | SEQNO | SEQNO | 2376 * +---------------+---------------+---------------+---------------+ 2377 * 4| SEQNO | SEQNO | 2378 * +---------------+---------------+ 2379 */ 2380typedef protocol_binary_response_no_extras 2381 protocol_binary_response_get_all_vb_seqnos; 2382 2383/** 2384 * Message format for PROTOCOL_BINARY_CMD_GET_KEYS 2385 * 2386 * The extras field may contain a 32 bit integer specifying the number 2387 * of keys to fetch. If no value specified 1000 keys is transmitted. 2388 * 2389 * Key is mandatory and specifies the starting key 2390 * 2391 * Get keys is used to fetch a sequence of keys from the server starting 2392 * at the specified key. 2393 */ 2394typedef protocol_binary_request_no_extras protocol_binary_request_get_keys; 2395 2396 2397enum class TimeType : uint8_t { 2398 TimeOfDay, 2399 Uptime 2400}; 2401/** 2402 * Definition of the packet used to adjust timeofday and memcached uptime 2403 */ 2404typedef union { 2405 struct { 2406 protocol_binary_request_header header; 2407 struct { 2408 uint64_t offset; 2409 TimeType timeType; 2410 } body; 2411 } message; 2412 uint8_t bytes[sizeof(protocol_binary_request_header) + sizeof(uint64_t) + sizeof(TimeType)]; 2413} protocol_binary_adjust_time; 2414 2415/** 2416 * Definition of the packet returned by adjust_timeofday 2417 */ 2418typedef protocol_binary_response_no_extras protocol_binary_adjust_time_response; 2419 2420/** 2421 * Message format for PROTOCOL_BINARY_CMD_EWOULDBLOCK_CTL 2422 * 2423 * See engines/ewouldblock_engine for more information. 2424 */ 2425typedef union { 2426 struct { 2427 protocol_binary_request_header header; 2428 struct { 2429 uint32_t mode; // See EWB_Engine_Mode 2430 uint32_t value; 2431 uint32_t inject_error; // ENGINE_ERROR_CODE to inject. 2432 } body; 2433 } message; 2434 uint8_t bytes[sizeof(protocol_binary_request_header) + sizeof(uint32_t) + 2435 sizeof(uint32_t) + sizeof(uint32_t)]; 2436} protocol_binary_request_ewb_ctl; 2437typedef protocol_binary_response_no_extras protocol_binary_response_ewb_ctl; 2438 2439/** 2440 * Message format for PROTOCOL_BINARY_CMD_GET_ERRORMAP 2441 * 2442 * The payload (*not* specified as extras) contains a 2 byte payload 2443 * containing a 16 bit encoded version number. This version number should 2444 * indicate the highest version number of the error map the client is able 2445 * to understand. The server will return a JSON-formatted error map 2446 * which is formatted to either the version requested by the client, or 2447 * a lower version (thus, clients must be ready to parse lower version 2448 * formats). 2449 */ 2450typedef union { 2451 struct { 2452 protocol_binary_request_header header; 2453 struct { 2454 uint16_t version; 2455 } body; 2456 } message; 2457 uint8_t bytes[sizeof(protocol_binary_request_header) + 2]; 2458} protocol_binary_request_get_errmap; 2459 2460typedef protocol_binary_response_no_extras protocol_binary_response_get_errmap; 2461 2462/** 2463 * Message format for PROTOCOL_BINARY_CMD_COLLECTIONS_SET_MANIFEST 2464 * 2465 * The body contains a JSON collections manifest. 2466 * No key and no extras 2467 */ 2468typedef union { 2469 struct { 2470 protocol_binary_request_header header; 2471 } message; 2472 uint8_t bytes[sizeof(protocol_binary_request_header)]; 2473} protocol_binary_collections_set_manifest; 2474 2475typedef protocol_binary_response_no_extras 2476 protocol_binary_response_collections_set_manifest; 2477 2478/** 2479 * @} 2480 */ 2481inline protocol_binary_subdoc_flag operator|(protocol_binary_subdoc_flag a, 2482 protocol_binary_subdoc_flag b) { 2483 return protocol_binary_subdoc_flag(static_cast<uint8_t>(a) | 2484 static_cast<uint8_t>(b)); 2485} 2486 2487namespace mcbp { 2488namespace subdoc { 2489inline mcbp::subdoc::doc_flag operator|(mcbp::subdoc::doc_flag a, 2490 mcbp::subdoc::doc_flag b) { 2491 return mcbp::subdoc::doc_flag(static_cast<uint8_t>(a) | 2492 static_cast<uint8_t>(b)); 2493} 2494 2495inline mcbp::subdoc::doc_flag operator&(mcbp::subdoc::doc_flag a, 2496 mcbp::subdoc::doc_flag b) { 2497 return mcbp::subdoc::doc_flag(static_cast<uint8_t>(a) & 2498 static_cast<uint8_t>(b)); 2499} 2500 2501inline mcbp::subdoc::doc_flag operator~(mcbp::subdoc::doc_flag a) { 2502 return mcbp::subdoc::doc_flag(~static_cast<uint8_t>(a)); 2503} 2504 2505inline std::string to_string(mcbp::subdoc::doc_flag a) { 2506 switch (a) { 2507 case mcbp::subdoc::doc_flag::None: 2508 return "None"; 2509 case mcbp::subdoc::doc_flag::Mkdoc: 2510 return "Mkdoc"; 2511 case mcbp::subdoc::doc_flag::AccessDeleted: 2512 return "AccessDeleted"; 2513 case mcbp::subdoc::doc_flag::Add: 2514 return "Add"; 2515 } 2516 return std::to_string(static_cast<uint8_t>(a)); 2517} 2518 2519inline bool hasAccessDeleted(mcbp::subdoc::doc_flag a) { 2520 return (a & mcbp::subdoc::doc_flag::AccessDeleted) != 2521 mcbp::subdoc::doc_flag::None; 2522} 2523 2524inline bool hasMkdoc(mcbp::subdoc::doc_flag a) { 2525 return (a & mcbp::subdoc::doc_flag::Mkdoc) != mcbp::subdoc::doc_flag::None; 2526} 2527 2528inline bool hasAdd(mcbp::subdoc::doc_flag a) { 2529 return (a & mcbp::subdoc::doc_flag::Add) != mcbp::subdoc::doc_flag::None; 2530} 2531 2532inline bool isNone(mcbp::subdoc::doc_flag a) { 2533 return a == mcbp::subdoc::doc_flag::None; 2534} 2535inline bool impliesMkdir_p(mcbp::subdoc::doc_flag a) { 2536 return hasAdd(a) || hasMkdoc(a); 2537} 2538} // namespace subdoc 2539} // namespace mcbp 2540 2541// Create a namespace to handle the Datatypes 2542namespace mcbp { 2543namespace datatype { 2544const uint8_t highest = PROTOCOL_BINARY_DATATYPE_XATTR | 2545 PROTOCOL_BINARY_DATATYPE_SNAPPY | 2546 PROTOCOL_BINARY_DATATYPE_JSON; 2547inline bool is_raw(const protocol_binary_datatype_t datatype) { 2548 return datatype == PROTOCOL_BINARY_RAW_BYTES; 2549} 2550 2551inline bool is_json(const protocol_binary_datatype_t datatype) { 2552 return (datatype & PROTOCOL_BINARY_DATATYPE_JSON) == 2553 PROTOCOL_BINARY_DATATYPE_JSON; 2554} 2555 2556inline bool is_snappy(const protocol_binary_datatype_t datatype) { 2557 return (datatype & PROTOCOL_BINARY_DATATYPE_SNAPPY) == 2558 PROTOCOL_BINARY_DATATYPE_SNAPPY; 2559} 2560 2561inline bool is_xattr(const protocol_binary_datatype_t datatype) { 2562 return (datatype & PROTOCOL_BINARY_DATATYPE_XATTR) == 2563 PROTOCOL_BINARY_DATATYPE_XATTR; 2564} 2565 2566inline bool is_valid(const protocol_binary_datatype_t datatype) { 2567 return datatype <= highest; 2568} 2569 2570inline std::string to_string(const protocol_binary_datatype_t datatype) { 2571 if (is_valid(datatype)) { 2572 if (is_raw(datatype)) { 2573 return std::string{"raw"}; 2574 } else { 2575 std::stringstream ss; 2576 if (is_snappy(datatype)) { 2577 ss << "snappy,"; 2578 } 2579 if (is_json(datatype)) { 2580 ss << "json,"; 2581 } 2582 if (is_xattr(datatype)) { 2583 ss << "xattr,"; 2584 } 2585 2586 // remove the last ',' 2587 std::string ret = ss.str(); 2588 ret.resize(ret.size() - 1); 2589 return ret; 2590 } 2591 } else { 2592 return std::string{"invalid"}; 2593 } 2594} 2595} // namespace datatype 2596} // namespace mcbp 2597 2598namespace mcbp { 2599 2600namespace cas { 2601/** 2602 * The special value used as a wildcard and match all CAS values 2603 */ 2604const uint64_t Wildcard = 0x0; 2605} // namespace cas 2606} // namespace mcbp 2607