summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordknn <yoann.blein@free.fr>2012-07-08 20:23:27 (GMT)
committerdknn <yoann.blein@free.fr>2012-09-22 08:55:56 (GMT)
commitdc259819a687fa9a6f9007ed15b443f737c5d473 (patch)
treeb3322e7902705923cfe85d5a67e4bfda9697f3c3
parent9928de47c73430b4ed37db8a0cfb44adecc3e296 (diff)
downloadswift-contrib-dc259819a687fa9a6f9007ed15b443f737c5d473.zip
swift-contrib-dc259819a687fa9a6f9007ed15b443f737c5d473.tar.bz2
Udp stuff
-rw-r--r--Swiften/Network/BoostNetworkFactories.cpp7
-rw-r--r--Swiften/Network/BoostNetworkFactories.h6
-rw-r--r--Swiften/Network/BoostUDPSocket.cpp163
-rw-r--r--Swiften/Network/BoostUDPSocket.h70
-rw-r--r--Swiften/Network/BoostUDPSocketFactory.cpp24
-rw-r--r--Swiften/Network/BoostUDPSocketFactory.h28
-rw-r--r--Swiften/Network/HostAddressPort.cpp5
-rw-r--r--Swiften/Network/HostAddressPort.h3
-rw-r--r--Swiften/Network/NetworkFactories.h2
-rw-r--r--Swiften/Network/SConscript7
-rw-r--r--Swiften/Network/UDPSocket.h33
-rw-r--r--Swiften/Network/UDPSocketFactory.h20
12 files changed, 367 insertions, 1 deletions
diff --git a/Swiften/Network/BoostNetworkFactories.cpp b/Swiften/Network/BoostNetworkFactories.cpp
index 488e519..0930075 100644
--- a/Swiften/Network/BoostNetworkFactories.cpp
+++ b/Swiften/Network/BoostNetworkFactories.cpp
@@ -14,6 +14,7 @@
#include <Swiften/Network/NullNATTraverser.h>
#include <Swiften/TLS/PlatformTLSFactories.h>
#include <Swiften/Network/PlatformProxyProvider.h>
+#include <Swiften/Network/BoostUDPSocketFactory.h>
namespace Swift {
@@ -30,6 +31,9 @@ BoostNetworkFactories::BoostNetworkFactories(EventLoop* eventLoop) : eventLoop(e
xmlParserFactory = new PlatformXMLParserFactory();
tlsFactories = new PlatformTLSFactories();
proxyProvider = new PlatformProxyProvider();
+#ifdef SWIFT_EXPERIMENTAL_FT
+ udpSocketFactory = new BoostUDPSocketFactory(ioServiceThread.getIOService(), eventLoop);
+#endif
}
BoostNetworkFactories::~BoostNetworkFactories() {
@@ -41,6 +45,9 @@ BoostNetworkFactories::~BoostNetworkFactories() {
delete domainNameResolver;
delete connectionFactory;
delete timerFactory;
+#ifdef SWIFT_EXPERIMENTAL_FT
+ delete udpSocketFactory;
+#endif
}
TLSContextFactory* BoostNetworkFactories::getTLSContextFactory() const {
diff --git a/Swiften/Network/BoostNetworkFactories.h b/Swiften/Network/BoostNetworkFactories.h
index 1968acd..2cca6dd 100644
--- a/Swiften/Network/BoostNetworkFactories.h
+++ b/Swiften/Network/BoostNetworkFactories.h
@@ -58,6 +58,11 @@ namespace Swift {
return eventLoop;
}
+ virtual UDPSocketFactory* getUDPSocketFactory() const {
+ return udpSocketFactory;
+ }
+
+
private:
BoostIOServiceThread ioServiceThread;
TimerFactory* timerFactory;
@@ -69,5 +74,6 @@ namespace Swift {
PlatformTLSFactories* tlsFactories;
ProxyProvider* proxyProvider;
EventLoop* eventLoop;
+ UDPSocketFactory* udpSocketFactory;
};
}
diff --git a/Swiften/Network/BoostUDPSocket.cpp b/Swiften/Network/BoostUDPSocket.cpp
new file mode 100644
index 0000000..dff941f
--- /dev/null
+++ b/Swiften/Network/BoostUDPSocket.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Network/BoostUDPSocket.h>
+
+#include <Swiften/Base/Log.h>
+#include <Swiften/Base/Algorithm.h>
+#include <Swiften/EventLoop/EventLoop.h>
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Base/SafeAllocator.h>
+
+#include <boost/bind.hpp>
+#include <boost/asio/placeholders.hpp>
+
+namespace Swift {
+
+static const size_t BUFFER_SIZE = 4096;
+
+// -----------------------------------------------------------------------------
+
+// A reference-counted non-modifiable buffer class.
+class SharedBuffer {
+ public:
+ SharedBuffer(const SafeByteArray& data) :
+ data_(new std::vector<char, SafeAllocator<char> >(data.begin(), data.end())),
+ buffer_(boost::asio::buffer(*data_)) {
+ }
+
+ // ConstBufferSequence requirements.
+ typedef boost::asio::const_buffer value_type;
+ typedef const boost::asio::const_buffer* const_iterator;
+ const boost::asio::const_buffer* begin() const { return &buffer_; }
+ const boost::asio::const_buffer* end() const { return &buffer_ + 1; }
+
+ private:
+ boost::shared_ptr< std::vector<char, SafeAllocator<char> > > data_;
+ boost::asio::const_buffer buffer_;
+};
+
+// -----------------------------------------------------------------------------
+
+BoostUDPSocket::BoostUDPSocket(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) :
+ eventLoop(eventLoop), ioService(ioService), socket_(*ioService), sending_(false)
+{
+}
+
+BoostUDPSocket::~BoostUDPSocket()
+{
+}
+
+void BoostUDPSocket::bind(int port)
+{
+ if (!socket_.is_open())
+ socket_.open(boost::asio::ip::udp::v4());
+ socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port));
+}
+
+void BoostUDPSocket::listen()
+{
+ if (!socket_.is_open())
+ socket_.open(boost::asio::ip::udp::v4());
+ doRead();
+}
+
+void BoostUDPSocket::connect(const HostAddressPort &address)
+{
+ if (!socket_.is_open())
+ socket_.open(boost::asio::ip::udp::v4());
+ socket_.connect(address.toEndpoint()); // TODO: handle errors
+ eventLoop->postEvent(boost::bind(boost::ref(onConnected)), shared_from_this());
+}
+
+void BoostUDPSocket::connectToFirstIncoming()
+{
+ boost::shared_ptr<SafeByteArray> buf = boost::make_shared<SafeByteArray>(1);
+ socket_.async_receive_from(
+ boost::asio::buffer(*buf),
+ remoteEndpoint_,
+ boost::bind(&BoostUDPSocket::handleFirstRead, shared_from_this(), boost::asio::placeholders::error));
+}
+
+void BoostUDPSocket::close() {
+ boost::system::error_code errorCode;
+ socket_.shutdown(boost::asio::ip::udp::socket::shutdown_send, errorCode);
+ socket_.close();
+}
+
+void BoostUDPSocket::send(const SafeByteArray& data)
+{
+ boost::lock_guard<boost::mutex> lock(sendMutex_);
+ if (!sending_) {
+ sending_ = true;
+ doSend(data);
+ } else {
+ append(sendQueue_, data);
+ }
+}
+
+void BoostUDPSocket::doSend(const SafeByteArray& data)
+{
+ socket_.async_send(SharedBuffer(data), boost::bind(&BoostUDPSocket::handleDataWritten, shared_from_this(), boost::asio::placeholders::error));
+}
+
+void BoostUDPSocket::doRead()
+{
+ readBuffer_ = boost::make_shared<SafeByteArray>(BUFFER_SIZE);
+ socket_.async_receive(
+ boost::asio::buffer(*readBuffer_),
+ boost::bind(&BoostUDPSocket::handleSocketRead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+}
+
+void BoostUDPSocket::handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred)
+{
+ SWIFT_LOG(debug) << "Socket read " << error << std::endl;
+ if (!error) {
+ readBuffer_->resize(bytesTransferred);
+ eventLoop->postEvent(boost::bind(boost::ref(onDataRead), readBuffer_), shared_from_this());
+ doRead();
+ }
+// else if (/*error == boost::asio::error::eof ||*/ error == boost::asio::error::operation_aborted) {
+// eventLoop->postEvent(boost::bind(boost::ref(onDisconnected), boost::optional<Error>()), shared_from_this());
+// }
+// else {
+// eventLoop->postEvent(boost::bind(boost::ref(onDisconnected), ReadError), shared_from_this());
+ // }
+}
+
+void BoostUDPSocket::handleFirstRead(const boost::system::error_code &error)
+{
+ if (!error) {
+ socket_.connect(remoteEndpoint_); // TODO: handle errors
+ eventLoop->postEvent(boost::bind(boost::ref(onConnected)), shared_from_this());
+ }
+}
+
+void BoostUDPSocket::handleDataWritten(const boost::system::error_code& error)
+{
+ SWIFT_LOG(debug) << "Data written " << error << std::endl;
+
+ // if (!error) {
+ // eventLoop->postEvent(boost::ref(onDataWritten), shared_from_this());
+ // }
+ // else if (/*error == boost::asio::error::eof || */error == boost::asio::error::operation_aborted) {
+ // eventLoop->postEvent(boost::bind(boost::ref(onDisconnected), boost::optional<Error>()), shared_from_this());
+ // }
+ // else {
+ // eventLoop->postEvent(boost::bind(boost::ref(onDisconnected), WriteError), shared_from_this());
+ // }
+
+ boost::lock_guard<boost::mutex> lock(sendMutex_);
+ if (sendQueue_.empty()) {
+ sending_ = false;
+ } else {
+ doSend(sendQueue_);
+ sendQueue_.clear();
+ }
+}
+
+}
diff --git a/Swiften/Network/BoostUDPSocket.h b/Swiften/Network/BoostUDPSocket.h
new file mode 100644
index 0000000..5cc8b1d
--- /dev/null
+++ b/Swiften/Network/BoostUDPSocket.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Network/UDPSocket.h>
+#include <Swiften/EventLoop/EventOwner.h>
+//#include <Swiften/Base/SafeByteArray.h>
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/udp.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/thread/mutex.hpp>
+
+namespace boost {
+ class thread;
+ namespace system {
+ class error_code;
+ }
+}
+
+namespace Swift {
+ class EventLoop;
+ class HostAddressPort;
+
+ class BoostUDPSocket : public UDPSocket, public EventOwner, public boost::enable_shared_from_this<BoostUDPSocket> {
+ public:
+ typedef boost::shared_ptr<BoostUDPSocket> ref;
+
+ virtual ~BoostUDPSocket();
+
+ static ref create(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) {
+ return ref(new BoostUDPSocket(ioService, eventLoop));
+ }
+
+ virtual void bind(int port);
+ virtual void listen();
+ virtual void connect(const HostAddressPort& address);
+ virtual void connectToFirstIncoming();
+ virtual void send(const SafeByteArray& data);
+ virtual void close();
+
+ boost::asio::ip::udp::socket& getSocket() {
+ return socket_;
+ }
+
+ private:
+ BoostUDPSocket(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop);
+
+ void handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred);
+ void handleFirstRead(const boost::system::error_code& error);
+ void handleDataWritten(const boost::system::error_code& error);
+ void doRead();
+ void doSend(const SafeByteArray& data);
+
+ private:
+ EventLoop* eventLoop;
+ boost::shared_ptr<boost::asio::io_service> ioService;
+ boost::asio::ip::udp::socket socket_;
+ boost::shared_ptr<SafeByteArray> readBuffer_;
+ boost::mutex sendMutex_;
+ bool sending_;
+ SafeByteArray sendQueue_;
+ boost::asio::ip::udp::endpoint remoteEndpoint_;
+
+ };
+}
diff --git a/Swiften/Network/BoostUDPSocketFactory.cpp b/Swiften/Network/BoostUDPSocketFactory.cpp
new file mode 100644
index 0000000..6cd6949
--- /dev/null
+++ b/Swiften/Network/BoostUDPSocketFactory.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Network/BoostUDPSocketFactory.h>
+
+#include <Swiften/Network/BoostUDPSocket.h>
+
+namespace Swift {
+
+BoostUDPSocketFactory::BoostUDPSocketFactory(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) : ioService(ioService), eventLoop(eventLoop) {
+}
+
+BoostUDPSocketFactory::~BoostUDPSocketFactory()
+{
+}
+
+boost::shared_ptr<UDPSocket> BoostUDPSocketFactory::createUDPSocket() {
+ return BoostUDPSocket::create(ioService, eventLoop);
+}
+
+}
diff --git a/Swiften/Network/BoostUDPSocketFactory.h b/Swiften/Network/BoostUDPSocketFactory.h
new file mode 100644
index 0000000..50dc588
--- /dev/null
+++ b/Swiften/Network/BoostUDPSocketFactory.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Network/UDPSocketFactory.h>
+#include <boost/asio/io_service.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class BoostUDPSocket;
+ class EventLoop;
+
+ class BoostUDPSocketFactory : public UDPSocketFactory {
+ public:
+ BoostUDPSocketFactory(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop);
+ virtual ~BoostUDPSocketFactory();
+
+ virtual boost::shared_ptr<UDPSocket> createUDPSocket();
+
+ private:
+ boost::shared_ptr<boost::asio::io_service> ioService;
+ EventLoop* eventLoop;
+ };
+}
diff --git a/Swiften/Network/HostAddressPort.cpp b/Swiften/Network/HostAddressPort.cpp
index e2e6012..0540e24 100644
--- a/Swiften/Network/HostAddressPort.cpp
+++ b/Swiften/Network/HostAddressPort.cpp
@@ -21,3 +21,8 @@ HostAddressPort::HostAddressPort(const boost::asio::ip::tcp::endpoint& endpoint)
std::string HostAddressPort::toString() const {
return getAddress().toString() + ":" + boost::lexical_cast<std::string>(getPort());
}
+
+boost::asio::ip::udp::endpoint HostAddressPort::toEndpoint() const
+{
+ return boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(address_.toString()), port_);
+}
diff --git a/Swiften/Network/HostAddressPort.h b/Swiften/Network/HostAddressPort.h
index 68f3a1c..bf97bff 100644
--- a/Swiften/Network/HostAddressPort.h
+++ b/Swiften/Network/HostAddressPort.h
@@ -7,6 +7,7 @@
#pragma once
#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ip/udp.hpp>
#include <Swiften/Base/API.h>
#include <Swiften/Network/HostAddress.h>
@@ -35,6 +36,8 @@ namespace Swift {
std::string toString() const;
+ boost::asio::ip::udp::endpoint toEndpoint() const;
+
private:
HostAddress address_;
int port_;
diff --git a/Swiften/Network/NetworkFactories.h b/Swiften/Network/NetworkFactories.h
index c8009a6..eecb95c 100644
--- a/Swiften/Network/NetworkFactories.h
+++ b/Swiften/Network/NetworkFactories.h
@@ -17,6 +17,7 @@ namespace Swift {
class CertificateFactory;
class ProxyProvider;
class EventLoop;
+ class UDPSocketFactory;
/**
* An interface collecting network factories.
@@ -34,5 +35,6 @@ namespace Swift {
virtual TLSContextFactory* getTLSContextFactory() const = 0;
virtual ProxyProvider* getProxyProvider() const = 0;
virtual EventLoop* getEventLoop() const = 0;
+ virtual UDPSocketFactory* getUDPSocketFactory() const = 0;
};
}
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index b742bfe..648e969 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -73,7 +73,7 @@ else :
objects = myenv.SwiftenObject(sourceList)
if myenv["experimental"] :
- # LibNATPMP classes
+ # LibNATPMP classes
natpmp_env = myenv.Clone()
natpmp_env.Append(CPPDEFINES = natpmp_env["LIBNATPMP_FLAGS"].get("INTERNAL_CPPDEFINES", []))
objects += natpmp_env.SwiftenObject([
@@ -89,5 +89,10 @@ if myenv["experimental"] :
objects += myenv.SwiftenObject([
"PlatformNATTraversalWorker.cpp",
])
+ # Screen sharing
+ objects += myenv.SwiftenObject([
+ "BoostUDPSocket.cpp",
+ "BoostUDPSocketFactory.cpp",
+ ])
swiften_env.Append(SWIFTEN_OBJECTS = [objects])
diff --git a/Swiften/Network/UDPSocket.h b/Swiften/Network/UDPSocket.h
new file mode 100644
index 0000000..ff324fd
--- /dev/null
+++ b/Swiften/Network/UDPSocket.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/SafeByteArray.h>
+
+namespace Swift {
+ class EventLoop;
+ class HostAddressPort;
+
+ class UDPSocket {
+ public:
+ typedef boost::shared_ptr<UDPSocket> ref;
+
+ virtual ~UDPSocket() {}
+
+ virtual void bind(int port) = 0;
+ virtual void listen() = 0;
+ virtual void connect(const HostAddressPort& address) = 0;
+ virtual void connectToFirstIncoming() = 0;
+ virtual void send(const SafeByteArray& data) = 0;
+ virtual void close() = 0;
+
+ public:
+ boost::signal<void (boost::shared_ptr<SafeByteArray>)> onDataRead;
+ boost::signal<void ()> onConnected;
+ };
+}
diff --git a/Swiften/Network/UDPSocketFactory.h b/Swiften/Network/UDPSocketFactory.h
new file mode 100644
index 0000000..33dd78c
--- /dev/null
+++ b/Swiften/Network/UDPSocketFactory.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class UDPSocket;
+
+ class UDPSocketFactory {
+ public:
+ virtual ~UDPSocketFactory();
+
+ virtual boost::shared_ptr<UDPSocket> createUDPSocket() = 0;
+ };
+}