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
NIO SSL client/server sometimes fails to process data after a handshake #906
Comments
In the connections that succeed, the handshake goes like this: In the connections that fail, the handshake goes like this: That suggests to me that the server has some memory of the particular client and is short-circuiting the handshake. I'm looking into that further to see if there's a way I can configure restlet to disable that behavior as a workaround. |
Failed request log:
Succeeded request log:
|
I verified with Wireshark that there is SSL session reuse going on and that's what's causing the different handshake behavior. Tried setting a very short timeout on the SSLSessionContext returned by SSLContext.getServerSessionContext. However, on Android 4.0.4 that appears to not be sufficient. I suspect OpenSSL has its own cache underneath that is not affected by this call. |
Further confirmation and an ugly workaround: I inherited from HttpsServerHelper and overrode getSslContext to return a new SSLContext with each call. It seriously slows down startup and creates a ton of contexts, but it does prevent session reuse and thus prevents this bug from reproducing. At least for a while...who knows what happens when we recycle a connection from the pool. It'll get me by for a bit, anyway. |
Thanks Jonathan for the investigation. We'll try to look into this for V2.2.2 |
Hello, Between client and LB we tracked this log: Then client times-out:
According our analysis, very likely the handshake has been done, but the message wasn't sent. Many thanks for any help. |
@lotto99 Could you add the org.restlet.ext.net.jar library to your classpath to replace the internal HTTP client? That should help workaround the issue |
Hello Jerome,
Additionaly, the problem is not present in 100% of communication, but only about 50% of handshakes fail..I observed the timeout problem by PUT and POST methods (but this is probably irrelevant in relation to handshake). Since this is getting quite critical problem for us, is there any plan to make some fix about this (maybe something as jkeljo mentioned)? You mentioned release 2.2.2... Or you have any hint to make progress in my case? I can try to get TCP dump if necessary. |
My Client is used such way: httpClient = new org.restlet.Client(ctx, protocol);
Response response = httpClient.handle(request); Should I try the org.restlet.ext.net.HttpClientHelper as you mentioned this library? I didn't find any tutorial to this.. |
Hello @lotto99 , if you want to try this you just to update the classpath of your jvm with:
If you have downloaded the framework via the zip file, these dependencies are shipped in the |
Hello Restlet guys, I used it like this: Additionaly, it needed the import of server certificate to the client java, because the rest call was via https. |
Hi @jlouvel & @thboileau , When will you fix this issue as this has already been pending since long? Please fix it ASAP as this is creating major blocking for us. Hi @jkeljo , Could you please help us to understand the workaround provided by you ? I am using Android 5.0. or I have to return a new SSLContext with each call as you mentioned above. Could you please share the source code for the same, if possible? Request you to please help me to fix this issue. Do we have any other workaround where we can change the IO state accordingly to fix this issue? Regards, |
Hello @jlouvel & @thboileau, Waiting for your response on the above issue. Please help me solve this issue as it is a major obstacle for us. Regards, |
@amitchaturvedi The workaround consist in using the Apache HTTP extension of Restlet (org.restlet.ext.httpclient.jar basically) but you can also use the (org.restlet.ext.net one based on HttpURLConnection's class from JRE. The NIO issue lies in the custom/internal HTTP implementation that we had developed in V2.1 directly based on NIO that is very difficilut to fix and stabilize. Moving forward (V3 and beyond), we have decided to rely on Netty NIO library instead. Sorry for the trouble. Let us know if you need further help. |
@jlouvel thank you for your prompt reply. As I understood, the problem is with SSL Session Reuse. Could you please suggest, if somehow we can disable the Session Reuse option by configuring some restlet parameters and can fix the issue. Or some other alternative. Actually we have an immediate release and changing the complete design based on some other framework will not be possible at this point of time. I am sure that you can suggest something which will definitely help me to avoid this situation. The workaround which is provided by @jkeljo may also help . Could you please suggest me how to implement this ? Regards, |
The suggestion of changing the HTTP connector used by your Restlet client app doesn't require changing your design or code. Basically, you need to add the org.restlet.net.jar file to your Android project and manually register it with the Restlet Engine using Engine.getInstance().getRegisteredClients().add(0, new org.restlet.net.HttpClientHelper(null)). See additional help here: |
Hi @jlouvel , I don't have any Restlet Client App. I have Restlet Server App which runs on Android 5.0. I have also a Client App which is not based on Restlet. When this App communicates with my Restlet server, I can observe that most of the requests get timed out. I have also taken the wireshark logs. This issue is same as what @jkeljo has defined in the first 3 comments. Will the suggestion provided by you work with Restlet Server App also ? Please confirm. |
For Android HTTP server, this is going to be more difficult unfortunately. Your best bet, would be to use the i-Jetty port of Jetty for Android: and then, to adapt our Restlet/Jetty server connector code to work with it: I can provide assistance if you undertake this coding effort. |
Hi @jlouvel I have few queries regarding the Android HTTP Restlet Server and request you to share your views on the same :
Engine.getInstance().getRegisteredServers().add(new HttpServerHelper(null)); And the HttpServerHelper is available in import org.restlet.ext.nio.HttpServerHelper. May I know if the NIO is required to run the Restlet server, in case i am using Restlet JAX-RS extension to configure and run my Restlet server ? Thanking you in Advance. Regards, |
I've observed this connecting to the NIO SSL server on Android 4.0.4 from Chrome or Postman, however my investigation suggests that the problem is not unique to Android or to the server side.
Typically I'm seeing the first request to a given server succeed, and subsequent requests time out. The difference between successful and failed requests appears to be how the handshake goes:
The root of the issue is in SslConnection.onFinished. It unconditionally sets the inbound way's ioState to INTEREST, overriding its previous state of READY and causing the Way's buffer processor to break out of the READY loop. If the request had already been read into the buffer, it will simply be left there, unprocessed. It should probably be changed to only set INTEREST if the state is currently IDLE.
Presumably a parallel issue exists for a client's outbound way if the last handshake packet comes from the client, however I haven't reproduced that.
The text was updated successfully, but these errors were encountered: