waiting DNS lookups. This had to do with c-ares query cache causing a
different (unexpected) code path in UnrealIRCd.
And, somewhat related, c-ares also didn't obey our DNS timeout, as that
value is a "hint" nowadays, so now we set the "max timeout" value.
Fun.
Ignore these for entire src/dns.c.
Quoting https://github.com/c-ares/c-ares/pull/732#issuecomment-2028454381:
"Those deprecated functions will remain available until there is an ABI
break, which honestly will likely never happen. It's more to encourage
integrators to move to the more modern functions."
Also, keep in mind that several of these 'deprecations' happened in early 2024
while the new function was introduced in March 2020, like for ares_getaddrinfo().
That isn't all that long ago, only 4 years. So we would need compatibility code
for both the old and new function for a while.
So: we can look into that in some major new UnrealIRCd version, nothing urgent,
and perhaps by then it is long enough that we don't need the fallback to older
functions.
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
For example if the 1st DNS resolver is refusing or ignoring requests.
We forgot to call unrealdns_timeout() in the waiting loop, so DNS requests
never timed out and c-ares didn't try the 2nd/3rd server either.
Issue reported by Elodie.
It means you can no longer modify eg parv[1] in-place with strtoken and such.
The main reason for this is that as a command handler you have no idea
where the arguments may come from. It could be from a do_cmd() with
read-only storage (eg a string literal) and so on.
It started with an experiment of how far I could get and how annoying the
side-effects would be, but they seem to be quite managable, so I'm
committing this stuff.
Hopefully this catches/solves some stupid bugs somewhere :)
have that in dns.c. Also remove verify_hostname() from dns.c and
integrate it in valid_host() which now takes a second argument
named 'strict'. Call valid_host() with strict set to 1 if the
hostname should be checked to be a valid DNS hostname, eg the
host may not contain stuff like ':' or '/'. Use 0 otherwise
for the loose check, eg if you are not sure if the passed host
is an IP address or a host, or if it is for a vhost.
* Converted 90% of the socket and linking errors to use unreal_log()
* Add log_data_socket_error(fd) and $socket_error
* This also makes connect_server() 'void' and removes all of the error
reporting from the callers (there was 3x code duplication due to that)
* Don't use report_error and report_baderror anymore in socket.c
* More to follow...
later fd_close() call. This also removes fd_map() since fd_open w/FDCLOSE_NONE
now does that.
* If you use fd_socket() or fd_accept(), then no change.
When fd_close() is called we call close() on *NIX and closesocket() on Win.
* If you use fd_fileopen(), then no change.
When fd_close() is called we will call close() on both *NIX and Win.
* If you used fd_open() and then fd_unmap() because you didn't want us
to close the socket, then use fd_open() with FDCLOSE_NONE and
just call fd_close() instead of fd_unmap().
We will not actually close the fd in fd_close() (FDCLOSE_NONE).
* If you called fd_open() with other intentions then either specify a
FDCLOSE_SOCKET / FDCLOSE_FILE as the last argument, or more likely:
don't use fd_open() at all and use fd_socket() or fd_fileopen() instead.
For reasons on this change, see previous patch. This way is more sane and
makes it harder to make mistakes even beyond Windows-specific issues.
This fixes a file descriptor leak in Windows that happened in the
logging code. The most visible effect of this was if you had a
log::maxsize set then on Windows you would see:
"Max file size reached, starting new log file"
Every other line, forever (and not actually starting a new log).
fd_close() previously did not close the file descriptor of a file
on Windows because on Windows it needs to call close() for a file
and closesocket() for a socket, and it always did the latter.
On *NIX it's more easy and you can just always close() any fd.
When connecting, use slightly different wording (and use it consistently):
"Trying to activate link with server xyz"
When the connection is lost before synced:
"Unable to link with server xyz"
When the connection is lost after fully synced (eg: minutes later):
"Lost server link to xyz"
Important small changes (other than text):
* Log ERRORs from remote servers to the log (previously only shown to ircops)
* Some link errors could have been previously suppressed due to
old code assuming other parts of the code would send or log the error
(this would be the case for an error when calling SSL/TLS write functions)
* More?
This so I - and others - don't constantly have to wonder whether the client
is called sptr, cptr or acptr in a simple routine.
Insane --> 212 files changed, 6814 insertions(+), 6945 deletions(-)
Couldn't just mass-replace of course since there are places where there
are multiple clients involved. So had to check each function.
Also renamed some 'acptr' to 'target' and such.
I will write a page with new style rules later.. but in short if there is
only 1 client involved it will now be called 'client'.
code changes in UnrealIRCd itself:
1) Clients are no longer freed directly by exit_client. Most fields
are freed, but 'sptr' itself is not, so you can use IsDead() on it.
2) exit_client now returns void rather than int
3) ALL command functions return void rather than int.
Of course this also affects do_cmd, command overrides, etc.
This is a direct consequence of the removal of 'cptr' earlier, as that
was used to signal certain things that are now no longer possible
(and it raises the question if things were always correctly signaled
in the first place, so may fix some bugs).
It also makes the code more resillient against cases where you forgot
to check if the client was freed. Still, you are encouraged to do an
IsDead(sptr) if you are calling functions that may kill clients,
such as command functions or things that may use spamfilter.
More changes will follow, such as the removal of FLUSH_BUFFER.
which specifies the time in milliseconds rather than seconds. This
allows for additional precision, or at least multiple calls per second.
The minimum allowed every_msec value is 100 at this time.
The prototype is now: EventAdd(Module *module, char *name,
vFP event, void *data, long every_msec, int count);
aChannel to Channel, and some more. Third party module coders will
love this. But.. it makes things more logical and the doxygen output
will look more clean and logical as well.
(More changes will follow)