spicec: do not call connect_secure when connect_unsecure fails due to protocol version mismatch (v2)

If connect_unsecure failed due to protocol version mismatch, don't try to
connect_secure with the same version, but retry (connect_secure or
connect_unsecure) with older version. catch (...) is handled by caller
at RedChannel::run().

This solves the following bug: when "new" Spice client (protocol version 2)
with given secure_port connects to "old" server which is not using the same
secure_port (or not using a secure_port at all), the client exits immediately.

In this scenario, the client first tries to use Spice protocol version 2 to
connect the unsecure port, and altough this fails due to version mismatch, it
tries to connect to the secure port with the same protocol version 2, which is
a wrong behavior, fails due to socket error 10061 (WSAECONNREFUSED -
Connection refused) and handled mistakenly by immediate exit, instead of
retrying with protocol version 1.
This commit is contained in:
Arnon Gilboa 2010-12-07 12:44:34 +02:00
parent 9dfeeaefbe
commit 8a7e6fef27

View File

@ -217,8 +217,10 @@ void RedChannelBase::connect(const ConnectionOptions& options, uint32_t connecti
RedPeer::connect_unsecure(host, options.unsecure_port);
link(connection_id, password, protocol);
return;
} catch (...) {
if (!options.allow_secure()) {
} catch (Exception& e) {
// On protocol version mismatch, don't connect_secure with the same version
if (e.get_error_code() == SPICEC_ERROR_CODE_VERSION_MISMATCH ||
!options.allow_secure()) {
throw;
}
RedPeer::close();
@ -228,9 +230,9 @@ void RedChannelBase::connect(const ConnectionOptions& options, uint32_t connecti
RedPeer::connect_secure(options, host);
link(connection_id, password, protocol);
} catch (Exception& e) {
if (protocol == 2 &&
options.protocol == 0 &&
e.get_error_code() == SPICEC_ERROR_CODE_VERSION_MISMATCH) {
// On protocol version mismatch, retry with older version
if (e.get_error_code() == SPICEC_ERROR_CODE_VERSION_MISMATCH &&
protocol == 2 && options.protocol == 0) {
RedPeer::cleanup();
protocol = 1;
goto retry;