forked from qt-creator/qt-creator
SSH: Take more care when closing channels.
We can't just pretend a channel is already gone after we request it to close; it's only closed when the server has sent the acknowledgement. Change-Id: Ib6e8b9bf77635995259885af13755f5fc0e825a9 Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
@@ -176,16 +176,23 @@ void SshChannelManager::insertChannel(AbstractSshChannel *priv,
|
|||||||
m_sessions.insert(priv, pub);
|
m_sessions.insert(priv, pub);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SshChannelManager::closeAllChannels()
|
int SshChannelManager::closeAllChannels(CloseAllMode mode)
|
||||||
{
|
{
|
||||||
const int count = m_channels.count();
|
const int count = m_channels.count();
|
||||||
for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it)
|
for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it)
|
||||||
it.value()->closeChannel();
|
it.value()->closeChannel();
|
||||||
|
if (mode == CloseAllAndReset) {
|
||||||
m_channels.clear();
|
m_channels.clear();
|
||||||
m_sessions.clear();
|
m_sessions.clear();
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SshChannelManager::channelCount() const
|
||||||
|
{
|
||||||
|
return m_channels.count();
|
||||||
|
}
|
||||||
|
|
||||||
void SshChannelManager::removeChannel(ChannelIterator it)
|
void SshChannelManager::removeChannel(ChannelIterator it)
|
||||||
{
|
{
|
||||||
Q_ASSERT(it != m_channels.end() && "Unexpected channel lookup failure.");
|
Q_ASSERT(it != m_channels.end() && "Unexpected channel lookup failure.");
|
||||||
|
@@ -55,7 +55,10 @@ public:
|
|||||||
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
|
QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command);
|
||||||
QSharedPointer<SshRemoteProcess> createRemoteShell();
|
QSharedPointer<SshRemoteProcess> createRemoteShell();
|
||||||
QSharedPointer<SftpChannel> createSftpChannel();
|
QSharedPointer<SftpChannel> createSftpChannel();
|
||||||
int closeAllChannels();
|
int channelCount() const;
|
||||||
|
|
||||||
|
enum CloseAllMode { CloseAllRegular, CloseAllAndReset };
|
||||||
|
int closeAllChannels(CloseAllMode mode);
|
||||||
|
|
||||||
void handleChannelRequest(const SshIncomingPacket &packet);
|
void handleChannelRequest(const SshIncomingPacket &packet);
|
||||||
void handleChannelOpen(const SshIncomingPacket &packet);
|
void handleChannelOpen(const SshIncomingPacket &packet);
|
||||||
|
@@ -194,13 +194,18 @@ QSharedPointer<SftpChannel> SshConnection::createSftpChannel()
|
|||||||
int SshConnection::closeAllChannels()
|
int SshConnection::closeAllChannels()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return d->m_channelManager->closeAllChannels();
|
return d->m_channelManager->closeAllChannels(Internal::SshChannelManager::CloseAllRegular);
|
||||||
} catch (const Botan::Exception &e) {
|
} catch (const Botan::Exception &e) {
|
||||||
qDebug("%s: %s", Q_FUNC_INFO, e.what());
|
qDebug("%s: %s", Q_FUNC_INFO, e.what());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SshConnection::channelCount() const
|
||||||
|
{
|
||||||
|
return d->m_channelManager->channelCount();
|
||||||
|
}
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn,
|
SshConnectionPrivate::SshConnectionPrivate(SshConnection *conn,
|
||||||
@@ -680,7 +685,7 @@ void SshConnectionPrivate::closeConnection(SshErrorCode sshError,
|
|||||||
m_keepAliveTimer.stop();
|
m_keepAliveTimer.stop();
|
||||||
disconnect(&m_keepAliveTimer, 0, this, 0);
|
disconnect(&m_keepAliveTimer, 0, this, 0);
|
||||||
try {
|
try {
|
||||||
m_channelManager->closeAllChannels();
|
m_channelManager->closeAllChannels(SshChannelManager::CloseAllAndReset);
|
||||||
m_sendFacility.sendDisconnectPacket(sshError, serverErrorString);
|
m_sendFacility.sendDisconnectPacket(sshError, serverErrorString);
|
||||||
} catch (Botan::Exception &) {} // Nothing sensible to be done here.
|
} catch (Botan::Exception &) {} // Nothing sensible to be done here.
|
||||||
if (m_error != SshNoError)
|
if (m_error != SshNoError)
|
||||||
|
@@ -107,6 +107,8 @@ public:
|
|||||||
// -1 if an error occurred, number of channels closed otherwise.
|
// -1 if an error occurred, number of channels closed otherwise.
|
||||||
int closeAllChannels();
|
int closeAllChannels();
|
||||||
|
|
||||||
|
int channelCount() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connected();
|
void connected();
|
||||||
void disconnected();
|
void disconnected();
|
||||||
|
@@ -97,6 +97,8 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (connection->thread() != QThread::currentThread()) {
|
if (connection->thread() != QThread::currentThread()) {
|
||||||
|
if (connection->channelCount() != 0)
|
||||||
|
continue;
|
||||||
QMetaObject::invokeMethod(this, "switchToCallerThread",
|
QMetaObject::invokeMethod(this, "switchToCallerThread",
|
||||||
Qt::BlockingQueuedConnection,
|
Qt::BlockingQueuedConnection,
|
||||||
Q_ARG(SshConnection *, connection),
|
Q_ARG(SshConnection *, connection),
|
||||||
|
Reference in New Issue
Block a user