summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2012-09-19 20:42:30 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2012-09-19 20:42:30 +0400
commit0a9d9f994e0e959c207676cbf01ca74c59ce1554 (patch)
tree80bb58ad210530d16a5a0b38bb95c970815bba99
parent91d183b8f4719ecc6b339cc3e8d9239bf7594e30 (diff)
downloadrspamd-0a9d9f994e0e959c207676cbf01ca74c59ce1554.tar.gz
rspamd-0a9d9f994e0e959c207676cbf01ca74c59ce1554.zip
* Add map_watch_interval configurable.
Support floating point values for time intervals.
-rw-r--r--conf/rspamd-basic.xml.in4
-rw-r--r--src/cfg_file.h2
-rw-r--r--src/cfg_utils.c6
-rw-r--r--src/cfg_xml.c19
-rw-r--r--src/cfg_xml.h1
-rw-r--r--src/map.c248
6 files changed, 150 insertions, 130 deletions
diff --git a/conf/rspamd-basic.xml.in b/conf/rspamd-basic.xml.in
index d78ab931f..06bd80c03 100644
--- a/conf/rspamd-basic.xml.in
+++ b/conf/rspamd-basic.xml.in
@@ -25,13 +25,15 @@
<dns_retransmits>5</dns_retransmits>
<!-- File for saving settings of symbols cache -->
<cache_file>@LOCALSTATES_PREFIX@/symbols.cache</cache_file>
+ <!-- Maps watch timeout (floating point number in seconds, for file maps this timeout is reduced by two) -->
+ <map_watch_interval>10.0s</map_watch_interval>
</options>
<!-- End of options section -->
<!-- Logging section -->
<logging>
<level>info</level>
- <log_urls>yes</log_urls>
+ <log_urls>no</log_urls>
<type>console</type>
<!-- Other types
<type filename="/var/log/rspamd/rspamd.log">file</type>
diff --git a/src/cfg_file.h b/src/cfg_file.h
index 279f35988..e2c1c7678 100644
--- a/src/cfg_file.h
+++ b/src/cfg_file.h
@@ -409,7 +409,7 @@ guint64 parse_limit (const gchar *limit, guint len);
* @param default_type dimension of time if no suffix is specified
* @return value of time in milliseconds
*/
-guint cfg_parse_time (const gchar *t, enum time_type default_type);
+gdouble cfg_parse_time (const gchar *t, enum time_type default_type);
/**
* Parse flag
diff --git a/src/cfg_utils.c b/src/cfg_utils.c
index 1651f16ff..d554ae7fb 100644
--- a/src/cfg_utils.c
+++ b/src/cfg_utils.c
@@ -340,7 +340,7 @@ parse_limit (const gchar *limit, guint len)
return result;
}
-guint
+gdouble
cfg_parse_time (const gchar *t, enum time_type default_type)
{
union {
@@ -444,10 +444,10 @@ cfg_parse_time (const gchar *t, enum time_type default_type)
}
}
if (use_double) {
- return rint (result.d);
+ return result.d;
}
else {
- return result.i;
+ return (gdouble)result.i;
}
}
diff --git a/src/cfg_xml.c b/src/cfg_xml.c
index 1f0c0aa78..e47ead1c8 100644
--- a/src/cfg_xml.c
+++ b/src/cfg_xml.c
@@ -306,6 +306,12 @@ static struct xml_parser_rule grammar[] = {
G_STRUCT_OFFSET (struct config_file, max_diff),
NULL
},
+ {
+ "map_watch_interval",
+ xml_handle_double,
+ G_STRUCT_OFFSET (struct config_file, map_timeout),
+ NULL
+ },
NULL_ATTR
},
NULL_DEF_ATTR
@@ -1604,12 +1610,23 @@ xml_handle_seconds (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GH
guint32 *dest;
dest = (guint32 *)G_STRUCT_MEMBER_P (dest_struct, offset);
- *dest = cfg_parse_time (data, TIME_SECONDS);
+ *dest = rint (cfg_parse_time (data, TIME_SECONDS));
return TRUE;
}
gboolean
+xml_handle_seconds_double (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
+{
+ gdouble *dest;
+
+ dest = (gdouble *)G_STRUCT_MEMBER_P (dest_struct, offset);
+ *dest = cfg_parse_time (data, TIME_SECONDS);
+
+ return TRUE;
+}
+
+gboolean
xml_handle_boolean (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
{
gboolean *dest;
diff --git a/src/cfg_xml.h b/src/cfg_xml.h
index bfe8123a0..ed41c7515 100644
--- a/src/cfg_xml.h
+++ b/src/cfg_xml.h
@@ -104,6 +104,7 @@ gboolean xml_handle_size (struct config_file *cfg, struct rspamd_xml_userdata *c
gboolean xml_handle_size_64 (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
gboolean xml_handle_double (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
gboolean xml_handle_seconds (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
+gboolean xml_handle_seconds_double (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
gboolean xml_handle_int (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
gboolean xml_handle_uint32 (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
gboolean xml_handle_uint16 (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
diff --git a/src/map.c b/src/map.c
index 0bc5b92ac..2ce8f2113 100644
--- a/src/map.c
+++ b/src/map.c
@@ -448,130 +448,6 @@ read_map_file (struct rspamd_map *map, struct file_map_data *data)
*map->user_data = cbdata.cur_data;
}
-gboolean
-check_map_proto (const gchar *map_line, gint *res, const gchar **pos)
-{
- if (g_ascii_strncasecmp (map_line, "http://", sizeof ("http://") - 1) == 0) {
- if (res && pos) {
- *res = PROTO_HTTP;
- *pos = map_line + sizeof ("http://") - 1;
- }
- }
- else if (g_ascii_strncasecmp (map_line, "file://", sizeof ("file://") - 1) == 0) {
- if (res && pos) {
- *res = PROTO_FILE;
- *pos = map_line + sizeof ("file://") - 1;
- }
- }
- else if (*map_line == '/') {
- /* Trivial file case */
- *res = PROTO_FILE;
- *pos = map_line;
- }
- else {
- msg_warn ("invalid map fetching protocol: %s", map_line);
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-add_map (struct config_file *cfg, const gchar *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback, void **user_data)
-{
- struct rspamd_map *new_map;
- enum fetch_proto proto;
- const gchar *def, *p, *hostend;
- struct file_map_data *fdata;
- struct http_map_data *hdata;
- gchar portbuf[6];
- gint i, s, fd;
- struct hostent *hent;
-
- /* First of all detect protocol line */
- if (!check_map_proto (map_line, (int *)&proto, &def)) {
- return FALSE;
- }
- /* Constant pool */
- if (cfg->map_pool == NULL) {
- cfg->map_pool = memory_pool_new (memory_pool_get_size ());
- }
- new_map = memory_pool_alloc0 (cfg->map_pool, sizeof (struct rspamd_map));
- new_map->read_callback = read_callback;
- new_map->fin_callback = fin_callback;
- new_map->user_data = user_data;
- new_map->protocol = proto;
-
- /* Now check for each proto separately */
- if (proto == PROTO_FILE) {
- if ((fd = open (def, O_RDONLY)) == -1) {
- msg_warn ("cannot open file '%s': %s", def, strerror (errno));
- return FALSE;
- }
- fdata = memory_pool_alloc0 (cfg->map_pool, sizeof (struct file_map_data));
- fdata->filename = memory_pool_strdup (cfg->map_pool, def);
- fstat (fd, &fdata->st);
- new_map->map_data = fdata;
- }
- else if (proto == PROTO_HTTP) {
- hdata = memory_pool_alloc0 (cfg->map_pool, sizeof (struct http_map_data));
- /* Try to search port */
- if ((p = strchr (def, ':')) != NULL) {
- hostend = p;
- i = 0;
- p++;
- while (g_ascii_isdigit (*p) && i < (gint)sizeof (portbuf) - 1) {
- portbuf[i++] = *p++;
- }
- if (*p != '/') {
- msg_info ("bad http map definition: %s", def);
- return FALSE;
- }
- portbuf[i] = '\0';
- hdata->port = atoi (portbuf);
- }
- else {
- /* Default http port */
- hdata->port = 80;
- /* Now separate host from path */
- if ((p = strchr (def, '/')) == NULL) {
- msg_info ("bad http map definition: %s", def);
- return FALSE;
- }
- hostend = p;
- }
- hdata->host = memory_pool_alloc (cfg->map_pool, hostend - def + 1);
- rspamd_strlcpy (hdata->host, def, hostend - def + 1);
- hdata->path = memory_pool_strdup (cfg->map_pool, p);
- hdata->rlen = 0;
- /* Now try to resolve */
- if (!inet_aton (hdata->host, &hdata->addr)) {
- /* Resolve using dns */
- hent = gethostbyname (hdata->host);
- if (hent == NULL) {
- msg_info ("cannot resolve: %s", hdata->host);
- return FALSE;
- }
- else {
- memcpy (&hdata->addr, hent->h_addr, sizeof (struct in_addr));
- }
- }
- /* Now try to connect */
- if ((s = make_tcp_socket (&hdata->addr, hdata->port, FALSE, FALSE)) == -1) {
- msg_info ("cannot connect to http server %s: %d, %s", hdata->host, errno, strerror (errno));
- return FALSE;
- }
- close (s);
- new_map->map_data = hdata;
- }
- /* Temp pool */
- new_map->pool = memory_pool_new (memory_pool_get_size ());
-
- cfg->maps = g_list_prepend (cfg->maps, new_map);
-
- return TRUE;
-}
-
/**
* FSM for parsing lists
*/
@@ -1073,3 +949,127 @@ remove_all_maps (struct config_file *cfg)
}
}
+gboolean
+check_map_proto (const gchar *map_line, gint *res, const gchar **pos)
+{
+ if (g_ascii_strncasecmp (map_line, "http://", sizeof ("http://") - 1) == 0) {
+ if (res && pos) {
+ *res = PROTO_HTTP;
+ *pos = map_line + sizeof ("http://") - 1;
+ }
+ }
+ else if (g_ascii_strncasecmp (map_line, "file://", sizeof ("file://") - 1) == 0) {
+ if (res && pos) {
+ *res = PROTO_FILE;
+ *pos = map_line + sizeof ("file://") - 1;
+ }
+ }
+ else if (*map_line == '/') {
+ /* Trivial file case */
+ *res = PROTO_FILE;
+ *pos = map_line;
+ }
+ else {
+ msg_warn ("invalid map fetching protocol: %s", map_line);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+add_map (struct config_file *cfg, const gchar *map_line, map_cb_t read_callback, map_fin_cb_t fin_callback, void **user_data)
+{
+ struct rspamd_map *new_map;
+ enum fetch_proto proto;
+ const gchar *def, *p, *hostend;
+ struct file_map_data *fdata;
+ struct http_map_data *hdata;
+ gchar portbuf[6];
+ gint i, s, fd;
+ struct hostent *hent;
+
+ /* First of all detect protocol line */
+ if (!check_map_proto (map_line, (int *)&proto, &def)) {
+ return FALSE;
+ }
+ /* Constant pool */
+ if (cfg->map_pool == NULL) {
+ cfg->map_pool = memory_pool_new (memory_pool_get_size ());
+ }
+ new_map = memory_pool_alloc0 (cfg->map_pool, sizeof (struct rspamd_map));
+ new_map->read_callback = read_callback;
+ new_map->fin_callback = fin_callback;
+ new_map->user_data = user_data;
+ new_map->protocol = proto;
+ new_map->cfg = cfg;
+
+ /* Now check for each proto separately */
+ if (proto == PROTO_FILE) {
+ if ((fd = open (def, O_RDONLY)) == -1) {
+ msg_warn ("cannot open file '%s': %s", def, strerror (errno));
+ return FALSE;
+ }
+ fdata = memory_pool_alloc0 (cfg->map_pool, sizeof (struct file_map_data));
+ fdata->filename = memory_pool_strdup (cfg->map_pool, def);
+ fstat (fd, &fdata->st);
+ new_map->map_data = fdata;
+ }
+ else if (proto == PROTO_HTTP) {
+ hdata = memory_pool_alloc0 (cfg->map_pool, sizeof (struct http_map_data));
+ /* Try to search port */
+ if ((p = strchr (def, ':')) != NULL) {
+ hostend = p;
+ i = 0;
+ p++;
+ while (g_ascii_isdigit (*p) && i < (gint)sizeof (portbuf) - 1) {
+ portbuf[i++] = *p++;
+ }
+ if (*p != '/') {
+ msg_info ("bad http map definition: %s", def);
+ return FALSE;
+ }
+ portbuf[i] = '\0';
+ hdata->port = atoi (portbuf);
+ }
+ else {
+ /* Default http port */
+ hdata->port = 80;
+ /* Now separate host from path */
+ if ((p = strchr (def, '/')) == NULL) {
+ msg_info ("bad http map definition: %s", def);
+ return FALSE;
+ }
+ hostend = p;
+ }
+ hdata->host = memory_pool_alloc (cfg->map_pool, hostend - def + 1);
+ rspamd_strlcpy (hdata->host, def, hostend - def + 1);
+ hdata->path = memory_pool_strdup (cfg->map_pool, p);
+ hdata->rlen = 0;
+ /* Now try to resolve */
+ if (!inet_aton (hdata->host, &hdata->addr)) {
+ /* Resolve using dns */
+ hent = gethostbyname (hdata->host);
+ if (hent == NULL) {
+ msg_info ("cannot resolve: %s", hdata->host);
+ return FALSE;
+ }
+ else {
+ memcpy (&hdata->addr, hent->h_addr, sizeof (struct in_addr));
+ }
+ }
+ /* Now try to connect */
+ if ((s = make_tcp_socket (&hdata->addr, hdata->port, FALSE, FALSE)) == -1) {
+ msg_info ("cannot connect to http server %s: %d, %s", hdata->host, errno, strerror (errno));
+ return FALSE;
+ }
+ close (s);
+ new_map->map_data = hdata;
+ }
+ /* Temp pool */
+ new_map->pool = memory_pool_new (memory_pool_get_size ());
+
+ cfg->maps = g_list_prepend (cfg->maps, new_map);
+
+ return TRUE;
+}