Subject: bug#22493: 25.1.50; open-gnutls-stream doesn't respect :nowait, so the connections are synchronous

From: Eli Zaretskii <[email-masked]>
Date: Sat, 30 Jan 2016 11:21:43 +0200

> From: Lars Ingebrigtsen <[email-masked]>
> Date: Sat, 30 Jan 2016 05:45:21 +0100
> 
> First of all, gnutls-open-stream should call open-network-stream with
> :nowait, and put a sentinel on the stream to see when it's opened, and
> then it should call gnutls-negotiate from the sentinel.
> 
> The problem is, though, that the process isn't marked as a gnutls
> process until gnutls_boot is called, so this needs to happen much
> earlier.  Possibly by adding another keyword to make-network-process
> that just sets
> 
>   XPROCESS (proc)->gnutls_p = 1;

Why do you need to mark a process gnutls_p, when it definitely still
isn't, not until the GnuTLS negotiation is successfully completed?
That'd just add confusion (a.k.a. "bugs waiting to happen") on the C
level.  Can't we use a GnuTLS-specific sentinel instead?

> The other problem is that reading/writing from these things will just
> send plain text if the gnutls stuff hasn't been initialised:
> 
> #ifdef HAVE_GNUTLS
> 	      if (p->gnutls_p && p->gnutls_state)
> 		written = emacs_gnutls_write (p, cur_buf, cur_len);
> 	      else
> #endif
> 		written = emacs_write_sig (outfd, cur_buf, cur_len);
> 
> I think that looks rather nonsensical.

Does this happen today?  If so, in what scenario?

> If it's p->gnutls_p, then it should never write to the process, no
> matter what the state is.  Rather is should just skip writing until
> p->gnutls_state gets set (which happens during gnutls_boot).
> 
> Or is there something subtle here I'm missing?  When would we ever want
> to write plain text to something that's p->gnutls_p?

If you want GnuTLS negotiation to happen from the sentinel, you need
some machinery to block such process objects from communicating.
I'm not sure silently skipping I/O is TRT for that: won't Lisp
programs that happen to start communicating too early become confused
about what's going on?

More generally, what advantages do we expect to gain by making these
changes?  Let DNS resolution proceed in the background, only to have
to wait for GnuTLS negotiations anyway, before we can start using the
stream?  Or are there more significant advantages?

Thanks.