summaryrefslogtreecommitdiff
path: root/proxy_network.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-11-30 16:25:26 -0800
committerdormando <dormando@rydia.net>2022-11-30 16:25:26 -0800
commit30d1a951876498212b0931756be996c2b6845be8 (patch)
tree2ff5d132272dc5b1479ef3bd7453ddb39ece3d4a /proxy_network.c
parent6f7725c4ba39ce8c979d0feaa4e2b71f4f4d36be (diff)
downloadmemcached-30d1a951876498212b0931756be996c2b6845be8.tar.gz
proxy: add more backend failure messages
previously the "parsing" bucket held all backend state machine errors. This cleans up an unused state machine branch and adds specific errors. Still doesn't have a good way of getting the mcmc parsing error without a debugger but that path needs more work regardless.
Diffstat (limited to 'proxy_network.c')
-rw-r--r--proxy_network.c104
1 files changed, 51 insertions, 53 deletions
diff --git a/proxy_network.c b/proxy_network.c
index 29d3aff..07f00e8 100644
--- a/proxy_network.c
+++ b/proxy_network.c
@@ -12,6 +12,11 @@ enum proxy_be_failures {
P_BE_FAIL_WRITING,
P_BE_FAIL_READING,
P_BE_FAIL_PARSING,
+ P_BE_FAIL_CLOSED,
+ P_BE_FAIL_UNHANDLEDRES,
+ P_BE_FAIL_OOM,
+ P_BE_FAIL_ENDSYNC,
+ P_BE_FAIL_TRAILINGDATA,
};
const char *proxy_be_failure_text[] = {
@@ -23,6 +28,11 @@ const char *proxy_be_failure_text[] = {
[P_BE_FAIL_WRITING] = "writing",
[P_BE_FAIL_READING] = "reading",
[P_BE_FAIL_PARSING] = "parsing",
+ [P_BE_FAIL_CLOSED] = "closedsock",
+ [P_BE_FAIL_UNHANDLEDRES] = "unhandledres",
+ [P_BE_FAIL_OOM] = "outofmemory",
+ [P_BE_FAIL_ENDSYNC] = "missingend",
+ [P_BE_FAIL_TRAILINGDATA] = "trailingdata",
NULL
};
@@ -594,14 +604,13 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
// socket, getsockopt, or something else simply for logging or
// statistical purposes.
// In this case we know it's going to be a close so error.
- flags = -1;
+ flags = P_BE_FAIL_CLOSED;
P_DEBUG("%s: read event but nothing in IO queue\n", __func__);
return flags;
}
while (!stop) {
mcp_resp_t *r;
- int res = 1;
switch(be->state) {
case mcp_backend_read:
@@ -618,7 +627,7 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
if (r->resp.code == MCMC_WANT_READ) {
return EV_READ;
}
- flags = -1;
+ flags = P_BE_FAIL_PARSING;
stop = true;
break;
}
@@ -649,58 +658,48 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
default:
P_DEBUG("%s: Unhandled response from backend: %d\n", __func__, r->resp.type);
// unhandled :(
- flags = -1;
+ flags = P_BE_FAIL_UNHANDLEDRES;
stop = true;
break;
}
- if (res) {
- if (p->ascii_multiget && r->resp.type == MCMC_RESP_END) {
- // Ascii multiget hack mode; consume END's
- be->state = mcp_backend_next;
- break;
- }
+ if (p->ascii_multiget && r->resp.type == MCMC_RESP_END) {
+ // Ascii multiget hack mode; consume END's
+ be->state = mcp_backend_next;
+ break;
+ }
- // r->resp.reslen + r->resp.vlen is the total length of the response.
- // TODO (v2): need to associate a buffer with this response...
- // for now lets abuse write_and_free on mc_resp and simply malloc the
- // space we need, stuffing it into the resp object.
+ // r->resp.reslen + r->resp.vlen is the total length of the response.
+ // TODO (v2): need to associate a buffer with this response...
+ // for now lets abuse write_and_free on mc_resp and simply malloc the
+ // space we need, stuffing it into the resp object.
- r->blen = r->resp.reslen + r->resp.vlen;
- r->buf = malloc(r->blen + extra_space);
- if (r->buf == NULL) {
- flags = -1; // TODO (v2): specific error.
- stop = true;
- break;
- }
+ r->blen = r->resp.reslen + r->resp.vlen;
+ r->buf = malloc(r->blen + extra_space);
+ if (r->buf == NULL) {
+ flags = P_BE_FAIL_OOM;
+ stop = true;
+ break;
+ }
- P_DEBUG("%s: r->status: %d, r->bread: %d, r->vlen: %lu\n", __func__, r->status, r->bread, r->resp.vlen);
- if (r->resp.vlen != r->resp.vlen_read) {
- // shouldn't be possible to have excess in buffer
- // if we're dealing with a partial value.
- assert(be->rbufused == r->resp.reslen+r->resp.vlen_read);
- P_DEBUG("%s: got a short read, moving to want_read\n", __func__);
- // copy the partial and advance mcmc's buffer digestion.
- memcpy(r->buf, be->rbuf, r->resp.reslen + r->resp.vlen_read);
- r->bread = r->resp.reslen + r->resp.vlen_read;
- be->rbufused = 0;
- be->state = mcp_backend_want_read;
- flags |= EV_READ;
- stop = true;
- break;
- } else {
- // mcmc's already counted the value as read if it fit in
- // the original buffer...
- memcpy(r->buf, be->rbuf, r->resp.reslen+r->resp.vlen_read);
- }
- } else {
- // TODO (v2): no response read?
- // nothing currently sets res to 0. should remove if that
- // never comes up and handle the error entirely above.
- P_DEBUG("%s: no response read from backend\n", __func__);
- flags = -1;
+ P_DEBUG("%s: r->status: %d, r->bread: %d, r->vlen: %lu\n", __func__, r->status, r->bread, r->resp.vlen);
+ if (r->resp.vlen != r->resp.vlen_read) {
+ // shouldn't be possible to have excess in buffer
+ // if we're dealing with a partial value.
+ assert(be->rbufused == r->resp.reslen+r->resp.vlen_read);
+ P_DEBUG("%s: got a short read, moving to want_read\n", __func__);
+ // copy the partial and advance mcmc's buffer digestion.
+ memcpy(r->buf, be->rbuf, r->resp.reslen + r->resp.vlen_read);
+ r->bread = r->resp.reslen + r->resp.vlen_read;
+ be->rbufused = 0;
+ be->state = mcp_backend_want_read;
+ flags = 0;
stop = true;
break;
+ } else {
+ // mcmc's already counted the value as read if it fit in
+ // the original buffer...
+ memcpy(r->buf, be->rbuf, r->resp.reslen+r->resp.vlen_read);
}
// had a response, advance the buffer.
@@ -723,8 +722,7 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
if (be->rbufused >= ENDLEN) {
if (memcmp(be->rbuf, ENDSTR, ENDLEN) != 0) {
- // TODO (v2): specific error.
- flags = -1;
+ flags = P_BE_FAIL_ENDSYNC;
stop = true;
break;
} else {
@@ -744,7 +742,7 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
}
}
} else {
- flags |= EV_READ;
+ flags = 0;
stop = true;
break;
}
@@ -781,7 +779,7 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
assert(tocopy == be->rbufused);
// signal to caller to issue a read.
be->rbufused = 0;
- flags |= EV_READ;
+ flags = 0;
stop = true;
}
@@ -802,7 +800,7 @@ static int proxy_backend_drive_machine(mcp_backend_t *be) {
// should also be empty.
// Get a specific return code for errors to surface this.
if (be->rbufused > 0) {
- flags = -1;
+ flags = P_BE_FAIL_TRAILINGDATA;
}
break;
} else {
@@ -1178,8 +1176,8 @@ static void proxy_backend_handler(const int fd, const short which, void *arg) {
if (read > 0) {
be->rbufused += read;
int res = proxy_backend_drive_machine(be);
- if (res == -1) {
- _reset_bad_backend(be, P_BE_FAIL_PARSING);
+ if (res != 0) {
+ _reset_bad_backend(be, res);
_backend_failed(be);
return;
}