Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stopped working with OpenSSL changes in PHP 5.6.7 #84

Open
shawn-digitalpoint opened this issue Mar 21, 2015 · 30 comments
Open

Stopped working with OpenSSL changes in PHP 5.6.7 #84

shawn-digitalpoint opened this issue Mar 21, 2015 · 30 comments

Comments

@shawn-digitalpoint
Copy link

Times out with the fread() function in the ApnsPHP_Push->_readErrorMessage() method with the changes PHP 5.6.7 made. Reverting back to PHP 5.6.6 (same compile options) and everything back to working.

Not sure it makes a difference, but it's with the OpenSSL 1.0.2a libs.

Haven't had time to dig too much into the underlying issue, but seeing how PHP 5.6.7 made a bunch of changes to OpenSSL and how it handles timeouts, I wonder if they introduced a bug. http://php.net/ChangeLog-5.php#5.6.7

@ghost
Copy link

ghost commented Mar 25, 2015

Reproducable with PHP 5.6.7 and 5.5.23.

@TimE90
Copy link

TimE90 commented Mar 26, 2015

Same here… socket timeout slows down the stream to 60seconds per read…

Tried to set timeout socket to a short time but doesn't affect when calling via CGI.
duccio, we need a urgent fix here please :)

PHP fixed bug #61285, #68329, #68046, #41631 (encrypted streams don't observe socket timeouts).

@aporat
Copy link
Contributor

aporat commented Apr 2, 2015

Looks like rolling back to PHP 5.6.6 is the best alternative right now

@sshilko
Copy link

sshilko commented Apr 2, 2015

Same issue with 5.5.23 upgrade from 5.5.22

Any PPA's for 5.5.22 ?? . deb.sury is 5.5.23 :( ubuntu 12.04

anyone, any workarounds?

Full 5.5.22 -> 5.5.23 diff here

https://launchpadlibrarian.net/201114140/php5_5.5.22%2Bdfsg-1%2Bdeb.sury.org~precise%2B1_5.5.23%2Bdfsg-1%2Bdeb.sury.org~precise%2B2.diff.gz

Original git merge thread

php/php-src#971

@sshilko
Copy link

sshilko commented Apr 7, 2015

php issue submitted

https://bugs.php.net/bug.php?id=69393

@EugenMayer
Copy link

could that also affect PECL over proxy? https://pecl.php.net/package-changelog.php?package=pecl_http&release=2.4.3

@sshilko
Copy link

sshilko commented Apr 12, 2015

@EugenMayer not sure, not using that package. try changing the

ini_get("default_socket_timeout") 

value, it uses that timeout for socket operations.. and check difference if using 5.5.22 and 5.5.23

i'am using this workaround atm

ini_ini("default_socket_timeout", 1) 

on dev machines where i can upgrade, not a workaround for production tho.

@sshilko
Copy link

sshilko commented Apr 14, 2015

Though this bug has been fixed upstream, it wasn't discovered until 5.5.23 and 5.6.7 were already in the RC stage and couldn't be included in these releases. The next set of bugfix releases resolves this issue.

hi everyone, the bug was confirmed and the fix is in upstream, everyone interested in ApnsPHP invited to use https://packagist.org/packages/sshilko/backq https://github.com/sshilko/backq as a solution to dispatch push notifications, its stable and in production.

@beeradmoore
Copy link

Issue still occurs in 5.5.24.
EDIT: Can confirm for the issue I was seeing (100% CPU for 60sec while sending to sandbox server) that it did not happen when I downgraded to 5.5.22.

@sshilko
Copy link

sshilko commented Apr 20, 2015

5.6.8 and 5.5.24 were in RC already, fix expected in 5.5.25.. look into
comments from dev
On Apr 19, 2015 12:45 PM, "ytn3rd" notifications@github.com wrote:

Issue still occurs in 5.5.24.


Reply to this email directly or view it on GitHub
#84 (comment).

@beeradmoore
Copy link

I did.
"it wasn't discovered until 5.5.23 and 5.6.7 were already in the RC stage and couldn't be included in these releases. The next set of bugfix releases resolves this issue."

Had assumed that when they say the next set of bugfix release would mean 5.5.24 which it clearly isn't fixed in.

@sshilko
Copy link

sshilko commented Apr 20, 2015

Fix Bug #69402: Reading empty SSL stream hangs until timeout
https://bugs.php.net/bug.php?id=69402

believe thats the fix
https://git.php.net/?p=php-src.git;a=commit;h=81f356b4aea79cd8f86e16096c7ccfbc455bfc3c

and the comment says

This is now fixed upstream in 5.5 and 5.6 branches. 
The RC period has already begun for 5.5.24 and 5.6.8 
so this fix will not be reflected in releases
until 5.5.25 and 5.6.9. 

@beeradmoore
Copy link

Ah, gotya. Was reading the bugreport you had posted earlier. Your new comment was not there at the time of writing. Good to know it'll all be fixed for 5.5.25 though.

"php issue submitted
https://bugs.php.net/bug.php?id=69393"

@iquito
Copy link

iquito commented Apr 30, 2015

I experience this problem aswell - but I cannot easily downgrade my PHP version. How do you work around this problem? For now ApnsPHP just does not work as long as this bug is still around. Setting socket timeout values has no effect, so what else can be done?

@sshilko
Copy link

sshilko commented Apr 30, 2015

i mentioned a workaround above, u can control "how long it will be stuck" reading with

ini_ini("default_socket_timeout", 1) 

this way it will be stuck for 1 second each time it tries to read from socket (when bug happends).

@iquito
Copy link

iquito commented Apr 30, 2015

I already did that - it does not work. The script is still permanently stuck.

@iquito
Copy link

iquito commented Apr 30, 2015

No timeout seems to actually have an effect - without explicitely killing processes they are running forever, never stopping and all using 100% CPU. I have actually had a CPU load of 20000 within 24 hours just because of all the cron jobs calling ApnsPHP.

@sshilko
Copy link

sshilko commented Apr 30, 2015

do it before you connect, not before you execute read from stream.. worked for me at 5.5.23 and currently works too

//5.5.23-1+deb.sury.org~precise+2
//execute before initializing stream_socket_client or use 4th argument of stream_socket_client
ini_ini("default_socket_timeout", 1) 

/*
resource stream_socket_client ( string $remote_socket [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") [, int $flags = STREAM_CLIENT_CONNECT [, resource $context ]]]]] )
*/

$socket = stream_socket_client($url,
                               $error1,
                               $error2,
                               $timeoutValueInSeconds,
                               STREAM_CLIENT_CONNECT,
                               $streamContext);

stream_set_blocking($socket, 0);
stream_set_write_buffer($socket, 0);
stream_set_read_buffer($socket, 0);


and yeah..
ads :)

use https://github.com/sshilko/backq

@iquito
Copy link

iquito commented Apr 30, 2015

That is what I did - I called the ini_set command at the very beginning of the script, before anything happens at all. Yet the cron script just goes to 100% CPU and stays there forever - even after 12 hours it is still going, when every possible timeout should have been reached.

@sshilko
Copy link

sshilko commented Apr 30, 2015

works for me, i'am setting 2 seconds timeout as an stream_socket_client 4th argument, and seeing it work
(taking 2 seconds, instead of 1 second in 5.5.22 as should be according to stream_set_timeout)

$ time php test.php
Sending 172 bytes over tls://gateway.sandbox.push.apple.com:2195:
Socket state:
Array
(
    [stream_type] => tcp_socket/ssl
    [mode] => r+
    [unread_bytes] => 0
    [seekable] => 
    [timed_out] => 
    [blocked] => 
    [eof] => 
)
stream_set_timeout timeout set: 1 second
Has errors: string(0) ""

real    0m2.685s
user    0m0.836s
sys     0m1.708s

@iquito
Copy link

iquito commented Apr 30, 2015

Nope, setting the stream_socket_client connect timeout does not work either - that's a connect timeout, so it should not have any effect on reading from a remote host anyway, as the connection is not the problem. "default_socket_timeout" should have been it, but that definitely does not work, unfortunately.

The only thing which works and still lets the script run it course is by commenting out the contents of _readErrorMessage() in ApnsPHP_Push - which disables all error handling, but at least the servers are not completely overloaded. Having a server load of 20000 really is quite frightening.

@jakobjw
Copy link

jakobjw commented May 6, 2015

All the workarounds seem to work only if there is no "invalid" (unregistered) APNS token contained in the queue. To me it seems that it works till the first invalid token, all receivers with tokens after that one don't receive messages. Although the log output of ApnsPHP looks completely successful.

Maybe the reason is that the APNS server wants to send an error response after an invalid token and, from this point on, the ApnsPHP workaround hinders from successfully communicating with the server.

@sshilko
Copy link

sshilko commented May 6, 2015

apple doc clearly states that messages after error would not be processed
as i remember. read apple docs. thats why there are disconnect+resend logic
in apns.

maybe iam wrong ')
On May 6, 2015 7:50 PM, "jakobjw" notifications@github.com wrote:

All the workarounds seem to work only if there is no "invalid"
(unregistered) APNS token contained in the queue. To me it seems that it
works till the first invalid token, all receivers with tokens after that
one don't receive messages. Although the log output of ApnsPHP looks
completely successful.

Maybe the reason is that the APNS server wants to send an error response
after an invalid token and, from this point on, the ApnsPHP workaround
hinders from successfully communicating with the server.


Reply to this email directly or view it on GitHub
#84 (comment).

@sshilko
Copy link

sshilko commented May 6, 2015

also the workaround was to prevent the 100%cpu load infinitely/60sec . not
really to fix the logic. tho iam sending the messages 1by1 in backq
probably thats why fix workex for me.
On May 6, 2015 7:50 PM, "jakobjw" notifications@github.com wrote:

All the workarounds seem to work only if there is no "invalid"
(unregistered) APNS token contained in the queue. To me it seems that it
works till the first invalid token, all receivers with tokens after that
one don't receive messages. Although the log output of ApnsPHP looks
completely successful.

Maybe the reason is that the APNS server wants to send an error response
after an invalid token and, from this point on, the ApnsPHP workaround
hinders from successfully communicating with the server.


Reply to this email directly or view it on GitHub
#84 (comment).

@mfrr1118
Copy link

mfrr1118 commented May 6, 2015

For me that workaround does the same as commenting the fread line.
It disconnects after the first invalid token is found.

@jakobjw
Copy link

jakobjw commented May 10, 2015

My problem is that I have a list of about 3000 receiver tokens and this list also contains invalid tokens which I don't know. I suppose that sending them 1by1 would be too inefficient. Do you have any suggestions for me?

@sshilko
Copy link

sshilko commented May 11, 2015

jakobjw 1by1 not too inefficient in 1 thread, but if u have 100 workers running should not be an issue, isnt it.

@aporat
Copy link
Contributor

aporat commented May 26, 2015

Seems that the latest PHP 5.6.9 release solves this issue.

@rwforsythe
Copy link

Ditto for PHP 5.5.25; seems like it now works. Phew.

@sshilko
Copy link

sshilko commented May 26, 2015

yes, seems so
http://php.net/ChangeLog-5.php#5.5.25

Fixed bug #69402 (Reading empty SSL stream hangs until timeout).

Didnt tested yet tho, https://launchpad.net/~ondrej/+archive/ubuntu/php5 updated just 2 days ago

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants