11#error "asio.hpp must be included before including this, see asiolink.h as to why" 
   25#include <boost/numeric/conversion/cast.hpp> 
   27#include <netinet/in.h> 
   28#include <sys/socket.h> 
   48class TCPSocket : 
public IOAsioSocket<C> {
 
   51    TCPSocket(
const TCPSocket&);
 
   52    TCPSocket& operator=(
const TCPSocket&);
 
   61    TCPSocket(boost::asio::ip::tcp::socket& socket);
 
   76        return (socket_.native_handle());
 
 
  101        if (socket_.is_open()) {
 
  103            const bool non_blocking_orig = socket_.non_blocking();
 
  106            socket_.non_blocking(
true);
 
  108            boost::system::error_code ec;
 
  114                socket_.receive(boost::asio::buffer(
data, 
sizeof(
data)),
 
  115                                boost::asio::socket_base::message_peek,
 
  119            socket_.non_blocking(non_blocking_orig);
 
  127            return (!ec || (ec.value() == boost::asio::error::try_again) ||
 
  128                    (ec.value() == boost::asio::error::would_block));
 
 
  170    void asyncSend(
const void* 
data, 
size_t length, C& callback);
 
  202                                     size_t& cumulative, 
size_t& offset,
 
  229    std::unique_ptr<boost::asio::ip::tcp::socket> socket_ptr_;
 
  232    boost::asio::ip::tcp::socket& socket_;
 
  255TCPSocket<C>::TCPSocket(boost::asio::ip::tcp::socket& socket) :
 
  256    socket_ptr_(), socket_(socket), send_buffer_() {
 
 
  262TCPSocket<C>::TCPSocket(
const IOServicePtr& io_service) : io_service_(io_service),
 
  263    socket_ptr_(new boost::asio::ip::
tcp::socket(io_service_->getInternalIOService())),
 
  264    socket_(*socket_ptr_) {
 
 
  276template <
typename C> 
void 
  280    if (socket_.is_open() && !
isUsable()) {
 
  286    if (!socket_.is_open()) {
 
  288            socket_.open(boost::asio::ip::tcp::v4());
 
  290            socket_.open(boost::asio::ip::tcp::v6());
 
  297        socket_.set_option(boost::asio::socket_base::reuse_address(
true));
 
 
  317template <
typename C> 
void 
  319    if (socket_.is_open()) {
 
  323            send_buffer_->writeData(
data, length);
 
  326            socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
 
  327                                                   send_buffer_->getLength()),
 
  329        } 
catch (
const boost::numeric::bad_numeric_cast&) {
 
  331                      "attempt to send buffer larger than 64kB");
 
  336            "attempt to send on a TCP socket that is not open");
 
 
  340template <
typename C> 
void 
  343    if (socket_.is_open()) {
 
  350            uint16_t count = boost::numeric_cast<uint16_t>(length);
 
  354            send_buffer_->writeUint16(count);
 
  355            send_buffer_->writeData(
data, length);
 
  358            socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
 
  359                               send_buffer_->getLength()), callback);
 
  360        } 
catch (
const boost::numeric::bad_numeric_cast&) {
 
  362                      "attempt to send buffer larger than 64kB");
 
  367            "attempt to send on a TCP socket that is not open");
 
 
  374template <
typename C> 
void 
  377    if (socket_.is_open()) {
 
  396        if (offset >= length) {
 
  398                                      "TCP receive buffer");
 
  400        void* buffer_start = 
static_cast<void*
>(
static_cast<uint8_t*
>(
data) + offset);
 
  403        socket_.async_receive(boost::asio::buffer(buffer_start, length - offset), callback);
 
  407            "attempt to receive from a TCP socket that is not open");
 
 
  413template <
typename C> 
bool 
  415                                  size_t& cumulative, 
size_t& offset,
 
  419    const uint8_t* 
data = 
static_cast<const uint8_t*
>(staging);
 
  420    size_t data_length = length;
 
  424    if (cumulative < 2) {
 
  428        cumulative += length;
 
  429        if (cumulative < 2) {
 
  448        data_length = cumulative - 2;
 
  452        cumulative += length;
 
  462    if (expected >= outbuff->getLength()) {
 
  466        size_t copy_amount = std::min(expected - outbuff->getLength(), data_length);
 
  467        outbuff->writeData(
data, copy_amount);
 
  471    return (expected == outbuff->getLength());
 
 
  476template <
typename C> 
void 
  478    if (socket_.is_open()) {
 
 
  486template <
typename C> 
void 
  488    if (socket_.is_open() && socket_ptr_) {
 
 
 
 
 
 
 
 
 
 
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
The IOEndpoint class is an abstract base class to represent a communication endpoint.
virtual short getFamily() const =0
Returns the address family of the endpoint.
virtual short getProtocol() const =0
Returns the protocol number of the endpoint (TCP, UDP...)
IOError(const char *file, size_t line, const char *what)
The TCPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a TCP ...
const boost::asio::ip::tcp::endpoint & getASIOEndpoint() const
bool isUsable() const
Checks if the connection is usable.
virtual void close()
Close socket.
virtual boost::asio::ip::tcp::socket & getASIOSocket() const
Returns reference to the underlying ASIO socket.
virtual void cancel()
Cancel I/O On Socket.
virtual void open(const IOEndpoint *endpoint, C &callback)
Open Socket.
virtual int getProtocol() const
Return protocol of socket.
virtual void asyncSend(const void *data, size_t length, const IOEndpoint *endpoint, C &callback)
Send Asynchronously.
virtual void asyncReceive(void *data, size_t length, size_t offset, IOEndpoint *endpoint, C &callback)
Receive Asynchronously.
virtual int getNative() const
Return file descriptor of underlying socket.
virtual bool processReceivedData(const void *staging, size_t length, size_t &cumulative, size_t &offset, size_t &expected, isc::util::OutputBufferPtr &buff)
Process received data packet.
virtual bool isOpenSynchronous() const
Is "open()" synchronous?
virtual ~TCPSocket()
Destructor.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define isc_throw_assert(expr)
Replacement for assert() that throws if the expression is false.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
boost::shared_ptr< OutputBuffer > OutputBufferPtr
Type of pointers to output buffers.
Defines the logger used by the top-level component of kea-lfc.