summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp')
-rw-r--r--Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp95
1 files changed, 60 insertions, 35 deletions
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp
index 2260fc20..cb34c58 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -8,4 +8,5 @@
#include <boost/bind.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <iostream>
@@ -15,4 +16,5 @@
#include <Swiften/Base/Concat.h>
#include <Swiften/Base/Log.h>
+#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/BytestreamException.h>
@@ -20,11 +22,18 @@
namespace Swift {
-SOCKS5BytestreamServerSession::SOCKS5BytestreamServerSession(boost::shared_ptr<Connection> connection, SOCKS5BytestreamRegistry* bytestreams) : connection(connection), bytestreams(bytestreams), state(Initial), chunkSize(131072) {
- connection->onDisconnected.connect(boost::bind(&SOCKS5BytestreamServerSession::handleDisconnected, this, _1));
+SOCKS5BytestreamServerSession::SOCKS5BytestreamServerSession(
+ boost::shared_ptr<Connection> connection,
+ SOCKS5BytestreamRegistry* bytestreams) :
+ connection(connection),
+ bytestreams(bytestreams),
+ state(Initial),
+ chunkSize(131072),
+ waitingForData(false) {
+ disconnectedConnection = connection->onDisconnected.connect(boost::bind(&SOCKS5BytestreamServerSession::handleDisconnected, this, _1));
}
SOCKS5BytestreamServerSession::~SOCKS5BytestreamServerSession() {
if (state != Finished && state != Initial) {
- std::cerr << "Warning: SOCKS5BytestremServerSession unfinished" << std::endl;
+ std::cerr << "Warning: SOCKS5BytestreamServerSession unfinished" << std::endl;
finish(false);
}
@@ -33,32 +42,34 @@ SOCKS5BytestreamServerSession::~SOCKS5BytestreamServerSession() {
void SOCKS5BytestreamServerSession::start() {
SWIFT_LOG(debug) << std::endl;
- connection->onDataRead.connect(boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1));
+ dataReadConnection = connection->onDataRead.connect(
+ boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1));
state = WaitingForAuthentication;
}
void SOCKS5BytestreamServerSession::stop() {
- connection->onDataWritten.disconnect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this));
- connection->onDataRead.disconnect(boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1));
- connection->disconnect();
- state = Finished;
+ finish(false);
}
-void SOCKS5BytestreamServerSession::startTransfer() {
- if (state == ReadyForTransfer) {
- if (readBytestream) {
+void SOCKS5BytestreamServerSession::startSending(boost::shared_ptr<ReadBytestream> stream) {
+ if (state != ReadyForTransfer) { SWIFT_LOG(debug) << "Not ready for transfer!" << std::endl; return; }
+
+ readBytestream = stream;
state = WritingData;
- connection->onDataWritten.connect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this));
+ dataAvailableConnection = readBytestream->onDataAvailable.connect(
+ boost::bind(&SOCKS5BytestreamServerSession::handleDataAvailable, this));
+ dataWrittenConnection = connection->onDataWritten.connect(
+ boost::bind(&SOCKS5BytestreamServerSession::sendData, this));
sendData();
}
- else if(writeBytestream) {
+
+void SOCKS5BytestreamServerSession::startReceiving(boost::shared_ptr<WriteBytestream> stream) {
+ if (state != ReadyForTransfer) { SWIFT_LOG(debug) << "Not ready for transfer!" << std::endl; return; }
+
+ writeBytestream = stream;
state = ReadingData;
writeBytestream->write(unprocessedData);
- onBytesReceived(unprocessedData.size());
+ // onBytesReceived(unprocessedData.size());
unprocessedData.clear();
}
- } else {
- SWIFT_LOG(debug) << "Not ready for transfer!" << std::endl;
- }
-}
HostAddressPort SOCKS5BytestreamServerSession::getAddressPort() const {
@@ -72,5 +83,11 @@ void SOCKS5BytestreamServerSession::handleDataRead(boost::shared_ptr<SafeByteArr
} else {
writeBytestream->write(createByteArray(vecptr(*data), data->size()));
- onBytesReceived(data->size());
+ // onBytesReceived(data->size());
+ }
+}
+
+void SOCKS5BytestreamServerSession::handleDataAvailable() {
+ if (waitingForData) {
+ sendData();
}
}
@@ -78,7 +95,5 @@ void SOCKS5BytestreamServerSession::handleDataRead(boost::shared_ptr<SafeByteArr
void SOCKS5BytestreamServerSession::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);
- }
+ finish(error ? true : false);
}
@@ -119,13 +134,12 @@ void SOCKS5BytestreamServerSession::process() {
}
unprocessedData.clear();
- std::string streamID = byteArrayToString(requestID);
- readBytestream = bytestreams->getReadBytestream(streamID);
- writeBytestream = bytestreams->getWriteBytestream(streamID);
+ streamID = byteArrayToString(requestID);
+ bool hasBytestream = bytestreams->hasBytestream(streamID);
SafeByteArray result = createSafeByteArray("\x05", 1);
- result.push_back((readBytestream || writeBytestream) ? 0x0 : 0x4);
+ result.push_back(hasBytestream ? 0x0 : 0x4);
append(result, createByteArray("\x00\x03", 2));
- result.push_back(static_cast<char>(requestID.size()));
+ result.push_back(boost::numeric_cast<unsigned char>(requestID.size()));
append(result, concat(requestID, createByteArray("\x00\x00", 2)));
- if (!readBytestream && !writeBytestream) {
+ if (!hasBytestream) {
SWIFT_LOG(debug) << "Readstream or Wrtiestream with ID " << streamID << " not found!" << std::endl;
connection->write(result);
@@ -133,7 +147,6 @@ void SOCKS5BytestreamServerSession::process() {
}
else {
- SWIFT_LOG(debug) << "Found " << (readBytestream ? "Readstream" : "Writestream") << ". Sent OK." << std::endl;
+ SWIFT_LOG(debug) << "Found stream. Sent OK." << std::endl;
connection->write(result);
- bytestreams->serverSessions[streamID] = this;
state = ReadyForTransfer;
}
@@ -146,7 +159,13 @@ void SOCKS5BytestreamServerSession::sendData() {
if (!readBytestream->isFinished()) {
try {
- SafeByteArray dataToSend = createSafeByteArray(*readBytestream->read(chunkSize));
+ SafeByteArray dataToSend = createSafeByteArray(*readBytestream->read(boost::numeric_cast<size_t>(chunkSize)));
+ if (!dataToSend.empty()) {
connection->write(dataToSend);
onBytesSent(dataToSend.size());
+ waitingForData = false;
+ }
+ else {
+ waitingForData = true;
+ }
}
catch (const BytestreamException&) {
@@ -160,7 +179,13 @@ void SOCKS5BytestreamServerSession::sendData() {
void SOCKS5BytestreamServerSession::finish(bool error) {
- connection->onDataWritten.disconnect(boost::bind(&SOCKS5BytestreamServerSession::sendData, this));
- connection->onDataRead.disconnect(boost::bind(&SOCKS5BytestreamServerSession::handleDataRead, this, _1));
- connection->onDisconnected.disconnect(boost::bind(&SOCKS5BytestreamServerSession::handleDisconnected, this, _1));
+ SWIFT_LOG(debug) << error << " " << state << std::endl;
+ if (state == Finished) {
+ return;
+ }
+
+ disconnectedConnection.disconnect();
+ dataReadConnection.disconnect();
+ dataWrittenConnection.disconnect();
+ dataAvailableConnection.disconnect();
readBytestream.reset();
state = Finished;