summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-09-01 13:57:59 -0700
committerdormando <dormando@rydia.net>2022-09-02 23:07:58 -0700
commitd855e7ed9394d3c8ed110f22694930a22894de10 (patch)
treeac18cb783d67b88eadd3aa11246ca2cfc123d473 /vendor
parent597645db6a2b138710f01ffe5e92e453117b987a (diff)
downloadmemcached-d855e7ed9394d3c8ed110f22694930a22894de10.tar.gz
proxy: update mcmc and calling conventions
upstream fixes: mcmc would return OK to garbage responses, which was probably causing issues in the past. This does remove the MCMC_CODE_MISS and replace it with MCMC_CODE_END.
Diffstat (limited to 'vendor')
-rw-r--r--vendor/mcmc/example.c4
-rw-r--r--vendor/mcmc/mcmc.c65
-rw-r--r--vendor/mcmc/mcmc.h16
3 files changed, 40 insertions, 45 deletions
diff --git a/vendor/mcmc/example.c b/vendor/mcmc/example.c
index 4631053..7a93f61 100644
--- a/vendor/mcmc/example.c
+++ b/vendor/mcmc/example.c
@@ -24,9 +24,9 @@ static void show_response_buffer(void *c, char *rbuf, size_t bufsize) {
// need to know how far to advance the buffer.
// resp->reslen + resp->vlen_read works, but feels awkward.
status = mcmc_parse_buf(c, rbuf, bread, &resp);
- } while (status == MCMC_WANT_READ);
+ } while (resp.code == MCMC_WANT_READ);
- if (status != MCMC_OK) {
+ if (status == MCMC_ERR) {
printf("bad response\n");
}
diff --git a/vendor/mcmc/mcmc.c b/vendor/mcmc/mcmc.c
index 89a2753..ff400b6 100644
--- a/vendor/mcmc/mcmc.c
+++ b/vendor/mcmc/mcmc.c
@@ -1,15 +1,15 @@
#include <stdlib.h>
-#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/uio.h>
+#include <sys/types.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
-#include <stdint.h>
#include <errno.h>
#include <stdio.h>
+// TODO: move these structs into mcmc.h, but only expose them if
+// MCMC_EXPOSE_INTERNALS is defined... for tests and this thing.
#include "mcmc.h"
// TODO: if there's a parse error or unknown status code, we likely have a
@@ -24,8 +24,6 @@
// at least doubled for wiggle room.
#define MIN_BUFFER_SIZE 2048
-#define FLAG_BUF_IS_ERROR 0x1
-#define FLAG_BUF_IS_NUMERIC 0x2
#define FLAG_BUF_WANTED_READ 0x4
#define STATE_DEFAULT 0 // looking for any kind of response
@@ -62,9 +60,7 @@ static int _mcmc_parse_value_line(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
int keylen;
p = memchr(p, ' ', l - 6);
if (p == NULL) {
- // FIXME: these should return MCMC_ERR and set the internal parse
- // error code.
- return MCMC_PARSE_ERROR;
+ return -MCMC_ERR_VALUE;
}
keylen = p - key;
@@ -76,14 +72,14 @@ static int _mcmc_parse_value_line(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
errno = 0;
uint32_t flags = strtoul(p, &n, 10);
if ((errno == ERANGE) || (p == n) || (*n != ' ')) {
- return MCMC_PARSE_ERROR;
+ return -MCMC_ERR_VALUE;
}
p = n;
errno = 0;
uint32_t bytes = strtoul(p, &n, 10);
if ((errno == ERANGE) || (p == n)) {
- return MCMC_PARSE_ERROR;
+ return -MCMC_ERR_VALUE;
}
p = n;
@@ -93,7 +89,7 @@ static int _mcmc_parse_value_line(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
errno = 0;
cas = strtoull(p, &n, 10);
if ((errno == ERANGE) || (p == n)) {
- return MCMC_PARSE_ERROR;
+ return -MCMC_ERR_VALUE;
}
}
@@ -116,7 +112,7 @@ static int _mcmc_parse_value_line(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
// NOTE: if value_offset < buffer_used, has part of the value in the
// buffer already.
- return MCMC_OK;
+ return MCMC_CODE_OK;
}
// FIXME: This is broken for ASCII multiget.
@@ -147,18 +143,17 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
if (buf[0] >= '0' && buf[0] <= '9') {
// TODO: parse it as a number on request.
// TODO: validate whole thing as digits here?
- ctx->status_flags |= FLAG_BUF_IS_NUMERIC;
r->type = MCMC_RESP_NUMERIC;
+ r->code = MCMC_CODE_OK;
return MCMC_OK;
}
if (rlen < 2) {
- ctx->error = MCMC_PARSE_ERROR_SHORT;
+ r->code = MCMC_ERR_SHORT;
return MCMC_ERR;
}
- int rv = MCMC_OK;
- int code = MCMC_CODE_OK;
+ int code = MCMC_ERR;
switch (rlen) {
case 2:
// meta, "OK"
@@ -173,8 +168,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
switch (buf[0]) {
case 'E':
if (buf[1] == 'N') {
- code = MCMC_CODE_MISS;
- // TODO: RESP type
+ code = MCMC_CODE_END;
} else if (buf[1] == 'X') {
code = MCMC_CODE_EXISTS;
}
@@ -194,7 +188,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
// TODO: this just gets returned as an rline?
// specific code? specific type?
// ME <key> <key=value debug line>
- rv = MCMC_OK;
+ code = MCMC_CODE_OK;
}
break;
case 'N':
@@ -208,6 +202,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
if (buf[1] == 'K') {
// Used by many random management commands
r->type = MCMC_RESP_GENERIC;
+ code = MCMC_CODE_OK;
}
break;
case 'V':
@@ -218,7 +213,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
char *n = NULL;
uint32_t vsize = strtoul(cur, &n, 10);
if ((errno == ERANGE) || (cur == n)) {
- rv = MCMC_ERR;
+ code = -MCMC_ERR_PARSE;
} else {
r->vlen = vsize + 2; // tag in the \r\n.
// FIXME: macro.
@@ -232,9 +227,10 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
if (*cur != ' ') {
more = 0;
}
+ code = MCMC_CODE_OK;
}
} else {
- rv = MCMC_ERR;
+ code = -MCMC_ERR_PARSE;
}
}
break;
@@ -253,10 +249,8 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
if (memcmp(buf, "END", 3) == 0) {
// Either end of STAT results, or end of ascii GET key list.
ctx->state = STATE_DEFAULT;
- // FIXME: caller needs to understand if this is a real miss.
- code = MCMC_CODE_MISS;
+ code = MCMC_CODE_END;
r->type = MCMC_RESP_END;
- rv = MCMC_OK;
}
break;
case 4:
@@ -270,9 +264,9 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
if (memcmp(buf, "VALUE", 5) == 0) {
if (more) {
// <key> <flags> <bytes> [<cas unique>]
- rv = _mcmc_parse_value_line(ctx, r);
+ code = _mcmc_parse_value_line(ctx, r);
} else {
- rv = MCMC_ERR; // FIXME: parse error.
+ code = -MCMC_ERR_PARSE;
}
}
break;
@@ -310,14 +304,13 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) {
break;
}
- r->code = code;
- if (rv == -1) {
- // TODO: Finish this.
- ctx->status_flags |= FLAG_BUF_IS_ERROR;
- rv = MCMC_ERR;
+ if (code < MCMC_OK) {
+ r->code = -code;
+ return MCMC_ERR;
+ } else {
+ r->code = code;
+ return MCMC_OK;
}
-
- return rv;
}
// EXTERNAL API
@@ -348,13 +341,13 @@ int mcmc_parse_buf(void *c, char *buf, size_t read, mcmc_resp_t *r) {
mcmc_ctx_t *ctx = c;
char *el;
+ memset(r, 0, sizeof(*r));
el = memchr(buf, '\n', read);
if (el == NULL) {
- return MCMC_WANT_READ;
+ r->code = MCMC_WANT_READ;
+ return MCMC_ERR;
}
- memset(r, 0, sizeof(*r));
-
// Consume through the newline, note where the value would start if exists
r->value = el+1;
diff --git a/vendor/mcmc/mcmc.h b/vendor/mcmc/mcmc.h
index 19e4ce4..50cadf3 100644
--- a/vendor/mcmc/mcmc.h
+++ b/vendor/mcmc/mcmc.h
@@ -1,6 +1,9 @@
#ifndef MCMC_HEADER
#define MCMC_HEADER
+#include <sys/uio.h>
+#include <stdint.h>
+
#define MCMC_OK 0
#define MCMC_ERR -1
#define MCMC_NOT_CONNECTED 1
@@ -8,7 +11,6 @@
#define MCMC_CONNECTING 3 // nonblock mode.
#define MCMC_WANT_WRITE 4
#define MCMC_WANT_READ 5
-#define MCMC_HAS_RESULT 7
// TODO: either internally set a flag for "ok" or "not ok" and use a func,
// or use a bitflag here (1<<6) for "OK", (1<<5) for "FAIL", etc.
// or, we directly return "OK" or "FAIL" and you can ask for specific error.
@@ -21,10 +23,10 @@
#define MCMC_CODE_NOT_STORED 14
#define MCMC_CODE_OK 15
#define MCMC_CODE_NOP 16
-#define MCMC_PARSE_ERROR_SHORT 17
-#define MCMC_PARSE_ERROR 18
-#define MCMC_CODE_MISS 19 // FIXME
-
+#define MCMC_CODE_END 17
+#define MCMC_ERR_SHORT 18
+#define MCMC_ERR_PARSE 19
+#define MCMC_ERR_VALUE 20
// response types
#define MCMC_RESP_GET 100
@@ -45,8 +47,8 @@
#define MCMC_ERROR_MSG_MAX 512
typedef struct {
- unsigned short type;
- unsigned short code;
+ short type;
+ short code;
char *value; // pointer to start of value in buffer.
size_t reslen; // full length of the response line
size_t vlen_read; // amount of value that was in supplied buffer.