diff options
-rw-r--r-- | interface/index.html | 5 | ||||
-rw-r--r-- | interface/js/app/upload.js | 10 | ||||
-rw-r--r-- | lualib/lua_cfg_transform.lua | 20 | ||||
-rw-r--r-- | src/plugins/fuzzy_check.c | 124 | ||||
-rw-r--r-- | src/rspamd_proxy.c | 12 | ||||
-rw-r--r-- | test/functional/cases/120_fuzzy/lib.robot | 23 | ||||
-rw-r--r-- | test/functional/cases/120_fuzzy/read-only.robot | 14 | ||||
-rw-r--r-- | test/functional/cases/120_fuzzy/split-servers.robot | 18 | ||||
-rw-r--r-- | test/functional/cases/120_fuzzy/write-only.robot | 14 | ||||
-rw-r--r-- | test/functional/configs/fuzzy-split-servers.conf | 97 |
10 files changed, 297 insertions, 40 deletions
diff --git a/interface/index.html b/interface/index.html index a759ac48f..8329a74dd 100644 --- a/interface/index.html +++ b/interface/index.html @@ -488,7 +488,7 @@ </div> <div class="col-lg-6"> <div class="card bg-light shadow card-body card p-2"> - <p>Learn Fuzzy storage:</p> + <p>Fuzzy hash storage management:</p> <form class="d-flex"> <div class="d-flex align-items-center"> <label for="fuzzyFlagText">Flag:</label> @@ -498,7 +498,8 @@ <label for="fuzzyWeightText">Weight:</label> <input name="fuzzyWeightText" id="fuzzyWeightText" class="form-control ms-1" type="number" value="1"/> </div> - <button class="btn btn-warning ms-2 d-flex align-items-center" data-upload="fuzzy" disabled><i class="fas fa-upload me-2"></i>Upload FUZZY</button> + <button class="btn btn-warning ms-2 d-flex align-items-center" data-upload="fuzzyadd" disabled><i class="fas fa-circle-plus me-2"></i>Add hash</button> + <button class="btn btn-danger ms-2 d-flex align-items-center" data-upload="fuzzydel" disabled><i class="fas fa-trash-can me-2"></i>Delete hash</button> </form> </div> </div> diff --git a/interface/js/app/upload.js b/interface/js/app/upload.js index a484a41aa..d85196296 100644 --- a/interface/js/app/upload.js +++ b/interface/js/app/upload.js @@ -42,8 +42,10 @@ define(["jquery", "app/common", "app/libft"], url = "learnspam"; } else if (source === "ham") { url = "learnham"; - } else if (source === "fuzzy") { + } else if (source === "fuzzyadd") { url = "fuzzyadd"; + } else if (source === "fuzzydel") { + url = "fuzzydel"; } else if (source === "scan") { url = "checkv2"; } @@ -245,11 +247,15 @@ define(["jquery", "app/common", "app/libft"], getFuzzyHashes(data); } else { let headers = {}; - if (source === "fuzzy") { + if (source === "fuzzyadd") { headers = { flag: $("#fuzzyFlagText").val(), weight: $("#fuzzyWeightText").val() }; + } else if (source === "fuzzydel") { + headers = { + flag: $("#fuzzyFlagText").val(), + }; } uploadText(data, source, headers); } diff --git a/lualib/lua_cfg_transform.lua b/lualib/lua_cfg_transform.lua index 265ca34c0..aaa0c7390 100644 --- a/lualib/lua_cfg_transform.lua +++ b/lualib/lua_cfg_transform.lua @@ -198,20 +198,22 @@ end local function symbol_transform(cfg, k, v) local groups = cfg:at('group') - -- first try to find any group where there is a definition of this symbol - for gr_n, gr in groups:pairs() do - local symbols = gr:at('symbols') - if symbols and symbols:at(k) then - -- We override group symbol with ungrouped symbol - logger.infox("overriding group symbol %s in the group %s", k, gr_n) - symbols[k] = lua_util.override_defaults(symbols:at(k):unwrap(), v:unwrap()) - return + if groups then + -- first try to find any group where there is a definition of this symbol + for gr_n, gr in groups:pairs() do + local symbols = gr:at('symbols') + if symbols and symbols:at(k) then + -- We override group symbol with ungrouped symbol + logger.infox("overriding group symbol %s in the group %s", k, gr_n) + symbols[k] = lua_util.override_defaults(symbols:at(k):unwrap(), v:unwrap()) + return + end end end -- Now check what Rspamd knows about this symbol local sym = rspamd_config:get_symbol(k) - if not sym or not sym.group then + if groups and (not sym or not sym.group) then -- Otherwise we just use group 'ungrouped' if not groups:at('ungrouped') then groups.ungrouped = { diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index 4ed94a141..85ea3b00c 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -78,7 +78,8 @@ enum fuzzy_rule_mode { }; struct fuzzy_rule { - struct upstream_list *servers; + struct upstream_list *read_servers; /* Servers for read operations */ + struct upstream_list *write_servers; /* Servers for write operations */ const char *symbol; const char *algorithm_str; const char *name; @@ -543,22 +544,68 @@ fuzzy_parse_rule(struct rspamd_config *cfg, const ucl_object_t *obj, } if ((value = ucl_object_lookup(obj, "servers")) != NULL) { - rule->servers = rspamd_upstreams_create(cfg->ups_ctx); - /* pass max_error and revive_time configuration in upstream for fuzzy storage - * it allows to configure error_rate threshold and upstream dead timer - */ - rspamd_upstreams_set_limits(rule->servers, + rule->read_servers = rspamd_upstreams_create(cfg->ups_ctx); + rspamd_upstreams_set_limits(rule->read_servers, (double) fuzzy_module_ctx->revive_time, NAN, NAN, NAN, (unsigned int) fuzzy_module_ctx->max_errors, 0); rspamd_mempool_add_destructor(cfg->cfg_pool, (rspamd_mempool_destruct_t) rspamd_upstreams_destroy, - rule->servers); - if (!rspamd_upstreams_from_ucl(rule->servers, value, DEFAULT_PORT, NULL)) { + rule->read_servers); + if (!rspamd_upstreams_from_ucl(rule->read_servers, value, DEFAULT_PORT, NULL)) { msg_err_config("cannot read servers definition"); return -1; } + + rule->write_servers = rule->read_servers; + } + else { + /* Check for read_servers and write_servers */ + gboolean has_read = FALSE, has_write = FALSE; + + if ((value = ucl_object_lookup(obj, "read_servers")) != NULL) { + rule->read_servers = rspamd_upstreams_create(cfg->ups_ctx); + rspamd_upstreams_set_limits(rule->read_servers, + (double) fuzzy_module_ctx->revive_time, NAN, NAN, NAN, + (unsigned int) fuzzy_module_ctx->max_errors, 0); + + rspamd_mempool_add_destructor(cfg->cfg_pool, + (rspamd_mempool_destruct_t) rspamd_upstreams_destroy, + rule->read_servers); + if (!rspamd_upstreams_from_ucl(rule->read_servers, value, DEFAULT_PORT, NULL)) { + msg_err_config("cannot read read_servers definition"); + return -1; + } + has_read = TRUE; + } + + if ((value = ucl_object_lookup(obj, "write_servers")) != NULL) { + rule->write_servers = rspamd_upstreams_create(cfg->ups_ctx); + rspamd_upstreams_set_limits(rule->write_servers, + (double) fuzzy_module_ctx->revive_time, NAN, NAN, NAN, + (unsigned int) fuzzy_module_ctx->max_errors, 0); + + rspamd_mempool_add_destructor(cfg->cfg_pool, + (rspamd_mempool_destruct_t) rspamd_upstreams_destroy, + rule->write_servers); + if (!rspamd_upstreams_from_ucl(rule->write_servers, value, DEFAULT_PORT, NULL)) { + msg_err_config("cannot read write_servers definition"); + return -1; + } + has_write = TRUE; + } + + /* If we have both read and write servers, we don't need the common servers list */ + if (has_read && !has_write) { + /* Use read_servers for all operations */ + rule->write_servers = rule->read_servers; + } + else if (has_write && !has_read) { + /* Use write_servers for all operations */ + rule->read_servers = rule->write_servers; + } } + if ((value = ucl_object_lookup(obj, "fuzzy_map")) != NULL) { it = NULL; while ((cur = ucl_object_iterate(value, &it, true)) != NULL) { @@ -636,7 +683,7 @@ fuzzy_parse_rule(struct rspamd_config *cfg, const ucl_object_t *obj, strlen(shingles_key_str), NULL, 0); rule->shingles_key->len = 16; - if (rspamd_upstreams_count(rule->servers) == 0) { + if (rspamd_upstreams_count(rule->read_servers) == 0) { msg_err_config("no servers defined for fuzzy rule with name: %s", rule->name); return -1; @@ -898,6 +945,24 @@ int fuzzy_check_module_init(struct rspamd_config *cfg, struct module_ctx **ctx) 0); rspamd_rcl_add_doc_by_path(cfg, "fuzzy_check.rule", + "List of servers to check (read-only operations)", + "read_servers", + UCL_STRING, + NULL, + 0, + NULL, + 0); + rspamd_rcl_add_doc_by_path(cfg, + "fuzzy_check.rule", + "List of servers to learn (write operations)", + "write_servers", + UCL_STRING, + NULL, + 0, + NULL, + 0); + rspamd_rcl_add_doc_by_path(cfg, + "fuzzy_check.rule", "If true then never try to learn this fuzzy storage", "read_only", UCL_BOOLEAN, @@ -1249,7 +1314,7 @@ int fuzzy_check_module_config(struct rspamd_config *cfg, bool validate) LL_FOREACH(value, cur) { - if (ucl_object_lookup(cur, "servers")) { + if (ucl_object_lookup_any(cur, "servers", "read_servers", "write_servers", NULL) != NULL) { /* Unnamed rule */ fuzzy_parse_rule(cfg, cur, NULL, cb_id); nrules++; @@ -3398,8 +3463,8 @@ register_fuzzy_client_call(struct rspamd_task *task, int sock; if (!rspamd_session_blocked(task->s)) { - /* Get upstream */ - selected = rspamd_upstream_get(rule->servers, RSPAMD_UPSTREAM_ROUND_ROBIN, + /* Get upstream - use read_servers for check operations */ + selected = rspamd_upstream_get(rule->read_servers, RSPAMD_UPSTREAM_ROUND_ROBIN, NULL, 0); if (selected) { addr = rspamd_upstream_addr_next(selected); @@ -3526,9 +3591,8 @@ register_fuzzy_controller_call(struct rspamd_http_connection_entry *entry, int sock; int ret = -1; - /* Get upstream */ - - while ((selected = rspamd_upstream_get_forced(rule->servers, + /* Get upstream - use write_servers for learn/unlearn operations */ + while ((selected = rspamd_upstream_get_forced(rule->write_servers, RSPAMD_UPSTREAM_SEQUENTIAL, NULL, 0))) { /* Create UDP socket */ addr = rspamd_upstream_addr_next(selected); @@ -3542,6 +3606,9 @@ register_fuzzy_controller_call(struct rspamd_http_connection_entry *entry, rspamd_upstream_fail(selected, TRUE, strerror(errno)); } else { + msg_info_task("fuzzy storage %s (%s rule) is used for write", + rspamd_inet_address_to_string_pretty(addr), + rule->name); s = rspamd_mempool_alloc0(session->pool, sizeof(struct fuzzy_learn_session)); @@ -3624,6 +3691,7 @@ fuzzy_modify_handler(struct rspamd_http_connection_entry *conn_ent, PTR_ARRAY_FOREACH(fuzzy_module_ctx->fuzzy_rules, i, rule) { if (rule->mode == fuzzy_rule_read_only) { + msg_debug_task("skip rule %s as it is read-only", rule->name); continue; } @@ -3733,6 +3801,8 @@ fuzzy_modify_handler(struct rspamd_http_connection_entry *conn_ent, else { commands = fuzzy_generate_commands(task, rule, cmd, flag, value, flags); + msg_debug_task("fuzzy command %d for rule %s, flag %d, value %d", + cmd, rule->name, flag, value); if (commands != NULL) { res = register_fuzzy_controller_call(conn_ent, rule, @@ -3898,7 +3968,7 @@ fuzzy_check_send_lua_learn(struct fuzzy_rule *rule, /* Get upstream */ if (!rspamd_session_blocked(task->s)) { - while ((selected = rspamd_upstream_get(rule->servers, + while ((selected = rspamd_upstream_get(rule->write_servers, RSPAMD_UPSTREAM_SEQUENTIAL, NULL, 0))) { /* Create UDP socket */ addr = rspamd_upstream_addr_next(selected); @@ -4495,9 +4565,21 @@ fuzzy_lua_list_storages(lua_State *L) lua_setfield(L, -2, "read_only"); /* Push servers */ - lua_createtable(L, rspamd_upstreams_count(rule->servers), 0); - rspamd_upstreams_foreach(rule->servers, lua_upstream_str_inserter, L); - lua_setfield(L, -2, "servers"); + if (rule->read_servers == rule->write_servers) { + /* Same servers for both operations */ + lua_createtable(L, rspamd_upstreams_count(rule->read_servers), 0); + rspamd_upstreams_foreach(rule->read_servers, lua_upstream_str_inserter, L); + lua_setfield(L, -2, "servers"); + } + else { + /* Different servers for read and write */ + lua_createtable(L, rspamd_upstreams_count(rule->read_servers), 0); + rspamd_upstreams_foreach(rule->read_servers, lua_upstream_str_inserter, L); + lua_setfield(L, -2, "read_servers"); + lua_createtable(L, rspamd_upstreams_count(rule->write_servers), 0); + rspamd_upstreams_foreach(rule->write_servers, lua_upstream_str_inserter, L); + lua_setfield(L, -2, "write_servers"); + } /* Push flags */ GHashTableIter it; @@ -4784,7 +4866,7 @@ fuzzy_lua_ping_storage(lua_State *L) rspamd_ptr_array_free_hard, addrs); } else { - struct upstream *selected = rspamd_upstream_get(rule_found->servers, + struct upstream *selected = rspamd_upstream_get(rule_found->read_servers, RSPAMD_UPSTREAM_ROUND_ROBIN, NULL, 0); addr = rspamd_upstream_addr_next(selected); } @@ -4828,4 +4910,4 @@ fuzzy_lua_ping_storage(lua_State *L) lua_pushboolean(L, TRUE); return 1; -}
\ No newline at end of file +} diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c index 694e87c12..b7decbbcc 100644 --- a/src/rspamd_proxy.c +++ b/src/rspamd_proxy.c @@ -1600,8 +1600,8 @@ proxy_backend_master_error_handler(struct rspamd_http_connection *conn, GError * session->retries++; msg_info_session("abnormally closing connection from backend: %s, error: %e," " retries left: %d", - rspamd_inet_address_to_string_pretty( - rspamd_upstream_addr_cur(session->master_conn->up)), + session->master_conn->up ? rspamd_inet_address_to_string_pretty( + rspamd_upstream_addr_cur(session->master_conn->up)) : "self-scan", err, session->ctx->max_retries - session->retries); rspamd_upstream_fail(bk_conn->up, FALSE, err ? err->message : "unknown"); @@ -1632,8 +1632,8 @@ proxy_backend_master_error_handler(struct rspamd_http_connection *conn, GError * else { msg_info_session("retry connection to: %s" " retries left: %d", - rspamd_inet_address_to_string( - rspamd_upstream_addr_cur(session->master_conn->up)), + session->master_conn->up ? rspamd_inet_address_to_string( + rspamd_upstream_addr_cur(session->master_conn->up)) : "self-scan", session->ctx->max_retries - session->retries); } } @@ -2216,8 +2216,8 @@ proxy_client_finish_handler(struct rspamd_http_connection *conn, } else { msg_info_session("finished master connection to %s; HTTP code: %d", - rspamd_inet_address_to_string_pretty( - rspamd_upstream_addr_cur(session->master_conn->up)), + session->master_conn->up ? rspamd_inet_address_to_string_pretty( + rspamd_upstream_addr_cur(session->master_conn->up)) : "self-scan", msg->code); proxy_backend_close_connection(session->master_conn); REF_RELEASE(session); diff --git a/test/functional/cases/120_fuzzy/lib.robot b/test/functional/cases/120_fuzzy/lib.robot index fda0af54a..a57ecc742 100644 --- a/test/functional/cases/120_fuzzy/lib.robot +++ b/test/functional/cases/120_fuzzy/lib.robot @@ -16,6 +16,7 @@ ${RSPAMD_FUZZY_ENCRYPTED_ONLY} false ${RSPAMD_FUZZY_ENCRYPTION_KEY} null ${RSPAMD_FUZZY_INCLUDE} ${RSPAMD_TESTDIR}/configs/empty.conf ${RSPAMD_FUZZY_KEY} null +${RSPAMD_FUZZY_SERVER_MODE} servers ${RSPAMD_FUZZY_SHINGLES_KEY} null ${RSPAMD_SCOPE} Suite ${SETTINGS_FUZZY_CHECK} ${EMPTY} @@ -109,6 +110,7 @@ Fuzzy Setup Encrypted Set Suite Variable ${RSPAMD_FUZZY_ENCRYPTION_KEY} ${RSPAMD_KEY_PUB1} Set Suite Variable ${RSPAMD_FUZZY_CLIENT_ENCRYPTION_KEY} ${RSPAMD_KEY_PUB1} Set Suite Variable ${RSPAMD_FUZZY_INCLUDE} ${RSPAMD_TESTDIR}/configs/fuzzy-encryption-key.conf + Set Suite Variable ${RSPAMD_FUZZY_SERVER_MODE} servers Rspamd Redis Setup Fuzzy Setup Encrypted Dyn1 @@ -142,6 +144,8 @@ Fuzzy Setup Encrypted Keyed Fuzzy Setup Plain [Arguments] ${algorithm} Set Suite Variable ${RSPAMD_FUZZY_ALGORITHM} ${algorithm} + Set Suite Variable ${RSPAMD_FUZZY_SERVER_MODE} servers + Set Suite Variable ${SETTINGS_FUZZY_CHECK} servers = "${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_FUZZY}"; Rspamd Redis Setup Fuzzy Setup Keyed @@ -149,6 +153,7 @@ Fuzzy Setup Keyed Set Suite Variable ${RSPAMD_FUZZY_ALGORITHM} ${algorithm} Set Suite Variable ${RSPAMD_FUZZY_KEY} mYN888sydwLTfE32g2hN Set Suite Variable ${RSPAMD_FUZZY_SHINGLES_KEY} hXUCgul9yYY3Zlk1QIT2 + Set Suite Variable ${RSPAMD_FUZZY_SERVER_MODE} servers Rspamd Redis Setup Fuzzy Setup Plain Fasthash @@ -218,3 +223,21 @@ Fuzzy Multimessage Overwrite Test FOR ${i} IN @{MESSAGES} Fuzzy Overwrite Test ${i} END + +Fuzzy Setup Split Servers + Set Suite Variable ${RSPAMD_FUZZY_ALGORITHM} siphash + Set Suite Variable ${RSPAMD_FUZZY_SERVER_MODE} split + Set Suite Variable ${SETTINGS_FUZZY_CHECK} read_servers = "${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_FUZZY}"; write_servers = "${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_FUZZY}"; + Rspamd Redis Setup + +Fuzzy Setup Read Only + Set Suite Variable ${RSPAMD_FUZZY_ALGORITHM} siphash + Set Suite Variable ${RSPAMD_FUZZY_SERVER_MODE} read_only + Set Suite Variable ${SETTINGS_FUZZY_CHECK} read_only = true; + Rspamd Redis Setup + +Fuzzy Setup Write Only + Set Suite Variable ${RSPAMD_FUZZY_ALGORITHM} siphash + Set Suite Variable ${RSPAMD_FUZZY_SERVER_MODE} write_only + Set Suite Variable ${SETTINGS_FUZZY_CHECK} mode = "write_only"; + Rspamd Redis Setup diff --git a/test/functional/cases/120_fuzzy/read-only.robot b/test/functional/cases/120_fuzzy/read-only.robot new file mode 100644 index 000000000..0c3be7fec --- /dev/null +++ b/test/functional/cases/120_fuzzy/read-only.robot @@ -0,0 +1,14 @@ +*** Settings *** +Suite Setup Fuzzy Setup Read Only +Suite Teardown Rspamd Redis Teardown +Resource lib.robot + +*** Test Cases *** +Fuzzy Add + Fuzzy Multimessage Add Test + +Fuzzy Fuzzy + Fuzzy Multimessage Fuzzy Test + +Fuzzy Miss + Fuzzy Multimessage Miss Test diff --git a/test/functional/cases/120_fuzzy/split-servers.robot b/test/functional/cases/120_fuzzy/split-servers.robot new file mode 100644 index 000000000..41acb23ff --- /dev/null +++ b/test/functional/cases/120_fuzzy/split-servers.robot @@ -0,0 +1,18 @@ +*** Settings *** +Suite Setup Fuzzy Setup Split Servers +Suite Teardown Rspamd Redis Teardown +Resource lib.robot +Variables ${RSPAMD_TESTDIR}/lib/vars.py + +*** Variables *** +${CONFIG} ${RSPAMD_TESTDIR}/configs/fuzzy-split-servers.conf + +*** Test Cases *** +Fuzzy Add + Fuzzy Multimessage Add Test + +Fuzzy Fuzzy + Fuzzy Multimessage Fuzzy Test + +Fuzzy Miss + Fuzzy Multimessage Miss Test diff --git a/test/functional/cases/120_fuzzy/write-only.robot b/test/functional/cases/120_fuzzy/write-only.robot new file mode 100644 index 000000000..ee017a1d3 --- /dev/null +++ b/test/functional/cases/120_fuzzy/write-only.robot @@ -0,0 +1,14 @@ +*** Settings *** +Suite Setup Fuzzy Setup Write Only +Suite Teardown Rspamd Redis Teardown +Resource lib.robot + +*** Test Cases *** +Fuzzy Add + Fuzzy Multimessage Add Test + +Fuzzy Fuzzy + Fuzzy Multimessage Fuzzy Test + +Fuzzy Miss + Fuzzy Multimessage Miss Test diff --git a/test/functional/configs/fuzzy-split-servers.conf b/test/functional/configs/fuzzy-split-servers.conf new file mode 100644 index 000000000..e7c3bb922 --- /dev/null +++ b/test/functional/configs/fuzzy-split-servers.conf @@ -0,0 +1,97 @@ +redis { + servers = "{= env.REDIS_ADDR =}:{= env.REDIS_PORT =}"; +} +lua = "{= env.TESTDIR =}/lua/test_coverage.lua"; +options = { + filters = "fuzzy_check"; + pidfile = "{= env.TMPDIR =}/rspamd.pid"; + control_socket = "{= env.TMPDIR =}/rspamd.sock mode=0600"; + url_tld = "{= env.TESTDIR =}/../lua/unit/test_tld.dat"; + dns { + retransmits = 10; + timeout = 2s; + } +} +logging = { + type = "file", + level = "debug" + filename = "{= env.TMPDIR =}/rspamd.log" +} +metric = { + name = "default", + actions = { + reject = 100500, + } + unknown_weight = 1 + symbol { + weight = 10.0; + name = "{= env.FLAG1_SYMBOL =}"; + } + symbol { + weight = -1.0; + name = "{= env.FLAG2_SYMBOL =}"; + } +} + +worker { + type = normal + bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_NORMAL =}"; + count = 1 + task_timeout = 60s; +} + +worker { + type = controller + bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_CONTROLLER =}"; + count = 1 + secure_ip = ["{= env.LOCAL_ADDR =}"]; + stats_path = "{= env.TMPDIR =}/stats.ucl"; +} + +worker { + count = 1; + backend = "{= env.FUZZY_BACKEND =}"; + bind_socket = "{= env.LOCAL_ADDR =}:{= env.PORT_FUZZY =}"; + type = "fuzzy"; + hashfile = "{= env.TMPDIR =}/fuzzy.db"; + allow_update = ["{= env.LOCAL_ADDR =}"]; + encrypted_only = {= env.FUZZY_ENCRYPTED_ONLY =}; + keypair { + privkey = "{= env.KEY_PVT1 =}"; + pubkey = "{= env.KEY_PUB1 =}"; + } + dynamic_keys_map = "{= env.TESTDIR =}/configs/maps/fuzzy_keymap.map"; +} + +fuzzy_check { + min_bytes = 100; + timeout = 1s; + retransmits = 10; + + rule { + min_bytes = 0; + min_length = 0; + algorithm = "{= env.FUZZY_ALGORITHM =}"; + read_servers = "{= env.LOCAL_ADDR =}:{= env.PORT_FUZZY =}"; + write_servers = "{= env.LOCAL_ADDR =}:{= env.PORT_FUZZY =}"; + symbol = "R_TEST_FUZZY"; + max_score = 10.0; + mime_types = ["application/*"]; + read_only = false; + skip_unknown = true; + skip_hashes = "{= env.TMPDIR =}/skip_hash.map"; + fuzzy_key = {= env.FUZZY_KEY =}; + fuzzy_shingles_key = {= env.FUZZY_SHINGLES_KEY =}; +.include "{= env.FUZZY_INCLUDE =}"; + fuzzy_map = { + R_TEST_FUZZY_DENIED { + max_score = 10.0; + flag = {= env.FLAG1_NUMBER =}; + } + R_TEST_FUZZY_WHITE { + max_score = 1.0; + flag = {= env.FLAG2_NUMBER =}; + } + } + } +} |