Commit Graph

2098 Commits

Author SHA1 Message Date
Daniel Stenberg
be92f0a2e4
lib: reserve 'result' for CURLcode, even more
Closes #21245
2026-04-07 07:48:58 +02:00
Daniel Stenberg
9f5d1a38d1
lib: reserve 'result' for CURLcode
For consistency, whereever we use a local variable named 'result' that
is a CURLcode type. Make other types use other names.

Closes #21244
2026-04-06 23:12:06 +02:00
Viktor Szakats
0b06b944fe
spelling: fix typos
Closes #21198
2026-04-01 22:50:12 +02:00
Viktor Szakats
0df6c01db3
tidy-up: rename Curl_safefree()/tool_safefree() to curlx_safefree()
To sync names for the same macro logic between lib and src, and to move
it to the curlx namespace, to match `curlx_free()` that it's calling.

Closes #21151
2026-04-01 19:53:53 +02:00
Stefan Eissing
2b3dfb4ad4
lib: make resolving HTTPS DNS records reliable:
- allow to specify when they are wanted on starting a resolve
- match dns cache entries accordingly. An entry which never
  tried to get HTTPS-RRs is no answer for a resolve that wants
  it.
- fix late arrivals of resolve answers to match the "async"
  records that started them - if it still exists.
- provide for multiple "async" resolves in a transfer at the
  same time. We may need to resolve an IP interface while the
  main connection resolve has not finished yet.
- allow lookup of HTTPS-RR information as soon as it is
  available, even if A/AAAA queries are still ongoing.

For this, the "async" infrastructure is changed:

- Defined bits for DNS queries `CURL_DNSQ_A`, `CURL_DNSQ_AAAA`
  and `CURL_DNSQ_HTTPS`. These replace `ip_version` which says
  nothing about HTTPS.
  Use them in dns cache entries for matching.
- enhance the `async->id` to be a unique `uint32_t` for
  resolves inside one multi. This is weak, as the id may
  wrap around. However it is combined with the `mid` of
  the easy handle, making collisions highly unlikely.
  `data->state.async` is only accessed in few places where
  the mid/async-id match is performed.
- vtls: for ECH supporting TLS backends (openssl, rustls, wolfssl),
  retrieve the HTTPS-RR information from the dns connection filter.
  Delay the connect if the HTTPS-RR is needed, but has not
  been resolved yet.

The implementation of all this is complete for the threaded
resolver. c-ares resolver and DoH do not take advantage of
all new async features yet. To be done in separate PRs.

Details:

c-ares: cleanup settings and initialisation. Any ares channel
is only being created on starting a resolve and propagating
operations in setopt.c to the channel are not helpful.

Changed threaded+ares pollset handling so that they do not
overwrite each others `ASYNC_NAME` timeouts.

Add trace name 'threads' for tracing thread queue and
pool used by threaded resolver.

Closes #21175
2026-04-01 15:36:31 +02:00
Daniel Stenberg
7deed5bb55
wolfssl: fix build without TLS 1.3 support
Follow-up to: eac64c1879

Closes #21161
2026-03-30 18:50:02 +02:00
Daniel Stenberg
eac64c1879
wolfssl: refactor Curl_wssl_ctx_init into sub functions
Reduce complexity. It was at complexity 60, with is the current max
allowed. After this, the worst in wolfssl.c is at 29.

Closes #21128
2026-03-30 16:46:53 +02:00
Viktor Szakats
3c72928471
build: drop redundant USE_QUICHE guards
When used together with `USE_OPENSSL`. `USE_QUICHE` always implies
`USE_OPENSSL`.

Also: merge two (now identical) `#if` blocks in `openssl.c`.

Closes #21135
2026-03-30 13:46:14 +02:00
Viktor Szakats
f0f0a7f7d6
boringssl: fix more coexist cases with Schannel/WinCrypt
By moving the coexist workaround from vtls/openssl.c to vtls/openssl.h.
This way it also applies to vtls.c (and possibly other sources including
`vtls/openssl.h`), which may need it in unity builds before BoringSSL
header `openssl/ssl.h` pulling in the conflicting symbols and causing
conflicts otherwise.

Seen with build config:
```
-DCURL_USE_SCHANNEL=ON -DCURL_USE_OPENSSL=ON
-DCMAKE_UNITY_BUILD=ON -DCMAKE_UNITY_BUILD_BATCH_SIZE=30
```

Fixing:
```
In file included from _cm-win-boringssl/lib/CMakeFiles/libcurl_object.dir/Unity/unity_5_c.c:7:
In file included from lib/vtls/vtls.c:54:
In file included from lib/vtls/openssl.h:33:
In file included from /path/to/boringssl/_x64-win-ucrt/usr/include/openssl/opensslv.h:18:
In file included from /path/to/boringssl/_x64-win-ucrt/usr/include/openssl/crypto.h:18:
/path/to/boringssl/_x64-win-ucrt/usr/include/openssl/base.h:293:29: error: expected ')'
  293 | typedef struct X509_name_st X509_NAME;
      |                             ^
/path/to/llvm-mingw/x86_64-w64-mingw32/include/wincrypt.h:1515:29: note: expanded from macro 'X509_NAME'
 1515 | #define X509_NAME ((LPCSTR) 7)
      |                             ^
[...]
```

Ref: 2a92c39a21 #20567

Closes #21136
2026-03-28 15:52:41 +01:00
Viktor Szakats
9b01f73ac2
keylog.h: replace literal number with macro in declaration
Also syncing with the defintion.

Closes #21141
2026-03-28 15:51:04 +01:00
Viktor Szakats
31ec67651a
keylog: drop unused/redundant includes and guards
Closes #21137
2026-03-28 12:20:03 +01:00
Viktor Szakats
c025082967
openssl: fix build with 4.0.0-beta1 no-deprecated
```
lib/vtls/openssl.c:4238:22: error: ‘SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED’ undeclared (first use in this function); did you mean ‘SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED’?
 4238 |           (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) {
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                      SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED
lib/vtls/openssl.c:4238:22: note: each undeclared identifier is reported only once for each function it appears in
```
Ref: https://github.com/curl/curl/actions/runs/23641366299/job/68863072427#step:24:189

Cherry-picked from #21118

Closes #21119
2026-03-27 12:05:51 +01:00
Viktor Szakats
372d721e92
wolfssl: document v5.0.0 (2021-11-01) as minimum required
The previously documented version was based on version checks made in
the source. In practice though, curl doesn't build with <5.0.0.

Also:
- bump main internal version check.
- drop superfluous internal version checks.

Closes #21080
2026-03-24 11:08:23 +01:00
Viktor Szakats
757fd6aae9
gnutls: fix clang-tidy warning with !verbose
with
`-DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_USE_GNUTLS=ON -DCURL_CLANG_TIDY=ON`.

```
lib/vtls/gtls.c:268:7: error: Value stored to 'strerr' is never read [clang-analyzer-deadcode.DeadStores,-warnings-as-errors]
  268 |       strerr = gnutls_strerror(rc);
      |       ^        ~~~~~~~~~~~~~~~~~~~
```

Closes #21060
2026-03-22 19:15:56 +01:00
Stefan Eissing
96d5b5c688
dnscache: own source file, improvements
- Rename `Curl_resolv_unlink()` to `Curl_dns_entry_unlink()`.
- Change `Curl_dnscache_get()` to return CURLcode result. Returns
  now `CURLE_COULDNT_RESOLVE_HOST` for "negative" cache entries.
- Add `Curl_dnscache_add_negative()` to put a "negative" entry
  into the cache.

Closes #20864
2026-03-21 12:04:36 +01:00
Stefan Eissing
b0f6e9a3d7
openssl channel_binding: lookup digest algorithm without NID
Use an alternate OpenSSL API to get the digest algorithm tied
to a certificate signature to compute the channel binding.

Fixes #20590
Reported-by: Rob Crittenden
Closes #20734
2026-03-21 12:00:17 +01:00
Stefan Eissing
708b3f8b4e
wolfssl: fix handling of abrupt connection close
A closed connection without TLS notify shutdowns, has been reported as a
correct EOF instead of an error. Fix the error handling in wolfSSL
backend receive handling.

Spotted by Codex Security

Closes #21002
2026-03-20 17:48:56 +01:00
Daniel Stenberg
14782b36fe
x509asn1: fixed and adapted for ASN1tostr unit testing
- move defines to header file
- make bit2str require < 8 unused bits
- make bool strings stricter
- make UTime2str show + or - for custom time zones
- removed unused 'type' argument to ASN1tostr() function
- fix int2str for negative values. All values below 10000 are now shown
  in decimal properly, also possibly negative values.

Add unit test 1667 to verify ASN1tostr

Closes #21013
2026-03-20 13:03:40 +01:00
Daniel Stenberg
98d8e82c74
lib: move all UNITTEST prototypes to C files
- make extract-unit-protos handle multi-line prototypes - but they need
  to be above the implementation

- Prototypes for static functions we use in unit tests should not be in
  header files. We generate lib/unitprotos.h for this purpose

- Removed some function wrappers written for unit tests and make them
  use UNITTEST function directly.

- Renamed time2str() in the tool to timebuf() since we have the same
  name in lib/ and in unit tests they can both be used non-static in a
  build.

This reverts commit f95fadd116.

Follow-up to #21010

Closes #21014
2026-03-20 07:47:57 +01:00
Viktor Szakats
f95fadd116
x509asn1: move declaration to header
Fixing clang-tidy warning:
```
tests/unit/unit1666.c:50:12: error: call to undeclared function 'encodeOID'; ISO C99 and later do not support implicit function declarations [clang-diagnostic-implicit-function-declaration]
   50 |   result = encodeOID(dbuf, oid, oid + spec->size);
      |            ^
```
Ref: https://github.com/curl/curl/actions/runs/23297585235/job/67749144361?pr=21008#step:46:736

Follow-up to 673e14cd33 #21003

Closes #21010
2026-03-19 15:04:12 +01:00
Daniel Stenberg
673e14cd33
x509asn1: improve encodeOID
- return error on zero length input
- return error on OOM or doing too large output
- fix full 32-bit number support
- fix the broken handling of the first and second numbers
- support up to 32-bit minus 80 for the second number
- a field with a leading 0x80 is now considered an error, since it only
  works as padding and is then no longer the shortest possible version

Add unit tests in 1666

Bonus: removed the last argument to OID2str() as it was always set TRUE.

Closes #21003
2026-03-19 13:55:34 +01:00
Viktor Szakats
6c0772fd7f
openssl: fix memory leaks in ECH code (OpenSSL 3)
Also drop an unnecessary cast.

Found by Codex Security

Follow-up to a362962b72 #11922

Closes #20993
2026-03-19 12:02:10 +01:00
Viktor Szakats
86c25c06c9
x509asn1: fix to return error in an error case from encodeOID()
Found by Codex Security

Follow-up to d8b0318ad6 #3582

Closes #20991
2026-03-19 11:17:17 +01:00
Viktor Szakats
454db7aeee
badwords: prefer 'null-terminated'
Aligning with existing text.

Closes #20979
2026-03-18 11:40:13 +01:00
Stefan Eissing
aeee5dd616
connection bits: move 'connect_only' here
Move the bit `connection_only` from `connectdata` to `ConnectBits`.
Since we keep all other bits there, seems the correct place.

Closes #20959
2026-03-17 15:01:29 +01:00
Viktor Szakats
3e74a3e062
openssl: drop obsolete SSLv2 logic
Closes #20945
2026-03-17 14:36:54 +01:00
Stefan Eissing
9325eb5fc4
urldata: import port types and conn destination format
Convert more `int port` to `uint16_t` port types. Reshuffle ports in
connectdata to save some bytes. Change `conn->destination` format to

- make it more readable and thus usable in tracing
- add the IPv6 scope_id only when not default (global)
  and make it resemble more the textual format for IPv6
  (e.g. suffix '%<scope_id>')

Closes #20918
2026-03-15 12:02:26 +01:00
Viktor Szakats
7a4fa90048
openssl: trace count of found / imported Windows native CA roots
To help understanding what's happening on systems where native CA misses
to verify legitimate public websites.

Also:
- drop a superfluous, hanging, `else`.

Ref: #20897

Closes #20899
2026-03-12 10:49:21 +01:00
Viktor Szakats
435eabeac8
badwords: rework exceptions, fix many of them
Also:
- support per-directory and per-upper-directory whitelist entries.
- convert badlist input grep tweak into the above format.
  (except for 'And' which had just a few hits.)
- fix many code exceptions, but do not enforce.
  (there also remain about 350 'will' uses in lib)
- fix badwords in example code, drop exceptions.
- badwords-all: convert to Perl.
  To make it usable from CMake.
- FAQ: reword to not use 'will'. Drop exception.

Closes #20886
2026-03-12 01:01:16 +01:00
Stefan Eissing
5fc7d50cec
vtls: ECH definitions cleanup
- Move ECH related defines to vtls.h
- Prefix all defines with `CURLECH_`
- Move base64.h include from vtls.h to implementations

Closes #20887
2026-03-11 23:45:29 +01:00
Daniel Stenberg
248dd9e55f
x509asn1: make encodeOID stop on too long input
Plus a minor fixup.

Reported-by: John Rodriguez

Closes #20871
2026-03-09 22:06:45 +01:00
Daniel Stenberg
13f48dfb52
docs: avoid starting sentences with However,
An unnecessary filling word

Closes #20834
2026-03-07 23:49:11 +01:00
Stefan Eissing
3c007d6351
openssl+ech: workaround for insecure handshakes
OpenSSL 4.0.0-dev supports ECH with one flaw. If peer verification
is not enabled, it will report SSL_ECH_STATUS_BAD_NAME on the ECH
status.

Provide a workaround in libcurl that checks the inner name used in
ECH was the peer's hostname, both verify peer and host are disabled
and then accept the BAD_NAME without failing the connect.

Fixes #20655
Reported-by: Dexter Gerig
Closes #20821
2026-03-06 22:42:40 +01:00
Daniel Stenberg
7577ed7e86
schannel: fix UAF in client cert store thumbprint handling
Follow-up to 10bb489b22

Found by Codex Security
Closes #20801
2026-03-03 22:14:26 +01:00
Daniel Stenberg
d9c2c64337
openssl: adapt to OpenSSL master adding const to more APIs
Closes #20797
2026-03-03 17:42:34 +01:00
Daniel Stenberg
b4dba346cd
stop using the word 'just'
Everywhere. In documentation and code comments.

It is almost never a good word and almost always a filler that should be
avoided.

Closes #20793
2026-03-03 15:30:22 +01:00
Daniel Díaz
3aa63896ae
mbedtls: guard TLS 1.3 + session tickets usage inside ifdef
If TLS 1.3 is not supported, the call to
`mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets()` fails
during compilation:
```
curl-8.18.0/lib/vtls/mbedtls.c: In function 'mbed_connect_step1':
curl-8.18.0/lib/vtls/mbedtls.c:809:3: error: implicit declaration of function 'mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets' [-Werror=implicit-function-declaration]
   mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&backend->config,
   ^
curl-8.18.0/lib/vtls/mbedtls.c:809:3: warning: nested extern declaration of 'mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets' [-Wnested-externs]
```

Protect this call inside the `#ifdef` block by making sure that support
for TLS 1.3 is defined.

Closes #20789
2026-03-03 00:28:35 +01:00
Viktor Szakats
35bbb2e830
clang-tidy: fix issues found with build-fuzzing
- curl_sha512_256: add missing, drop redundant, parentheses.
- doh: drop redundant returns.
- url: add missing parentheses.
- vtls: fix unused const variables.
- tests/unit: fix missing header with clang-tidy and !threaded-resolver.
  Follow-up to 57ff2d6c91 #20106

Closes #20774
2026-03-01 00:04:18 +01:00
Viktor Szakats
bcc8144b89
clang-tidy: silence more minor issues found by v22
Also one found manually in lib/curl_sha512_256.c.

Follow-up to 7a08c5d820 #20762

Closes #20770
2026-02-28 13:16:54 +01:00
Viktor Szakats
b56e103d4d
build: do not include wolfSSL header in curl_setup.h
To fix building tests/server with cmake and both wolfSSL and OpenSSL
enabled (MultiSSL).

tests/server do not have libcurl dependency header paths setup because
it does not use libcurl. The code however includes `curl_setup.h`, which
tried including `wolfssl/version.h` before this patch to verify if the
wolfSSL coexist feature is available. Without a header path, it failed:
```
In file included from bld/tests/server/servers.c:3:
In file included from tests/server/first.h:40:
lib/curl_setup.h:737:12: fatal error: 'wolfssl/version.h' file not found
  737 | #  include <wolfssl/version.h>
      |            ^~~~~~~~~~~~~~~~~~~
1 error generated.
```
Ref: https://github.com/curl/curl/actions/runs/22410066319/job/64880787424#step:46:76

Fix by moving the include and version check to `vtls/wolfssl.c`.

Also: add an early version check to cmake.

Follow-up to 16f073ef49 #16973
Cherry-picked from #20720

Closes #20726
2026-02-26 01:36:16 +01:00
Viktor Szakats
3b9d8412c0
clang-tidy: add more missing parentheses in macro values
Reported when running `HeaderFilterRegex: '.*'` in CI.

Also replace an underscored symbol with a regular one in macro
definition.

Cherry-picked from #20720

Closes #20721
2026-02-25 15:43:23 +01:00
Viktor Szakats
af78b199b2
tidy-up: miscellaneous
- vms/curlmsg_vms.h: delete unused/commented code.
- vtls/schannel_verify: sort includes.
- typecheck-gcc.h: fix indent and alignment.
- lib/config-win32.h: drop idle `#undef`.
- spacecheck: check for stray empty lines before after curly braces.
- make literals more readable: 1048576 -> 1024 * 1024
- scope variables.
- use ISO date in a comment.
- drop redundant parentheses.
- drop empty comments.
- unfold lines.
- duplicate/stray spaces in comments.
- fix indent, whitespace, minor typos.

Closes #20690
2026-02-25 14:44:56 +01:00
Viktor Szakats
ac46392f44
clang-tidy: enable bugprone-signed-char-misuse, fix fallouts
Examples:
```
lib/vtls/openssl.c:2585:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
 2585 |       msg_type = *(const char *)buf;
lib/vtls/openssl.c:2593:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
 2593 |       msg_type = *(const char *)buf;
tests/server/mqttd.c:514:10: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse]
  514 |       if(passwd_flag == (char)(conn_flags & passwd_flag)) {
tests/server/tftpd.c:362:13: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  362 |         c = test->rptr[0];
tests/server/tftpd.c:454:9: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  454 |     c = *p++;                     /* pick up a character */
src/tool_urlglob.c:272:46: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  272 |     pat->c.ascii.letter = pat->c.ascii.min = min_c;
src/tool_urlglob.c:273:24: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
  273 |     pat->c.ascii.max = max_c;
tests/libtest/cli_h2_pausing.c:164:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
  164 |   memset(&resolve, 0, sizeof(resolve));
tests/libtest/cli_upload_pausing.c:158:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
  158 |   memset(&resolve, 0, sizeof(resolve));
tests/libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
   86 |     coptopt = arg[optpos];
```

Also:
- tests/server/mqttd: drop a redundant and a wrongly signed cast.

Ref: https://clang.llvm.org/extra/clang-tidy/checks/bugprone/signed-char-misuse.html

Closes #20654
2026-02-25 14:44:56 +01:00
Viktor Szakats
3e198f7586
build: fix building rare combinations
- http/2 + !headers
- gnutls + !verbose
- ssls-export + !verbose

Closes #20712
2026-02-24 20:49:06 +01:00
Viktor Szakats
102d4c8ba9
tidy-up: macro parentheses
Add missing and drop redundant parentheses.

Also: fix whitespace.

Ref: #20690

Closes #20710
2026-02-24 16:30:05 +01:00
Viktor Szakats
ba685ad5e5
openssl: fix potential NULL dereference when loading certs (Windows)
This could happen if the first cert to be loaded missed EKU (Enhanced
Key Usage) data, when using native CA on Windows.

Fix by skipping certs without Enhanced Key Usage data.

Detected by clang-tidy:
```
lib/vtls/openssl.c:2922:15: warning: Access to field 'cUsageIdentifier'
 results in a dereference of a null pointer (loaded from variable
 'enhkey_usage') [clang-analyzer-core.NullDereference]
 2922 |           if(!enhkey_usage->cUsageIdentifier) {
      |               ^
```

Refs:
https://learn.microsoft.com/windows/win32/secgloss/e-gly
https://learn.microsoft.com/windows/win32/api/wincrypt/nf-wincrypt-certgetenhancedkeyusage
https://gitlab.winehq.org/wine/wine/-/blob/wine-11.2/dlls/crypt32/cert.c?ref_type=tags#L3061-3164

Assisted-by: Stefan Eissing

Closes #20634
2026-02-24 12:34:19 +01:00
Daniel Stenberg
7981594df5
mbedtls: split mbed_connect_step1 into sub functions
Increase readability. Reduce complexity.

Closes #20689
2026-02-24 11:19:20 +01:00
Viktor Szakats
453470fab1
spacecheck: double spaces in folded strings, fix fallouts
Closes #20695
2026-02-24 00:48:12 +01:00
Viktor Szakats
65262be0ab
clang-tidy: enable readability-math-missing-parentheses, adjust code
No functional changes.

Also:
- md4, md5: drop redundant parentheses from macro values.

Closes #20691
2026-02-23 18:57:40 +01:00
Viktor Szakats
3058ed3df8
lib: use lib source directory as base include path
Backtrack on previous change that aimed to solve the wrong `share.h`
being included. It turns out it did not fix this issue. At the same time
it introduced relative header filenames and the need to include the same
headers differently depending on the source files' location, reducing
readability and editability.

Replace this method by re-adding curl's lib source directory to the
header path and addressing headers by the their full, relative name to
that base directory. Aligning with this method already used in src and
tests.

With these advantages:
- makes includes easier to read, recognize, grep, sort, write, and copy
  between sources,
- syncs the way these headers are included across curl components,
- avoids the ambiguity between system `schannel.h`, `rustls.h` vs.
  local headers using the same names in `lib/vtls`,
- silences clang-tidy `readability-duplicate-include` checker, which
  detects the above issue,
  Ref: https://clang.llvm.org/extra/clang-tidy/checks/readability/duplicate-include.html
- possibly silences TIOBE coding standard warnings:
  `6.10.2.a: Don't use relative paths in #include statements.`
- long shot: it works well with concatenated test sources, for
  clang-tidy-friendly custom unity builds. Ref: #20667

Slight downside: it's not enforced.

If there happens to be a collision between a local `lib/*.h` header and
a system one, the solution is to rename (possibly with its `.c`
counterpart) into the `curl_` namespace. This is also the method used by
curl in the past.

Also:
- curlx/inet_pton: reduce scope of an include.
- toolx/tool_time: apply this to an include, and update VS project
  files accordingly. Also dropping unnecessary lib/curlx header path.
- clang-tidy: enable `readability-duplicate-include`.

Follow-up to 3887069c66 #19676
Follow-up to 625f2c1644 #16991 #16949

Closes #20623
2026-02-23 16:00:42 +01:00