diff options
Diffstat (limited to 'Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp')
-rw-r--r-- | Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp | 392 |
1 files changed, 196 insertions, 196 deletions
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp index 1a23e29..98a0988 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp +++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp @@ -27,250 +27,250 @@ namespace Swift { SOCKS5BytestreamClientSession::SOCKS5BytestreamClientSession( - boost::shared_ptr<Connection> connection, - const HostAddressPort& addressPort, - const std::string& destination, - TimerFactory* timerFactory) : - connection(connection), - addressPort(addressPort), - destination(destination), - state(Initial), - chunkSize(131072) { - weFailedTimeout = timerFactory->createTimer(3000); - weFailedTimeout->onTick.connect( - boost::bind(&SOCKS5BytestreamClientSession::handleWeFailedTimeout, this)); + boost::shared_ptr<Connection> connection, + const HostAddressPort& addressPort, + const std::string& destination, + TimerFactory* timerFactory) : + connection(connection), + addressPort(addressPort), + destination(destination), + state(Initial), + chunkSize(131072) { + weFailedTimeout = timerFactory->createTimer(3000); + weFailedTimeout->onTick.connect( + boost::bind(&SOCKS5BytestreamClientSession::handleWeFailedTimeout, this)); } SOCKS5BytestreamClientSession::~SOCKS5BytestreamClientSession() { - weFailedTimeout->onTick.disconnect( - boost::bind(&SOCKS5BytestreamClientSession::handleWeFailedTimeout, this)); - weFailedTimeout->stop(); + weFailedTimeout->onTick.disconnect( + boost::bind(&SOCKS5BytestreamClientSession::handleWeFailedTimeout, this)); + weFailedTimeout->stop(); } void SOCKS5BytestreamClientSession::start() { - assert(state == Initial); - SWIFT_LOG(debug) << "Trying to connect via TCP to " << addressPort.toString() << "." << std::endl; - weFailedTimeout->start(); - connectFinishedConnection = connection->onConnectFinished.connect( - boost::bind(&SOCKS5BytestreamClientSession::handleConnectFinished, this, _1)); - connection->connect(addressPort); + assert(state == Initial); + SWIFT_LOG(debug) << "Trying to connect via TCP to " << addressPort.toString() << "." << std::endl; + weFailedTimeout->start(); + connectFinishedConnection = connection->onConnectFinished.connect( + boost::bind(&SOCKS5BytestreamClientSession::handleConnectFinished, this, _1)); + connection->connect(addressPort); } void SOCKS5BytestreamClientSession::stop() { - SWIFT_LOG(debug) << std::endl; - if (state < Ready) { - weFailedTimeout->stop(); - } - if (state == Finished) { - return; - } - closeConnection(); - readBytestream.reset(); - state = Finished; + SWIFT_LOG(debug) << std::endl; + if (state < Ready) { + weFailedTimeout->stop(); + } + if (state == Finished) { + return; + } + closeConnection(); + readBytestream.reset(); + state = Finished; } void SOCKS5BytestreamClientSession::process() { - SWIFT_LOG(debug) << "unprocessedData.size(): " << unprocessedData.size() << std::endl; - ByteArray bndAddress; - switch(state) { - case Initial: - hello(); - break; - case Hello: - if (unprocessedData.size() > 1) { - unsigned char version = unprocessedData[0]; - unsigned char authMethod = unprocessedData[1]; - if (version != 5 || authMethod != 0) { - // signal failure to upper level - finish(true); - return; - } - unprocessedData.clear(); - authenticate(); - } - break; - case Authenticating: - if (unprocessedData.size() < 5) { - // need more data to start progressing - break; - } - if (unprocessedData[0] != '\x05') { - // wrong version - // disconnect & signal failure - finish(true); - break; - } - if (unprocessedData[1] != '\x00') { - // no success - // disconnect & signal failure - finish(true); - break; - } - if (unprocessedData[3] != '\x03') { - // we expect x'03' = DOMAINNAME here - // disconnect & signal failure - finish(true); - break; - } - if (static_cast<size_t>(unprocessedData[4]) + 1 > unprocessedData.size() + 5) { - // complete domainname and port not available yet - break; - } - bndAddress = createByteArray(&vecptr(unprocessedData)[5], unprocessedData[4]); - if (unprocessedData[unprocessedData[4] + 5] != 0 && bndAddress == createByteArray(destination)) { - // we expect a 0 as port - // disconnect and fail - finish(true); - } - unprocessedData.clear(); - state = Ready; - SWIFT_LOG(debug) << "session ready" << std::endl; - // issue ready signal so the bytestream can be used for reading or writing - weFailedTimeout->stop(); - onSessionReady(false); - break; - case Ready: - SWIFT_LOG(debug) << "Received further data in Ready state." << std::endl; - break; - case Reading: - case Writing: - case Finished: - SWIFT_LOG(debug) << "Unexpected receive of data. Current state: " << state << std::endl; - SWIFT_LOG(debug) << "Data: " << Hexify::hexify(unprocessedData) << std::endl; - unprocessedData.clear(); - //assert(false); - } + SWIFT_LOG(debug) << "unprocessedData.size(): " << unprocessedData.size() << std::endl; + ByteArray bndAddress; + switch(state) { + case Initial: + hello(); + break; + case Hello: + if (unprocessedData.size() > 1) { + unsigned char version = unprocessedData[0]; + unsigned char authMethod = unprocessedData[1]; + if (version != 5 || authMethod != 0) { + // signal failure to upper level + finish(true); + return; + } + unprocessedData.clear(); + authenticate(); + } + break; + case Authenticating: + if (unprocessedData.size() < 5) { + // need more data to start progressing + break; + } + if (unprocessedData[0] != '\x05') { + // wrong version + // disconnect & signal failure + finish(true); + break; + } + if (unprocessedData[1] != '\x00') { + // no success + // disconnect & signal failure + finish(true); + break; + } + if (unprocessedData[3] != '\x03') { + // we expect x'03' = DOMAINNAME here + // disconnect & signal failure + finish(true); + break; + } + if (static_cast<size_t>(unprocessedData[4]) + 1 > unprocessedData.size() + 5) { + // complete domainname and port not available yet + break; + } + bndAddress = createByteArray(&vecptr(unprocessedData)[5], unprocessedData[4]); + if (unprocessedData[unprocessedData[4] + 5] != 0 && bndAddress == createByteArray(destination)) { + // we expect a 0 as port + // disconnect and fail + finish(true); + } + unprocessedData.clear(); + state = Ready; + SWIFT_LOG(debug) << "session ready" << std::endl; + // issue ready signal so the bytestream can be used for reading or writing + weFailedTimeout->stop(); + onSessionReady(false); + break; + case Ready: + SWIFT_LOG(debug) << "Received further data in Ready state." << std::endl; + break; + case Reading: + case Writing: + case Finished: + SWIFT_LOG(debug) << "Unexpected receive of data. Current state: " << state << std::endl; + SWIFT_LOG(debug) << "Data: " << Hexify::hexify(unprocessedData) << std::endl; + unprocessedData.clear(); + //assert(false); + } } void SOCKS5BytestreamClientSession::hello() { - // Version 5, 1 auth method, No authentication - const SafeByteArray hello = createSafeByteArray("\x05\x01\x00", 3); - connection->write(hello); - state = Hello; + // Version 5, 1 auth method, No authentication + const SafeByteArray hello = createSafeByteArray("\x05\x01\x00", 3); + connection->write(hello); + state = Hello; } void SOCKS5BytestreamClientSession::authenticate() { - SWIFT_LOG(debug) << std::endl; - SafeByteArray header = createSafeByteArray("\x05\x01\x00\x03", 4); - SafeByteArray message = header; - append(message, createSafeByteArray(boost::numeric_cast<char>(destination.size()))); - authenticateAddress = createByteArray(destination); - append(message, authenticateAddress); - append(message, createSafeByteArray("\x00\x00", 2)); // 2 byte for port - connection->write(message); - state = Authenticating; + SWIFT_LOG(debug) << std::endl; + SafeByteArray header = createSafeByteArray("\x05\x01\x00\x03", 4); + SafeByteArray message = header; + append(message, createSafeByteArray(boost::numeric_cast<char>(destination.size()))); + authenticateAddress = createByteArray(destination); + append(message, authenticateAddress); + append(message, createSafeByteArray("\x00\x00", 2)); // 2 byte for port + connection->write(message); + state = Authenticating; } void SOCKS5BytestreamClientSession::startReceiving(boost::shared_ptr<WriteBytestream> writeStream) { - if (state == Ready) { - state = Reading; - writeBytestream = writeStream; - writeBytestream->write(unprocessedData); - unprocessedData.clear(); - } else { - SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; - } + if (state == Ready) { + state = Reading; + writeBytestream = writeStream; + writeBytestream->write(unprocessedData); + unprocessedData.clear(); + } else { + SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; + } } void SOCKS5BytestreamClientSession::startSending(boost::shared_ptr<ReadBytestream> readStream) { - if (state == Ready) { - state = Writing; - readBytestream = readStream; - dataWrittenConnection = connection->onDataWritten.connect( - boost::bind(&SOCKS5BytestreamClientSession::sendData, this)); - sendData(); - } else { - SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; - } + if (state == Ready) { + state = Writing; + readBytestream = readStream; + dataWrittenConnection = connection->onDataWritten.connect( + boost::bind(&SOCKS5BytestreamClientSession::sendData, this)); + sendData(); + } else { + SWIFT_LOG(debug) << "Session isn't ready for transfer yet!" << std::endl; + } } HostAddressPort SOCKS5BytestreamClientSession::getAddressPort() const { - return addressPort; + return addressPort; } void SOCKS5BytestreamClientSession::sendData() { - if (!readBytestream->isFinished()) { - try { - boost::shared_ptr<ByteArray> dataToSend = readBytestream->read(boost::numeric_cast<size_t>(chunkSize)); - connection->write(createSafeByteArray(*dataToSend)); - onBytesSent(dataToSend->size()); - } - catch (const BytestreamException&) { - finish(true); - } - } - else { - finish(false); - } + if (!readBytestream->isFinished()) { + try { + boost::shared_ptr<ByteArray> dataToSend = readBytestream->read(boost::numeric_cast<size_t>(chunkSize)); + connection->write(createSafeByteArray(*dataToSend)); + onBytesSent(dataToSend->size()); + } + catch (const BytestreamException&) { + finish(true); + } + } + else { + finish(false); + } } void SOCKS5BytestreamClientSession::finish(bool error) { - SWIFT_LOG(debug) << std::endl; - if (state < Ready) { - weFailedTimeout->stop(); - } - closeConnection(); - readBytestream.reset(); - if (state == Initial || state == Hello || state == Authenticating) { - onSessionReady(true); - } - else { - state = Finished; - if (error) { - onFinished(boost::optional<FileTransferError>(FileTransferError::ReadError)); - } else { - onFinished(boost::optional<FileTransferError>()); - } - } + SWIFT_LOG(debug) << std::endl; + if (state < Ready) { + weFailedTimeout->stop(); + } + closeConnection(); + readBytestream.reset(); + if (state == Initial || state == Hello || state == Authenticating) { + onSessionReady(true); + } + else { + state = Finished; + if (error) { + onFinished(boost::optional<FileTransferError>(FileTransferError::ReadError)); + } else { + onFinished(boost::optional<FileTransferError>()); + } + } } void SOCKS5BytestreamClientSession::handleConnectFinished(bool error) { - connectFinishedConnection.disconnect(); - if (error) { - SWIFT_LOG(debug) << "Failed to connect via TCP to " << addressPort.toString() << "." << std::endl; - finish(true); - } else { - SWIFT_LOG(debug) << "Successfully connected via TCP" << addressPort.toString() << "." << std::endl; - disconnectedConnection = connection->onDisconnected.connect( - boost::bind(&SOCKS5BytestreamClientSession::handleDisconnected, this, _1)); - dataReadConnection = connection->onDataRead.connect( - boost::bind(&SOCKS5BytestreamClientSession::handleDataRead, this, _1)); - weFailedTimeout->stop(); - weFailedTimeout->start(); - process(); - } + connectFinishedConnection.disconnect(); + if (error) { + SWIFT_LOG(debug) << "Failed to connect via TCP to " << addressPort.toString() << "." << std::endl; + finish(true); + } else { + SWIFT_LOG(debug) << "Successfully connected via TCP" << addressPort.toString() << "." << std::endl; + disconnectedConnection = connection->onDisconnected.connect( + boost::bind(&SOCKS5BytestreamClientSession::handleDisconnected, this, _1)); + dataReadConnection = connection->onDataRead.connect( + boost::bind(&SOCKS5BytestreamClientSession::handleDataRead, this, _1)); + weFailedTimeout->stop(); + weFailedTimeout->start(); + process(); + } } void SOCKS5BytestreamClientSession::handleDataRead(boost::shared_ptr<SafeByteArray> data) { - SWIFT_LOG(debug) << "state: " << state << " data.size() = " << data->size() << std::endl; - if (state != Reading) { - append(unprocessedData, *data); - process(); - } - else { - writeBytestream->write(createByteArray(vecptr(*data), data->size())); - //onBytesReceived(data->size()); - } + SWIFT_LOG(debug) << "state: " << state << " data.size() = " << data->size() << std::endl; + if (state != Reading) { + append(unprocessedData, *data); + process(); + } + else { + writeBytestream->write(createByteArray(vecptr(*data), data->size())); + //onBytesReceived(data->size()); + } } void SOCKS5BytestreamClientSession::handleDisconnected(const boost::optional<Connection::Error>& error) { - SWIFT_LOG(debug) << (error ? (error == Connection::ReadError ? "Read Error" : "Write Error") : "No Error") << std::endl; - if (error) { - finish(true); - } + SWIFT_LOG(debug) << (error ? (error == Connection::ReadError ? "Read Error" : "Write Error") : "No Error") << std::endl; + if (error) { + finish(true); + } } void SOCKS5BytestreamClientSession::handleWeFailedTimeout() { - SWIFT_LOG(debug) << "Failed due to timeout!" << std::endl; - finish(true); + SWIFT_LOG(debug) << "Failed due to timeout!" << std::endl; + finish(true); } void SOCKS5BytestreamClientSession::closeConnection() { - connectFinishedConnection.disconnect(); - dataWrittenConnection.disconnect(); - dataReadConnection.disconnect(); - disconnectedConnection.disconnect(); - connection->disconnect(); + connectFinishedConnection.disconnect(); + dataWrittenConnection.disconnect(); + dataReadConnection.disconnect(); + disconnectedConnection.disconnect(); + connection->disconnect(); } } |