This is quite a bit higher than client DNS lookups (1500ms first, on retry 3000ms)
and is because some DNSBL are reported to be quite a bit slower than ordinary DNS.
(Maybe just some, but.. the higher timeout does not hurt anyone anyway)
Note that all this has no effect on client handshake times, as DNSBL checks are
done in the background. Only side-effect is that if we do get a "late hit" then
you may now see a kill a few seconds after the client is online (which was actually
already possible before too for quick clients, but.. yeah...)
These settings can be overriden via set::dns, these are the defaults:
set {
dns {
client {
timeout 1500;
retry 2;
}
dnsbl {
timeout 3000;
retry 2;
}
}
}
When you REHASH we will check if the values are different than the current
c-ares settings and if so, reinitialize the resolver. Reinitializing the
resolver will destroy outstanding DNS requests, eg DNS lookups for clients
currently connecting, but so be it. Not a super-huge issue since changing
this is rare.
Requested by BlackBishop in https://bugs.unrealircd.org/view.php?id=6306
#define UNREALIRCD_DEFAULT_ECDH_CURVES "secp521r1:secp384r1:prime256v1"
#endif
+/* These are just defaults, which you can override via set::dns */
+#define DNS_DEFAULT_CLIENT_TIMEOUT 1500
+#define DNS_DEFAULT_CLIENT_RETRIES 2
+#define DNS_DEFAULT_DNSBL_TIMEOUT 3000
+#define DNS_DEFAULT_DNSBL_RETRIES 2
+
/* ------------------------- END CONFIGURATION SECTION -------------------- */
#define MOTD MPATH
#define RULES RPATH
int server_notice_show_event;
LimitSVSCMDS limit_svscmds;
int high_connection_rate;
+ int dns_client_timeout;
+ int dns_client_retry;
+ int dns_dnsbl_timeout;
+ int dns_dnsbl_retry;
};
extern MODVAR Configuration iConf;
extern void parse_chanmodes_protoctl(Client *client, const char *str);
extern void concat_params(char *buf, int len, int parc, const char *parv[]);
extern void charsys_check_for_changes(void);
+extern void dns_check_for_changes(void);
extern MODVAR int maxclients;
extern int fast_badword_match(ConfigItem_badword *badword, const char *line);
extern int fast_badword_replace(ConfigItem_badword *badword, const char *line, char *buf, int max);
i->central_spamfilter_except = safe_alloc(sizeof(SecurityGroup));
i->central_spamfilter_except->reputation_score = 2016; /* 7 days unregged, or 3.5 days identified */
unreal_add_mask_string(&i->central_spamfilter_except->mask, "*.irccloud.com");
+ i->dns_client_timeout = DNS_DEFAULT_CLIENT_TIMEOUT;
+ i->dns_client_retry = DNS_DEFAULT_CLIENT_RETRIES;
+ i->dns_dnsbl_timeout = DNS_DEFAULT_DNSBL_TIMEOUT;
+ i->dns_dnsbl_retry = DNS_DEFAULT_DNSBL_RETRIES;
}
/* Some settings have been moved to here - we (re)set some defaults */
} else if (!strcmp(cep->name, "best-practices"))
{
/* This is handled in config test already (there is no other way) */
+ } else if (!strcmp(cep->name, "dns"))
+ {
+ for (cepp = cep->items; cepp; cepp = cepp->next)
+ {
+ if (!strcmp(cepp->name, "client"))
+ {
+ for (ceppp = cepp->items; ceppp; ceppp = ceppp->next)
+ {
+ if (!strcmp(ceppp->name, "timeout"))
+ tempiConf.dns_client_timeout = atoi(ceppp->value);
+ else if (!strcmp(ceppp->name, "retry"))
+ tempiConf.dns_client_retry = atoi(ceppp->value);
+ }
+ } else
+ if (!strcmp(cepp->name, "dnsbl"))
+ {
+ for (ceppp = cepp->items; ceppp; ceppp = ceppp->next)
+ {
+ if (!strcmp(ceppp->name, "timeout"))
+ tempiConf.dns_dnsbl_timeout = atoi(ceppp->value);
+ else if (!strcmp(ceppp->name, "retry"))
+ tempiConf.dns_dnsbl_retry = atoi(ceppp->value);
+ }
+ }
+ }
} else if (config_set_dynamic_set_block_item(conf, &dynamic_set, cep))
{
/* Handled by config_set_dynamic_set_block_item - nothing to do here */
continue;
}
}
+ } else if (!strcmp(cep->name, "dns"))
+ {
+ for (cepp = cep->items; cepp; cepp = cepp->next)
+ {
+ if (!strcmp(cepp->name, "client") || !strcmp(cepp->name, "dnsbl"))
+ {
+ for (ceppp = cepp->items; ceppp; ceppp = ceppp->next)
+ {
+ CheckNull(ceppp);
+ if (!strcmp(ceppp->name, "timeout"))
+ {
+ int v = atoi(ceppp->value);
+ if ((v < 1000) || (v > 10000))
+ {
+ config_error("%s:%i: the timeout needs to be in milliseconds and in the range 1000-10000.",
+ ceppp->file->filename, ceppp->line_number);
+ errors++;
+ }
+ } else
+ if (!strcmp(ceppp->name, "retry"))
+ {
+ int v = atoi(ceppp->value);
+ if ((v < 0) || (v > 5))
+ {
+ config_error("%s:%i: retry value needs to be in range 0-5.",
+ ceppp->file->filename, ceppp->line_number);
+ errors++;
+ }
+ } else
+ {
+ config_error_unknown(ceppp->file->filename,
+ ceppp->line_number, "set::dns::..::",
+ ceppp->name);
+ errors++;
+ continue;
+ }
+ }
+ } else
+ {
+ config_error_unknown(cepp->file->filename,
+ cepp->line_number, "set::dns",
+ cepp->name);
+ errors++;
+ continue;
+ }
+ }
} else if ((n = test_dynamic_set_block_item(conf, NULL, cep)) >= 0)
{
/* Handled by test_dynamic_set_block_item:
if (!loop.booted)
add_proc_io_server();
free_all_config_resources();
+ dns_check_for_changes();
}
int _conf_offchans(ConfigFile *conf, ConfigEntry *ce)
}
memset(&options, 0, sizeof(options));
- options.timeout = 1500; /* 1.5 seconds */
- options.tries = 2;
- /* Note that the effective DNS timeout is NOT simply 1500*2=3000.
- * This is because c-ares does some incremental timeout stuff itself
- * that may add up to twice the timeout in the second round,
- * so effective max is 1500ms first and then up to 3000s, so 4500ms in total
- * (until they change the algorithm again, that is...).
- */
options.flags |= ARES_FLAG_NOALIASES|ARES_FLAG_IGNTC;
options.sock_state_cb = unrealdns_sock_state_cb;
/* Don't search domains or you'll get lookups for like
optmask |= ARES_OPT_LOOKUPS;
#endif
- /* First the client channel */
+ /*** First the client channel ***/
options.sock_state_cb_data = RESOLVER_CHANNEL_CLIENT;
+ options.timeout = iConf.dns_client_timeout ? iConf.dns_client_timeout : DNS_DEFAULT_CLIENT_TIMEOUT;
+ options.tries = iConf.dns_client_retry ? iConf.dns_client_retry : DNS_DEFAULT_CLIENT_RETRIES;
n = ares_init_options(&resolver_channel_client, &options, optmask);
if (n != ARES_SUCCESS)
{
/* And then the DNSBL channel */
options.sock_state_cb_data = RESOLVER_CHANNEL_DNSBL;
+ options.timeout = iConf.dns_dnsbl_timeout ? iConf.dns_dnsbl_timeout : DNS_DEFAULT_DNSBL_TIMEOUT;
+ options.tries = iConf.dns_dnsbl_retry ? iConf.dns_dnsbl_retry : DNS_DEFAULT_DNSBL_RETRIES;
n = ares_init_options(&resolver_channel_dnsbl, &options, optmask);
if (n != ARES_SUCCESS)
{
}
+void dns_check_for_changes(void)
+{
+ struct ares_options inf;
+ int changed = 0;
+ int optmask;
+
+ memset(&inf, 0, sizeof(inf));
+ ares_save_options(resolver_channel_client, &inf, &optmask);
+ if ((inf.timeout != iConf.dns_client_timeout) || (inf.tries != iConf.dns_client_retry))
+ changed = 1;
+ ares_destroy_options(&inf);
+
+ memset(&inf, 0, sizeof(inf));
+ ares_save_options(resolver_channel_dnsbl, &inf, &optmask);
+ if ((inf.timeout != iConf.dns_dnsbl_timeout) || (inf.tries != iConf.dns_dnsbl_retry))
+ changed = 1;
+ ares_destroy_options(&inf);
+
+ if (changed)
+ {
+ if (loop.booted)
+ config_status("DNS Configuration changed, reinitializing DNS...");
+ ares_destroy(resolver_channel_client);
+ ares_destroy(resolver_channel_dnsbl);
+ init_resolver(0);
+ }
+}
+
CMD_FUNC(cmd_dns)
{
DNSCache *c;
sendtxtnumeric(client, " timeout: %d", inf.timeout);
if (optmask & ARES_OPT_TRIES)
sendtxtnumeric(client, " tries: %d", inf.tries);
+ ares_destroy_options(&inf);
sendtxtnumeric(client, "=== DNSBL resolver channel ===");
i = 0;
sendtxtnumeric(client, " timeout: %d", inf.timeout);
if (optmask & ARES_OPT_TRIES)
sendtxtnumeric(client, " tries: %d", inf.tries);
+ ares_destroy_options(&inf);
sendtxtnumeric(client, "****** End of DNS Configuration Info ******");
- ares_destroy_options(&inf);
} else /* STATISTICS */
{
sendtxtnumeric(client, "DNS CACHE Stats:");