MEMCACHED_BEHAVIOR_BLOCK,
MEMCACHED_BEHAVIOR_TCP_NODELAY,
MEMCACHED_BEHAVIOR_TCP_DELAY,
+ MEMCACHED_BEHAVIOR_MD5_HASHING,
} memcached_behavior;
typedef enum {
unsigned int limit_maxbytes;
};
-#define MEM_NO_BLOCK (1 << 0)
-#define MEM_TCP_NODELAY (1 << 1)
-#define MEM_REUSE_MEMORY (1 << 2)
-
struct memcached_string_st {
char *string;
char *end;
memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string);
void memcached_string_free(memcached_st *ptr, memcached_string_st *string);
+char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat,
+ char *key, memcached_return *error);
+char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat,
+ memcached_return *error);
+
/* Some personal debugging functions */
#define WATCHPOINT printf("\nWATCHPOINT %s:%d (%s)\n", __FILE__, __LINE__,__func__);fflush(stdout);
#define WATCHPOINT_ERROR(A) printf("\nWATCHPOINT %s:%d %s\n", __FILE__, __LINE__, memcached_strerror(NULL, A));fflush(stdout);
#include "libmemcached_probes.h"
-void md5_signature(const unsigned char *key, unsigned int length, char *result);
+#define MEM_NO_BLOCK (1 << 0)
+#define MEM_TCP_NODELAY (1 << 1)
+#define MEM_REUSE_MEMORY (1 << 2)
+#define MEM_USE_MD5 (1 << 3)
+
+void md5_signature(unsigned char *key, unsigned int length, unsigned char *result);
memcached_return memcached_connect(memcached_st *ptr);
memcached_return memcached_response(memcached_st *ptr,
char *buffer, size_t buffer_length,
unsigned int server_key);
-unsigned int memcached_generate_hash(char *key, size_t key_length);
-char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat,
- char *key, memcached_return *error);
-char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat,
- memcached_return *error);
+unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length);
#endif /* __COMMON_H__ */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
-static void MD5Init PROTO_LIST ((MD5_CTX *));
-static void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int));
-static void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+static void MD5Init (MD5_CTX *context); /* context */
+static void MD5Update ( MD5_CTX *context, /* context */
+ unsigned char *input, /* input block */
+ unsigned int inputLen); /* length of input block */
+static void MD5Final ( unsigned char digest[16], /* message digest */
+ MD5_CTX *context); /* context */
/* Constants for MD5Transform routine. */
#define S44 21
-static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
-static void Encode PROTO_LIST
- ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
- ((UINT4 *, unsigned char *, unsigned int));
-static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+static void MD5Transform (UINT4 state[4],
+ unsigned char block[64]);
+static void Encode (unsigned char *output,
+ UINT4 *input,
+ unsigned int len);
+static void Decode(UINT4 *output, unsigned char *input, unsigned int len);
+static void MD5_memcpy(unsigned char *, unsigned char *, unsigned int);
+static void MD5_memset(unsigned char *, int, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*
Just a simple method for getting the signature
- result must be == 32
+ result must be == 16
*/
-void md5_signature(const unsigned char *key, unsigned int length, char *result)
+void md5_signature(unsigned char *key, unsigned int length, unsigned char *result)
{
- const char *hex = "0123456789abcdef";
MD5_CTX my_md5;
- unsigned char hash[16];
- char *r, i;
MD5Init(&my_md5);
- (void)MD5Update(&my_md5, buf, length);
- MD5Final(hash, &my_md5);
-
- for (i = 0, r = result; i < 16; i++)
- {
- *r++ = hex[hash[i] >> 4];
- *r++ = hex[hash[i] & 0xF];
- }
+ (void)MD5Update(&my_md5, key, length);
+ MD5Final(result, &my_md5);
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
if (rc != MEMCACHED_SUCCESS)
return rc;
- server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
+ server_key= memcached_generate_hash(ptr, key, key_length);
send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
"%s %.*s %u\r\n", verb,
-#include <memcached.h>
+#include "common.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
/* We quit all connections so we can reset the sockets */
memcached_quit(ptr);
ptr->flags+= MEM_TCP_NODELAY;
+ case MEMCACHED_BEHAVIOR_MD5_HASHING:
+ ptr->flags+= MEM_USE_MD5;
break;
}
if (rc != MEMCACHED_SUCCESS)
return rc;
- server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
+ server_key= memcached_generate_hash(ptr, key, key_length);
if (expiration)
send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
if (*error != MEMCACHED_SUCCESS)
goto error;
- server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
+ server_key= memcached_generate_hash(ptr, key, key_length);
send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "get %.*s\r\n",
(int)key_length, key);
{
unsigned int server_key;
- server_key= memcached_generate_hash(keys[x], key_length[x]) % ptr->number_of_hosts;
+ server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);
if (cursor_key_exec[server_key])
{
#include "common.h"
-unsigned int memcached_generate_hash(char *key, size_t key_length)
+/* Prototypes */
+static unsigned int internal_generate_hash(char *key, size_t key_length);
+
+unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length)
+{
+ unsigned int return_value;
+
+ if (ptr->flags & MEM_USE_MD5)
+ {
+ unsigned char results[16];
+
+ md5_signature((unsigned char*)key, (unsigned int)key_length, results);
+
+ return_value= (unsigned int)(( results[3] << 24 )
+ | ( results[2] << 16 )
+ | ( results[1] << 8 )
+ | results[0] );
+ }
+ else
+ return_value= internal_generate_hash(key, key_length);
+
+ return return_value % ptr->number_of_hosts;
+}
+
+static unsigned int internal_generate_hash(char *key, size_t key_length)
{
char *ptr= key;
unsigned int value= 0;
Basic socket buffered IO
*/
-#include <memcached.h>
+#include "common.h"
#include "memcached_io.h"
#include <sys/select.h>
/* Leaveing this assert in since only a library fubar could blow this */
assert(ptr->write_buffer_offset == 0);
- server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
+ server_key= memcached_generate_hash(ptr, key, key_length);
write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
"%s %.*s %x %llu %zu\r\n", storage_op_string(verb),
Found key bytes_written
Found key limit_maxbytes
Found key threads
+Error 0 -> SUCCESS
+Error 1 -> FAILURE
+Error 2 -> HOSTNAME LOOKUP FAILURE
+Error 3 -> CONNECTION FAILURE
+Error 4 -> CONNECTION BIND FAILURE
+Error 5 -> WRITE FAILURE
+Error 6 -> READ FAILURE
+Error 7 -> UNKNOWN READ FAILURE
+Error 8 -> PROTOCOL ERROR
+Error 9 -> CLIENT ERROR
+Error 10 -> SERVER ERROR
+Error 11 -> CONNECTION SOCKET CREATE FAILURE
+Error 12 -> CONNECTION DATA EXISTS
+Error 13 -> CONNECTION DATA DOES NOT EXIST
+Error 14 -> NOT STORED
+Error 15 -> STORED
+Error 16 -> NOT FOUND
+Error 17 -> MEMORY ALLOCATION FAILURE
+Error 18 -> PARTIAL READ
+Error 19 -> SOME ERRORS WERE REPORTED
+Error 20 -> NO SERVERS DEFINED
+Error 21 -> SERVER END
+Error 22 -> SERVER DELETE
+Error 23 -> SERVER VALUE
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
+Found key pid
+Found key uptime
+Found key time
+Found key version
+Found key pointer_size
+Found key rusage_user
+Found key rusage_system
+Found key rusage_user_seconds
+Found key rusage_user_microseconds
+Found key rusage_system_seconds
+Found key rusage_system_microseconds
+Found key curr_items
+Found key total_items
+Found key bytes
+Found key curr_connections
+Found key total_connections
+Found key connection_structures
+Found key cmd_get
+Found key cmd_set
+Found key get_hits
+Found key get_misses
+Found key evictions
+Found key bytes_read
+Found key bytes_written
+Found key limit_maxbytes
+Found key threads
memcached_free(memc);
}
+ fprintf(stderr, "\nMD5 Hashing\n\n");
+ for (x= 0; tests[x].function_name; x++)
+ {
+ memcached_st *memc;
+ memcached_return rc;
+ memc= memcached_create(NULL);
+ assert(memc);
+
+ rc= memcached_server_push(memc, servers);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ fprintf(stderr, "Testing %s", tests[x].function_name);
+ memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_MD5_HASHING, NULL);
+ tests[x].function(memc);
+ fprintf(stderr, "\t\t\t\t\t[ ok ]\n");
+ assert(memc);
+ memcached_free(memc);
+ }
+
/* Clean up whatever we might have left */
{
memcached_st *memc;