diff options
author | dormando <dormando@rydia.net> | 2023-03-09 21:42:25 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2023-03-26 16:48:37 -0700 |
commit | 5910b652428ac96dc6d9917d4bc73d8d400ab0f3 (patch) | |
tree | 0797e6bb8b048d03f88cf21d817c7ff317fcf206 | |
parent | db0e5b33b0d1043bb51346e7d7cf9bd317a64921 (diff) | |
download | memcached-5910b652428ac96dc6d9917d4bc73d8d400ab0f3.tar.gz |
mcmc: upstream updates
-rw-r--r-- | vendor/mcmc/mcmc.c | 49 | ||||
-rw-r--r-- | vendor/mcmc/mcmc.h | 9 |
2 files changed, 55 insertions, 3 deletions
diff --git a/vendor/mcmc/mcmc.c b/vendor/mcmc/mcmc.c index cdd5142..902e704 100644 --- a/vendor/mcmc/mcmc.c +++ b/vendor/mcmc/mcmc.c @@ -115,6 +115,33 @@ static int _mcmc_parse_value_line(mcmc_ctx_t *ctx, mcmc_resp_t *r) { return MCMC_CODE_OK; } +static int _mcmc_parse_stat_line(mcmc_ctx_t *ctx, mcmc_resp_t *r) { + char *buf = ctx->buffer_head; + char *p = buf+5; // pass "STAT " + size_t l = ctx->buffer_request_len; + + // STAT key value + char *sname = p; + p = memchr(p, ' ', l-5); + if (p == NULL) { + return -MCMC_ERR_VALUE; + } + + int snamelen = p - sname; + while (*p == ' ') { + p++; + } + char *stat = p; + int statlen = l - (p - ctx->buffer_head) - 2; + + r->sname = sname; + r->snamelen = snamelen; + r->stat = stat; + r->statlen = statlen; + + return MCMC_CODE_OK; +} + // FIXME: This is broken for ASCII multiget. // if we get VALUE back, we need to stay in ASCII GET read mode until an END // is seen. @@ -125,7 +152,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) { int rlen; // response code length. int more = 0; r->reslen = ctx->buffer_request_len; - r->type = MCMC_RESP_GENERIC; + r->type = MCMC_RESP_FAIL; // walk until the \r\n while (l-- > 2) { @@ -213,6 +240,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)) { + r->type = MCMC_RESP_FAIL; code = -MCMC_ERR_PARSE; } else { r->vlen = vsize + 2; // tag in the \r\n. @@ -230,6 +258,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) { code = MCMC_CODE_OK; } } else { + r->type = MCMC_RESP_FAIL; code = -MCMC_ERR_PARSE; } } @@ -257,7 +286,7 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) { if (memcmp(buf, "STAT", 4) == 0) { r->type = MCMC_RESP_STAT; ctx->state = STATE_STAT_RESP; - // TODO: initialize stat reader mode. + code = _mcmc_parse_stat_line(ctx, r); } break; case 5: @@ -268,20 +297,27 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) { } else { code = -MCMC_ERR_PARSE; } + } else if (memcmp(buf, "ERROR", 5) == 0) { + r->type = MCMC_RESP_ERRMSG; + code = -MCMC_CODE_ERROR; } break; case 6: if (memcmp(buf, "STORED", 6) == 0) { + r->type = MCMC_RESP_GENERIC; code = MCMC_CODE_STORED; } else if (memcmp(buf, "EXISTS", 6) == 0) { + r->type = MCMC_RESP_GENERIC; code = MCMC_CODE_EXISTS; // TODO: type -> ASCII? } break; case 7: if (memcmp(buf, "DELETED", 7) == 0) { + r->type = MCMC_RESP_GENERIC; code = MCMC_CODE_DELETED; } else if (memcmp(buf, "TOUCHED", 7) == 0) { + r->type = MCMC_RESP_GENERIC; code = MCMC_CODE_TOUCHED; } else if (memcmp(buf, "VERSION", 7) == 0) { code = MCMC_CODE_VERSION; @@ -291,16 +327,25 @@ static int _mcmc_parse_response(mcmc_ctx_t *ctx, mcmc_resp_t *r) { break; case 9: if (memcmp(buf, "NOT_FOUND", 9) == 0) { + r->type = MCMC_RESP_GENERIC; code = MCMC_CODE_NOT_FOUND; } break; case 10: if (memcmp(buf, "NOT_STORED", 10) == 0) { + r->type = MCMC_RESP_GENERIC; code = MCMC_CODE_NOT_STORED; } break; default: // Unknown code, assume error. + if (memcmp(buf, "SERVER_ERROR", 12) == 0) { + r->type = MCMC_RESP_ERRMSG; + code = -MCMC_CODE_SERVER_ERROR; + } else if (memcmp(buf, "CLIENT_ERROR", 12) == 0) { + r->type = MCMC_RESP_ERRMSG; + code = -MCMC_CODE_CLIENT_ERROR; + } break; } diff --git a/vendor/mcmc/mcmc.h b/vendor/mcmc/mcmc.h index d6c426e..132ed1a 100644 --- a/vendor/mcmc/mcmc.h +++ b/vendor/mcmc/mcmc.h @@ -27,6 +27,9 @@ #define MCMC_ERR_SHORT 18 #define MCMC_ERR_PARSE 19 #define MCMC_ERR_VALUE 20 +#define MCMC_CODE_ERROR 21 +#define MCMC_CODE_CLIENT_ERROR 22 +#define MCMC_CODE_SERVER_ERROR 23 // response types #define MCMC_RESP_GET 100 @@ -36,6 +39,8 @@ #define MCMC_RESP_END 105 #define MCMC_RESP_VERSION 106 #define MCMC_RESP_NUMERIC 107 // for weird incr/decr syntax. +#define MCMC_RESP_ERRMSG 108 // ERROR, CLIENT_ERROR, SERVER_ERRROR +#define MCMC_RESP_FAIL 109 // Complete failure to parse, garbage, etc #define MCMC_OPTION_BLANK 0 #define MCMC_OPTION_NONBLOCK 1 @@ -69,8 +74,10 @@ typedef struct { }; // STAT response struct { + char *sname; + size_t snamelen; char *stat; - size_t slen; + size_t statlen; }; }; } mcmc_resp_t; |