diff --git a/ChangeLog b/ChangeLog index ec6c108c..873fd434 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +v1.7.4-stable +============= +Bug #4721 - High CPU usage for Windows service on client +Bug #4712 - Unable to send clipboard with size above 1KB when using SSL +Bug #4584 - Drag and drop with SSL causes crash +Bug #3774 - Missing MinGW dependencies after install on Windows +Bug #4749 - Clipboard thread race condition causes assertion failure +Bug #4723 - Waiting for active desktop result freezes Windows service +Bug #4690 - Log line 'activeDesktop' does not use logging system +Bug #4720 - Plugin download shows 'Could not get Linux package type' error +Bug #4737 - Using error log level does not show SSL fingerprint dialog +Enhancement #4696 - Include 'ns' plugin in installers instead of wizard download +Enhancement #4796 - Improve secure socket intensive try operations +Enhancement #4327 - GUI setting to disable drag and drop feature +Enhancement #4745 - Tray icon notification for clipboard data transfer progress +Enhancement #4793 - Additional logging to output OpenSSL version + v1.7.3-stable ============= Bug #4565 - Incorrect plugin downloads on Debian and Mint diff --git a/src/gui/res/ServerConfigDialogBase.ui b/src/gui/res/ServerConfigDialogBase.ui index 6d257ba2..cc44f66e 100644 --- a/src/gui/res/ServerConfigDialogBase.ui +++ b/src/gui/res/ServerConfigDialogBase.ui @@ -491,7 +491,21 @@ Double click on a screen to edit its settings. + + + + Ignore auto config clients + + + + + + Enable drag and drop file transfers + + + + Qt::Vertical @@ -504,13 +518,6 @@ Double click on a screen to edit its settings. - - - - Ignore auto config clients - - - diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 4db1a65f..1ecfde01 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -467,24 +467,26 @@ void MainWindow::checkFingerprint(const QString& line) void MainWindow::checkTransmission(const QString& line) { - if (line.contains("Transmission")) { - if (line.contains("Started")) { - setSynergyState(synergyTransfering); - } - else if (line.contains("Failed") || - line.contains("Complete") || - line.contains("Interrupted")) { - setSynergyState(synergyConnected); - } + if (appConfig().logLevel() >= 2) { + if (line.contains("Transmission")) { + if (line.contains("Started")) { + setSynergyState(synergyTransfering); + } + else if (line.contains("Failed") || + line.contains("Complete") || + line.contains("Interrupted")) { + setSynergyState(synergyConnected); + } - // NOTIFY: Title: Detail - int p1 = line.indexOf(':'); - if (p1 > 0) { - int p2 = line.indexOf(':', p1 + 1); - if (p2 > 0) { - QString title = line.mid(p1 + 2, p2 - p1 - 2); - QString detail = line.mid(p2 + 2); - m_pTrayIcon->showMessage(title, detail); + // NOTIFY: Title: Detail + int p1 = line.indexOf(':'); + if (p1 > 0) { + int p2 = line.indexOf(':', p1 + 1); + if (p2 > 0) { + QString title = line.mid(p1 + 2, p2 - p1 - 2); + QString detail = line.mid(p2 + 2); + m_pTrayIcon->showMessage(title, detail); + } } } } @@ -546,7 +548,9 @@ void MainWindow::startSynergy() #ifndef Q_OS_LINUX - args << "--enable-drag-drop"; + if (m_ServerConfig.enableDragAndDrop()) { + args << "--enable-drag-drop"; + } #endif diff --git a/src/gui/src/ServerConfig.cpp b/src/gui/src/ServerConfig.cpp index 70f5d46e..d84f91f0 100644 --- a/src/gui/src/ServerConfig.cpp +++ b/src/gui/src/ServerConfig.cpp @@ -50,6 +50,7 @@ ServerConfig::ServerConfig(QSettings* settings, int numColumns, int numRows , m_NumRows(numRows), m_ServerName(serverName), m_IgnoreAutoConfigClient(false), + m_EnableDragAndDrop(false), m_pMainWindow(mainWindow) { Q_ASSERT(m_pSettings); @@ -114,6 +115,7 @@ void ServerConfig::saveSettings() settings().setValue("switchDoubleTap", switchDoubleTap()); settings().setValue("switchCornerSize", switchCornerSize()); settings().setValue("ignoreAutoConfigClient", ignoreAutoConfigClient()); + settings().setValue("enableDragAndDrop", enableDragAndDrop()); writeSettings(settings(), switchCorners(), "switchCorner"); @@ -157,6 +159,7 @@ void ServerConfig::loadSettings() setSwitchDoubleTap(settings().value("switchDoubleTap", 250).toInt()); setSwitchCornerSize(settings().value("switchCornerSize").toInt()); setIgnoreAutoConfigClient(settings().value("ignoreAutoConfigClient").toBool()); + setEnableDragAndDrop(settings().value("enableDragAndDrop", true).toBool()); readSettings(settings(), switchCorners(), "switchCorner", false, NumSwitchCorners); diff --git a/src/gui/src/ServerConfig.h b/src/gui/src/ServerConfig.h index 9600b35d..15214a7e 100644 --- a/src/gui/src/ServerConfig.h +++ b/src/gui/src/ServerConfig.h @@ -61,6 +61,7 @@ class ServerConfig : public BaseConfig const QList& switchCorners() const { return m_SwitchCorners; } const HotkeyList& hotkeys() const { return m_Hotkeys; } bool ignoreAutoConfigClient() const { return m_IgnoreAutoConfigClient; } + bool enableDragAndDrop() const { return m_EnableDragAndDrop; } void saveSettings(); void loadSettings(); @@ -88,6 +89,7 @@ class ServerConfig : public BaseConfig void setSwitchCorner(int c, bool on) { m_SwitchCorners[c] = on; } void setSwitchCornerSize(int val) { m_SwitchCornerSize = val; } void setIgnoreAutoConfigClient(bool on) { m_IgnoreAutoConfigClient = on; } + void setEnableDragAndDrop(bool on) { m_EnableDragAndDrop = on; } QList& switchCorners() { return m_SwitchCorners; } HotkeyList& hotkeys() { return m_Hotkeys; } @@ -119,6 +121,7 @@ class ServerConfig : public BaseConfig HotkeyList m_Hotkeys; QString m_ServerName; bool m_IgnoreAutoConfigClient; + bool m_EnableDragAndDrop; MainWindow* m_pMainWindow; }; diff --git a/src/gui/src/ServerConfigDialog.cpp b/src/gui/src/ServerConfigDialog.cpp index 3fc04fab..501c758c 100644 --- a/src/gui/src/ServerConfigDialog.cpp +++ b/src/gui/src/ServerConfigDialog.cpp @@ -56,6 +56,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget* parent, ServerConfig& config, co m_pCheckBoxIgnoreAutoConfigClient->setChecked(serverConfig().ignoreAutoConfigClient()); + m_pCheckBoxEnableDragAndDrop->setChecked(serverConfig().enableDragAndDrop()); + foreach(const Hotkey& hotkey, serverConfig().hotkeys()) m_pListHotkeys->addItem(hotkey.text()); @@ -97,6 +99,7 @@ void ServerConfigDialog::accept() serverConfig().setSwitchCorner(BaseConfig::BottomRight, m_pCheckBoxCornerBottomRight->isChecked()); serverConfig().setSwitchCornerSize(m_pSpinBoxSwitchCornerSize->value()); serverConfig().setIgnoreAutoConfigClient(m_pCheckBoxIgnoreAutoConfigClient->isChecked()); + serverConfig().setEnableDragAndDrop(m_pCheckBoxEnableDragAndDrop->isChecked()); // now that the dialog has been accepted, copy the new server config to the original one, // which is a reference to the one in MainWindow. diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 52258d69..ad586809 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -273,6 +273,7 @@ Client::leave() if (m_sendClipboardThread != NULL) { StreamChunker::interruptClipboard(); + m_sendClipboardThread->wait(); m_sendClipboardThread = NULL; } diff --git a/src/lib/net/TCPSocket.cpp b/src/lib/net/TCPSocket.cpp index 91655ae3..ab8d189b 100644 --- a/src/lib/net/TCPSocket.cpp +++ b/src/lib/net/TCPSocket.cpp @@ -469,34 +469,47 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job, } bool needNewJob = false; - static UInt32 s_retryOutputBufferSize = 0; + + static bool s_retry = false; + static int s_retrySize = 0; + static void* s_staticBuffer = NULL; if (write) { try { // write data - int buffSize = m_outputBuffer.getSize(); + int bufferSize = 0; int bytesWrote = 0; int status = 0; - if (s_retryOutputBufferSize > 0) { - buffSize = s_retryOutputBufferSize; + if (s_retry) { + bufferSize = s_retrySize; } + else { + bufferSize = m_outputBuffer.getSize(); + s_staticBuffer = malloc(bufferSize); + memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize); + } - const void* buffer = m_outputBuffer.peek(buffSize); + if (bufferSize == 0) { + return job; + } if (isSecure()) { if (isSecureReady()) { - status = secureWrite(buffer, buffSize, bytesWrote); + status = secureWrite(s_staticBuffer, bufferSize, bytesWrote); if (status > 0) { - s_retryOutputBufferSize = 0; - + s_retry = false; + bufferSize = 0; + free(s_staticBuffer); + s_staticBuffer = NULL; } else if (status < 0) { return NULL; } else if (status == 0) { - s_retryOutputBufferSize = buffSize; - return job; + s_retry = true; + s_retrySize = bufferSize; + return newJob(); } } else { @@ -504,7 +517,10 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job, } } else { - bytesWrote = (UInt32)ARCH->writeSocket(m_socket, buffer, buffSize); + bytesWrote = (UInt32)ARCH->writeSocket(m_socket, s_staticBuffer, bufferSize); + bufferSize = 0; + free(s_staticBuffer); + s_staticBuffer = NULL; } // discard written data @@ -559,7 +575,7 @@ TCPSocket::serviceConnected(ISocketMultiplexerJob* job, return NULL; } else if (status == 0) { - return job; + return newJob(); } } else { diff --git a/src/lib/net/TCPSocket.h b/src/lib/net/TCPSocket.h index c30a2d7e..b4c833ba 100644 --- a/src/lib/net/TCPSocket.h +++ b/src/lib/net/TCPSocket.h @@ -96,6 +96,10 @@ private: serviceConnected(ISocketMultiplexerJob*, bool, bool, bool); +protected: + bool m_readable; + bool m_writable; + private: Mutex m_mutex; ArchSocket m_socket; @@ -103,8 +107,6 @@ private: StreamBuffer m_outputBuffer; CondVar m_flushed; bool m_connected; - bool m_readable; - bool m_writable; IEventQueue* m_events; SocketMultiplexer* m_socketMultiplexer; }; diff --git a/src/lib/plugin/ns/SecureSocket.cpp b/src/lib/plugin/ns/SecureSocket.cpp index 639220ed..b753188a 100644 --- a/src/lib/plugin/ns/SecureSocket.cpp +++ b/src/lib/plugin/ns/SecureSocket.cpp @@ -417,14 +417,21 @@ SecureSocket::checkResult(int status, int& retry) break; case SSL_ERROR_WANT_READ: + m_readable = true; + retry++; + LOG((CLOG_DEBUG2 "want to read, error=%d, attempt=%d", errorCode, retry)); + break; + case SSL_ERROR_WANT_WRITE: + m_writable = true; + retry++; + LOG((CLOG_DEBUG2 "want to write, error=%d, attempt=%d", errorCode, retry)); + break; + case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_WANT_ACCEPT: - // it seems like these sort of errors are part of openssl's normal behavior, - // so we should expect a very high amount of these. sleeping doesn't seem to - // help... maybe you just have to swallow the errors (yuck). retry++; - LOG((CLOG_DEBUG2 "passive ssl error, error=%d, attempt=%d", errorCode, retry)); + LOG((CLOG_DEBUG2 "want to connect, error=%d, attempt=%d", errorCode, retry)); break; case SSL_ERROR_SYSCALL: diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index 4420b2dd..1f04489c 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -509,6 +509,8 @@ Server::switchScreen(BaseClientProxy* dst, // clipboard data could be corrupted on the other side if (m_sendClipboardThread != NULL) { StreamChunker::interruptClipboard(); + m_sendClipboardThread->wait(); + m_sendClipboardThread = NULL; } // send the clipboard data to new active screen diff --git a/src/setup/win32/Product.wxs b/src/setup/win32/Product.wxs index 6cdac1b2..c47aa063 100644 --- a/src/setup/win32/Product.wxs +++ b/src/setup/win32/Product.wxs @@ -112,13 +112,13 @@ - - - - - + + + + + - +