/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING memcached */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "istream.h"
#include "ostream.h"
#include "connection.h"
#include "dict-private.h"
/* we need only very limited memcached functionality, so just define the binary
protocol ourself instead requiring protocol_binary.h */
enum memcached_response {
};
struct memcached_connection {
struct {
const unsigned char *value;
bool reply_received;
} reply;
};
struct memcached_dict {
char *key_prefix;
unsigned int timeout_msecs;
bool connected;
};
{
}
{
const unsigned char *data;
if (size < MEMCACHED_REPLY_HDR_LENGTH)
return 0;
if (data[0] != MEMCACHED_REPLY_HDR_MAGIC) {
i_error("memcached: Invalid reply magic: %u != %u",
return -1;
}
/* we haven't read the whole response yet */
return 0;
}
if (data_type != MEMCACHED_DATA_TYPE_RAW) {
i_error("memcached: Unsupported data type: %u != %u",
data[0], MEMCACHED_DATA_TYPE_RAW);
return -1;
}
return -1;
}
return 1;
}
{
case 0:
return;
case -1:
return;
default:
break;
}
if (memcached_input_get(conn) < 0)
}
{
(struct memcached_connection *)_conn;
if (!success) {
i_error("memcached: connect(%s, %u) failed: %m",
} else {
}
}
};
};
static int
{
const char *const *args;
int ret = 0;
if (memcached_connections == NULL) {
}
i_unreached();
*args+5);
ret = -1;
}
*args+5);
ret = -1;
}
ret = -1;
}
} else {
*args);
ret = -1;
}
}
if (ret < 0) {
return -1;
}
return 0;
}
{
}
{
i_error("memcached: Lookup timed out in %u.%03u secs",
}
{
}
static int
{
else {
return -1;
}
if (key_len > 0xffff) {
return -1;
}
i_error("memcached: Couldn't connect to %s:%u",
} else {
/* wait for connection */
}
}
timeout_remove(&to);
}
/* we failed in some way. make sure we disconnect since the
connection state isn't known anymore */
*error_r = "memcached: Communication failure";
return -1;
}
case MEMCACHED_RESPONSE_OK:
return 1;
return 0;
*error_r = "memcached: Lookup failed: Internal error";
return -1;
case MEMCACHED_RESPONSE_BUSY:
*error_r = "memcached: Lookup failed: Busy";
return -1;
*error_r = "memcached: Lookup failed: Temporary failure";
return -1;
}
return -1;
}
.name = "memcached",
{
}
};