Files
ppsspp/Common/Net/Resolve.h
T
Henrik Rydgård a0873e5b0e Enable HTTPS on Linux, through naett's libcurl backend
naett has had a complete libcurl backend all along; we just never built it,
so Linux ran with HTTPS_NOT_AVAILABLE. That means no homebrew store over
HTTPS, and RetroAchievements talking to plain http://retroachievements.org.

libcurl is loaded with dlopen rather than linked, the same way we handle the
Vulkan loader, so it stays a soft dependency: we need the curl headers at
build time, but a build made here still starts on a machine without libcurl
installed - it just reports HTTPS as unavailable, exactly like today. Distro
packagers get the behavior they'd expect either way, and certificate
validation comes free from the system CA store.

New net::HTTPSAvailable() answers "did that work", and SDLMain folds it into
SYSPROP_SUPPORTS_HTTPS, which everything downstream already degrades on.

Four fixes to the backend itself, all noted in ext/naett/README-ppsspp.md:

- panic() called exit(1) on a pipe or curl_multi_perform failure. Taking the
  emulator down because a download failed isn't acceptable - the backend now
  disables itself and requests complete with naettGenericError.
- CURLINFO_RESPONSE_CODE writes a long into res->code, which is an int. Eight
  bytes into four, getting away with it only because the next field absorbs
  the zeroes.
- curl_easy_setopt is varargs and wants a long for these options; int literals
  and int variables are UB on LP64.
- naettPlatformCloseResponse called through a null function pointer when
  libcurl was missing. Found by testing that path, which segfaulted.

CI needs libcurl4-openssl-dev (curl-dev on Alpine) or it would quietly keep
building without HTTPS.
2026-09-02 17:42:04 +02:00

50 lines
2.0 KiB
C++

#pragma once
#include <cstdint>
#include <string>
#include <vector>
struct addrinfo;
namespace net {
// All platforms should call these on process start and end.
void Init();
void Shutdown();
// Whether we have a working HTTPS backend. False if PPSSPP was built without one, and on
// Linux also if libcurl couldn't be loaded at runtime. Safe to call before Init().
// Platform ports should factor this into SYSPROP_SUPPORTS_HTTPS.
bool HTTPSAvailable();
enum class DNSType {
ANY = 0,
IPV4 = 1,
IPV6 = 2,
};
// This checks whether a TCP connection to host : port can be established within a given timeout.
// It does this by attempting a new, non - blocking TCP connect() and waiting for it to succeed or time out.
// The socket is closed immediately after the check.
// It does not inspect or detect existing connections from other applications; it only tests reachability by making its own connection attempt.
bool HostPortExists(const std::string &host, int port, int timeout_ms);
// Uses OS getaddrinfo to resolve an address. Blocking.
bool DNSResolve(const std::string &host, const std::string &service, addrinfo **res, std::string &error, DNSType type = DNSType::ANY);
// Call this when you're done using the result of DNSResolve.
void DNSResolveFree(addrinfo *res);
// Uses tricks like getifaddrs to get a list of local IPv4 addresses. Returns false on failure, true on success (even if the list is empty).
bool GetLocalIP4List(std::vector<std::string>& IP4s);
// IP address parser.
int inet_pton(int af, const char* src, void* dst);
// Does a DNS lookup without involving the OS, so you can ask any DNS server you want, instead of
// just the one configured in the OS. Also blocking, currently.
// NOTE: This contains an internal cache that cannot be invalidated currently. TODO: At least add a timeout,
// although a process restart will clear it up anyway so maybe not that important...
bool DirectDNSLookupIPV4(const char *dnsServer, const char *host, uint32_t *ipv4_addr);
} // namespace net