Browse Source

* Rewrite buffered input for line policy (again)

* Fix issue with links that are ip addresses in numeric form in surbl
* On Darwin use BSD style sendfile definition
* Reorganize platform specific knobs in CMakeLists
* Use gettimeofday on systems that have not clock_getres
* Use ftime for dns trans id generation on systems without clock_getres
tags/0.3.1
Vsevolod Stakhov 14 years ago
parent
commit
e9d2ad6a1b
14 changed files with 208 additions and 111 deletions
  1. 52
    59
      CMakeLists.txt
  2. 10
    1
      config.h.in
  3. 41
    34
      src/buffer.c
  4. 11
    3
      src/cfg_utils.c
  5. 8
    0
      src/evdns/evdns.c
  6. 4
    0
      src/main.h
  7. 12
    0
      src/plugins/fuzzy_check.c
  8. 3
    3
      src/plugins/surbl.c
  9. 5
    0
      src/protocol.c
  10. 6
    1
      src/smtp.c
  11. 26
    6
      src/symbols_cache.c
  12. 17
    1
      src/util.c
  13. 4
    0
      src/util.h
  14. 9
    3
      src/worker.c

+ 52
- 59
CMakeLists.txt View File

INCLUDE(CheckCCompilerFlag) INCLUDE(CheckCCompilerFlag)
INCLUDE(FindPerl) INCLUDE(FindPerl)


# Initial set
SET(CMAKE_REQUIRED_LIBRARIES m)
SET(CMAKE_REQUIRED_INCLUDES sys/mman.h stdlib.h stdio.h unistd.h time.h sched.h)

# Platform specific routines
IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_BSD_SOURCE -DFREEBSD")
CONFIGURE_FILE(freebsd/rspamd.sh.in freebsd/rspamd.sh @ONLY)

IF(ENABLE_REDIRECTOR MATCHES "ON")
CONFIGURE_FILE(freebsd/redirector.sh.in freebsd/redirector.sh @ONLY)
ENDIF(ENABLE_REDIRECTOR MATCHES "ON")
IF(NOT ETC_PREFIX)
SET(ETC_PREFIX /usr/local/etc)
SET(PREFIX /usr/local)
ENDIF(NOT ETC_PREFIX)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES intl)

ENDIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")

IF(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_BSD_SOURCE -DDARWIN")

IF(NOT ETC_PREFIX)
SET(ETC_PREFIX /usr/local/etc)
SET(PREFIX /usr/local)
ENDIF(NOT ETC_PREFIX)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES intl)

ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Darwin")

IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE -DLINUX")
IF(NOT ETC_PREFIX)
SET(ETC_PREFIX /etc)
SET(PREFIX /usr)
ENDIF(NOT ETC_PREFIX)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES rt)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES dl)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")

IF(ENABLE_PERL MATCHES "ON") IF(ENABLE_PERL MATCHES "ON")


IF(NOT PERL_EXECUTABLE) IF(NOT PERL_EXECUTABLE)
INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS})
LINK_DIRECTORIES(${GLIB2_LIBRARY_DIRS}) LINK_DIRECTORIES(${GLIB2_LIBRARY_DIRS})


SET(CMAKE_REQUIRED_LIBRARIES m)
SET(CMAKE_REQUIRED_INCLUDES sys/mman.h stdlib.h stdio.h unistd.h time.h sched.h)


# Check for libevent # Check for libevent


IF(HAVE_SYS_WAIT_H) IF(HAVE_SYS_WAIT_H)
LIST(APPEND CMAKE_REQUIRED_INCLUDES sys/wait.h) LIST(APPEND CMAKE_REQUIRED_INCLUDES sys/wait.h)
ENDIF(HAVE_SYS_WAIT_H) ENDIF(HAVE_SYS_WAIT_H)
IF(HAVE_TIME_H)
LIST(APPEND CMAKE_REQUIRED_INCLUDES time.h)
ENDIF(HAVE_TIME_H)


CHECK_FUNCTION_EXISTS(setproctitle HAVE_SETPROCTITLE) CHECK_FUNCTION_EXISTS(setproctitle HAVE_SETPROCTITLE)
CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE) CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE)
CHECK_FUNCTION_EXISTS(tanhl HAVE_TANHL) CHECK_FUNCTION_EXISTS(tanhl HAVE_TANHL)
CHECK_FUNCTION_EXISTS(sendfile HAVE_SENDFILE) CHECK_FUNCTION_EXISTS(sendfile HAVE_SENDFILE)
CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP) CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP)
CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)


CHECK_SYMBOL_EXISTS(PATH_MAX limits.h HAVE_PATH_MAX) CHECK_SYMBOL_EXISTS(PATH_MAX limits.h HAVE_PATH_MAX)
CHECK_SYMBOL_EXISTS(MAXPATHLEN sys/param.h HAVE_MAXPATHLEN) CHECK_SYMBOL_EXISTS(MAXPATHLEN sys/param.h HAVE_MAXPATHLEN)
CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON) CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON)
CHECK_SYMBOL_EXISTS(MAP_NOCORE sys/mman.h HAVE_MMAP_NOCORE) CHECK_SYMBOL_EXISTS(MAP_NOCORE sys/mman.h HAVE_MMAP_NOCORE)
CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN) CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN)
CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID)
CHECK_SYMBOL_EXISTS(SA_SIGINFO signal.h HAVE_SA_SIGINFO) CHECK_SYMBOL_EXISTS(SA_SIGINFO signal.h HAVE_SA_SIGINFO)
CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL)

IF(HAVE_CLOCK_GETTIME)
CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID)
CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL)
ELSE(HAVE_CLOCK_GETTIME)
CHECK_INCLUDE_FILES(sys/timeb.h HAVE_SYS_TIMEDB_H)
ENDIF(HAVE_CLOCK_GETTIME)


CHECK_C_SOURCE_COMPILES ("#include <sys/types.h> CHECK_C_SOURCE_COMPILES ("#include <sys/types.h>
int main (int argc, char **argv) { int main (int argc, char **argv) {


SET(CMAKE_C_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_C_FLAGS} ${CMAKE_C_WARN_FLAGS}") SET(CMAKE_C_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_C_FLAGS} ${CMAKE_C_WARN_FLAGS}")


# Platform specific routines
IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_BSD_SOURCE -DFREEBSD")
CONFIGURE_FILE(freebsd/rspamd.sh.in freebsd/rspamd.sh @ONLY)

IF(ENABLE_REDIRECTOR MATCHES "ON")
CONFIGURE_FILE(freebsd/redirector.sh.in freebsd/redirector.sh @ONLY)
ENDIF(ENABLE_REDIRECTOR MATCHES "ON")
IF(NOT ETC_PREFIX)
SET(ETC_PREFIX /usr/local/etc)
SET(PREFIX /usr/local)
ENDIF(NOT ETC_PREFIX)

ENDIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")

IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE -DLINUX")
IF(NOT ETC_PREFIX)
SET(ETC_PREFIX /etc)
SET(PREFIX /usr)
ENDIF(NOT ETC_PREFIX)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")


IF(ENABLE_REDIRECTOR MATCHES "ON") IF(ENABLE_REDIRECTOR MATCHES "ON")
CONFIGURE_FILE(utils/redirector.pl.in utils/redirector.pl @ONLY) CONFIGURE_FILE(utils/redirector.pl.in utils/redirector.pl @ONLY)
TARGET_LINK_LIBRARIES(rspamd rspamd_lua) TARGET_LINK_LIBRARIES(rspamd rspamd_lua)
TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}") TARGET_LINK_LIBRARIES(rspamd "${LUA_LIBRARY}")


TARGET_LINK_LIBRARIES(rspamd m)
IF(LIBUTIL_LIBRARY)
TARGET_LINK_LIBRARIES(rspamd util)
ENDIF(LIBUTIL_LIBRARY)
IF(LIBJUDY_LIBRARY) IF(LIBJUDY_LIBRARY)
TARGET_LINK_LIBRARIES(rspamd Judy) TARGET_LINK_LIBRARIES(rspamd Judy)
ENDIF(LIBJUDY_LIBRARY) ENDIF(LIBJUDY_LIBRARY)
IF(ENABLE_STATIC MATCHES "ON") IF(ENABLE_STATIC MATCHES "ON")
TARGET_LINK_LIBRARIES(rspamd ${PCRE_LIBRARIES}) TARGET_LINK_LIBRARIES(rspamd ${PCRE_LIBRARIES})
ENDIF(ENABLE_STATIC MATCHES "ON") ENDIF(ENABLE_STATIC MATCHES "ON")
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(rspamd rt)
TARGET_LINK_LIBRARIES(rspamd dl)
ELSE(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(rspamd intl)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")


IF(ENABLE_GPERF_TOOLS MATCHES "ON") IF(ENABLE_GPERF_TOOLS MATCHES "ON")
TARGET_LINK_LIBRARIES(rspamd profiler) TARGET_LINK_LIBRARIES(rspamd profiler)


ADD_EXECUTABLE(test/rspamd-test ${TESTDEPENDS} ${CONTRIBSRC} ${TESTSRC}) ADD_EXECUTABLE(test/rspamd-test ${TESTDEPENDS} ${CONTRIBSRC} ${TESTSRC})
SET_TARGET_PROPERTIES(test/rspamd-test PROPERTIES LINKER_LANGUAGE C) SET_TARGET_PROPERTIES(test/rspamd-test PROPERTIES LINKER_LANGUAGE C)
TARGET_LINK_LIBRARIES(test/rspamd-test m)
IF(LIBUTIL_LIBRARY)
TARGET_LINK_LIBRARIES(test/rspamd-test util)
ENDIF(LIBUTIL_LIBRARY)
TARGET_LINK_LIBRARIES(test/rspamd-test event) TARGET_LINK_LIBRARIES(test/rspamd-test event)
TARGET_LINK_LIBRARIES(test/rspamd-test ${GLIB2_LIBRARIES}) TARGET_LINK_LIBRARIES(test/rspamd-test ${GLIB2_LIBRARIES})
IF(GMIME2_FOUND) IF(GMIME2_FOUND)
IF(ENABLE_STATIC MATCHES "ON") IF(ENABLE_STATIC MATCHES "ON")
TARGET_LINK_LIBRARIES(test/rspamd-test ${PCRE_LIBRARIES}) TARGET_LINK_LIBRARIES(test/rspamd-test ${PCRE_LIBRARIES})
ENDIF(ENABLE_STATIC MATCHES "ON") ENDIF(ENABLE_STATIC MATCHES "ON")
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(test/rspamd-test rt)
ELSE(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(test/rspamd-test intl)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")


ADD_EXECUTABLE(utils/url-extracter ${UTILSDEPENDS} ${CONTRIBSRC} ${UTILSSRC}) ADD_EXECUTABLE(utils/url-extracter ${UTILSDEPENDS} ${CONTRIBSRC} ${UTILSSRC})
SET_TARGET_PROPERTIES(utils/url-extracter PROPERTIES LINKER_LANGUAGE C) SET_TARGET_PROPERTIES(utils/url-extracter PROPERTIES LINKER_LANGUAGE C)
TARGET_LINK_LIBRARIES(utils/url-extracter m)
IF(LIBUTIL_LIBRARY)
TARGET_LINK_LIBRARIES(utils/url-extracter util)
ENDIF(LIBUTIL_LIBRARY)
TARGET_LINK_LIBRARIES(utils/url-extracter ${GLIB2_LIBRARIES}) TARGET_LINK_LIBRARIES(utils/url-extracter ${GLIB2_LIBRARIES})
IF(GMIME2_FOUND) IF(GMIME2_FOUND)
TARGET_LINK_LIBRARIES(utils/url-extracter ${GMIME2_LIBRARIES}) TARGET_LINK_LIBRARIES(utils/url-extracter ${GMIME2_LIBRARIES})
IF(ENABLE_STATIC MATCHES "ON") IF(ENABLE_STATIC MATCHES "ON")
TARGET_LINK_LIBRARIES(utils/url-extracter ${PCRE_LIBRARIES}) TARGET_LINK_LIBRARIES(utils/url-extracter ${PCRE_LIBRARIES})
ENDIF(ENABLE_STATIC MATCHES "ON") ENDIF(ENABLE_STATIC MATCHES "ON")
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(utils/url-extracter rt)
ELSE(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(utils/url-extracter intl)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")


ADD_EXECUTABLE(utils/expression-parser ${UTILSDEPENDS} ${CONTRIBSRC} ${EXPRSRC}) ADD_EXECUTABLE(utils/expression-parser ${UTILSDEPENDS} ${CONTRIBSRC} ${EXPRSRC})
SET_TARGET_PROPERTIES(utils/expression-parser PROPERTIES LINKER_LANGUAGE C) SET_TARGET_PROPERTIES(utils/expression-parser PROPERTIES LINKER_LANGUAGE C)
IF(ENABLE_STATIC MATCHES "ON") IF(ENABLE_STATIC MATCHES "ON")
TARGET_LINK_LIBRARIES(utils/expression-parser ${PCRE_LIBRARIES}) TARGET_LINK_LIBRARIES(utils/expression-parser ${PCRE_LIBRARIES})
ENDIF(ENABLE_STATIC MATCHES "ON") ENDIF(ENABLE_STATIC MATCHES "ON")
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(utils/expression-parser rt)
ELSE(CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES(utils/expression-parser intl)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")


##################### INSTALLATION ########################################## ##################### INSTALLATION ##########################################



+ 10
- 1
config.h.in View File

#cmakedefine HAVE_SYS_PARAM_H 1 #cmakedefine HAVE_SYS_PARAM_H 1
#cmakedefine HAVE_SYS_FILE_H 1 #cmakedefine HAVE_SYS_FILE_H 1
#cmakedefine HAVE_SYS_RESOURCE_H 1 #cmakedefine HAVE_SYS_RESOURCE_H 1
#cmakedefine HAVE_SYS_TIMEDB_H 1


#cmakedefine HAVE_PIDFILE 1 #cmakedefine HAVE_PIDFILE 1


#cmakedefine BUILD_STATIC 1 #cmakedefine BUILD_STATIC 1


#cmakedefine HAVE_SENDFILE 1 #cmakedefine HAVE_SENDFILE 1
#cmakedefine HAVE_MKSTEMP 1
#cmakedefine HAVE_SYS_SENDFILE_H 1 #cmakedefine HAVE_SYS_SENDFILE_H 1


#cmakedefine HAVE_MKSTEMP 1

#cmakedefine HAVE_CLOCK_GETTIME 1

#define RVERSION "${RSPAMD_VERSION}" #define RVERSION "${RSPAMD_VERSION}"
#define RSPAMD_MASTER_SITE_URL "${RSPAMD_MASTER_SITE_URL}" #define RSPAMD_MASTER_SITE_URL "${RSPAMD_MASTER_SITE_URL}"


#include <time.h> #include <time.h>
#endif #endif


/* timedb */
#ifdef HAVE_SYS_TIMEDB_H
#include <sys/timedb.h>
#endif

/* sysexits */ /* sysexits */
#ifdef HAVE_SYSEXITS_H #ifdef HAVE_SYSEXITS_H
#include <sysexits.h> #include <sysexits.h>

+ 41
- 34
src/buffer.c View File

GError *err; GError *err;


#ifdef HAVE_SENDFILE #ifdef HAVE_SENDFILE
#if defined(FREEBSD)
#if defined(FREEBSD) || defined(DARWIN)
off_t off = 0; off_t off = 0;
/* FreeBSD version */ /* FreeBSD version */
if (sendfile (d->sendfile_fd, d->fd, d->offset, 0, 0, &off, 0) != 0) { if (sendfile (d->sendfile_fd, d->fd, d->offset, 0, 0, &off, 0) != 0) {
GError *err; GError *err;
f_str_t res; f_str_t res;
char *c, *b; char *c, *b;
char **pos;
size_t *len;
char *end;
size_t len;
enum io_policy saved_policy; enum io_policy saved_policy;


if (d->wanna_die) { if (d->wanna_die) {
d->in_buf->pos = d->in_buf->data->begin; d->in_buf->pos = d->in_buf->data->begin;
} }


pos = &d->in_buf->pos;
len = &d->in_buf->data->len;
end = d->in_buf->pos;
len = d->in_buf->data->len;


if (BUFREMAIN (d->in_buf) == 0) { if (BUFREMAIN (d->in_buf) == 0) {
/* Buffer is full, try to call callback with overflow error */ /* Buffer is full, try to call callback with overflow error */
} }
else if (!skip_read) { else if (!skip_read) {
/* Try to read the whole buffer */ /* Try to read the whole buffer */
r = read (fd, *pos, BUFREMAIN (d->in_buf));
r = read (fd, end, BUFREMAIN (d->in_buf));
if (r == -1 && errno != EAGAIN) { if (r == -1 && errno != EAGAIN) {
if (d->err_callback) { if (d->err_callback) {
err = g_error_new (G_DISPATCHER_ERROR, errno, "%s", strerror (errno)); err = g_error_new (G_DISPATCHER_ERROR, errno, "%s", strerror (errno));
return; return;
} }
else { else {
*pos += r;
*len += r;
/* Set current position in buffer */
d->in_buf->pos += r;
d->in_buf->data->len += r;
} }
debug_ip (d->peer_addr, "read %z characters, policy is %s, watermark is: %z", r, debug_ip (d->peer_addr, "read %z characters, policy is %s, watermark is: %z", r,
d->policy == BUFFER_LINE ? "LINE" : "CHARACTER", d->nchars); d->policy == BUFFER_LINE ? "LINE" : "CHARACTER", d->nchars);


saved_policy = d->policy; saved_policy = d->policy;
c = d->in_buf->data->begin; c = d->in_buf->data->begin;
end = d->in_buf->pos;
len = d->in_buf->data->len;
b = c; b = c;
r = 0; r = 0;
* c - pointer to current position (buffer->begin + r) * c - pointer to current position (buffer->begin + r)
* res - result string * res - result string
*/ */
while (r < *len) {
while (r < len) {
if (*c == '\n') { if (*c == '\n') {
res.begin = b; res.begin = b;
res.len = c - b; res.len = c - b;
} }
if (d->policy != saved_policy) { if (d->policy != saved_policy) {
/* Drain buffer as policy is changed */ /* Drain buffer as policy is changed */
len = &d->in_buf->data->len;
pos = &d->in_buf->pos;
if (c != *pos) {
memmove (d->in_buf->data->begin, c + 1, *len - r - 1);
*len = *len -r - 1;
*pos = d->in_buf->data->begin + *len;
/* Note that d->in_buffer is other pointer now, so we need to reinit all pointers */
/* First detect how much symbols do we have */
if (end == c) {
/* In fact we read the whole buffer and change input policy, so just set current pos to begin of buffer */
d->in_buf->pos = d->in_buf->data->begin;
d->in_buf->data->len = 0;
} }
else { else {
*len = 0;
*pos = d->in_buf->data->begin;
/* Otherwise we need to move buffer */
/* Reinit pointers */
len = d->in_buf->data->len - r - 1;
end = d->in_buf->data->begin + r + 1;
memmove (d->in_buf->data->begin, end, len);
d->in_buf->data->len = len;
d->in_buf->pos = d->in_buf->data->begin + len;
/* Process remaining buffer */
read_buffers (fd, d, TRUE);
} }
debug_ip (d->peer_addr, "policy changed during callback, restart buffer's processing");
read_buffers (fd, d, TRUE);
return; return;
} }
} }
r++; r++;
c++; c++;
} }
/* Now drain buffer */
len = &d->in_buf->data->len;
pos = &d->in_buf->pos;
/* Now drain remaining characters in buffer */
memmove (d->in_buf->data->begin, b, c - b); memmove (d->in_buf->data->begin, b, c - b);
*len = c - b;
*pos = d->in_buf->data->begin + *len;
d->in_buf->data->len = c - b;
d->in_buf->pos = d->in_buf->data->begin + (c - b);
break; break;
case BUFFER_CHARACTER: case BUFFER_CHARACTER:
r = d->nchars; r = d->nchars;
if (*len >= r) {
if (len >= r) {
res.begin = b; res.begin = b;
res.len = r; res.len = r;
c = b + r; c = b + r;
return; return;
} }
/* Move remaining string to begin of buffer (draining) */ /* Move remaining string to begin of buffer (draining) */
len = &d->in_buf->data->len;
pos = &d->in_buf->pos;
memmove (d->in_buf->data->begin, c, *len - r);
b = d->in_buf->data->begin;
c = b;
*len -= r;
*pos = b + *len;
if (d->policy != saved_policy) {
if (len > r) {
len -= r;
memmove (d->in_buf->data->begin, c, len);
d->in_buf->data->len = len;
d->in_buf->pos = d->in_buf->data->begin + len;
b = d->in_buf->data->begin;
c = b;
}
if (d->policy != saved_policy && len != r) {
debug_ip (d->peer_addr, "policy changed during callback, restart buffer's processing"); debug_ip (d->peer_addr, "policy changed during callback, restart buffer's processing");
read_buffers (fd, d, TRUE); read_buffers (fd, d, TRUE);
return; return;
break; break;
case BUFFER_ANY: case BUFFER_ANY:
res.begin = d->in_buf->data->begin; res.begin = d->in_buf->data->begin;
res.len = *len;
res.len = len;
if (d->read_callback) { if (d->read_callback) {
if (!d->read_callback (&res, d->user_data)) { if (!d->read_callback (&res, d->user_data)) {
return; return;

+ 11
- 3
src/cfg_utils.c View File

void void
post_load_config (struct config_file *cfg) post_load_config (struct config_file *cfg)
{ {
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts; struct timespec ts;
#endif
struct metric *def_metric; struct metric *def_metric;


g_hash_table_foreach (cfg->variables, substitute_all_variables, cfg); g_hash_table_foreach (cfg->variables, substitute_all_variables, cfg);
parse_filters_str (cfg, cfg->filters_str); parse_filters_str (cfg, cfg->filters_str);
fill_cfg_params (cfg); fill_cfg_params (cfg);


#ifdef HAVE_CLOCK_GETTIME
#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID #ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
clock_getres (CLOCK_PROCESS_CPUTIME_ID, &ts); clock_getres (CLOCK_PROCESS_CPUTIME_ID, &ts);
#elif defined(HAVE_CLOCK_VIRTUAL)
# elif defined(HAVE_CLOCK_VIRTUAL)
clock_getres (CLOCK_VIRTUAL, &ts); clock_getres (CLOCK_VIRTUAL, &ts);
#else
# else
clock_getres (CLOCK_REALTIME, &ts); clock_getres (CLOCK_REALTIME, &ts);
#endif
# endif

cfg->clock_res = (int)log10 (1000000 / ts.tv_nsec); cfg->clock_res = (int)log10 (1000000 / ts.tv_nsec);
if (cfg->clock_res < 0) { if (cfg->clock_res < 0) {
cfg->clock_res = 0; cfg->clock_res = 0;
if (cfg->clock_res > 3) { if (cfg->clock_res > 3) {
cfg->clock_res = 3; cfg->clock_res = 3;
} }
#else
/* For gettimeofday */
cfg->clock_res = 1;
#endif


if ((def_metric = g_hash_table_lookup (cfg->metrics, DEFAULT_METRIC)) == NULL) { if ((def_metric = g_hash_table_lookup (cfg->metrics, DEFAULT_METRIC)) == NULL) {
def_metric = check_metric_conf (cfg, NULL); def_metric = check_metric_conf (cfg, NULL);

+ 8
- 0
src/evdns/evdns.c View File

default_transaction_id_fn(void) default_transaction_id_fn(void)
{ {
u16 trans_id; u16 trans_id;
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts; struct timespec ts;
static int clkid = -1; static int clkid = -1;
if (clkid == -1) { if (clkid == -1) {
} }
clock_gettime(clkid, &ts); clock_gettime(clkid, &ts);
trans_id = ts.tv_nsec & 0xffff; trans_id = ts.tv_nsec & 0xffff;
#elif defined(HAVE_SYS_TIMEDB_H)
struct timeb tb;
ftime(&tb);
trans_id = tb.millitm & 0xffff;
#else
# error Cannot find way to generate dns transaction id
#endif


return trans_id; return trans_id;
} }

+ 4
- 0
src/main.h View File

char *last_error; /**< last error */ char *last_error; /**< last error */
int error_code; /**< code of last error */ int error_code; /**< code of last error */
memory_pool_t *task_pool; /**< memory pool for task */ memory_pool_t *task_pool; /**< memory pool for task */
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts; /**< time of connection */ struct timespec ts; /**< time of connection */
#else
struct timeval tv; /**< time of connection */
#endif
struct rspamd_view *view; /**< matching view */ struct rspamd_view *view; /**< matching view */
gboolean view_checked; gboolean view_checked;
gboolean pass_all_filters; /**< pass task throught every rule */ gboolean pass_all_filters; /**< pass task throught every rule */

+ 12
- 0
src/plugins/fuzzy_check.c View File

} }


/* Get upstream */ /* Get upstream */
#ifdef HAVE_CLOCK_GETTIME
selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num, selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num,
sizeof (struct storage_server), task->ts.tv_sec, sizeof (struct storage_server), task->ts.tv_sec,
DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe));
#else
selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num,
sizeof (struct storage_server), task->tv.tv_sec,
DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe));
#endif
if (selected) { if (selected) {
if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) { if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) {
msg_warn ("cannot connect to %s, %d, %s", selected->name, errno, strerror (errno)); msg_warn ("cannot connect to %s, %d, %s", selected->name, errno, strerror (errno));
continue; continue;
} }
/* Get upstream */ /* Get upstream */
#ifdef HAVE_CLOCK_GETTIME
selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num, selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num,
sizeof (struct storage_server), task->ts.tv_sec, sizeof (struct storage_server), task->ts.tv_sec,
DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe)); DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe));
#else
selected = (struct storage_server *)get_upstream_by_hash (fuzzy_module_ctx->servers, fuzzy_module_ctx->servers_num,
sizeof (struct storage_server), task->tv.tv_sec,
DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS, part->fuzzy->hash_pipe, sizeof (part->fuzzy->hash_pipe));
#endif
if (selected) { if (selected) {
/* Create UDP socket */ /* Create UDP socket */
if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) { if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) {

+ 3
- 3
src/plugins/surbl.c View File

r = snprintf (result, len, "%*s.%*s.%*s.%*s", r = snprintf (result, len, "%*s.%*s.%*s.%*s",
(int)(hostname->len - (dots[2] - hostname->begin + 1)), (int)(hostname->len - (dots[2] - hostname->begin + 1)),
dots[2] + 1, dots[2] + 1,
(int)(dots[2] - (dots[1] - hostname->begin + 1)),
(int)(dots[2] - dots[1] - 1),
dots[1], dots[1],
(int)(dots[1] - (dots[0] - hostname->begin + 1)),
(int)(dots[1] - dots[0] - 1),
dots[0], dots[0],
(int)(dots[0] - (hostname->begin + 1)),
(int)(dots[0] - hostname->begin),
hostname->begin); hostname->begin);
} }
else if (is_numeric && dots_num == 0) { else if (is_numeric && dots_num == 0) {

+ 5
- 0
src/protocol.c View File

show_metric_symbols (metric_res, cd); show_metric_symbols (metric_res, cd);
} }
} }
#ifdef HAVE_CLOCK_GETTIME
cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %ld, time: %sms", cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %ld, time: %sms",
(long int)task->msg->len, calculate_check_time (&task->ts, task->cfg->clock_res)); (long int)task->msg->len, calculate_check_time (&task->ts, task->cfg->clock_res));
#else
cd->log_offset += snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %ld, time: %sms",
(long int)task->msg->len, calculate_check_time (&task->tv, task->cfg->clock_res));
#endif
} }


static void static void

+ 6
- 1
src/smtp.c View File

case SMTP_COMMAND_NOOP: case SMTP_COMMAND_NOOP:
break; break;
case SMTP_COMMAND_MAIL: case SMTP_COMMAND_MAIL:
if ((session->state == SMTP_STATE_GREETING || session->state == SMTP_STATE_HELO && !session->ctx->helo_required)
if (((session->state == SMTP_STATE_GREETING || session->state == SMTP_STATE_HELO) && !session->ctx->helo_required)
|| session->state == SMTP_STATE_FROM) { || session->state == SMTP_STATE_FROM) {
if (parse_smtp_from (session, cmd)) { if (parse_smtp_from (session, cmd)) {
session->state = SMTP_STATE_RCPT; session->state = SMTP_STATE_RCPT;
cur = g_list_next (cur); cur = g_list_next (cur);
} }
g_list_free (symbols); g_list_free (symbols);
#ifdef HAVE_CLOCK_GETTIME
r += snprintf (logbuf + r, sizeof (logbuf) - r, "]), len: %ld, time: %sms", r += snprintf (logbuf + r, sizeof (logbuf) - r, "]), len: %ld, time: %sms",
(long int)session->task->msg->len, calculate_check_time (&session->task->ts, session->cfg->clock_res)); (long int)session->task->msg->len, calculate_check_time (&session->task->ts, session->cfg->clock_res));
#else
r += snprintf (logbuf + r, sizeof (logbuf) - r, "]), len: %ld, time: %sms",
(long int)session->task->msg->len, calculate_check_time (&session->task->tv, session->cfg->clock_res));
#endif
msg_info ("%s", logbuf); msg_info ("%s", logbuf);


if (is_spam) { if (is_spam) {

+ 26
- 6
src/symbols_cache.c View File

gboolean gboolean
call_symbol_callback (struct worker_task * task, struct symbols_cache * cache, gpointer *save) call_symbol_callback (struct worker_task * task, struct symbols_cache * cache, gpointer *save)
{ {
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts1, ts2; struct timespec ts1, ts2;
#else
struct timeval tv1, tv2;
#endif
uint64_t diff; uint64_t diff;
struct cache_item *item = NULL; struct cache_item *item = NULL;
struct symbol_callback_data *s = *save; struct symbol_callback_data *s = *save;
return FALSE; return FALSE;
} }
if (check_view (task->cfg->views, item->s->symbol, task)) { if (check_view (task->cfg->views, item->s->symbol, task)) {
#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
#ifdef HAVE_CLOCK_GETTIME
# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts1); clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts1);
#elif defined(HAVE_CLOCK_VIRTUAL)
# elif defined(HAVE_CLOCK_VIRTUAL)
clock_gettime (CLOCK_VIRTUAL, &ts1); clock_gettime (CLOCK_VIRTUAL, &ts1);
#else
# else
clock_gettime (CLOCK_REALTIME, &ts1); clock_gettime (CLOCK_REALTIME, &ts1);
# endif
#else
if (gettimeofday (&tv1, NULL) == -1) {
msg_warn ("gettimeofday failed: %s", strerror (errno));
}
#endif #endif
item->func (task, item->user_data); item->func (task, item->user_data);


#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
#ifdef HAVE_CLOCK_GETTIME
# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts2); clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts2);
#elif defined(HAVE_CLOCK_VIRTUAL)
# elif defined(HAVE_CLOCK_VIRTUAL)
clock_gettime (CLOCK_VIRTUAL, &ts2); clock_gettime (CLOCK_VIRTUAL, &ts2);
#else
# else
clock_gettime (CLOCK_REALTIME, &ts2); clock_gettime (CLOCK_REALTIME, &ts2);
# endif
#else
if (gettimeofday (&tv2, NULL) == -1) {
msg_warn ("gettimeofday failed: %s", strerror (errno));
}
#endif #endif


#ifdef HAVE_CLOCK_GETTIME
diff = (ts2.tv_sec - ts1.tv_sec) * 1000000 + (ts2.tv_nsec - ts1.tv_nsec) / 1000; diff = (ts2.tv_sec - ts1.tv_sec) * 1000000 + (ts2.tv_nsec - ts1.tv_nsec) / 1000;
#else
diff = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec);
#endif
item->s->avg_time = set_counter (item->s->symbol, diff); item->s->avg_time = set_counter (item->s->symbol, diff);
} }



+ 17
- 1
src/util.c View File

return new; return new;
} }


#ifdef HAVE_CLOCK_GETTIME
const char * const char *
calculate_check_time (struct timespec *begin, int resolution) calculate_check_time (struct timespec *begin, int resolution)
#else
const char *
calculate_check_time (struct timeval *begin, int resolution)
#endif
{ {
struct timespec ts;
double diff; double diff;
static char res[sizeof ("100000.000")]; static char res[sizeof ("100000.000")];
static char fmt[sizeof ("%.10f")]; static char fmt[sizeof ("%.10f")];
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;


#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID #ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts); clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts);


diff = (ts.tv_sec - begin->tv_sec) * 1000. + /* Seconds */ diff = (ts.tv_sec - begin->tv_sec) * 1000. + /* Seconds */
(ts.tv_nsec - begin->tv_nsec) / 1000000.; /* Nanoseconds */ (ts.tv_nsec - begin->tv_nsec) / 1000000.; /* Nanoseconds */
#else
struct timeval tv;

if (gettimeofday (&tv, NULL) == -1) {
msg_warn ("gettimeofday failed: %s", strerror (errno));
}
diff = (tv.tv_sec - begin->tv_sec) * 1000. + /* Seconds */
(tv.tv_usec - begin->tv_usec) / 1000.; /* Microseconds */
#endif

sprintf (fmt, "%%.%df", resolution); sprintf (fmt, "%%.%df", resolution);
snprintf (res, sizeof (res), fmt, diff); snprintf (res, sizeof (res), fmt, diff);



+ 4
- 0
src/util.h View File



/* Replace %r with rcpt value and %f with from value, new string is allocated in pool */ /* Replace %r with rcpt value and %f with from value, new string is allocated in pool */
char* resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from); char* resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from);
#ifdef HAVE_CLOCK_GETTIME
const char* calculate_check_time (struct timespec *begin, int resolution); const char* calculate_check_time (struct timespec *begin, int resolution);
#else
const char* calculate_check_time (struct timeval *begin, int resolution);
#endif


double set_counter (const char *name, long int value); double set_counter (const char *name, long int value);



+ 9
- 3
src/worker.c View File

new_task->cfg = worker->srv->cfg; new_task->cfg = worker->srv->cfg;
new_task->from_addr.s_addr = INADDR_NONE; new_task->from_addr.s_addr = INADDR_NONE;
new_task->view_checked = FALSE; new_task->view_checked = FALSE;
#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
#ifdef HAVE_CLOCK_GETTIME
# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &new_task->ts); clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &new_task->ts);
#elif defined(HAVE_CLOCK_VIRTUAL)
# elif defined(HAVE_CLOCK_VIRTUAL)
clock_gettime (CLOCK_VIRTUAL, &new_task->ts); clock_gettime (CLOCK_VIRTUAL, &new_task->ts);
#else
# else
clock_gettime (CLOCK_REALTIME, &new_task->ts); clock_gettime (CLOCK_REALTIME, &new_task->ts);
# endif
#else
if (gettimeofday (&new_task->tv, NULL) == -1) {
msg_warn ("gettimeofday failed: %s", strerror (errno));
}
#endif #endif
io_tv.tv_sec = WORKER_IO_TIMEOUT; io_tv.tv_sec = WORKER_IO_TIMEOUT;
io_tv.tv_usec = 0; io_tv.tv_usec = 0;

Loading…
Cancel
Save