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>
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;
113 socket_.receive(boost::asio::buffer(data,
sizeof(data)),
114 boost::asio::socket_base::message_peek,
118 socket_.non_blocking(non_blocking_orig);
126 return (!ec || (ec.value() == boost::asio::error::try_again) ||
127 (ec.value() == boost::asio::error::would_block));
169 void asyncSend(
const void* data,
size_t length, C& callback);
201 size_t& cumulative,
size_t& offset,
228 std::unique_ptr<boost::asio::ip::tcp::socket> socket_ptr_;
231 boost::asio::ip::tcp::socket& socket_;
255 socket_ptr_(), socket_(socket), send_buffer_() {
262 socket_ptr_(new boost::asio::ip::tcp::socket(io_service_->getInternalIOService())),
263 socket_(*socket_ptr_) {
275template <
typename C>
void
279 if (socket_.is_open() && !isUsable()) {
285 if (!socket_.is_open()) {
287 socket_.open(boost::asio::ip::tcp::v4());
289 socket_.open(boost::asio::ip::tcp::v6());
296 socket_.set_option(boost::asio::socket_base::reuse_address(
true));
316template <
typename C>
void
318 if (socket_.is_open()) {
322 send_buffer_->writeData(data, length);
325 socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
326 send_buffer_->getLength()),
328 }
catch (
const boost::numeric::bad_numeric_cast&) {
330 "attempt to send buffer larger than 64kB");
335 "attempt to send on a TCP socket that is not open");
339template <
typename C>
void
342 if (socket_.is_open()) {
349 uint16_t count = boost::numeric_cast<uint16_t>(length);
353 send_buffer_->writeUint16(count);
354 send_buffer_->writeData(data, length);
357 socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
358 send_buffer_->getLength()), callback);
359 }
catch (
const boost::numeric::bad_numeric_cast&) {
361 "attempt to send buffer larger than 64kB");
366 "attempt to send on a TCP socket that is not open");
373template <
typename C>
void
376 if (socket_.is_open()) {
395 if (offset >= length) {
397 "TCP receive buffer");
399 void* buffer_start =
static_cast<void*
>(
static_cast<uint8_t*
>(data) + offset);
402 socket_.async_receive(boost::asio::buffer(buffer_start, length - offset), callback);
406 "attempt to receive from a TCP socket that is not open");
412template <
typename C>
bool
414 size_t& cumulative,
size_t& offset,
418 const uint8_t* data =
static_cast<const uint8_t*
>(staging);
419 size_t data_length = length;
423 if (cumulative < 2) {
427 cumulative += length;
428 if (cumulative < 2) {
447 data_length = cumulative - 2;
451 cumulative += length;
461 if (expected >= outbuff->getLength()) {
465 size_t copy_amount = std::min(expected - outbuff->getLength(), data_length);
466 outbuff->writeData(data, copy_amount);
470 return (expected == outbuff->getLength());
475template <
typename C>
void
477 if (socket_.is_open()) {
485template <
typename C>
void
487 if (socket_.is_open() && socket_ptr_) {
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
I/O Socket with asynchronous operations.
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...)
An exception that is thrown if an error occurs within the IO module.
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
The TCPSocket class is a concrete derived class of IOAsioSocket that represents a TCP socket.
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.
TCPSocket(const IOServicePtr &service)
Constructor.
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.
void asyncSend(const void *data, size_t length, C &callback)
Send Asynchronously without count.
TCPSocket(boost::asio::ip::tcp::socket &socket)
Constructor from an ASIO TCP socket.
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.
A wrapper interface for the ASIO library.
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.