[gnutls-dev] [PATCH]: broken gnutls_bye() state machine
yoann at prelude-ids.org
Wed Jan 25 21:52:25 CET 2006
Attached is a patch that fix several issues in GnuTLS 1.2.9:
# When gnutls_bye() reach STATE62, if _gnutls_recv_int() return EAGAIN,
then upcoming gnutls_bye() call will resume at STATE61.
This mean that the GNUTLS_A_CLOSE_NOTIFY alert will be sent several
time, even through the peer might have stopped reading the socket.
This lead to garbage remaining to be read, even through gnutls_bye()
returned 0 on both end of the connection (thus, unusable connection).
# gnutls_bye() not returning an alert sent by the peer, in the specific
1. the peer send an alert, followed by a call to gnutls_bye() then
immediate connection closure.
2. Before noticing the hang-up, we try to send something to the peer,
and get GNUTLS_E_PUSH_ERROR, since the peer has already closed the
The problem happen here: the internal GnuTLS code will call the
session_invalidate() function as a result of the send() error.
Unfortunately, this mean that we won't be able to read the remaining
data (the alert sent earlier, in #1), since _gnutls_recv_int() check
whether the session has been invalidated before reading the socket.
This is why the attached patch remove the session_invalidate() call, and
set session->internals.may_not_write to 1.
3. We thus call gnutls_bye(), but never get the alert sent in #1, since
_gnutls_recv_int() will always return an error prior trying to read the
socket, due to the session being already invalidated.
With the attached patch, I can not reproduce both problem anymore. I'm
not sure whether the patch is fully correct through.
Hope it help,
Yoann Vandoorselaere | Responsable R&D / CTO | PreludeIDS Technologies
Tel: +33 (0)8 70 70 21 58 Fax: +33(0)4 78 42 21 58
Yoann Vandoorselaere <yoann at prelude-ids.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 596 bytes
Desc: not available
More information about the Gnutls-devel