Tuntable
Tuntable

Reputation: 3574

Java TLS Session Reuse after closed connection

I have a Java TLS client that can send a series of requests to a server, each followed by a response from the server.

However, there are many different servers. Some are "multi-message" servers that keep a connection open after the first request, so that subsequent requests can be sent over the first connection. Others are "single-message" servers that close the connection after each message and so a new connection is required for subsequent messages. There is no a priori way for the client to know what type of server it is talking to, nor to fix the servers.

It is very desirable for single-message servers to be able to resume a session without the full handshake.

My original client code just tried to send subsequent requests down the same connection. If that failed it just opened a new connection to the server. It could thus handle both single and multi-message servers.

However, the failure when sending the second message to single-message servers seems to kill the session resumption.

My dirty work around is to notice if a message fails and then assume that it is talking to a single-message server, in which case the client then explicitly closes the socket after each response has been received. This enables subsequent connections to resume sessions.

But there has to be a better way. Testing for isInputShutdown or isConnected does not help, unsurprisingly, as there are timing issues. The connection failure for single-message server actually happens during the read of the response, after the write of the request, presumably due to buffering.

Any ideas much appreciated?

Upvotes: 3

Views: 6681

Answers (1)

user207421
user207421

Reputation: 310885

Your initial solution is correct in the case of plaintext: you will get an IOException: connection reset by peer when sending the second message, and you can just recover accordingly by reconnecting.

However in the TLS case it won't work, as you will not get IOException: connection reset by peer but a SocketException, due to a fatal TLS unexpected_message alert. RFC 2246 #7.2 states:

Alert messages with a level of fatal result in the immediate termination of the connection. In this case, other connections corresponding to the session may continue, but the session identifier must be invalidated, preventing the failed session from being used to establish new connections.

[my emphasis], because the failed session is now deemed insecure, and

unexpected_message

An inappropriate message was received. This alert is always fatal and should never be observed in communication between proper implementations.

Your second solution seems appropriate to me.

NB:

  • isInputShutdown() can never be true, as you can't call shutdownInput() on an SSLSocket.
  • isConnected() will never be false once the socket has been connected.
  • Both tell you about the state of your socket, not of the connection, so even trying them was futile. And it has nothing to do with 'timing issues'.

Upvotes: 2

Related Questions