mjs / gevent_openssl

pyopenssl gevent compat. lib
Other
22 stars 18 forks source link

__iowait infinite loop #6

Closed pcdinh closed 9 years ago

pcdinh commented 9 years ago

Hi,

I am trying to combine your library and apns-client 0.2.1 in a environment of gevent-based multiple greenlets. However, when apns-client calls recv() against gevent_openssl's Connection, it runs into an infinite loop which blocks that thread forever.

Is it by design or a bug?

    def __iowait(self, io_func, *args, **kwargs):
        timeout = self._sock.gettimeout() or 0.1
        fd = self._sock.fileno()
        while True:
            try:
               # Commented by me: it always return None and throws no Exception
                return io_func(*args, **kwargs)
            except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantX509LookupError):
                sys.exc_clear()
                _, _, errors = select.select([fd], [], [fd], timeout)
                if errors:
                    break
            except OpenSSL.SSL.WantWriteError:
                sys.exc_clear()
                _, _, errors = select.select([], [fd], [fd], timeout)
                if errors:
                    break
zenoamaro commented 9 years ago

Can confirm that this issue still happens, as described by @pcdinh, on:

mjs commented 9 years ago

gevent_openssl v1.1 (just released) may have fixed this. Can you confirm?

zenoamaro commented 9 years ago

At a first look the issue doesn't appear to be solved.

I'm using apnsclient and it locks and hangs my requests like so:

DEBUG New session, WB: 2048b/20s, RB: 2048b/20s, TT: 3s, Pool: apnsclient.backends.stdio
DEBUG Certificate provided as string
DEBUG Private key provided as string with passphrase
DEBUG Entering networking session
DEBUG Open cached connection to ('gateway.push.apple.com', 2195).
DEBUG Opening POSIX socket/pyOpenSSL connection to ('gateway.push.apple.com', 2195)
DEBUG SSL handshaking to ('gateway.push.apple.com', 2195) completed

After that last line it hangs. Though this might be pyOpenSSL's fault.

mjs commented 9 years ago

Bummer. Can you provide a minimal example that triggers the problem? I'm not at all familiar with APNs but if I can reproduce the problem myself I can hopefully fix it.

zenoamaro commented 9 years ago

I've prepared a minimal implementation that triggers the issue: https://gist.github.com/zenoamaro/4ba0191b007bf0e208a6

I couldn't include private certificates, passphrases, and device tokens, though, at least not publicly, so you'd have to provide your own to test. A valid device token is something like f8f9e0c3231e71d2fbde162c46f52d373ef09478e58f947e46f059d529e265c1. Both the private key and certificate start with a data bag (bag attributes, friendly name, etc) and include a private key section and a certificate section respectively.

emfree commented 9 years ago

Holla @mjs -- this looks like it also affects IMAPClient in idle mode. I can consistently reproduce using something like the following:

import gevent_openssl
gevent_openssl.monkey_patch()
from backports import ssl
import imapclient

email = '<your email>'
token = '<your access token>'
host = 'imap.gmail.com'

context = imapclient.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
conn = imapclient.IMAPClient(host, port=993, use_uid=True, ssl=True,
                             ssl_context=context, timeout=120)

conn.oauth2_login(email, token)
conn.select_folder('[Gmail]/All Mail')
conn.idle()
conn.idle_check(30)

# Now go mark a message as read or similar to trigger a write to the idling
# connection -->  death loop in __iowait.
mjs commented 9 years ago

@emfree and @zenoamaro: Thanks very much for the repro details.

I'm short on time in at the moment (in a few days between a week off and work trip) but I will get to this as soon as I can.

mjs commented 9 years ago

I've pushed a branch which seems to fix this issue (it does for @emfree's example).

Please try installing gevent_openssl from here and seeing if it helps: https://github.com/mjs/gevent_openssl/tree/infinite-loop-fix

zenoamaro commented 9 years ago

Thank you, it looks like this did it!

I'll do more tests in the next days but it seems it's working correctly now!

mjs commented 9 years ago

@zenoamaro, @emfree: Great news. I'll do a new release today.