]> source.dussan.org Git - rspamd.git/commitdiff
* Add skeleton of libkvstorage API.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 18 Oct 2011 16:36:22 +0000 (19:36 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 18 Oct 2011 16:36:22 +0000 (19:36 +0300)
lib/CMakeLists.txt
lib/kvstorage/libkvstorageclient.c [new file with mode: 0644]
lib/kvstorage/libkvstorageclient.h [new file with mode: 0644]

index 555c13a87a69d41256d945e3c277abb6b028ea08..e7a9e51e07f512c42009efae86cda6fa52787fed 100644 (file)
@@ -77,3 +77,37 @@ SET_TARGET_PROPERTIES(rspamdserver PROPERTIES COMPILE_FLAGS "-DRSPAMD_LIB")
 TARGET_LINK_LIBRARIES(rspamdserver rspamd_lua)
 TARGET_LINK_LIBRARIES(rspamdserver rspamd_json)
 TARGET_LINK_LIBRARIES(rspamdserver rspamd_cdb)   
+
+
+# Libkvstorageclient
+SET(LIBRKVSTORAGESRC                     kvstorage/libkvstorageclient.c ../src/mem_pool.c ../src/upstream.c ../src/printf.c ../src/util.c)
+
+ADD_LIBRARY(kvstorageclient SHARED ${LIBRKVSTORAGESRC})
+ADD_LIBRARY(kvstorageclient_static STATIC ${LIBRKVSTORAGESRC})
+SET_TARGET_PROPERTIES(kvstorageclient PROPERTIES PUBLIC_HEADER "kvstorage/libkvstorageclient.h")
+
+IF(CMAKE_COMPILER_IS_GNUCC)
+SET_TARGET_PROPERTIES(kvstorageclient PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing")
+SET_TARGET_PROPERTIES(kvstorageclient_static PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing")
+ENDIF(CMAKE_COMPILER_IS_GNUCC)
+
+TARGET_LINK_LIBRARIES(kvstorageclient ${CMAKE_REQUIRED_LIBRARIES})
+TARGET_LINK_LIBRARIES(kvstorageclient pcre)
+TARGET_LINK_LIBRARIES(kvstorageclient ${GLIB2_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(kvstorageclient_static ${CMAKE_REQUIRED_LIBRARIES})
+TARGET_LINK_LIBRARIES(kvstorageclient_static ${GLIB2_LIBRARIES})
+
+SET_TARGET_PROPERTIES(kvstorageclient PROPERTIES VERSION ${RSPAMD_VERSION})
+SET_TARGET_PROPERTIES(kvstorageclient_static PROPERTIES VERSION ${RSPAMD_VERSION})
+
+IF(GLIB_COMPAT)
+       INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/contrib/lgpl")
+       TARGET_LINK_LIBRARIES(kvstorageclient glibadditions)
+ENDIF(GLIB_COMPAT)
+INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/src")
+
+INSTALL(TARGETS rspamdclient rspamdclient_static LIBRARY PUBLIC_HEADER 
+    LIBRARY DESTINATION lib 
+    PUBLIC_HEADER DESTINATION include
+    ARCHIVE DESTINATION lib)
diff --git a/lib/kvstorage/libkvstorageclient.c b/lib/kvstorage/libkvstorageclient.c
new file mode 100644 (file)
index 0000000..6ab1ea4
--- /dev/null
@@ -0,0 +1,351 @@
+/* Copyright (c) 2010, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "main.h"
+#include "libkvstorageclient.h"
+
+struct rspamd_kvstorage_connection {
+       gboolean asynced;
+       gint sock;
+       struct timeval tv;
+       enum {
+               KV_STATE_NONE = 0,
+               KV_STATE_CONNECTED,
+               KV_STATE_SET,
+               KV_STATE_GET,
+               KV_STATE_WRITE_DATA,
+               KV_STATE_READ_DATA,
+               KV_STATE_READ_REPLY
+       } state;
+       struct event ev;
+       kvstorage_connect_cb conn_cb;
+       kvstorage_read_cb read_cb;
+       kvstorage_write_cb write_cb;
+       gpointer cur_ud;
+       memory_pool_t *pool;
+       gpointer cur_key;
+       gpointer cur_value;
+};
+
+/* Callbacks for async API */
+static void
+rspamd_kvstorage_connect_cb (int fd, short what, gpointer ud)
+{
+       struct rspamd_kvstorage_connection              *c = ud;
+       kvstorage_connect_cb                     cb;
+
+       cb = (kvstorage_connect_cb)c->conn_cb;
+
+       if (what == EV_TIMEOUT) {
+               cb (KVSTORAGE_ERROR_TIMEOUT, c, c->cur_ud);
+       }
+       else {
+               cb (KVSTORAGE_ERROR_OK, c, c->cur_ud);
+       }
+       c->state = KV_STATE_CONNECTED;
+}
+
+static void
+rspamd_kvstorage_read_cb (int fd, short what, gpointer ud)
+{
+       struct rspamd_kvstorage_connection              *c = ud;
+       kvstorage_read_cb                                cb;
+
+       cb = (kvstorage_read_cb)c->read_cb;
+}
+
+static void
+rspamd_kvstorage_write_cb (int fd, short what, gpointer ud)
+{
+       struct rspamd_kvstorage_connection              *c = ud;
+       kvstorage_write_cb                       cb;
+
+       cb = (kvstorage_write_cb)c->write_cb;
+}
+
+static void
+rspamd_kvstorage_delete_cb (int fd, short what, gpointer ud)
+{
+       struct rspamd_kvstorage_connection              *c = ud;
+       kvstorage_write_cb                       cb;
+
+       cb = c->write_cb;
+}
+
+/**
+ *  Create async connection with rspamd
+ *  @param host hostname, ip or unix socket for a server
+ *  @param port port number in host byte order
+ *  @param tv timeout for operations
+ *  @param cb callback
+ *  @param ud user data for callback
+ *  @param conn target connection
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_connect_async (const gchar *host,
+               guint16 port, struct timeval *tv, kvstorage_connect_cb cb, gpointer ud,
+               struct rspamd_kvstorage_connection **conn)
+{
+       struct rspamd_kvstorage_connection              *new;
+       gint                                                                     sock;
+
+       /* Here we do NOT try to resolve hostname */
+       if ((sock = make_universal_stream_socket (host, port, TRUE, FALSE, FALSE)) == -1) {
+               return KVSTORAGE_ERROR_SERVER_ERROR;
+       }
+
+       /* Allocate new connection structure */
+       new = g_malloc (sizeof (struct rspamd_kvstorage_connection));
+
+       /* Set fields */
+       new->sock = sock;
+       new->state = KV_STATE_NONE;
+       new->asynced = TRUE;
+       if (tv != NULL) {
+               memcpy (&new->tv, tv, sizeof (struct timeval));
+       }
+       else {
+               memset (&new->tv, 0, sizeof (struct timeval));
+       }
+       new->conn_cb = cb;
+       new->cur_ud = ud;
+       new->pool = memory_pool_new (memory_pool_get_size ());
+
+       /* Set event */
+       event_set (&new->ev, new->sock, EV_WRITE, rspamd_kvstorage_connect_cb, new);
+       if (tv != NULL) {
+               event_add (&new->ev, &new->tv);
+       }
+       else {
+               event_add (&new->ev, NULL);
+       }
+
+       *conn = new;
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Read key asynced
+ * @param conn connection structure
+ * @param key key to read
+ * @param cb callback
+ * @param ud user data for callback
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_get_async (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, kvstorage_read_cb cb, gpointer ud)
+{
+       if (conn == NULL || conn->state != KV_STATE_CONNECTED) {
+               return KVSTORAGE_ERROR_INTERNAL_ERROR;
+       }
+       else {
+               conn->read_cb = cb;
+               conn->cur_ud = ud;
+               conn->cur_key = memory_pool_strdup (conn->pool, key);
+               conn->state = KV_STATE_GET;
+
+               /* Set event */
+               event_set (&conn->ev, conn->sock, EV_WRITE, rspamd_kvstorage_read_cb, conn);
+               if (conn->tv.tv_sec != 0) {
+                       event_add (&conn->ev, &conn->tv);
+               }
+               else {
+                       event_add (&conn->ev, NULL);
+               }
+       }
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Write key asynced
+ * @param conn connection structure
+ * @param key key to set
+ * @param value data to write
+ * @param cb callback
+ * @param ud user data for callback
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_set_async (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, const gpointer value, gsize len, guint expire, kvstorage_write_cb cb, gpointer ud)
+{
+       if (conn == NULL || conn->state != KV_STATE_CONNECTED) {
+               return KVSTORAGE_ERROR_INTERNAL_ERROR;
+       }
+       else {
+               conn->write_cb = cb;
+               conn->cur_ud = ud;
+               conn->cur_key = memory_pool_strdup (conn->pool, key);
+               conn->cur_value = value;
+               conn->state = KV_STATE_SET;
+
+               /* Set event */
+               event_set (&conn->ev, conn->sock, EV_WRITE, rspamd_kvstorage_write_cb, conn);
+               if (conn->tv.tv_sec != 0) {
+                       event_add (&conn->ev, &conn->tv);
+               }
+               else {
+                       event_add (&conn->ev, NULL);
+               }
+       }
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Delete key asynced
+ * @param conn connection structure
+ * @param key key to delete
+ * @param cb callback
+ * @param ud user data for callback
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_delete_async (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, kvstorage_write_cb cb, gpointer ud)
+{
+       if (conn == NULL || conn->state != KV_STATE_CONNECTED) {
+               return KVSTORAGE_ERROR_INTERNAL_ERROR;
+       }
+       else {
+               conn->write_cb = cb;
+               conn->cur_ud = ud;
+               conn->cur_key = memory_pool_strdup (conn->pool, key);
+               conn->state = KV_STATE_SET;
+
+               /* Set event */
+               event_set (&conn->ev, conn->sock, EV_WRITE, rspamd_kvstorage_delete_cb, conn);
+               if (conn->tv.tv_sec != 0) {
+                       event_add (&conn->ev, &conn->tv);
+               }
+               else {
+                       event_add (&conn->ev, NULL);
+               }
+       }
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Close connection
+ * @param conn connection structure
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_close_async (struct rspamd_kvstorage_connection *conn)
+{
+       close (conn->sock);
+       memory_pool_delete (conn->pool);
+       event_del (&conn->ev);
+       g_free (conn);
+
+       return KVSTORAGE_ERROR_OK;
+}
+
+/* Synced API */
+/**
+ *  Create sync connection with rspamd
+ *  @param host hostname, ip or unix socket for a server
+ *  @param port port number in host byte order
+ *  @param tv timeout for operations
+ *  @param conn target connection
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_connect_sync (const gchar *host,
+               guint16 port, struct timeval *tv,
+               struct rspamd_kvstorage_connection **conn)
+{
+       struct rspamd_kvstorage_connection              *new;
+       gint                                                                     sock;
+
+       if ((sock = make_universal_stream_socket (host, port, FALSE, FALSE, TRUE)) == -1) {
+               return KVSTORAGE_ERROR_INTERNAL_ERROR;
+       }
+
+       /* Allocate new connection structure */
+       new = g_malloc (sizeof (struct rspamd_kvstorage_connection));
+
+       /* Set fields */
+       new->sock = sock;
+       new->state = KV_STATE_NONE;
+       new->asynced = FALSE;
+       if (tv != NULL) {
+               memcpy (&new->tv, tv, sizeof (struct timeval));
+       }
+       else {
+               memset (&new->tv, 0, sizeof (struct timeval));
+       }
+       new->pool = memory_pool_new (memory_pool_get_size ());
+
+       *conn = new;
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Read key synced
+ * @param conn connection structure
+ * @param key key to read
+ * @param value value readed
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_get_sync (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, gpointer **value)
+{
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Write key synced
+ * @param conn connection structure
+ * @param key key to set
+ * @param value data to write
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_set_sync (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, const gpointer value, gsize len, guint expire)
+{
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Delete key synced
+ * @param conn connection structure
+ * @param key key to delete
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_delete_sync (struct rspamd_kvstorage_connection *conn,
+               const gpointer key)
+{
+       return KVSTORAGE_ERROR_OK;
+}
+
+/**
+ * Close connection
+ * @param conn connection structure
+ */
+enum rspamd_kvstorage_error
+rspamd_kvstorage_close_sync (struct rspamd_kvstorage_connection *conn)
+{
+       close (conn->sock);
+       memory_pool_delete (conn->pool);
+       g_free (conn);
+
+       return KVSTORAGE_ERROR_OK;
+}
diff --git a/lib/kvstorage/libkvstorageclient.h b/lib/kvstorage/libkvstorageclient.h
new file mode 100644 (file)
index 0000000..788303a
--- /dev/null
@@ -0,0 +1,148 @@
+/* Copyright (c) 2010, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef LIBKVSTORAGECLIENT_H_
+#define LIBKVSTORAGECLIENT_H_
+
+#include <glib.h>
+
+/* Errors */
+enum rspamd_kvstorage_error {
+       KVSTORAGE_ERROR_OK = 0,
+       KVSTORAGE_ERROR_TIMEOUT,
+       KVSTORAGE_ERROR_NOT_EXIST,
+       KVSTORAGE_ERROR_NOT_STORED,
+       KVSTORAGE_ERROR_SERVER_ERROR,
+       KVSTORAGE_ERROR_INTERNAL_ERROR
+};
+
+/* Forwarded definition */
+struct rspamd_kvstorage_connection;
+
+/* Callbacks for async API */
+typedef void (*kvstorage_connect_cb) (enum rspamd_kvstorage_error code,
+                                                                       struct rspamd_kvstorage_connection *conn, gpointer user_data);
+typedef void (*kvstorage_read_cb) (enum rspamd_kvstorage_error code, const gpointer key,
+                                                                       const gpointer value, gsize datalen, struct rspamd_kvstorage_connection *conn,
+                                                                       gpointer user_data);
+typedef void (*kvstorage_write_cb) (enum rspamd_kvstorage_error code, const gpointer key, struct rspamd_kvstorage_connection *conn,
+                                                                       gpointer user_data);
+
+/* Asynced API */
+
+/**
+ *  Create async connection with rspamd
+ *  @param host hostname, ip or unix socket for a server
+ *  @param port port number in host byte order
+ *  @param tv timeout for operations
+ *  @param cb callback
+ *  @param ud user data for callback
+ *  @param conn target connection
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_connect_async (const gchar *host,
+               guint16 port, struct timeval *tv, kvstorage_connect_cb cb, gpointer ud,
+               struct rspamd_kvstorage_connection **conn);
+
+/**
+ * Read key asynced
+ * @param conn connection structure
+ * @param key key to read
+ * @param cb callback
+ * @param ud user data for callback
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_get_async (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, kvstorage_read_cb cb, gpointer ud);
+
+/**
+ * Write key asynced
+ * @param conn connection structure
+ * @param key key to set
+ * @param value data to write
+ * @param cb callback
+ * @param ud user data for callback
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_set_async (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, const gpointer value, gsize len, guint expire, kvstorage_write_cb cb, gpointer ud);
+
+/**
+ * Delete key asynced
+ * @param conn connection structure
+ * @param key key to delete
+ * @param cb callback
+ * @param ud user data for callback
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_delete_async (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, kvstorage_write_cb cb, gpointer ud);
+
+/**
+ * Close connection
+ * @param conn connection structure
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_close_async (struct rspamd_kvstorage_connection *conn);
+
+/* Synced API */
+/**
+ *  Create sync connection with rspamd
+ *  @param host hostname, ip or unix socket for a server
+ *  @param port port number in host byte order
+ *  @param tv timeout for operations
+ *  @param conn target connection
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_connect_sync (const gchar *host,
+               guint16 port, struct timeval *tv,
+               struct rspamd_kvstorage_connection **conn);
+
+/**
+ * Read key synced
+ * @param conn connection structure
+ * @param key key to read
+ * @param value value readed
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_get_sync (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, gpointer **value);
+
+/**
+ * Write key synced
+ * @param conn connection structure
+ * @param key key to set
+ * @param value data to write
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_set_sync (struct rspamd_kvstorage_connection *conn,
+               const gpointer key, const gpointer value, gsize len, guint expire);
+
+/**
+ * Delete key synced
+ * @param conn connection structure
+ * @param key key to delete
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_delete_sync (struct rspamd_kvstorage_connection *conn,
+               const gpointer key);
+
+/**
+ * Close connection
+ * @param conn connection structure
+ */
+enum rspamd_kvstorage_error rspamd_kvstorage_close_sync (struct rspamd_kvstorage_connection *conn);
+
+#endif /* LIBKVSTORAGECLIENT_H_ */