diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-05-10 19:15:03 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-05-10 19:15:03 +0400 |
commit | 1fd435e5d4fc3c51fae8a1a184b347bdf6039d26 (patch) | |
tree | f17ee669ea0d5bfa497b3c952e8d7bed9885501a /lib | |
parent | 683b90f4c6c744557f7429ce6ff77c0f7d2175e1 (diff) | |
download | rspamd-1fd435e5d4fc3c51fae8a1a184b347bdf6039d26.tar.gz rspamd-1fd435e5d4fc3c51fae8a1a184b347bdf6039d26.zip |
* Rework build process:
- add librspamdserver
- link this library to all daemons and utils of rspamd
- use subdirectories more often
* Rework global variables logic - move them to the main process
* Fix logging to handle utf-8 correctly
* Add statshow utility and make it working
* Move printf functions to separate source file
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CMakeLists.txt | 50 | ||||
-rw-r--r-- | lib/librspamdclient.c | 163 |
2 files changed, 200 insertions, 13 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5b30f041b..951551e62 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,5 +1,5 @@ -# Librspamd -SET(LIBRSPAMDSRC librspamdclient.c ../src/util.c ../src/upstream.c ../src/mem_pool.c) +# Librspamdclient +SET(LIBRSPAMDSRC librspamdclient.c ../src/mem_pool.c ../src/upstream.c ../src/printf.c) ADD_LIBRARY(rspamdclient SHARED ${LIBRSPAMDSRC}) ADD_LIBRARY(rspamdclient_static STATIC ${LIBRSPAMDSRC}) @@ -9,6 +9,7 @@ SET_TARGET_PROPERTIES(rspamdclient_static PROPERTIES COMPILE_FLAGS "-fno-strict- TARGET_LINK_LIBRARIES(rspamdclient ${CMAKE_REQUIRED_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamdclient ${GLIB2_LIBRARIES}) + TARGET_LINK_LIBRARIES(rspamdclient_static ${CMAKE_REQUIRED_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamdclient_static ${GLIB2_LIBRARIES}) @@ -19,3 +20,48 @@ INSTALL(TARGETS rspamdclient rspamdclient_static LIBRARY PUBLIC_HEADER LIBRARY DESTINATION lib PUBLIC_HEADER DESTINATION include ARCHIVE DESTINATION lib) + + +# Librspamdserver +SET(RSPAMDLIBSRC ../src/binlog.c + ../src/bloom.c + ../src/buffer.c + ../src/cfg_utils.c + ../src/cfg_xml.c + ../src/dns.c + ../src/events.c + ../src/expressions.c + ../src/filter.c + ../src/fstring.c + ../src/fuzzy.c + ../src/hash.c + ../src/html.c + ../src/images.c + ../src/lmtp_proto.c + ../src/logger.c + ../src/map.c + ../src/memcached.c + ../src/mem_pool.c + ../src/message.c + ../src/printf.c + ../src/protocol.c + ../src/radix.c + ../src/settings.c + ../src/spf.c + ../src/smtp_proto.c + ../src/smtp_utils.c + ../src/statfile.c + ../src/statfile_sync.c + ../src/symbols_cache.c + ../src/trie.c + ../src/upstream.c + ../src/url.c + ../src/util.c + ../src/view.c) + +ADD_LIBRARY(rspamdserver STATIC ${RSPAMDLIBSRC}) +SET_TARGET_PROPERTIES(rspamdserver PROPERTIES LINKER_LANGUAGE C) +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)
\ No newline at end of file diff --git a/lib/librspamdclient.c b/lib/librspamdclient.c index fa92df208..0c624e2e2 100644 --- a/lib/librspamdclient.c +++ b/lib/librspamdclient.c @@ -27,10 +27,13 @@ #include "upstream.h" #include "util.h" #include "cfg_file.h" +#include "logger.h" #define MAX_RSPAMD_SERVERS 255 #define DEFAULT_CONNECT_TIMEOUT 500 #define DEFAULT_READ_TIMEOUT 5000 +/* Default connect timeout for sync sockets */ +#define CONNECT_TIMEOUT 3 #define G_RSPAMD_ERROR rspamd_error_quark () struct rspamd_server { @@ -60,6 +63,144 @@ struct rspamd_connection { static struct rspamd_client *client = NULL; +/** Util functions **/ +gint +make_socket_nonblocking (gint fd) +{ + gint ofl; + + ofl = fcntl (fd, F_GETFL, 0); + + if (fcntl (fd, F_SETFL, ofl | O_NONBLOCK) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + return -1; + } + return 0; +} + +gint +make_socket_blocking (gint fd) +{ + gint ofl; + + ofl = fcntl (fd, F_GETFL, 0); + + if (fcntl (fd, F_SETFL, ofl & (~O_NONBLOCK)) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + return -1; + } + return 0; +} + +gint +poll_sync_socket (gint fd, gint timeout, short events) +{ + gint r; + struct pollfd fds[1]; + + fds->fd = fd; + fds->events = events; + fds->revents = 0; + while ((r = poll (fds, 1, timeout)) < 0) { + if (errno != EINTR) { + break; + } + } + + return r; +} + +static gint +make_inet_socket (gint family, struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +{ + gint fd, r, optlen, on = 1, s_error; + gint serrno; + struct sockaddr_in sin; + + /* Create socket */ + fd = socket (AF_INET, family, 0); + if (fd == -1) { + msg_warn ("socket failed: %d, '%s'", errno, strerror (errno)); + return -1; + } + + if (make_socket_nonblocking (fd) < 0) { + goto out; + } + + /* Set close on exec */ + if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) { + msg_warn ("fcntl failed: %d, '%s'", errno, strerror (errno)); + goto out; + } + + memset (&sin, 0, sizeof (sin)); + + /* Bind options */ + sin.sin_family = AF_INET; + sin.sin_port = htons (port); + sin.sin_addr.s_addr = addr->s_addr; + + if (is_server) { + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (gint)); + r = bind (fd, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); + } + else { + r = connect (fd, (struct sockaddr *)&sin, sizeof (struct sockaddr_in)); + } + + if (r == -1) { + if (errno != EINPROGRESS) { + msg_warn ("bind/connect failed: %d, '%s'", errno, strerror (errno)); + goto out; + } + if (!async) { + /* Try to poll */ + if (poll_sync_socket (fd, CONNECT_TIMEOUT * 1000, POLLOUT) <= 0) { + errno = ETIMEDOUT; + msg_warn ("bind/connect failed: timeout"); + goto out; + } + else { + /* Make synced again */ + if (make_socket_blocking (fd) < 0) { + goto out; + } + } + } + } + else { + /* Still need to check SO_ERROR on socket */ + optlen = sizeof (s_error); + getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *)&s_error, &optlen); + if (s_error) { + errno = s_error; + goto out; + } + } + + + return (fd); + + out: + serrno = errno; + close (fd); + errno = serrno; + return (-1); +} + +gint +make_tcp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +{ + return make_inet_socket (SOCK_STREAM, addr, port, is_server, async); +} + +gint +make_udp_socket (struct in_addr *addr, u_short port, gboolean is_server, gboolean async) +{ + return make_inet_socket (SOCK_DGRAM, addr, port, is_server, async); +} + /** Private functions **/ static inline GQuark rspamd_error_quark (void) @@ -847,16 +988,16 @@ rspamd_send_normal_command (struct rspamd_connection *c, const gchar *command, gint r; /* Write command */ - r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s RSPAMC/1.3\r\n", command); - r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "Content-Length: %uz\r\n", clen); + r = snprintf (outbuf, sizeof (outbuf), "%s RSPAMC/1.3\r\n", command); + r += snprintf (outbuf + r, sizeof (outbuf) - r, "Content-Length: %lu\r\n", (unsigned long)clen); /* Iterate through headers */ if (headers != NULL) { g_hash_table_iter_init (&it, headers); while (g_hash_table_iter_next (&it, &key, &value)) { - r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "%s: %s\r\n", key, value); + r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s: %s\r\n", (const gchar *)key, (const gchar *)value); } } - r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "\r\n"); + r += snprintf (outbuf + r, sizeof (outbuf) - r, "\r\n"); if ((r = write (c->socket, outbuf, r)) == -1) { if (*err == NULL) { @@ -967,7 +1108,7 @@ rspamd_controller_auth (struct rspamd_connection *c, const gchar *password, GErr gint r; GString *in; - r = rspamd_snprintf (outbuf, sizeof (outbuf), "password %s\r\n", password); + r = snprintf (outbuf, sizeof (outbuf), "password %s\r\n", password); in = rspamd_send_controller_command (c, outbuf, r, -1, err); if (in == NULL) { @@ -1249,7 +1390,7 @@ rspamd_learn_memory (const guchar *message, gsize length, const gchar *symbol, c r = length + sizeof ("learn %s %uz\r\n") + strlen (symbol) + sizeof ("4294967296"); outbuf = g_malloc (r); - r = rspamd_snprintf (outbuf, r, "learn %s %uz\r\n%s", symbol, length, message); + r = snprintf (outbuf, r, "learn %s %lu\r\n%s", symbol, (unsigned long)length, message); in = rspamd_send_controller_command (c, outbuf, r, -1, err); g_free (outbuf); if (in == NULL) { @@ -1337,7 +1478,7 @@ rspamd_learn_fd (int fd, const gchar *symbol, const gchar *password, GError **er } r = sizeof ("learn %s %uz\r\n") + strlen (symbol) + sizeof ("4294967296"); outbuf = g_malloc (r); - r = rspamd_snprintf (outbuf, r, "learn %s %uz\r\n", symbol, st.st_size); + r = snprintf (outbuf, r, "learn %s %lu\r\n", symbol, (unsigned long)st.st_size); in = rspamd_send_controller_command (c, outbuf, r, fd, err); g_free (outbuf); if (in == NULL) { @@ -1397,10 +1538,10 @@ rspamd_fuzzy_memory (const guchar *message, gsize length, const gchar *password, r = length + sizeof ("fuzzy_add %uz %d %d\r\n") + sizeof ("4294967296") * 3; outbuf = g_malloc (r); if (delete) { - r = rspamd_snprintf (outbuf, r, "fuzzy_del %uz %d %d\r\n%s", length, weight, flag, message); + r = snprintf (outbuf, r, "fuzzy_del %lu %d %d\r\n%s", (unsigned long)length, weight, flag, message); } else { - r = rspamd_snprintf (outbuf, r, "fuzzy_add %uz %d %d\r\n%s", length, weight, flag, message); + r = snprintf (outbuf, r, "fuzzy_add %lu %d %d\r\n%s", (unsigned long)length, weight, flag, message); } in = rspamd_send_controller_command (c, outbuf, r, -1, err); g_free (outbuf); @@ -1489,10 +1630,10 @@ rspamd_fuzzy_fd (int fd, const gchar *password, gint weight, gint flag, gboolean r = sizeof ("fuzzy_add %uz %d %d\r\n") + sizeof ("4294967296") * 3; outbuf = g_malloc (r); if (delete) { - r = rspamd_snprintf (outbuf, r, "fuzzy_del %uz %d %d\r\n", st.st_size, weight, flag); + r = snprintf (outbuf, r, "fuzzy_del %lu %d %d\r\n", (unsigned long)st.st_size, weight, flag); } else { - r = rspamd_snprintf (outbuf, r, "fuzzy_add %uz %d %d\r\n", st.st_size, weight, flag); + r = snprintf (outbuf, r, "fuzzy_add %lu %d %d\r\n", (unsigned long)st.st_size, weight, flag); } in = rspamd_send_controller_command (c, outbuf, r, fd, err); |