tlsfuzzer / tlslite-ng

TLS implementation in pure python, focused on interoperability testing
Other
227 stars 79 forks source link

select() support - tlsrecordlayer fileno() is not supported, required when integrating with hyper http2 client #414

Open martyur opened 4 years ago

martyur commented 4 years ago

Hi, When integrating tlslite to work with hyper http2 client we ran into an exception when sending a request. socket.can_read calls select.select() which needs fileno ,but it's not supported according to https://github.com/tomato42/tlslite-ng/blob/09f55888603c847a0ff68f82b69f29d48c78da69/tlslite/tlsrecordlayer.py#L654 .

If can_read is removed from hyper, then a successful request can be made ,but likely to be unstable and hang sometimes according to the developer of hyper. Fileno might not be required ,but some kind of way to check 'can_read' is needed for this to work. Any help would be greatly appreciated

martyur commented 4 years ago
@property
    def can_read(self):
        """
        Whether or not there is more data to read from the socket.
        """
        read = select.select([self._sck], [], [], 0)[0]
        if read:
            return True

        return False
tomato42 commented 4 years ago

you can try extracting the fileno of the wrapped socket (self.sock.fileno) but that has chance of working only when read() would block

martyur commented 4 years ago

@tomato42 is this right, so read only blocks until bytes are received via the socket so if select.select is called on self.sock.fileno before any bytes have been received then this might work ?

tomato42 commented 4 years ago

more or less, what I'm referring to is that inside tlslite-ng are 2 levels of buffering, one on record level and another on handshake/alert message processing level; if they are not cleared first (and by clear I mean "no data can be extracted from them", not "empty"; e.g. record layer buffering returns only full records to layers above in stack) then select() will block even if a read from the TLSConnection wouldn't block

martyur commented 4 years ago

that doesn't sound ideal, i would imagine this would also be a problem if we tried to integrate it to some other http clients that don't expect such a big abstraction layer that tls lite has. The way i see it an alternative is needed in tlslite which could be used to replace select([sock]..) that outputs the same result while dealing with the tls lite abstraction, but I'm not familiar enough with this to be able to implement it.

martyur commented 4 years ago

@tomato42 Could you please contact me via email martynas@outlook.com , I would like to get in touch for a quick chat if you don't mind.

tomato42 commented 4 years ago

this isn't something I need tlslite-ng for so I won't work on this, at most I can offer reviewing pull requests

HMaker commented 2 years ago

I have integrated TLSLite to asyncio and had no issues, you need to implement an async driver for tlslite, pass to it a non blocking socket and handle the "want read" and "want write" signals from its generator coroutines.

LennertW commented 2 years ago

@HMaker any chance you could share an example of how you did that? I would like to use tlslite-ng with grpclib (https://github.com/vmagamedov/grpclib).