CHECK_INCLUDE_FILES(pwd.h HAVE_PWD_H)
CHECK_INCLUDE_FILES(grp.h HAVE_GRP_H)
CHECK_INCLUDE_FILES(glob.h HAVE_GLOB_H)
+CHECK_INCLUDE_FILES(poll.h HAVE_POLL_H)
IF(HAVE_SYS_WAIT_H)
LIST(APPEND CMAKE_REQUIRED_INCLUDES sys/wait.h)
#cmakedefine HAVE_NETDB_H 1
+#cmakedefine HAVE_POLL_H 1
+
#cmakedefine HAVE_SYSLOG_H 1
#cmakedefine HAVE_LIBUTIL_H 1
#include <fcntl.h>
#endif
+/* poll */
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+
/* sys/stat */
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
if (dispatcher != NULL) {
event_del (dispatcher->ev);
memory_pool_delete (dispatcher->pool);
+ if (dispatcher->out_buffers) {
+ g_list_free (dispatcher->out_buffers);
+ }
g_free (dispatcher);
}
}
if (map_pool == NULL) {
map_pool = memory_pool_new (memory_pool_get_size ());
}
- new_map = memory_pool_alloc (map_pool, sizeof (struct rspamd_map));
+ new_map = memory_pool_alloc0 (map_pool, sizeof (struct rspamd_map));
new_map->read_callback = read_callback;
new_map->fin_callback = fin_callback;
new_map->user_data = user_data;
msg_warn ("add_map: cannot open file '%s': %s", def, strerror (errno));
return FALSE;
}
- fdata = memory_pool_alloc (map_pool, sizeof (struct file_map_data));
+ fdata = memory_pool_alloc0 (map_pool, sizeof (struct file_map_data));
fdata->filename = memory_pool_strdup (map_pool, def);
fstat (fd, &fdata->st);
new_map->map_data = fdata;
}
else if (proto == PROTO_HTTP) {
- hdata = memory_pool_alloc (map_pool, sizeof (struct http_map_data));
+ hdata = memory_pool_alloc0 (map_pool, sizeof (struct http_map_data));
/* Try to search port */
if ((p = strchr (def, ':')) != NULL) {
hostend = p;
return 0;
}
else {
+ memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, headerlist);
if (re->regexp == NULL) {
msg_debug ("process_regexp: regexp contains only header and it is found %s", re->header);
task_cache_add (task, re, 1);
- g_list_free (headerlist);
return 1;
}
cur = headerlist;
}
cur = g_list_next (cur);
}
- g_list_free (headerlist);
task_cache_add (task, re, 0);
return 0;
}
#define CHECK_TIME 60
/* More than 2 log messages per second */
#define BUF_INTENSITY 2
+/* Default connect timeout for sync sockets */
+#define CONNECT_TIMEOUT 3
#ifdef RSPAMD_MAIN
sig_atomic_t do_reopen_log = 0;
int
make_socket_nonblocking (int fd)
{
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
+ int ofl;
+
+ ofl = fcntl (fd, F_GETFL, 0);
+
+ if (fcntl (fd, F_SETFL, ofl | O_NONBLOCK) == -1) {
+ msg_warn ("make_socket_nonblocking: fcntl failed: %d, '%s'", errno, strerror (errno));
+ return -1;
+ }
+ return 0;
+}
+
+int
+make_socket_blocking (int fd)
+{
+ int ofl;
+
+ ofl = fcntl (fd, F_GETFL, 0);
+
+ if (fcntl (fd, F_SETFL, ofl & (~O_NONBLOCK)) == -1) {
msg_warn ("make_socket_nonblocking: fcntl failed: %d, '%s'", errno, strerror (errno));
return -1;
}
return 0;
}
+static int
+poll_sync_socket (int fd, int timeout, short events)
+{
+ int 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 int
make_inet_socket (int family, struct in_addr *addr, u_short port, gboolean is_server, gboolean async)
{
return -1;
}
- if (async && make_socket_nonblocking(fd) < 0) {
+ if (make_socket_nonblocking (fd) < 0) {
goto out;
}
}
if (r == -1) {
- if (!async || errno != EINPROGRESS) {
+ if (errno != EINPROGRESS) {
msg_warn ("make_tcp_socket: 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 ("make_tcp_socket: 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 */