| /* |
| * Copyright (C) Tildeslash Ltd. All rights reserved. |
| * |
| * This program is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU Affero General Public License version 3. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU Affero General Public License |
| * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| * |
| * In addition, as a special exception, the copyright holders give |
| * permission to link the code of portions of this program with the |
| * OpenSSL library under certain conditions as described in each |
| * individual source file, and distribute linked combinations |
| * including the two. |
| * |
| * You must obey the GNU Affero General Public License in all respects |
| * for all of the code used other than OpenSSL. |
| */ |
| |
| #include "config.h" |
| |
| #ifdef HAVE_STRING_H |
| #include <string.h> |
| #endif |
| |
| #include "protocol.h" |
| |
| #define MEMCACHELEN 24 |
| |
| /* Magic Byte */ |
| #define MAGIC_REQUEST 0x80 |
| #define MAGIC_RESPONSE 0x81 |
| |
| /* Response Status */ |
| #define NO_ERROR 0x0000 |
| #define KEY_NOT_FOUND 0x0001 |
| #define KEY_EXISTS 0x0002 |
| #define VALUE_TOO_BIG 0x0003 |
| #define INVALID_ARGUMENTS 0x0004 |
| #define ITEM_NOT_STORED 0x0005 |
| #define UNKNOWN_COMMAND 0x0081 |
| #define OUT_OF_MEMORY 0x0082 |
| |
| /** |
| * Memcache binary protocol |
| * |
| * Send No-op request |
| * |
| * @file |
| */ |
| int check_memcache(Socket_T socket) { |
| unsigned int length; |
| unsigned char response[STRLEN]; |
| unsigned int status; |
| |
| unsigned char request[MEMCACHELEN] = { |
| MAGIC_REQUEST, /** Magic */ |
| 0x0a, /** Opcode */ |
| 0x00, 0x00, /** Key length */ |
| 0x00, /** Extra length */ |
| 0x00, /** Data type */ |
| 0x00, 0x00, /** request Reserved / response Status */ |
| 0x00, 0x00, 0x00, 0x00, /** Total body */ |
| 0x00, 0x00, 0x00, 0x00, /** Opaque */ |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /** CAS */ |
| }; |
| |
| ASSERT(socket); |
| |
| if(socket_write(socket, (unsigned char *)request, sizeof(request)) <= 0) { |
| socket_setError(socket, "MEMCACHE: error sending data -- %s\n", STRERROR); |
| return FALSE; |
| } |
| |
| /* Response should have at least MEMCACHELEN bytes */ |
| length = socket_read(socket, (unsigned char *)response, sizeof(response)); |
| if (length != MEMCACHELEN) { |
| socket_setError(socket, "MEMCACHE: Received %d bytes from server, expected %d bytes\n", length, MEMCACHELEN); |
| return FALSE; |
| } |
| |
| if(response[0] != MAGIC_RESPONSE) { |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- error occured\n"); |
| return FALSE; |
| } |
| |
| status = (response[6] << 8) | response[7]; |
| switch( status ) { |
| case NO_ERROR: |
| return TRUE; |
| case OUT_OF_MEMORY: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Out of memory\n"); |
| return FALSE; |
| case UNKNOWN_COMMAND: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Unknown command\n"); |
| return FALSE; |
| case INVALID_ARGUMENTS: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Invalid arguments\n"); |
| return FALSE; |
| case VALUE_TOO_BIG: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Value too big\n"); |
| return FALSE; |
| case ITEM_NOT_STORED: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Item not stored\n"); |
| return FALSE; |
| case KEY_NOT_FOUND: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Key not found\n"); |
| return FALSE; |
| case KEY_EXISTS: |
| socket_setError(socket, "MEMCACHELEN: Invalid response code -- Key exists\n"); |
| return FALSE; |
| default: |
| socket_setError(socket, "MEMCACHELEN: Unknow response code %u -- error occured\n", status); |
| return FALSE; |
| } |
| } |
| |
| |