aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/Networking/Socket.h44
-rw-r--r--src/server/shared/Packets/ByteBuffer.h45
-rw-r--r--src/server/shared/Threading/ProducerConsumerQueue.h14
3 files changed, 78 insertions, 25 deletions
diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h
index 676418c27a7..9c3ec180b0a 100644
--- a/src/server/shared/Networking/Socket.h
+++ b/src/server/shared/Networking/Socket.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -26,12 +25,13 @@
#include <queue>
#include <memory>
#include <functional>
+#include <type_traits>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/write.hpp>
using boost::asio::ip::tcp;
-template<class T>
+template<class T, class PacketType>
class Socket : public std::enable_shared_from_this<T>
{
public:
@@ -44,31 +44,44 @@ public:
void AsyncReadHeader()
{
- _socket.async_read_some(boost::asio::buffer(_readBuffer, _headerSize), std::bind(&Socket<T>::ReadHeaderHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
+ _socket.async_read_some(boost::asio::buffer(_readBuffer, _headerSize), std::bind(&Socket<T, PacketType>::ReadHeaderHandlerInternal, this->shared_from_this(),
+ std::placeholders::_1, std::placeholders::_2));
}
void AsyncReadData(std::size_t size, std::size_t bufferOffset)
{
- _socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), std::bind(&Socket<T>::ReadDataHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
+ _socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), std::bind(&Socket<T, PacketType>::ReadDataHandlerInternal, this->shared_from_this(),
+ std::placeholders::_1, std::placeholders::_2));
}
void ReadData(std::size_t size, std::size_t bufferOffset)
{
- _socket.read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size));
+ boost::system::error_code error;
+
+ _socket.read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), error);
+
+ if (error)
+ {
+ TC_LOG_DEBUG("network", "Socket::ReadData: %s errored with: %i (%s)", GetRemoteIpAddress().to_string().c_str(), error.value(), error.message().c_str());
+
+ CloseSocket();
+ }
}
- void AsyncWrite(std::vector<uint8> const& data)
+ void AsyncWrite(PacketType const& data)
{
- boost::asio::async_write(_socket, boost::asio::buffer(data), std::bind(&Socket<T>::WriteHandler, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
+ boost::asio::async_write(_socket, boost::asio::buffer(data), std::bind(&Socket<T, PacketType>::WriteHandler, this->shared_from_this(), std::placeholders::_1,
+ std::placeholders::_2));
}
bool IsOpen() const { return _socket.is_open(); }
void CloseSocket()
{
- boost::system::error_code socketError;
- _socket.close(socketError);
- if (socketError)
- TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when closing socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(), socketError.value(), socketError.message().c_str());
+ boost::system::error_code error;
+ _socket.close(error);
+ if (error)
+ TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when closing socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(),
+ error.value(), error.message().c_str());
}
uint8* GetReadBuffer() { return _readBuffer; }
@@ -78,7 +91,7 @@ protected:
virtual void ReadDataHandler(boost::system::error_code error, size_t transferedBytes) = 0;
std::mutex _writeLock;
- std::queue<std::vector<uint8> > _writeQueue;
+ std::queue<PacketType> _writeQueue;
private:
void ReadHeaderHandlerInternal(boost::system::error_code error, size_t transferedBytes) { ReadHeaderHandler(error, transferedBytes); }
@@ -90,6 +103,7 @@ private:
{
std::lock_guard<std::mutex> deleteGuard(_writeLock);
+ DeletePacket(_writeQueue.front());
_writeQueue.pop();
if (!_writeQueue.empty())
@@ -99,6 +113,12 @@ private:
CloseSocket();
}
+ template<typename Q = PacketType>
+ typename std::enable_if<std::is_pointer<Q>::value>::type DeletePacket(PacketType& packet) { delete packet; }
+
+ template<typename Q = PacketType>
+ typename std::enable_if<!std::is_pointer<Q>::value>::type DeletePacket(PacketType const& /*packet*/) { }
+
tcp::socket _socket;
uint8 _readBuffer[4096];
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index ba4894fc32e..520c1a85fc2 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -32,6 +32,7 @@
#include <cstring>
#include <time.h>
#include <math.h>
+#include <boost/asio/buffer.hpp>
// Root of ByteBuffer exception hierarchy
class ByteBufferException : public std::exception
@@ -80,12 +81,30 @@ class ByteBuffer
_storage.reserve(reserve);
}
- // copy constructor
- ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
- _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf._storage)
+ ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos),
+ _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(std::move(buf._storage))
{
}
+ ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos),
+ _bitpos(right._bitpos), _curbitval(right._curbitval), _storage(right._storage)
+ {
+ }
+
+ ByteBuffer& operator=(ByteBuffer const& right)
+ {
+ if (this != &right)
+ {
+ _rpos = right._rpos;
+ _wpos = right._wpos;
+ _bitpos = right._bitpos;
+ _curbitval = right._curbitval;
+ _storage = right._storage;
+ }
+
+ return *this;
+ }
+
virtual ~ByteBuffer() { }
void clear()
@@ -510,18 +529,18 @@ class ByteBuffer
return *this;
}
- uint8 * contents()
+ uint8* contents()
{
if (_storage.empty())
throw ByteBufferException();
- return &_storage[0];
+ return _storage.data();
}
- const uint8 *contents() const
+ uint8 const* contents() const
{
if (_storage.empty())
throw ByteBufferException();
- return &_storage[0];
+ return _storage.data();
}
size_t size() const { return _storage.size(); }
@@ -737,5 +756,15 @@ inline void ByteBuffer::read_skip<std::string>()
read_skip<char*>();
}
-#endif
+namespace boost
+{
+ namespace asio
+ {
+ inline const_buffers_1 buffer(ByteBuffer const& packet)
+ {
+ return buffer(packet.contents(), packet.size());
+ }
+ }
+}
+#endif
diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h
index 45a1cbc692a..1fee1d0685f 100644
--- a/src/server/shared/Threading/ProducerConsumerQueue.h
+++ b/src/server/shared/Threading/ProducerConsumerQueue.h
@@ -22,12 +22,11 @@
#include <mutex>
#include <queue>
#include <atomic>
+#include <type_traits>
template <typename T>
class ProducerConsumerQueue
{
- static_assert(std::is_pointer<T>::value, "T for ProducerConsumerQueue must be a pointer");
-
private:
std::mutex _queueLock;
std::queue<T> _queue;
@@ -94,7 +93,7 @@ public:
{
T& value = _queue.front();
- delete value;
+ DeleteQueuedObject(value);
_queue.pop();
}
@@ -105,8 +104,13 @@ public:
_condition.notify_all();
}
-};
-#endif
+private:
+ template<typename E = T>
+ typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; }
+ template<typename E = T>
+ typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { }
+};
+#endif