Skip to content

libssh2: skip repeat checkp() for already-absent hashed key types - #22905

Closed
1rhino2 wants to merge 2 commits into
curl:masterfrom
1rhino2:libssh2-checkp-cache
Closed

1rhino2 wants to merge 2 commits into
curl:masterfrom
1rhino2:libssh2-checkp-cache

Conversation

@1rhino2

@1rhino2 1rhino2 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

follow-up to #22874 (landed in 323c184). that fix added a libssh2_knownhost_checkp() call per hashed known_hosts entry so the entry is matched against the requested host before its key type gets used. each checkp() rescans the whole known_hosts set though, so a file with many hashed entries of the same type does one full scan per entry.

this caches the key types already confirmed absent for the connecting host. checkp() returning NOTFOUND for a (host, port, type) means there is no entry of that type for the host at all, which does not depend on the key bytes passed in. so once a type comes back NOTFOUND, any later hashed entry of that same type can be skipped. if the host does have an entry of that type, checkp() returns MATCH or MISMATCH instead and nothing is cached, so real matches are still found. the MATCH path and the switch on store->typemask afterward are unchanged.

pure perf, no behavior change.

tested: runtests.pl 3500 1459 600, full SFTP/SCP keyword set (58/58), checksrc.pl.

ssh_force_knownhost_key_type() called libssh2_knownhost_checkp() once
per hashed known_hosts entry, and each call itself rescans the whole
known_hosts set. Cache key types already confirmed absent for the
connecting host so repeat entries of the same type do not each trigger
another full scan. checkp() NOTFOUND for a given (host, port, type) is
independent of the key bytes passed in, so this is safe.

Behavior for MATCH is unchanged, and only store->typemask is read
after a match, which is identical for any entry of the same type.

Tests: runtests.pl 3500 1459 600, full SFTP/SCP keyword set (58/58),
checksrc.pl.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The six-entry cache does not cover every libssh2 key-type value, leaving some repeated scans unoptimized.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Caches absent SSH host-key types to avoid redundant libssh2_knownhost_checkp() scans.

Changes:

  • Tracks key types returning NOTFOUND.
  • Skips repeated checks for cached types.
File summaries
File Description
lib/vssh/libssh2.c Adds absent key-type caching during known-host lookup.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/vssh/libssh2.c Outdated
The earlier cache used a 6-slot append list, but libssh2 exposes more
key types than that, so some entry orderings filled it before a type
was seen and kept rescanning that type. Use one slot per possible key
type, indexed by the type shifted down, so no ordering can overflow it.
Drops the linear scan too.
@bagder bagder closed this in dc055e8 Sep 11, 2026
@bagder

bagder commented Sep 11, 2026

Copy link
Copy Markdown
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

3 participants