git: d6678851308d - main - libfetch: Apply timeout to SSL handshake
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 02 Nov 2026 12:38:03 UTC
The branch main has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=d6678851308d3cec767f07b0712a429cdc5895de
commit d6678851308d3cec767f07b0712a429cdc5895de
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-11-02 12:27:53 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-11-02 12:28:39 +0000
libfetch: Apply timeout to SSL handshake
When the SSL handshake cannot proceed because the server is slow to
respond, poll() with a timeout instead of spinning.
MFC after: 1 week
PR: 298962
Event: Oslo Hackathon 2026
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D60975
---
lib/libfetch/common.c | 42 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
index da0ea6f8aaeb..c15b22a41603 100644
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -1219,7 +1219,9 @@ int
fetch_ssl(conn_t *conn, const struct url *URL, int verbose)
{
#ifdef WITH_SSL
- int ret, ssl_err;
+ struct timeval now, timeout, delta;
+ struct pollfd pfd;
+ int deltams, ret, ssl_err;
X509_NAME *name;
char *str;
@@ -1251,13 +1253,47 @@ fetch_ssl(conn_t *conn, const struct url *URL, int verbose)
return (-1);
}
#endif
+ if (fetchTimeout > 0) {
+ gettimeofday(&timeout, NULL);
+ timeout.tv_sec += fetchTimeout;
+ }
+ deltams = INFTIM;
+ pfd.fd = conn->sd;
while ((ret = SSL_connect(conn->ssl)) == -1) {
ssl_err = SSL_get_error(conn->ssl, ret);
- if (ssl_err != SSL_ERROR_WANT_READ &&
- ssl_err != SSL_ERROR_WANT_WRITE) {
+ switch (ssl_err) {
+ case SSL_ERROR_WANT_READ:
+ pfd.events = POLLIN;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ pfd.events = POLLOUT;
+ break;
+ default:
ERR_print_errors_fp(stderr);
return (-1);
}
+ /* check what's left of our timeout */
+ if (fetchTimeout > 0) {
+ gettimeofday(&now, NULL);
+ if (!timercmp(&timeout, &now, >)) {
+ errno = ETIMEDOUT;
+ fetch_syserr();
+ return (-1);
+ }
+ timersub(&timeout, &now, &delta);
+ deltams = delta.tv_sec * 1000 +
+ delta.tv_usec / 1000;
+ }
+ ret = poll(&pfd, 1, deltams);
+ if (ret == 0) {
+ fetch_info("SSL handshake timed out");
+ return (-1);
+ }
+ if (ret < 0) {
+ if (errno == EINTR && fetchRestartCalls)
+ continue;
+ return (-1);
+ }
}
conn->ssl_cert = SSL_get_peer_certificate(conn->ssl);