10 #ifndef BOOST_ASIO_HPP
11 #error "asio.hpp must be included before including this, see asiolink.h as to why"
14 #include <netinet/in.h>
15 #include <sys/socket.h>
21 #include <boost/numeric/conversion/cast.hpp>
63 TCPSocket(boost::asio::ip::tcp::socket& socket);
78 #if BOOST_VERSION < 106600
79 return (socket_.native());
81 return (socket_.native_handle());
107 if (socket_.is_open()) {
109 const bool non_blocking_orig = socket_.non_blocking();
112 socket_.non_blocking(
true);
114 boost::system::error_code ec;
119 socket_.receive(boost::asio::buffer(data,
sizeof(data)),
120 boost::asio::socket_base::message_peek,
124 socket_.non_blocking(non_blocking_orig);
132 return (!ec || (ec.value() == boost::asio::error::try_again) ||
133 (ec.value() == boost::asio::error::would_block));
160 virtual void asyncSend(
const void* data,
size_t length,
175 void asyncSend(
const void* data,
size_t length, C& callback);
188 virtual void asyncReceive(
void* data,
size_t length,
size_t offset,
207 size_t& cumulative,
size_t& offset,
215 virtual void close();
230 std::unique_ptr<boost::asio::ip::tcp::socket> socket_ptr_;
233 boost::asio::ip::tcp::socket& socket_;
255 template <
typename C>
257 socket_ptr_(), socket_(socket), send_buffer_()
263 template <
typename C>
265 socket_ptr_(new
boost::asio::ip::tcp::socket(service.get_io_service())),
266 socket_(*socket_ptr_)
272 template <
typename C>
279 template <
typename C>
void
283 if (socket_.is_open() && !isUsable()) {
289 if (!socket_.is_open()) {
291 socket_.open(boost::asio::ip::tcp::v4());
294 socket_.open(boost::asio::ip::tcp::v6());
301 socket_.set_option(boost::asio::socket_base::reuse_address(
true));
315 socket_.async_connect(tcp_endpoint->getASIOEndpoint(), callback);
321 template <
typename C>
void
324 if (socket_.is_open()) {
328 send_buffer_->writeData(data, length);
331 socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
332 send_buffer_->getLength()),
334 }
catch (
const boost::numeric::bad_numeric_cast&) {
336 "attempt to send buffer larger than 64kB");
341 "attempt to send on a TCP socket that is not open");
345 template <
typename C>
void
349 if (socket_.is_open()) {
356 uint16_t count = boost::numeric_cast<uint16_t>(length);
360 send_buffer_->writeUint16(count);
361 send_buffer_->writeData(data, length);
364 socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
365 send_buffer_->getLength()), callback);
366 }
catch (
const boost::numeric::bad_numeric_cast&) {
368 "attempt to send buffer larger than 64kB");
373 "attempt to send on a TCP socket that is not open");
380 template <
typename C>
void
384 if (socket_.is_open()) {
403 if (offset >= length) {
405 "TCP receive buffer");
407 void* buffer_start =
static_cast<void*
>(
static_cast<uint8_t*
>(data) + offset);
410 socket_.async_receive(boost::asio::buffer(buffer_start, length - offset), callback);
414 "attempt to receive from a TCP socket that is not open");
420 template <
typename C>
bool
422 size_t& cumulative,
size_t& offset,
427 const uint8_t* data =
static_cast<const uint8_t*
>(staging);
428 size_t data_length = length;
432 if (cumulative < 2) {
436 cumulative += length;
437 if (cumulative < 2) {
456 data_length = cumulative - 2;
460 cumulative += length;
470 if (expected >= outbuff->getLength()) {
474 size_t copy_amount = std::min(expected - outbuff->getLength(), data_length);
475 outbuff->writeData(data, copy_amount);
479 return (expected == outbuff->getLength());
484 template <
typename C>
void
486 if (socket_.is_open()) {
494 template <
typename C>
void
496 if (socket_.is_open() && socket_ptr_) {
504 #endif // TCP_SOCKET_H
virtual void asyncSend(const void *data, size_t length, const IOEndpoint *endpoint, C &callback)
Send Asynchronously.
The TCPSocket class is a concrete derived class of IOAsioSocket that represents a TCP socket...
#define isc_throw_assert(expr)
Replacement for assert() that throws if the expression is false.
virtual bool isOpenSynchronous() const
Is "open()" synchronous?
virtual int getNative() const
Return file descriptor of underlying socket.
virtual void close()
Close socket.
virtual void cancel()
Cancel I/O On Socket.
virtual int getProtocol() const
Return protocol of socket.
const boost::asio::ip::tcp::endpoint & getASIOEndpoint() const
virtual short getProtocol() const =0
Returns the protocol number of the endpoint (TCP, UDP...)
The IOService class is a wrapper for the ASIO io_service class.
virtual boost::asio::ip::tcp::socket & getASIOSocket() const
Returns reference to the underlying ASIO socket.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
The TCPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a TCP ...
bool isUsable() const
Checks if the connection is usable.
virtual short getFamily() const =0
Returns the address family of the endpoint.
virtual ~TCPSocket()
Destructor.
virtual bool processReceivedData(const void *staging, size_t length, size_t &cumulative, size_t &offset, size_t &expected, isc::util::OutputBufferPtr &outbuff)
Process received data packet.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Defines the logger used by the top-level component of kea-dhcp-ddns.
virtual void open(const IOEndpoint *endpoint, C &callback)
Open Socket.
virtual void asyncReceive(void *data, size_t length, size_t offset, IOEndpoint *endpoint, C &callback)
Receive Asynchronously.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
A wrapper interface for the ASIO library.
I/O Socket with asynchronous operations.
An exception that is thrown if an error occurs within the IO module.
boost::shared_ptr< OutputBuffer > OutputBufferPtr
The IOEndpoint class is an abstract base class to represent a communication endpoint.