libmemcached "protocol error" and "Server sent data for key not in request"

Richard Cameron camster at citeulike.org
Thu Mar 17 08:40:47 PST 2005


Does anyone else see these two errors with libmemcached:

regress: memcache.c:1096        protocol error: Unknown error: 0
regress: memcache.c:1031        Server sent data for key not in request.

I see them on Mac OS X but not on Linux. It's a reasonably slow 
machine, and it's got the disadvantage of not having a working 
TCP_NOPUSH, so what appears to be happening is the data seems to be 
coming back from the server in dribs and drabs.

It appears that there are some particularly unfortunate lengths of 
dribs which fool libmemcached into thinking it's getting mangled data 
back from the server. While this  is much more likely to happen on OS 
X, I presume that it's theoretically possible that it might happen on 
Linux too.

I'm using libmemcached version 1.2.3 and here's my patch which seems to 
calm things down:

Index: memcache.c
===================================================================
--- memcache.c  (revision 2201)
+++ memcache.c  (working copy)
@@ -1011,7 +1011,7 @@
         * If this fails we will scan the whole list. */
        if (res != NULL && res->entries.tqe_next != NULL) {
         for (res = res->entries.tqe_next; res != NULL; res = 
res->entries.tqe_next) {
-         if ((size_t)(rb - (cp - ms->cur)) > res->len) {
+         if ((size_t)(ms->read_cur - cp) >= res->len) {
             if (memcmp(cp, res->key, res->len) == 0) {
               break;
             }
@@ -1019,7 +1019,7 @@
         }
        } else {
         for (res = req->query.tqh_first; res != NULL; res = 
res->entries.tqe_next) {
-         if((size_t)(rb - (cp - ms->cur)) > res->len) {
+         if ((size_t)(ms->read_cur - cp) >= res->len) {
             if(memcmp(cp, res->key, res->len) == 0) {
               break;
             }
@@ -1067,8 +1067,8 @@

    bytes_read = ms->read_cur - cp;

-  /* Check if we have read all the data the plus a \r\n */
-  if (bytes_read >= len + 2) {
+  /* Check if we have read all the data the plus a \r\n (plus partial 
next item or END)*/
+  if (bytes_read > len + 2) {
      res->_flags |= MCM_RES_FOUND;
      if (res->size == 0) {
        res->val = ctxt->mcMallocAtomic(res->bytes);




More information about the memcached mailing list