11#error "asio.hpp must be included before including this, see asiolink.h as to why"
18#include <boost/noncopyable.hpp>
53#if BOOST_VERSION < 106600
54 return (socket_.native());
56 return (socket_.native_handle());
82 if (socket_.is_open()) {
84 const bool non_blocking_orig = socket_.non_blocking();
89 socket_.non_blocking(
true);
95 int cc = recv(
getNative(), data,
sizeof(data), MSG_PEEK);
105 socket_.non_blocking(non_blocking_orig);
114 return ((err == 0) || (err == EAGAIN) || (err == EWOULDBLOCK));
165 void asyncSend(
const void* data,
size_t length, C& callback);
197 size_t& cumulative,
size_t& offset,
236 std::unique_ptr<TlsStream<C>> stream_ptr_;
239 TlsStream<C>& stream_;
242 typename TlsStream<C>::lowest_layer_type& socket_;
266 stream_ptr_(), stream_(stream),
267 socket_(stream_.lowest_layer()), send_buffer_() {
274 : io_service_(io_service),
275 stream_ptr_(new TlsStream<C>(io_service, context)),
276 stream_(*stream_ptr_), socket_(stream_.lowest_layer()), send_buffer_() {
288template <
typename C>
void
293 if (!socket_.is_open()) {
294 if (endpoint->getFamily() == AF_INET) {
295 socket_.open(boost::asio::ip::tcp::v4());
297 socket_.open(boost::asio::ip::tcp::v6());
304 socket_.set_option(boost::asio::socket_base::reuse_address(
true));
318 socket_.async_connect(tcp_endpoint->getASIOEndpoint(), callback);
323template <
typename C>
void
325 if (!socket_.is_open()) {
327 "a TLS socket that is not open");
329 stream_.handshake(callback);
335template <
typename C>
void
337 if (!socket_.is_open()) {
339 "attempt to send on a TLS socket that is not open");
344 send_buffer_->writeData(data, length);
347 boost::asio::async_write(stream_,
348 boost::asio::buffer(send_buffer_->getData(),
349 send_buffer_->getLength()),
351 }
catch (
const boost::numeric::bad_numeric_cast&) {
353 "attempt to send buffer larger than 64kB");
357template <
typename C>
void
360 if (!socket_.is_open()) {
362 "attempt to send on a TLS socket that is not open");
370 uint16_t count = boost::numeric_cast<uint16_t>(length);
374 send_buffer_->writeUint16(count);
375 send_buffer_->writeData(data, length);
378 boost::asio::async_write(stream_,
379 boost::asio::buffer(send_buffer_->getData(),
380 send_buffer_->getLength()),
382 }
catch (
const boost::numeric::bad_numeric_cast&) {
384 "attempt to send buffer larger than 64kB");
391template <
typename C>
void
394 if (!socket_.is_open()) {
396 "attempt to receive from a TLS socket that is not open");
417 if (offset >= length) {
419 "TCP receive buffer");
422 static_cast<void*
>(
static_cast<uint8_t*
>(data) + offset);
425 stream_.async_read_some(boost::asio::buffer(buffer_start, length - offset),
431template <
typename C>
bool
433 size_t& cumulative,
size_t& offset,
437 const uint8_t* data =
static_cast<const uint8_t*
>(staging);
438 size_t data_length = length;
442 if (cumulative < 2) {
446 cumulative += length;
447 if (cumulative < 2) {
466 data_length = cumulative - 2;
470 cumulative += length;
480 if (expected >= outbuff->getLength()) {
484 size_t copy_amount = std::min(expected - outbuff->getLength(),
486 outbuff->writeData(data, copy_amount);
490 return (expected == outbuff->getLength());
495template <
typename C>
void
497 if (socket_.is_open()) {
504template <
typename C>
void
506 if (!socket_.is_open()) {
508 "a TLS socket that is not open");
510 stream_.shutdown(callback);
516template <
typename C>
void
518 if (socket_.is_open() && stream_ptr_) {
I/O Socket with asynchronous operations.
The IOEndpoint class is an abstract base class to represent a communication endpoint.
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 TLSSocket class is a concrete derived class of IOAsioSocket that represents a TLS socket.
virtual void asyncReceive(void *data, size_t length, size_t offset, IOEndpoint *endpoint, C &callback)
Receive Asynchronously.
virtual TlsStream< C >::lowest_layer_type & getASIOSocket() const
Returns reference to the underlying ASIO socket.
bool isUsable() const
Checks if the connection is usable.
virtual bool isOpenSynchronous() const
Is "open()" synchronous predicate.
virtual TlsStream< C > & getTlsStream() const
Returns reference to the underlying TLS stream.
virtual void asyncSend(const void *data, size_t length, const IOEndpoint *endpoint, C &callback)
Send Asynchronously.
TLSSocket(const IOServicePtr &service, TlsContextPtr context)
Constructor.
virtual void handshake(C &callback)
Perform Handshake.
virtual ~TLSSocket()
Destructor.
virtual int getProtocol() const
Return protocol of socket.
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 void shutdown(C &callback)
TLS shutdown.
virtual void cancel()
Cancel I/O On Socket.
virtual void open(const IOEndpoint *endpoint, C &callback)
Open Socket.
void asyncSend(const void *data, size_t length, C &callback)
Send Asynchronously without count.
TLSSocket(TlsStream< C > &stream)
Constructor from a TLS stream.
virtual void close()
Close socket.
virtual int getNative() const
Return file descriptor of underlying 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< TlsContext > TlsContextPtr
The type of shared pointers to TlsContext objects.
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.