The ssh libraries do not reveal if they still have data buffered from
the peer. Only when their buffers are read empty can curl be sure that
it is safe to rely on socket polling.
This change adds detection of EGAIN on receive in the transfer loop and
allows SFTP/SCP transfers to avoid a busy loop in such a case (which
should happen often when CPU exceeds network bandwidth).
Closes#17533
This started out as regression tests for the `curl_ws_recv()` and
`curl_ws_send()` implementation and ended up with a bugfix, additional
protocol validation and minor logging improvements.
- Fix reset of fragmented message decoder state when a PING/PONG is
received in between message fragments.
- Fix undefined behavior (applying zero offset to null pointer) in
curl_ws_send() when the given buffer is NULL.
- Detect invalid overlong PING/PONG/CLOSE frames.
- Detect invalid fragmented PING/PONG/CLOSE frames.
- Detect invalid sequences of fragmented frames.
- a) A continuation frame (0x80...) is received without any ongoing
fragmented message.
- b) A new fragmented message is started (0x81/0x01/0x82/0x02...)
before the ongoing fragmented message has terminated.
- Made logs for invalid opcodes easier to understand.
- Moved noisy logs to the `CURL_TRC_WS` log level.
- Unified the prefixes for WebSocket log messages: `[WS] ...`
- Add env var `CURL_WS_FORCE_ZERO_MASK` in debug builds.
- If set, it forces the bit mask applied to outgoing payloads to
0x00000000, which effectively means the payload is not masked at
all. This drastically simplifies defining the expected `<protocol>`
data in test cases.
- 2700: Frame types
- 2701: Invalid opcode 0x3
- 2702: Invalid opcode 0xB
- 2703: Invalid reserved bit RSV1 _(replaces 2310)_
- 2704: Invalid reserved bit RSV2
- 2705: Invalid reserved bit RSV3
- 2706: Invalid masked server message
- 2707: Peculiar frame sizes _(part. replaces 2311)_
- 2708: Automatic PONG
- 2709: No automatic PONG _(replaces 2312)_
- 2710: Unsolicited PONG
- 2711: Empty PING/PONG/CLOSE
- 2712: Max sized PING/PONG/CLOSE
- 2713: Invalid oversized PING _(replaces 2307)_
- 2714: Invalid oversized PONG
- 2715: Invalid oversized CLOSE
- 2716: Invalid fragmented PING
- 2717: Invalid fragmented PONG
- 2718: Invalid fragmented CLOSE
- 2719: Fragmented messages _(part. replaces 2311)_
- 2720: Fragmented messages with empty fragments
- 2721: Fragmented messages with interleaved pong
- 2722: Invalid fragmented message without initial frame
- 2723: Invalid fragmented message without final frame
- 2305: curl_ws_recv() loop reading three larger frames
- This test involuntarily sent an invalid sequence of opcodes (0x01...,0x01...,0x81...) , but neither libcurl nor the test caught this! The correct sequence was tested in 2311 (0x01...,0x00...,0x80...). See below for 2311.
- Validation of the opcode sequence was added to libcurl and is now tested in 2723.
- Superseded by 2719 (fragmented message) and 2707 (large frames).
- 2307: overlong PING payload
- The tested PING payload length check was actually missing, but the test didn't catch this since it involuntarily sent an invalid opcode (0x19... instead of 0x89...) so that the expected error occurred, but for the wrong reason.
- Superseded by 2713.
- 2310: unknown reserved bit set in frame header
- Superseded by 2703 and extended by 2704 and 2705.
- 2311: curl_ws_recv() read fragmented message
- Superseded by 2719 (fragmented message) and 2707 (large frames).
- 2312: WebSockets no auto ping
- Superseded by 2709.
- No tests for `CURLOPT_WRITEFUNCTION`.
- No tests for sending of invalid frames/fragments.
Closes#17136
Instead of curl.haxx.se
Also widen the .gitignore for libtest, since it missed libtest751,
so ignore three digit tests that start with 5-9 instead of just 5-6.
Closes#17502
When ftp_done() is called to terminate the transfer, it needs to tear
down any open SECONDARY filter chain. The condition on when to do that
was relying on there to be a valid socket. This is not sufficient as the
socket is only set *after* happy eyeballing has decided on one.
Instead of checking for a valid conn->sock, check if any connection
filter is installed.
Fixes#17482
Reported-by: Rasmus Melchior Jacobsen
Closes#17491
With a dash, using two Ls. Also for different forms of the word.
Use NULL in all uppercase if it means a zero pointer.
Follow-up to 307b7543eaCloses#17489
Early data was reported as being sent, but was not. While everything was
aligned with the Gods and early data was reported as accepted, the
actual sending required another call to wolfSSL.
Fixes#17481
Reported-by: Ethan Everett
Closes#17488
When inspecting a possible follow HTTP request, the result of a rewind
of the upload data was ignored as it was not clear at that point in time
if the request would become a GET.
This initiated the followup, rewound again, which failed again and
terminated the follow up.
This was confusing to users as it was not clear of the follow up was
done or not.
Fix: fail the early rewind when the request is not converted to GET.
Fixes#17472Closes#17474
Reported-by: Jeroen Ooms
Due to someone being stupid, the resizing of the multi's transfer
table was actually shrinking it. Oh my.
Add test751 to reproduce, add code assertion.
Fixes#17473
Reported-by: Jeroen Ooms
Closes#17475
7bf576064c moved local_ip6 from the parameter list to the actual
implementation of Curl_async_ares_set_dns_local_ip6. The no-op code for
!( defined(HAVE_CARES_SET_LOCAL) && defined(USE_IPV6) ) still had an
reference which is removed by this change.
Closes#17450
When TYPE was skipped for an immediate STORE command and the server
replied fast and the EPRT data connection was not ready, the transfer
was not initated, leading to no upload.
Fixes#17394Closes#17428
Reported-by: JoelAtWisetech on github
Since they are mostly independent, using them as bitfelds makes the code
easier.
- remove the unused struct field 'width'.
- convert 'speeder_c' to an unsigned char from int
Closes#17431
When SASL is unable to select an AUTH mechanism, give user help
in info message why no AUTH could be selected.
Fixes#17420Closes#17427
Reported-by: Aditya Garg
Used for both CURLOPT_SSL_OPTIONS and CURLOPT_PROXY_SSL_OPTIONS
Also: make the DoH code use the full original argument value instead of
each individual flag. Makes it easier to keep all of these in synk.
Closes#17429
Reduce Curl_ossl_ctx_init() complexity by splitting it up into
sub functions.
While splitting if ECH, add pytest fixed for AWS-LC and enable
it in CI.
Closes#17404
- Simplify canon_query() a bit. Avoid unconditionally using length -1
where length risks being zero at times. Pointed out by Coverity.
- Fix indent errors
- narrow some variable scopes
- fix keywords in tests
Closes#17402
These two conditions probably cannot actually happen, but these two
checks make that certain and should please the static code analyzers.
Pointed out by Coverity
Closes#17397
The `struct Curl_dns_entry *` used to established a connection
do not have the connection's lifetime, but the transfer's lifetime
(of the transfer that initiates the connect).
`Curl_dns_entry *` is reference counted with the "dns cache". That
cache might be owned by the multi or the transfer's share. In the
share, the reference count needs updating under lock.
Therefore, the dns entry can only be kept *and* released using the
same transfer it was initially looked up from. But a connection is
often discarded using another transfer.
So far, the problem of this has been avoided in clearing the connection's
dns entries in the "multi_don()" handling. So, connections had NULL
dns entries after the initial transfers and its connect had been handled.
Keeping the dns entries in data->state seems therefore a better choice.
Also: remove the `struct Curl_dns_entry *` from the connect filters
contexts. Use `data->state.dns` every time instead and fail correctly
when not present and needed.
Closes#17383
To avoid redundant work in CI and to avoid a single checksrc issue make
all autotools jobs fail. After this patch checksrc issues make fail
the checksrc job, the `dist / verify-out-of-tree-autotools-debug`,
`dist / maketgz-and-verify-in-tree` jobs and the fuzzer job (if run).
Of these, the `dist` jobs replicate local builds, also testing the build
logic.
Also add a script to check the complete local repository, optionally
with the build tree to verify generated C files.
Also:
- automatically run checksrc in subdirectories having a `checksrc`
target. (examples, OS400, tests http/client, unit and tunit)
- tests/libtest: make sure to run `checksrc` on generated `lib1521.c`.
(requires in-tree autotools build.)
- tests: run `checksrc` on targets also for non-`DEBUGBUILD`
builds. It ensures to check `lib1521.c` in CI via job
`dist / maketgz-and-verify-in-tree`.
- src: drop redundant `$(builddir)` in autotools builds.
- scripts: add `checksrc-all.sh` script to check all C sources and
the build directory as an option.
- use the above from CI, also make it verify all generated sources.
- silence `checksrc` issues in generated C sources.
- checksrc: add `-v` option to enable verbose mode.
- checksrc: make verbose mode show checked filename and fix to only
return error on failure.
- make sure that generated C files pass `checksrc`.
Assisted-by: Daniel Stenberg
Closes#17376
- use memchr() instead of for() loop
- add and use free_formlist() instead of duplicate code
- shorten some variable names
- reduce flag struct field from 'long' to 'unsigned char'
- pass in struct pointer, not individual fields, to addhttppost()
Closes#17370
Coverity assess correctly that a variable write under mutex lock could
overwrite values from another thread - if the function were ever called
from multiple thread for the same transfer - which it is not.
Closes#17365