You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
11 KiB

  1. // Package gomemcached is binary protocol packet formats and constants.
  2. package gomemcached
  3. import (
  4. "fmt"
  5. )
  6. const (
  7. REQ_MAGIC = 0x80
  8. RES_MAGIC = 0x81
  9. )
  10. // CommandCode for memcached packets.
  11. type CommandCode uint8
  12. const (
  13. GET = CommandCode(0x00)
  14. SET = CommandCode(0x01)
  15. ADD = CommandCode(0x02)
  16. REPLACE = CommandCode(0x03)
  17. DELETE = CommandCode(0x04)
  18. INCREMENT = CommandCode(0x05)
  19. DECREMENT = CommandCode(0x06)
  20. QUIT = CommandCode(0x07)
  21. FLUSH = CommandCode(0x08)
  22. GETQ = CommandCode(0x09)
  23. NOOP = CommandCode(0x0a)
  24. VERSION = CommandCode(0x0b)
  25. GETK = CommandCode(0x0c)
  26. GETKQ = CommandCode(0x0d)
  27. APPEND = CommandCode(0x0e)
  28. PREPEND = CommandCode(0x0f)
  29. STAT = CommandCode(0x10)
  30. SETQ = CommandCode(0x11)
  31. ADDQ = CommandCode(0x12)
  32. REPLACEQ = CommandCode(0x13)
  33. DELETEQ = CommandCode(0x14)
  34. INCREMENTQ = CommandCode(0x15)
  35. DECREMENTQ = CommandCode(0x16)
  36. QUITQ = CommandCode(0x17)
  37. FLUSHQ = CommandCode(0x18)
  38. APPENDQ = CommandCode(0x19)
  39. AUDIT = CommandCode(0x27)
  40. PREPENDQ = CommandCode(0x1a)
  41. GAT = CommandCode(0x1d)
  42. HELLO = CommandCode(0x1f)
  43. RGET = CommandCode(0x30)
  44. RSET = CommandCode(0x31)
  45. RSETQ = CommandCode(0x32)
  46. RAPPEND = CommandCode(0x33)
  47. RAPPENDQ = CommandCode(0x34)
  48. RPREPEND = CommandCode(0x35)
  49. RPREPENDQ = CommandCode(0x36)
  50. RDELETE = CommandCode(0x37)
  51. RDELETEQ = CommandCode(0x38)
  52. RINCR = CommandCode(0x39)
  53. RINCRQ = CommandCode(0x3a)
  54. RDECR = CommandCode(0x3b)
  55. RDECRQ = CommandCode(0x3c)
  56. SASL_LIST_MECHS = CommandCode(0x20)
  57. SASL_AUTH = CommandCode(0x21)
  58. SASL_STEP = CommandCode(0x22)
  59. SET_VBUCKET = CommandCode(0x3d)
  60. TAP_CONNECT = CommandCode(0x40) // Client-sent request to initiate Tap feed
  61. TAP_MUTATION = CommandCode(0x41) // Notification of a SET/ADD/REPLACE/etc. on the server
  62. TAP_DELETE = CommandCode(0x42) // Notification of a DELETE on the server
  63. TAP_FLUSH = CommandCode(0x43) // Replicates a flush_all command
  64. TAP_OPAQUE = CommandCode(0x44) // Opaque control data from the engine
  65. TAP_VBUCKET_SET = CommandCode(0x45) // Sets state of vbucket in receiver (used in takeover)
  66. TAP_CHECKPOINT_START = CommandCode(0x46) // Notifies start of new checkpoint
  67. TAP_CHECKPOINT_END = CommandCode(0x47) // Notifies end of checkpoint
  68. UPR_OPEN = CommandCode(0x50) // Open a UPR connection with a name
  69. UPR_ADDSTREAM = CommandCode(0x51) // Sent by ebucketMigrator to UPR Consumer
  70. UPR_CLOSESTREAM = CommandCode(0x52) // Sent by eBucketMigrator to UPR Consumer
  71. UPR_FAILOVERLOG = CommandCode(0x54) // Request failover logs
  72. UPR_STREAMREQ = CommandCode(0x53) // Stream request from consumer to producer
  73. UPR_STREAMEND = CommandCode(0x55) // Sent by producer when it has no more messages to stream
  74. UPR_SNAPSHOT = CommandCode(0x56) // Start of a new snapshot
  75. UPR_MUTATION = CommandCode(0x57) // Key mutation
  76. UPR_DELETION = CommandCode(0x58) // Key deletion
  77. UPR_EXPIRATION = CommandCode(0x59) // Key expiration
  78. UPR_FLUSH = CommandCode(0x5a) // Delete all the data for a vbucket
  79. UPR_NOOP = CommandCode(0x5c) // UPR NOOP
  80. UPR_BUFFERACK = CommandCode(0x5d) // UPR Buffer Acknowledgement
  81. UPR_CONTROL = CommandCode(0x5e) // Set flow control params
  82. SELECT_BUCKET = CommandCode(0x89) // Select bucket
  83. OBSERVE_SEQNO = CommandCode(0x91) // Sequence Number based Observe
  84. OBSERVE = CommandCode(0x92)
  85. GET_META = CommandCode(0xA0) // Get meta. returns with expiry, flags, cas etc
  86. GET_COLLECTIONS_MANIFEST = CommandCode(0xba) // Get entire collections manifest.
  87. COLLECTIONS_GET_CID = CommandCode(0xbb) // Get collection id.
  88. SUBDOC_GET = CommandCode(0xc5) // Get subdoc. Returns with xattrs
  89. SUBDOC_MULTI_LOOKUP = CommandCode(0xd0) // Multi lookup. Doc xattrs and meta.
  90. )
  91. // command codes that are counted toward DCP control buffer
  92. // when DCP clients receive DCP messages with these command codes, they need to provide acknowledgement
  93. var BufferedCommandCodeMap = map[CommandCode]bool{
  94. SET_VBUCKET: true,
  95. UPR_STREAMEND: true,
  96. UPR_SNAPSHOT: true,
  97. UPR_MUTATION: true,
  98. UPR_DELETION: true,
  99. UPR_EXPIRATION: true}
  100. // Status field for memcached response.
  101. type Status uint16
  102. // Matches with protocol_binary.h as source of truth
  103. const (
  104. SUCCESS = Status(0x00)
  105. KEY_ENOENT = Status(0x01)
  106. KEY_EEXISTS = Status(0x02)
  107. E2BIG = Status(0x03)
  108. EINVAL = Status(0x04)
  109. NOT_STORED = Status(0x05)
  110. DELTA_BADVAL = Status(0x06)
  111. NOT_MY_VBUCKET = Status(0x07)
  112. NO_BUCKET = Status(0x08)
  113. LOCKED = Status(0x09)
  114. AUTH_STALE = Status(0x1f)
  115. AUTH_ERROR = Status(0x20)
  116. AUTH_CONTINUE = Status(0x21)
  117. ERANGE = Status(0x22)
  118. ROLLBACK = Status(0x23)
  119. EACCESS = Status(0x24)
  120. NOT_INITIALIZED = Status(0x25)
  121. UNKNOWN_COMMAND = Status(0x81)
  122. ENOMEM = Status(0x82)
  123. NOT_SUPPORTED = Status(0x83)
  124. EINTERNAL = Status(0x84)
  125. EBUSY = Status(0x85)
  126. TMPFAIL = Status(0x86)
  127. UNKNOWN_COLLECTION = Status(0x88)
  128. SYNC_WRITE_IN_PROGRESS = Status(0xa2)
  129. SYNC_WRITE_AMBIGUOUS = Status(0xa3)
  130. // SUBDOC
  131. SUBDOC_PATH_NOT_FOUND = Status(0xc0)
  132. SUBDOC_BAD_MULTI = Status(0xcc)
  133. SUBDOC_MULTI_PATH_FAILURE_DELETED = Status(0xd3)
  134. )
  135. // for log redaction
  136. const (
  137. UdTagBegin = "<ud>"
  138. UdTagEnd = "</ud>"
  139. )
  140. var isFatal = map[Status]bool{
  141. DELTA_BADVAL: true,
  142. NO_BUCKET: true,
  143. AUTH_STALE: true,
  144. AUTH_ERROR: true,
  145. ERANGE: true,
  146. ROLLBACK: true,
  147. EACCESS: true,
  148. ENOMEM: true,
  149. NOT_SUPPORTED: true,
  150. }
  151. // the producer/consumer bit in dcp flags
  152. var DCP_PRODUCER uint32 = 0x01
  153. // the include XATTRS bit in dcp flags
  154. var DCP_OPEN_INCLUDE_XATTRS uint32 = 0x04
  155. // the include deletion time bit in dcp flags
  156. var DCP_OPEN_INCLUDE_DELETE_TIMES uint32 = 0x20
  157. // Datatype to Include XATTRS in SUBDOC GET
  158. var SUBDOC_FLAG_XATTR uint8 = 0x04
  159. // MCItem is an internal representation of an item.
  160. type MCItem struct {
  161. Cas uint64
  162. Flags, Expiration uint32
  163. Data []byte
  164. }
  165. // Number of bytes in a binary protocol header.
  166. const HDR_LEN = 24
  167. // Mapping of CommandCode -> name of command (not exhaustive)
  168. var CommandNames map[CommandCode]string
  169. // StatusNames human readable names for memcached response.
  170. var StatusNames map[Status]string
  171. func init() {
  172. CommandNames = make(map[CommandCode]string)
  173. CommandNames[GET] = "GET"
  174. CommandNames[SET] = "SET"
  175. CommandNames[ADD] = "ADD"
  176. CommandNames[REPLACE] = "REPLACE"
  177. CommandNames[DELETE] = "DELETE"
  178. CommandNames[INCREMENT] = "INCREMENT"
  179. CommandNames[DECREMENT] = "DECREMENT"
  180. CommandNames[QUIT] = "QUIT"
  181. CommandNames[FLUSH] = "FLUSH"
  182. CommandNames[GETQ] = "GETQ"
  183. CommandNames[NOOP] = "NOOP"
  184. CommandNames[VERSION] = "VERSION"
  185. CommandNames[GETK] = "GETK"
  186. CommandNames[GETKQ] = "GETKQ"
  187. CommandNames[APPEND] = "APPEND"
  188. CommandNames[PREPEND] = "PREPEND"
  189. CommandNames[STAT] = "STAT"
  190. CommandNames[SETQ] = "SETQ"
  191. CommandNames[ADDQ] = "ADDQ"
  192. CommandNames[REPLACEQ] = "REPLACEQ"
  193. CommandNames[DELETEQ] = "DELETEQ"
  194. CommandNames[INCREMENTQ] = "INCREMENTQ"
  195. CommandNames[DECREMENTQ] = "DECREMENTQ"
  196. CommandNames[QUITQ] = "QUITQ"
  197. CommandNames[FLUSHQ] = "FLUSHQ"
  198. CommandNames[APPENDQ] = "APPENDQ"
  199. CommandNames[PREPENDQ] = "PREPENDQ"
  200. CommandNames[RGET] = "RGET"
  201. CommandNames[RSET] = "RSET"
  202. CommandNames[RSETQ] = "RSETQ"
  203. CommandNames[RAPPEND] = "RAPPEND"
  204. CommandNames[RAPPENDQ] = "RAPPENDQ"
  205. CommandNames[RPREPEND] = "RPREPEND"
  206. CommandNames[RPREPENDQ] = "RPREPENDQ"
  207. CommandNames[RDELETE] = "RDELETE"
  208. CommandNames[RDELETEQ] = "RDELETEQ"
  209. CommandNames[RINCR] = "RINCR"
  210. CommandNames[RINCRQ] = "RINCRQ"
  211. CommandNames[RDECR] = "RDECR"
  212. CommandNames[RDECRQ] = "RDECRQ"
  213. CommandNames[SASL_LIST_MECHS] = "SASL_LIST_MECHS"
  214. CommandNames[SASL_AUTH] = "SASL_AUTH"
  215. CommandNames[SASL_STEP] = "SASL_STEP"
  216. CommandNames[TAP_CONNECT] = "TAP_CONNECT"
  217. CommandNames[TAP_MUTATION] = "TAP_MUTATION"
  218. CommandNames[TAP_DELETE] = "TAP_DELETE"
  219. CommandNames[TAP_FLUSH] = "TAP_FLUSH"
  220. CommandNames[TAP_OPAQUE] = "TAP_OPAQUE"
  221. CommandNames[TAP_VBUCKET_SET] = "TAP_VBUCKET_SET"
  222. CommandNames[TAP_CHECKPOINT_START] = "TAP_CHECKPOINT_START"
  223. CommandNames[TAP_CHECKPOINT_END] = "TAP_CHECKPOINT_END"
  224. CommandNames[UPR_OPEN] = "UPR_OPEN"
  225. CommandNames[UPR_ADDSTREAM] = "UPR_ADDSTREAM"
  226. CommandNames[UPR_CLOSESTREAM] = "UPR_CLOSESTREAM"
  227. CommandNames[UPR_FAILOVERLOG] = "UPR_FAILOVERLOG"
  228. CommandNames[UPR_STREAMREQ] = "UPR_STREAMREQ"
  229. CommandNames[UPR_STREAMEND] = "UPR_STREAMEND"
  230. CommandNames[UPR_SNAPSHOT] = "UPR_SNAPSHOT"
  231. CommandNames[UPR_MUTATION] = "UPR_MUTATION"
  232. CommandNames[UPR_DELETION] = "UPR_DELETION"
  233. CommandNames[UPR_EXPIRATION] = "UPR_EXPIRATION"
  234. CommandNames[UPR_FLUSH] = "UPR_FLUSH"
  235. CommandNames[UPR_NOOP] = "UPR_NOOP"
  236. CommandNames[UPR_BUFFERACK] = "UPR_BUFFERACK"
  237. CommandNames[UPR_CONTROL] = "UPR_CONTROL"
  238. CommandNames[SUBDOC_GET] = "SUBDOC_GET"
  239. CommandNames[SUBDOC_MULTI_LOOKUP] = "SUBDOC_MULTI_LOOKUP"
  240. CommandNames[GET_COLLECTIONS_MANIFEST] = "GET_COLLECTIONS_MANIFEST"
  241. CommandNames[COLLECTIONS_GET_CID] = "COLLECTIONS_GET_CID"
  242. StatusNames = make(map[Status]string)
  243. StatusNames[SUCCESS] = "SUCCESS"
  244. StatusNames[KEY_ENOENT] = "KEY_ENOENT"
  245. StatusNames[KEY_EEXISTS] = "KEY_EEXISTS"
  246. StatusNames[E2BIG] = "E2BIG"
  247. StatusNames[EINVAL] = "EINVAL"
  248. StatusNames[NOT_STORED] = "NOT_STORED"
  249. StatusNames[DELTA_BADVAL] = "DELTA_BADVAL"
  250. StatusNames[NOT_MY_VBUCKET] = "NOT_MY_VBUCKET"
  251. StatusNames[NO_BUCKET] = "NO_BUCKET"
  252. StatusNames[AUTH_STALE] = "AUTH_STALE"
  253. StatusNames[AUTH_ERROR] = "AUTH_ERROR"
  254. StatusNames[AUTH_CONTINUE] = "AUTH_CONTINUE"
  255. StatusNames[ERANGE] = "ERANGE"
  256. StatusNames[ROLLBACK] = "ROLLBACK"
  257. StatusNames[EACCESS] = "EACCESS"
  258. StatusNames[NOT_INITIALIZED] = "NOT_INITIALIZED"
  259. StatusNames[UNKNOWN_COMMAND] = "UNKNOWN_COMMAND"
  260. StatusNames[ENOMEM] = "ENOMEM"
  261. StatusNames[NOT_SUPPORTED] = "NOT_SUPPORTED"
  262. StatusNames[EINTERNAL] = "EINTERNAL"
  263. StatusNames[EBUSY] = "EBUSY"
  264. StatusNames[TMPFAIL] = "TMPFAIL"
  265. StatusNames[UNKNOWN_COLLECTION] = "UNKNOWN_COLLECTION"
  266. StatusNames[SUBDOC_PATH_NOT_FOUND] = "SUBDOC_PATH_NOT_FOUND"
  267. StatusNames[SUBDOC_BAD_MULTI] = "SUBDOC_BAD_MULTI"
  268. }
  269. // String an op code.
  270. func (o CommandCode) String() (rv string) {
  271. rv = CommandNames[o]
  272. if rv == "" {
  273. rv = fmt.Sprintf("0x%02x", int(o))
  274. }
  275. return rv
  276. }
  277. // String an op code.
  278. func (s Status) String() (rv string) {
  279. rv = StatusNames[s]
  280. if rv == "" {
  281. rv = fmt.Sprintf("0x%02x", int(s))
  282. }
  283. return rv
  284. }
  285. // IsQuiet will return true if a command is a "quiet" command.
  286. func (o CommandCode) IsQuiet() bool {
  287. switch o {
  288. case GETQ,
  289. GETKQ,
  290. SETQ,
  291. ADDQ,
  292. REPLACEQ,
  293. DELETEQ,
  294. INCREMENTQ,
  295. DECREMENTQ,
  296. QUITQ,
  297. FLUSHQ,
  298. APPENDQ,
  299. PREPENDQ,
  300. RSETQ,
  301. RAPPENDQ,
  302. RPREPENDQ,
  303. RDELETEQ,
  304. RINCRQ,
  305. RDECRQ:
  306. return true
  307. }
  308. return false
  309. }