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 ‘cons’ here:
(apply make-session connection-end/client
(if … '() (list …)))
> + (cond ((and
> + (or (eq? err error/again)
> + (eq? err error/interrupted))
> + (module-defined? (resolve-interface '(gnutls))
> + 'record-get-direction)) ; Guile-GnuTLS >=
> 4.0.0
> + (if (= 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.
Also, this only addresses handshake, but what about ‘error/again’ raise
while transferring data over the session record port?
Thanks,
Ludo’ “better late than never”.