Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
654 views
in Technique[技术] by (71.8m points)

ssl - 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 to 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 serves 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 severs 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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'.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...