[Date Prev][Date Next] [Chronological] [Thread] [Top]


bart@etpmod.phys.tue.nl wrote:
> On 16 Jun, Kurt D. Zeilenga wrote:
> > bart@etpmod.phys.tue.nl wrote:
> >> On 14 Jun, Kurt D. Zeilenga wrote:
> >> > David Boreham wrote:
> >> >
> >> >> You'll probably find that you need some sort
> >> >> of unread operation too. I did for the server.
> >> >> Big PITA it is too.
> >> >
> >> > I'm thinking that this could be avoided by having a dataAvailable
> >> > hook...  but, yes, something is needed to manage issues concerning
> >> > low-level I/O availability and ber-level data availability.
> >> > That is, a socket can be selectable but no data is yet available
> >> > due data decryption requirements.
> >>
> >> Well, the situation where there is data available on the socket (socket
> >> is selectable), but this new data is held up by the crypto layer is not
> >> a big problem. The read operation could just return a EWOULDBLOCK type
> >> error. If I remember correctly, both libldap and the servers handled
> >> this okay.
> >>
> >> It gets more interesting when there is no data on the socket, but there
> >> is data available from the crypto layer. For this situation, it will be
> >> necessary to modify all calls to 'select'.
> >
> > Hit me with a mallet, please.   How is this possible?
> >
> > As long as the caller drains the connection to EWOULDBLOCK, than the crypto
> > layer has given up all data that ready for the caller.... and data that's
> > not ready needs more from the wire.
> No, it is possible that the crypto system needs a packet of, say, 256
> bytes to decrypt. When 255 bytes come in over the network, the socket
> will be selectable, the caller will try to read, in turn triggering the
> crypto system to read. The crypto system reads the 255 bytes, but can't
> decrypt and hand data over to the caller before the last 256th byte is
> received. So it returns 'EWOULDBLOCK' (note quotes), and waits.
> If suddenly another 257 bytes arive, the procedure repeats itself. It is
> possible, depending on the TLS implementation, that all these bytes are
> read by the crypto layer in one go. This means that the crypto layer
> now has 2 packets ready for the caller. At the moment, (or rather, last
> time I looked, which has been a while :-) ), both the library and the
> server don't do read ahead, so they will request only a single LDAP
> message at a time. This means that the crypto layer will have to keep
> any superfluous data.

So, the problem is that the caller is NOT draining the stream to
EWOULDBLOCK...  which is what I thought (incorrectly) slapd did.

I see two ways of resolving this in slapd:
	1)	modify the code to drain the stream
	2)	redesign the select() away (use per stream threads that do
		blocking reads).

Option 1 is relatively straight forward and likely the best choice for
now.  Eventually, though, we need to serious consider ditching the
select event loop.  Mixing select and threads is problematic.