From: Vsevolod Stakhov Date: Mon, 9 Nov 2009 18:05:38 +0000 (+0300) Subject: * Avoid mmap'ing in binlog as mmapped areas must be aligned X-Git-Tag: 0.3.0~131 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=161f4d012cb00bf40853a0bb59f22d1373dbff53;p=rspamd.git * Avoid mmap'ing in binlog as mmapped areas must be aligned * Make binlog working for writing * Add config params for binlog --- diff --git a/src/binlog.c b/src/binlog.c index 457e56a42..0e92b09ca 100644 --- a/src/binlog.c +++ b/src/binlog.c @@ -24,6 +24,7 @@ #include "config.h" #include "binlog.h" +#include "cfg_file.h" #include "tokenizers/tokenizers.h" #define BINLOG_SUFFIX ".binlog" @@ -31,6 +32,9 @@ #define VALID_MAGIC { 'r', 's', 'l' } #define VALID_VERSION { '1', '0' } +static GHashTable *binlog_opened = NULL; +static memory_pool_t *binlog_pool = NULL; + static gboolean binlog_write_header (struct rspamd_binlog *log) { @@ -82,14 +86,6 @@ binlog_write_header (struct rspamd_binlog *log) unlock_file (log->fd, FALSE); return FALSE; } - g_free (log->cur_idx); - /* Now mmap it to memory */ - if ((log->cur_idx = mmap (NULL, sizeof (struct rspamd_index_block), - PROT_READ | PROT_WRITE, MAP_SHARED, log->fd, log->metaindex->indexes[0])) == MAP_FAILED) { - msg_warn ("binlog_write_header: cannot mmap file %s, error %d, %s", log->filename, errno, strerror (errno)); - unlock_file (log->fd, FALSE); - return FALSE; - } unlock_file (log->fd, FALSE); @@ -113,15 +109,23 @@ binlog_check_file (struct rspamd_binlog *log) return FALSE; } /* Now mmap metaindex and current index */ - if ((log->metaindex = mmap (NULL, sizeof (struct rspamd_binlog_metaindex), - PROT_READ | PROT_WRITE, MAP_SHARED, log->fd, sizeof (struct rspamd_binlog_header))) == MAP_FAILED) { - msg_warn ("binlog_check file: cannot mmap file %s, error %d, %s", log->filename, errno, strerror (errno)); + if (log->metaindex == NULL) { + log->metaindex = g_malloc (sizeof (struct rspamd_binlog_metaindex)); + } + if ((read (log->fd, log->metaindex, sizeof (struct rspamd_binlog_metaindex))) != sizeof (struct rspamd_binlog_metaindex)) { + msg_warn ("binlog_check file: cannot read metaindex of file %s, error %d, %s", log->filename, errno, strerror (errno)); return FALSE; } /* Current index */ - if ((log->cur_idx = mmap (NULL, sizeof (struct rspamd_index_block), - PROT_READ | PROT_WRITE, MAP_SHARED, log->fd, log->metaindex->indexes[log->metaindex->last_index])) == MAP_FAILED) { - msg_warn ("binlog_check_file: cannot mmap file %s, error %d, %s", log->filename, errno, strerror (errno)); + if (log->cur_idx == NULL) { + log->cur_idx = g_malloc (sizeof (struct rspamd_index_block)); + } + if (lseek (log->fd, log->metaindex->indexes[log->metaindex->last_index], SEEK_SET) == -1) { + msg_info ("binlog_check_file: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } + if ((read (log->fd, log->cur_idx, sizeof (struct rspamd_index_block))) != sizeof (struct rspamd_index_block)) { + msg_warn ("binlog_check_file: cannot read index in file %s, error %d, %s", log->filename, errno, strerror (errno)); return FALSE; } @@ -162,8 +166,11 @@ binlog_open (memory_pool_t *pool, const char *path, time_t rotate_time, int rota new = memory_pool_alloc0 (pool, sizeof (struct rspamd_binlog)); new->pool = pool; new->rotate_time = rotate_time; - new->rotate_jitter = g_random_int_range (0, rotate_jitter); new->fd = -1; + + if (rotate_time) { + new->rotate_jitter = g_random_int_range (0, rotate_jitter); + } new->filename = memory_pool_alloc (pool, len + sizeof (BINLOG_SUFFIX)); g_strlcpy (new->filename, path, len + 1); @@ -197,10 +204,10 @@ binlog_close (struct rspamd_binlog *log) { if (log) { if (log->metaindex) { - munmap (log->metaindex, sizeof (struct rspamd_binlog_metaindex)); + g_free (log->metaindex); } if (log->cur_idx) { - munmap (log->cur_idx, sizeof (struct rspamd_index_block)); + g_free (log->cur_idx); } close (log->fd); } @@ -230,22 +237,45 @@ write_binlog_tree (struct rspamd_binlog *log, GTree *nodes) { off_t seek; struct rspamd_binlog_index *idx; - - /* Seek to end of file */ - if ((seek = lseek (log->fd, 0, SEEK_END)) == -1) { + + lock_file (log->fd, FALSE); + /* Write index */ + log->cur_idx->last_index ++; + if (lseek (log->fd, log->metaindex->indexes[log->metaindex->last_index] + G_STRUCT_OFFSET (struct rspamd_index_block, last_index), SEEK_SET) == -1) { + unlock_file (log->fd, FALSE); msg_info ("binlog_insert: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); return FALSE; } + if (write (log->fd, &log->cur_idx->last_index, sizeof (log->cur_idx->last_index)) == -1) { + unlock_file (log->fd, FALSE); + msg_info ("binlog_insert: cannot write index to file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } - lock_file (log->fd, FALSE); - /* Write index */ - log->cur_idx->last_index ++; log->cur_seq ++; idx = &log->cur_idx->indexes[log->cur_idx->last_index]; idx->seek = seek; idx->time = (uint64_t)time (NULL); idx->len = g_tree_nnodes (nodes) * sizeof (struct rspamd_binlog_element); + if (lseek (log->fd, log->metaindex->indexes[log->metaindex->last_index] + + log->cur_idx->last_index * sizeof (struct rspamd_binlog_index), SEEK_SET) == -1) { + unlock_file (log->fd, FALSE); + msg_info ("binlog_insert: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } + if (write (log->fd, idx, sizeof (struct rspamd_binlog_index)) == -1) { + unlock_file (log->fd, FALSE); + msg_info ("binlog_insert: cannot write index to file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } + + /* Seek to end of file */ + if ((seek = lseek (log->fd, 0, SEEK_END)) == -1) { + unlock_file (log->fd, FALSE); + msg_info ("binlog_insert: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } /* Now write all nodes to file */ g_tree_foreach (nodes, binlog_tree_callback, (gpointer)log); @@ -260,34 +290,34 @@ create_new_metaindex_block (struct rspamd_binlog *log) { off_t seek; - /* Seek to end of file */ - if ((seek = lseek (log->fd, 0, SEEK_END)) == -1) { - msg_info ("create_new_metaindex_block: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); - return FALSE; - } lock_file (log->fd, FALSE); log->metaindex->last_index ++; /* Offset to metaindex */ log->metaindex->indexes[log->metaindex->last_index] = seek; - munmap (log->cur_idx, sizeof (struct rspamd_index_block)); - /* Alloc, write, mmap */ - log->cur_idx = g_malloc (sizeof (struct rspamd_index_block)); + /* Overwrite all metaindexes */ + if (lseek (log->fd, sizeof (struct rspamd_binlog_header), SEEK_SET) == -1) { + unlock_file (log->fd, FALSE); + msg_info ("create_new_metaindex_block: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } + if (write (log->fd, log->metaindex, sizeof (struct rspamd_binlog_metaindex)) == -1) { + unlock_file (log->fd, FALSE); + msg_info ("create_new_metaindex_block: cannot write metaindex in file: %s, error: %s", log->filename, strerror (errno)); + return FALSE; + } bzero (log->cur_idx, sizeof (struct rspamd_index_block)); - if (write (log->fd, log->cur_idx, sizeof (struct rspamd_index_block)) == -1) { + /* Seek to end of file */ + if ((seek = lseek (log->fd, 0, SEEK_END)) == -1) { unlock_file (log->fd, FALSE); - g_free (log->cur_idx); - msg_warn ("create_new_metaindex_block: cannot write file %s, error %d, %s", log->filename, errno, strerror (errno)); + msg_info ("create_new_metaindex_block: cannot seek in file: %s, error: %s", log->filename, strerror (errno)); return FALSE; } - g_free (log->cur_idx); - /* Now mmap it to memory */ - if ((log->cur_idx = mmap (NULL, sizeof (struct rspamd_index_block), - PROT_READ | PROT_WRITE, MAP_SHARED, log->fd, seek)) == MAP_FAILED) { - log->cur_idx = NULL; + if (write (log->fd, log->cur_idx, sizeof (struct rspamd_index_block)) == -1) { unlock_file (log->fd, FALSE); - msg_warn ("create_new_metaindex_block: cannot mmap file %s, error %d, %s", log->filename, errno, strerror (errno)); + g_free (log->cur_idx); + msg_warn ("create_new_metaindex_block: cannot write file %s, error %d, %s", log->filename, errno, strerror (errno)); return FALSE; } unlock_file (log->fd, FALSE); @@ -300,7 +330,7 @@ maybe_rotate_binlog (struct rspamd_binlog *log) { uint64_t now = time (NULL); - if ((now - log->header.create_time) > log->rotate_time + log->rotate_jitter) { + if (log->rotate_time && ((now - log->header.create_time) > log->rotate_time + log->rotate_jitter)) { return TRUE; } return FALSE; @@ -316,11 +346,11 @@ rotate_binlog (struct rspamd_binlog *log) /* Unmap mapped fragments */ if (log->metaindex) { - munmap (log->metaindex, sizeof (struct rspamd_binlog_metaindex)); + g_free (log->metaindex); log->metaindex = NULL; } if (log->cur_idx) { - munmap (log->cur_idx, sizeof (struct rspamd_index_block)); + g_free (log->cur_idx); log->cur_idx = NULL; } /* Format backup name */ @@ -403,7 +433,7 @@ binlog_sync (struct rspamd_binlog *log, uint64_t from_rev, uint64_t from_time, G } else { /* Unmap old fragment */ - munmap ((*rep)->data, (*rep)->len); + g_free ((*rep)->data); } if (from_rev == log->cur_seq) { @@ -420,14 +450,21 @@ binlog_sync (struct rspamd_binlog *log, uint64_t from_rev, uint64_t from_time, G else if (metaindex_num != log->metaindex->last_index) { /* Need to remap index block */ lock_file (log->fd, FALSE); - if ((idxb = mmap (NULL, sizeof (struct rspamd_index_block), - PROT_READ | PROT_WRITE, MAP_SHARED, - log->fd, log->metaindex->indexes[metaindex_num])) == MAP_FAILED) { + idxb = g_malloc (sizeof (struct rspamd_index_block)); + idx_mapped = TRUE; + if (lseek (log->fd, log->metaindex->indexes[metaindex_num], SEEK_SET) == -1) { unlock_file (log->fd, FALSE); - msg_warn ("binlog_sync: cannot mmap file %s, error %d, %s", log->filename, errno, strerror (errno)); - return FALSE; + msg_warn ("binlog_sync: cannot seek file %s, error %d, %s", log->filename, errno, strerror (errno)); + res = FALSE; + goto end; } - idx_mapped = TRUE; + if ((read (log->fd, &idxb, sizeof (struct rspamd_index_block))) != sizeof (struct rspamd_index_block)) { + unlock_file (log->fd, FALSE); + msg_warn ("binlog_sync: cannot read index from file %s, error %d, %s", log->filename, errno, strerror (errno)); + res = FALSE; + goto end; + } + unlock_file (log->fd, FALSE); } else { idxb = log->cur_idx; @@ -441,18 +478,87 @@ binlog_sync (struct rspamd_binlog *log, uint64_t from_rev, uint64_t from_time, G /* Now fill reply structure */ (*rep)->len = idx->len; - /* MMap result */ - if (((*rep)->data = mmap (NULL, idx->len, PROT_READ, MAP_SHARED, log->fd, idx->seek)) == MAP_FAILED) { - msg_warn ("binlog_sync: cannot mmap file %s, error %d, %s", log->filename, errno, strerror (errno)); + /* Read result */ + if (lseek (log->fd, idx->seek, SEEK_SET) == -1) { + msg_warn ("binlog_sync: cannot seek file %s, error %d, %s", log->filename, errno, strerror (errno)); + res = FALSE; + goto end; + } + + (*rep)->data = g_malloc (idx->len); + if ((read (log->fd, (*rep)->data, idx->len)) != idx->len) { + msg_warn ("binlog_sync: cannot read file %s, error %d, %s", log->filename, errno, strerror (errno)); res = FALSE; goto end; } end: if (idx_mapped) { - munmap (idxb, sizeof (struct rspamd_index_block)); + g_free (idxb); } return res; } +static gboolean +maybe_init_static () +{ + if (!binlog_opened) { + binlog_opened = g_hash_table_new (g_direct_hash, g_direct_equal); + if (!binlog_opened) { + return FALSE; + } + } + + if (!binlog_pool) { + binlog_pool = memory_pool_new (memory_pool_get_size ()); + if (!binlog_pool) { + return FALSE; + } + } + + return TRUE; +} + +void +maybe_write_binlog (struct classifier_config *ccf, const char *symbol, GTree *nodes) +{ + struct rspamd_binlog *log; + struct statfile *st = NULL; + GList *cur; + + if (ccf == NULL) { + return; + } + + cur = g_list_first (ccf->statfiles); + while (cur) { + st = cur->data; + if (strcmp (symbol, st->symbol) == 0) { + break; + } + st = NULL; + cur = g_list_next (cur); + } + + if (st == NULL || nodes == NULL || st->binlog == NULL || st->binlog->affinity != AFFINITY_MASTER) { + return; + } + + if (!maybe_init_static ()) { + return; + } + + if ((log = g_hash_table_lookup (binlog_opened, st)) == NULL) { + if ((log = binlog_open (binlog_pool, st->path, st->binlog->rotate_time, st->binlog->rotate_time / 2)) != NULL) { + g_hash_table_insert (binlog_opened, st, log); + } + else { + return; + } + } + + (void)binlog_insert (log, nodes); +} + + diff --git a/src/binlog.h b/src/binlog.h index bf2666840..eef5f4d19 100644 --- a/src/binlog.h +++ b/src/binlog.h @@ -51,9 +51,12 @@ struct rspamd_binlog { struct rspamd_index_block *cur_idx; }; +struct classifier_config; + struct rspamd_binlog* binlog_open (memory_pool_t *pool, const char *path, time_t rotate_time, int rotate_jitter); void binlog_close (struct rspamd_binlog *log); gboolean binlog_insert (struct rspamd_binlog *log, GTree *nodes); gboolean binlog_sync (struct rspamd_binlog *log, uint64_t from_rev, uint64_t from_time, GByteArray **rep); +void maybe_write_binlog (struct classifier_config *ccf, const char *symbol, GTree *nodes); #endif diff --git a/src/cfg_file.h b/src/cfg_file.h index f2cd97e23..43d424c70 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -129,6 +129,25 @@ struct statfile_autolearn_params { GList *symbols; /**< list of symbols */ }; +/** + * Sync affinity + */ +enum sync_affinity { + AFFINITY_NONE = 0, + AFFINITY_MASTER, + AFFINITY_SLAVE +}; + +/** + * Binlog params + */ +struct statfile_binlog_params { + enum sync_affinity affinity; + time_t rotate_time; + struct in_addr master_addr; + uint16_t master_port; +}; + /** * Statfile config definition */ @@ -138,6 +157,7 @@ struct statfile { size_t size; /**< size of statfile */ GList *sections; /**< list of sections in statfile */ struct statfile_autolearn_params *autolearn; /**< autolearn params */ + struct statfile_binlog_params *binlog; /**< binlog params */ }; /** @@ -255,6 +275,14 @@ struct config_file { */ int add_memcached_server (struct config_file *cf, char *str); +/** + * Parse host:port line + * @param ina host address + * @param port port + * @return TRUE if string was parsed + */ +gboolean parse_host_port (const char *str, struct in_addr *ina, uint16_t *port); + /** * Parse bind credits * @param cf config file to use diff --git a/src/cfg_file.l b/src/cfg_file.l index bc46bbc1f..fdb151b45 100644 --- a/src/cfg_file.l +++ b/src/cfg_file.l @@ -209,9 +209,13 @@ yes|YES|no|NO|[yY]|[nN] yylval.flag=parse_flag(yytext); return FLAG; autolearn return AUTOLEARN; min_mark return MIN_MARK; max_mark return MAX_MARK; +binlog return BINLOG; +binlog_master return BINLOG_MASTER; +binlog_rotate return BINLOG_ROTATE; [0-9]+ yylval.number=strtol(yytext, NULL, 10); return NUMBER; -?[0-9]+\.?[0-9]* yylval.fract=strtod(yytext, NULL); return FRACT; [0-9]+[kKmMgG]? yylval.limit=parse_limit(yytext); return SIZELIMIT; +[0-9]+[mMsShHdD]? yylval.seconds=parse_seconds(yytext); return SECONDS; \$[a-zA-Z_][a-zA-Z0-9_]+ yylval.string=strdup(yytext + 1); return VARIABLE; [a-zA-Z0-9_%-]+ yylval.string=strdup(yytext); return PARAM; \".+[^\\]\" yylval.string=strdup(yytext + 1); yylval.string[strlen(yylval.string) - 1] = '\0'; unescape_quotes(yylval.string); return QUOTEDSTRING; diff --git a/src/cfg_file.y b/src/cfg_file.y index dbee3a0bd..15a9a91da 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -55,7 +55,7 @@ struct rspamd_view *cur_view = NULL; %token REQUIRED_SCORE REJECT_SCORE FUNCTION FRACT COMPOSITES CONTROL PASSWORD %token LOGGING LOG_TYPE LOG_TYPE_CONSOLE LOG_TYPE_SYSLOG LOG_TYPE_FILE %token LOG_LEVEL LOG_LEVEL_DEBUG LOG_LEVEL_INFO LOG_LEVEL_WARNING LOG_LEVEL_ERROR LOG_FACILITY LOG_FILENAME LOG_URLS -%token STATFILE ALIAS PATTERN WEIGHT STATFILE_POOL_SIZE SIZE TOKENIZER CLASSIFIER +%token STATFILE ALIAS PATTERN WEIGHT STATFILE_POOL_SIZE SIZE TOKENIZER CLASSIFIER BINLOG BINLOG_MASTER BINLOG_ROTATE %token DELIVERY LMTP ENABLED AGENT SECTION LUACODE RAW_MODE PROFILE_FILE COUNT %token VIEW IP FROM SYMBOLS CLIENT_IP %token AUTOLEARN MIN_MARK MAX_MARK @@ -748,6 +748,9 @@ statfilecmd: | statfilesize | statfilesection | statfileautolearn + | statfilebinlog + | statfilebinlogrotate + | statfilebinlogmaster ; statfilesymbol: @@ -926,6 +929,53 @@ autolearnsymbols: } ; +statfilebinlog: + BINLOG EQSIGN QUOTEDSTRING { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + if (cur_statfile->binlog == NULL) { + cur_statfile->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); + } + if (g_ascii_strcasecmp ($3, "master") == 0) { + cur_statfile->binlog->affinity = AFFINITY_MASTER; + } + else if (g_ascii_strcasecmp ($3, "slave") == 0) { + cur_statfile->binlog->affinity = AFFINITY_SLAVE; + } + else { + cur_statfile->binlog->affinity = AFFINITY_NONE; + } + } + ; + +statfilebinlogrotate: + BINLOG_ROTATE EQSIGN QUOTEDSTRING { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + if (cur_statfile->binlog == NULL) { + cur_statfile->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); + } + cur_statfile->binlog->rotate_time = parse_seconds ($3); + } + ; + +statfilebinlogmaster: + BINLOG_MASTER EQSIGN QUOTEDSTRING { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + if (cur_statfile->binlog == NULL) { + cur_statfile->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); + } + if (!parse_host_port ($3, &cur_statfile->binlog->master_addr, &cur_statfile->binlog->master_port)) { + YYERROR; + } + } + ; + + statfile_pool_size: STATFILE_POOL_SIZE EQSIGN SIZELIMIT { cfg->max_statfile_size = $3; diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 13a5e091a..dee5db850 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -40,65 +40,90 @@ extern char *yytext; int add_memcached_server (struct config_file *cf, char *str) { - char *cur_tok, *err_str; struct memcached_server *mc; - struct hostent *hent; uint16_t port; if (str == NULL) return 0; - cur_tok = strsep (&str, ":"); - - if (cur_tok == NULL || *cur_tok == '\0') - return 0; - if (cf->memcached_servers_num == MAX_MEMCACHED_SERVERS) { yywarn ("yyparse: maximum number of memcached servers is reached %d", MAX_MEMCACHED_SERVERS); + return 0; } mc = &cf->memcached_servers[cf->memcached_servers_num]; - if (mc == NULL) - return 0; /* cur_tok - server name, str - server port */ - if (str == NULL) { - port = DEFAULT_MEMCACHED_PORT; - } - else { - port = (uint16_t) strtoul (str, &err_str, 10); - if (*err_str != '\0') { - return 0; - } + port = DEFAULT_MEMCACHED_PORT; + + if (!parse_host_port (str, &mc->addr, &port)) { + return 0; } - if (!inet_aton (cur_tok, &mc->addr)) { + mc->port = port; + cf->memcached_servers_num++; + return 1; +} + +gboolean +parse_host_port (const char *str, struct in_addr *ina, uint16_t *port) +{ + char **tokens, *err_str; + struct hostent *hent; + unsigned int port_parsed, saved_errno = errno; + + tokens = g_strsplit (str, ":", 0); + if (!tokens || !tokens[0]) { + return FALSE; + } + + /* Now try to parse host and write address to ina */ + if (!inet_aton (tokens[0], ina)) { /* Try to call gethostbyname */ - hent = gethostbyname (cur_tok); + hent = gethostbyname (tokens[0]); if (hent == NULL) { - return 0; + msg_warn ("parse_host_port: cannot resolve %s", tokens[0]); + goto err; } else { - memcpy ((char *)&mc->addr, hent->h_addr, sizeof (struct in_addr)); + memcpy (ina, hent->h_addr, sizeof (struct in_addr)); } } - mc->port = port; - cf->memcached_servers_num++; - return 1; + if (tokens[1] != NULL) { + /* Port part */ + errno = 0; + port_parsed = strtoul (tokens[1], &err_str, 10); + if (*err_str != '\0' || errno != 0) { + msg_warn ("parse_host_port: cannot parse port: %s, at symbol %c, error: %s", tokens[1], *err_str, strerror (errno)); + goto err; + } + if (port_parsed > G_MAXUINT16) { + errno = ERANGE; + msg_warn ("parse_host_port: cannot parse port: %s, error: %s", tokens[1], *err_str, strerror (errno)); + goto err; + } + *port = port_parsed; + } + + /* Restore errno */ + errno = saved_errno; + g_strfreev (tokens); + return TRUE; + +err: + errno = saved_errno; + g_strfreev (tokens); + return FALSE; } int parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) { - char *cur_tok, *err_str; - struct hostent *hent; - size_t s; char **host; int16_t *family, *port; struct in_addr *addr; if (str == NULL) return 0; - cur_tok = strsep (&str, ":"); host = &cf->bind_host; port = &cf->bind_port; @@ -106,70 +131,46 @@ parse_bind_line (struct config_file *cfg, struct worker_conf *cf, char *str) family = &cf->bind_family; addr = &cf->bind_addr; - if (cur_tok[0] == '/' || cur_tok[0] == '.') { + if (str[0] == '/' || str[0] == '.') { #ifdef HAVE_DIRNAME /* Try to check path of bind credit */ struct stat st; int fd; - char *copy = memory_pool_strdup (cfg->cfg_pool, cur_tok); + char *copy = memory_pool_strdup (cfg->cfg_pool, str); if (stat (copy, &st) == -1) { if (errno == ENOENT) { - if ((fd = open (cur_tok, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1) { - yyerror ("parse_bind_line: cannot open path %s for making socket, %s", cur_tok, strerror (errno)); + if ((fd = open (str, O_RDWR | O_TRUNC | O_CREAT, S_IWUSR | S_IRUSR)) == -1) { + yyerror ("parse_bind_line: cannot open path %s for making socket, %s", str, strerror (errno)); return 0; } else { close (fd); - unlink (cur_tok); + unlink (str); } } else { - yyerror ("parse_bind_line: cannot stat path %s for making socket, %s", cur_tok, strerror (errno)); + yyerror ("parse_bind_line: cannot stat path %s for making socket, %s", str, strerror (errno)); return 0; } } else { - if (unlink (cur_tok) == -1) { - yyerror ("parse_bind_line: cannot remove path %s for making socket, %s", cur_tok, strerror (errno)); + if (unlink (str) == -1) { + yyerror ("parse_bind_line: cannot remove path %s for making socket, %s", str, strerror (errno)); return 0; } } #endif - *host = memory_pool_strdup (cfg->cfg_pool, cur_tok); + *host = memory_pool_strdup (cfg->cfg_pool, str); *family = AF_UNIX; return 1; - } else { - if (*str != '\0') { - *port = (uint16_t) strtoul (str, &err_str, 10); - if (*err_str != '\0') { - yyerror ("parse_bind_line: cannot read numeric value: %s", err_str); - return 0; - } - } - if (strcmp (cur_tok, "*") == 0) { - *host = memory_pool_strdup (cfg->cfg_pool, cur_tok); - addr->s_addr = htonl (INADDR_ANY); - } - else if (!inet_aton (cur_tok, addr)) { - /* Try to call gethostbyname */ - hent = gethostbyname (cur_tok); - if (hent == NULL) { - return 0; - } - else { - *host = memory_pool_strdup (cfg->cfg_pool, cur_tok); - memcpy ((char *)addr, hent->h_addr, sizeof (struct in_addr)); - s = strlen (cur_tok) + 1; - } - } - else { - *host = memory_pool_strdup (cfg->cfg_pool, cur_tok); - } - *family = AF_INET; + if (parse_host_port (str, addr, port)) { + *host = memory_pool_strdup (cfg->cfg_pool, str); + *family = AF_INET; - return 1; + return 1; + } } return 0; diff --git a/src/controller.c b/src/controller.c index d59690da2..3b0179734 100644 --- a/src/controller.c +++ b/src/controller.c @@ -32,6 +32,7 @@ #include "modules.h" #include "tokenizers/tokenizers.h" #include "classifiers/classifiers.h" +#include "binlog.h" #define CRLF "\r\n" #define END "END" CRLF @@ -477,7 +478,8 @@ controller_read_socket (f_str_t * in, void *arg) session->learn_classifier->classifier->learn_func (cls_ctx, session->worker->srv->statfile_pool, session->learn_symbol, tokens, session->in_class); session->worker->srv->stat->messages_learned++; - + maybe_write_binlog (session->learn_classifier, session->learn_symbol, tokens); + free_task (task, FALSE); i = snprintf (out_buf, sizeof (out_buf), "learn ok" CRLF); if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) { diff --git a/src/filter.c b/src/filter.c index 11683d0d4..ca3270f47 100644 --- a/src/filter.c +++ b/src/filter.c @@ -32,6 +32,7 @@ #include "expressions.h" #include "settings.h" #include "view.h" +#include "binlog.h" #include "classifiers/classifiers.h" #include "tokenizers/tokenizers.h" @@ -488,6 +489,7 @@ process_autolearn (struct statfile *st, struct worker_task *task, GTree * tokens } classifier->learn_func (ctx, task->worker->srv->statfile_pool, st->symbol, tokens, TRUE); + maybe_write_binlog (ctx->cfg, st->symbol, tokens); } } }