bug#70645: Reliable HTTPS networking

Christopher Baines <[email protected]> Mon, 19 Jan 2026 22:03:42 +0000
Newsgroups gmane.lisp.guile.bugs
Message-ID <[email protected]>
--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Ludovic Court=C3=A8s <[email protected]> writes:

> Christopher Baines <[email protected]> skribis:
>
>> As described in the GnuTLS documentation on Asynchronous operation,
>> GNUTLS_NONBLOCK should be passed to gnutls_init, and the Guile
>> equivalent is passing connection-flag/nonblock to make-session.
>>
>> Additionally, error/again or error/interrupted should lead to a retry of
>> the handshake, after waiting for the appropriate I/O on the port.  As
>> record-get-direction is new in Guile-GnuTLS, specifically check if this
>> is defined.
>>
>> * module/web/client.scm (tls-wrap): Call make-session with
>> connection-flag/nonblock if the port is non-blocking, and handle waiting
>> for I/O when performing the handshake.
>
> [...]
>
>> +  (let ((session
>> +         (apply
>> +          make-session
>> +          (cons connection-end/client
>> +                (if (zero? (logand O_NONBLOCK (fcntl port F_GETFL)))
>> +                    '()
>> +                    ;; If the port is non-blocking, tell GnuTLS
>> +                    (list connection-flag/nonblock)))))
>
> You can avoid =E2=80=98cons=E2=80=99 here:
>
>   (apply make-session connection-end/client
>          (if =E2=80=A6 '() (list =E2=80=A6)))

That looks good to me.

>> +          (cond ((and
>> +                  (or (eq? err error/again)
>> +                      (eq? err error/interrupted))
>> +                  (module-defined? (resolve-interface '(gnutls))
>> +                                   'record-get-direction)) ; Guile-GnuT=
LS >=3D 4.0.0
>> +                 (if (=3D 0 (record-get-direction session))
>> +                     ((current-read-waiter) port)
>> +                     ((current-write-waiter) port))
>
> Should EINTR (error/interrupted) really be treated in the same way as
> EAGAIN?  That looks fishy.

I don't know, I got this from the documentation for record-get-direction
https://gnutls.org/manual/html_node/Asynchronous-operation.html

> Also, this only addresses handshake, but what about =E2=80=98error/again=
=E2=80=99 raise
> while transferring data over the session record port?

I'm not sure, but here I'm just trying to change the behaviour for the
handshake. I'm already using gnutls over nonblocking ports, and I'm not
aware of any significant issues.

I'm coming back to this issue after a while, and I've also opened a Pull
Request here now https://codeberg.org/guile/guile/pulls/95

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQKlBAEBCgCPFiEEPonu50WOcg2XVOCyXiijOwuE9XcFAmluqj5fFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF
ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcRHG1haWxAY2Jh
aW5lcy5uZXQACgkQXiijOwuE9XdwGg//bXiTgLBsCCLS/MxQWYNzVm+P9uMnuyK7
vOF0A5U4EyCETrDyYI2HrI8nEMPv0uLYULKylEw/FhP7V7NzbE5B6JAkr+vg+IKO
fmgUW+OFThim/eHxJR8uLWs+WmXEGKxJG3glhB2/8kpJdoCvj1X+U91ldHfehPZ4
RwWOE+KsT9A2RpxGtoSVvhrR7xWNS4r+eX7eZodr6H22WgGBi8DXDTHzW8PrICRl
UgIjYgw6BzWEPYmJKmnbdxWJ2GtwtCArw27upoqZalLAqsGegVTunEato50nNdh+
sluLtr9iNFpsRhIsZqJIoUY3Kde3au/aI7H4qbuC+0wu4qELirJ9rPjgKG5IMORZ
SGt7ht6VBBqLflNoFAoOwxH0h0i5axKr2Dq2EeIdx7PoM96rCy3s+tDkw6ylyffc
TUjDRHGRQWDfWKhRK4F5ubWe2ZpgcQo6hhW74dBllWv31BLX6fjWJlPQ4ke60CZH
JteOsEmH0CtfqaXyH1ScUA+zmfUEs0YFS5U+M35uQKeLZWQEqJimxPyhOksGG74I
Cu3rH0dm4JRR0NqJezc4DN82c3CIklNgv9H5GkPhr84rSybzneWwNOVF/l9QEj8O
RQkN1A3FjtsW+F5so7cOsyKBU6S9wPVSfJO5dRskOPJHlN3tUi0n3b9PlcNRj4jj
O8L1Yt4AMxQ=
=fgOE
-----END PGP SIGNATURE-----
--=-=-=--