Kea 2.7.6
isc::asiolink::IOAsioSocket< C > Class Template Referenceabstract

I/O Socket with asynchronous operations. More...

#include <io_asio_socket.h>

+ Inheritance diagram for isc::asiolink::IOAsioSocket< C >:

Constructors and Destructor

Note: The copy constructor and the assignment operator are intentionally defined as private, making this class non-copyable.

 IOAsioSocket ()
 The default constructor.
 
virtual ~IOAsioSocket ()=default
 The destructor.
 
virtual int getNative () const =0
 Return the "native" representation of the socket.
 
virtual int getProtocol () const =0
 Return the transport protocol of the socket.
 
virtual bool isOpenSynchronous () const =0
 Is Open() synchronous?
 
virtual void open (const IOEndpoint *endpoint, C &callback)=0
 Open AsioSocket.
 
virtual void asyncSend (const void *data, size_t length, const IOEndpoint *endpoint, C &callback)=0
 Send Asynchronously.
 
virtual void asyncReceive (void *data, size_t length, size_t offset, IOEndpoint *endpoint, C &callback)=0
 Receive Asynchronously.
 
virtual bool processReceivedData (const void *staging, size_t length, size_t &cumulative, size_t &offset, size_t &expected, isc::util::OutputBufferPtr &buff)=0
 Processes received data.
 
virtual void cancel ()=0
 Cancel I/O On AsioSocket.
 
virtual void close ()=0
 Close socket.
 

Additional Inherited Members

Detailed Description

template<typename C>
class isc::asiolink::IOAsioSocket< C >

I/O Socket with asynchronous operations.

This class is a wrapper for the ASIO socket classes such as ip::tcp::socket and ip::udp::socket.

This is the basic IOSocket with additional operations - open, send, receive and close. Depending on how the asiolink code develops, it may be a temporary class: its main use is to add the template parameter needed for the derived classes UDPSocket and TCPSocket but without changing the signature of the more basic IOSocket class.

We may revisit this decision when we generalize the wrapper and more modules use it. Also, at that point we may define a separate (visible) derived class for testing purposes rather than providing factory methods (i.e., getDummy variants below).

Parameters
CTemplate parameter identifying type of the callback object.

Definition at line 89 of file io_asio_socket.h.

Constructor & Destructor Documentation

◆ IOAsioSocket()

template<typename C >
isc::asiolink::IOAsioSocket< C >::IOAsioSocket ( )
inlineprotected

The default constructor.

This is intentionally defined as protected as this base class should never be instantiated (except as part of a derived class).

Definition at line 105 of file io_asio_socket.h.

◆ ~IOAsioSocket()

template<typename C >
virtual isc::asiolink::IOAsioSocket< C >::~IOAsioSocket ( )
virtualdefault

The destructor.

Member Function Documentation

◆ asyncReceive()

template<typename C >
virtual void isc::asiolink::IOAsioSocket< C >::asyncReceive ( void * data,
size_t length,
size_t offset,
IOEndpoint * endpoint,
C & callback )
pure virtual

Receive Asynchronously.

This corresponds to async_receive_from() for UDP sockets and async_receive() for TCP. In both cases, an endpoint argument is supplied to receive the source of the communication. For TCP it will be filled in with details of the connection.

Parameters
dataBuffer to receive incoming message
lengthLength of the data buffer
offsetOffset into buffer where data is to be put. Although the offset could be implied by adjusting "data" and "length" appropriately, using this argument allows data to be specified as "const void*" - the overhead of converting it to a pointer to a set of bytes is hidden away here.
endpointSource of the communication
callbackCallback object

Implemented in isc::asiolink::DummyAsioSocket< C >, isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, and isc::asiolink::UDPSocket< C >.

◆ asyncSend()

template<typename C >
virtual void isc::asiolink::IOAsioSocket< C >::asyncSend ( const void * data,
size_t length,
const IOEndpoint * endpoint,
C & callback )
pure virtual

Send Asynchronously.

This corresponds to async_send_to() for UDP sockets and async_send() for TCP. In both cases an endpoint argument is supplied indicating the target of the send - this is ignored for TCP.

Parameters
dataData to send
lengthLength of data to send
endpointTarget of the send
callbackCallback object.

Implemented in isc::asiolink::DummyAsioSocket< C >, isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, and isc::asiolink::UDPSocket< C >.

◆ cancel()

◆ close()

◆ getNative()

template<typename C >
virtual int isc::asiolink::IOAsioSocket< C >::getNative ( ) const
pure virtual

Return the "native" representation of the socket.

In practice, this is the file descriptor of the socket for UNIX-like systems so the current implementation simply uses int as the type of the return value. We may have to need revisit this decision later.

In general, the application should avoid using this method; it essentially discloses an implementation specific "handle" that can change the internal state of the socket (consider what would happen if the application closes it, for example). But we sometimes need to perform very low-level operations that requires the native representation. Passing the file descriptor to a different process is one example. This method is provided as a necessary evil for such limited purposes.

This method never throws an exception.

Returns
The native representation of the socket. This is the socket file descriptor for UNIX-like systems.

Implements isc::asiolink::IOSocket.

Implemented in isc::asiolink::DummyAsioSocket< C >, isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, isc::asiolink::TLSSocket< SocketCallback >, and isc::asiolink::UDPSocket< C >.

◆ getProtocol()

template<typename C >
virtual int isc::asiolink::IOAsioSocket< C >::getProtocol ( ) const
pure virtual

Return the transport protocol of the socket.

Currently, it returns IPPROTO_UDP for UDP sockets, and IPPROTO_TCP for TCP sockets.

This method never throws an exception.

Returns
IPPROTO_UDP for UDP sockets, IPPROTO_TCP for TCP sockets

Implements isc::asiolink::IOSocket.

Implemented in isc::asiolink::DummyAsioSocket< C >, isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, isc::asiolink::TLSSocket< SocketCallback >, and isc::asiolink::UDPSocket< C >.

◆ isOpenSynchronous()

template<typename C >
virtual bool isc::asiolink::IOAsioSocket< C >::isOpenSynchronous ( ) const
pure virtual

Is Open() synchronous?

On a TCP socket, an "open" operation is a call to the socket's "open()" method followed by a connection to the remote system: it is an asynchronous operation. On a UDP socket, it is just a call to "open()" and completes synchronously.

For TCP, signaling of the completion of the operation is done by by calling the callback function in the normal way. This could be done for UDP (by posting en event on the event queue); however, that will incur additional overhead in the most common case. So we give the caller the choice for calling this open() method synchronously or asynchronously.

Owing to the way that the stackless coroutines are implemented, we need to know before executing the "open" function whether or not it is asynchronous. So this method is called to provide that information.

(The reason there is a need to know is because the call to open() passes in the state of the coroutine at the time the call is made. On an asynchronous I/O, we need to set the state to point to the statement after the call to open() before we pass the coroutine to the open() call. Unfortunately, the macros that set the state of the coroutine also yield control - which we don't want to do if the open is synchronous. Hence we need to know before we make the call to open() whether that call will complete asynchronously.)

Implemented in isc::asiolink::DummyAsioSocket< C >, isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, isc::asiolink::TLSSocket< SocketCallback >, and isc::asiolink::UDPSocket< C >.

◆ open()

template<typename C >
virtual void isc::asiolink::IOAsioSocket< C >::open ( const IOEndpoint * endpoint,
C & callback )
pure virtual

Open AsioSocket.

Opens the socket for asynchronous I/O. The open will complete synchronously on UDP or asynchronously on TCP (in which case a callback will be queued).

Parameters
endpointPointer to the endpoint object. This is ignored for a UDP socket (the target is specified in the send call), but should be of type TCPEndpoint for a TCP connection.
callbackI/O Completion callback, called when the operation has completed, but only if the operation was asynchronous. (It is ignored on a UDP socket.)

Implemented in isc::asiolink::DummyAsioSocket< C >, isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, and isc::asiolink::UDPSocket< C >.

◆ processReceivedData()

template<typename C >
virtual bool isc::asiolink::IOAsioSocket< C >::processReceivedData ( const void * staging,
size_t length,
size_t & cumulative,
size_t & offset,
size_t & expected,
isc::util::OutputBufferPtr & buff )
pure virtual

Processes received data.

In the IOFetch code, data is received into a staging buffer before being copied into the target buffer. (This is because (a) we don't know how much data we will be receiving, so don't know how to size the output buffer and (b) TCP data is preceded by a two-byte count field that needs to be discarded before being returned to the user.)

An additional consideration is that TCP data is not received in one I/O - it may take a number of I/Os - each receiving any non-zero number of bytes - to read the entire message.

So the IOFetch code has to loop until it determines that all the data has been read. This is where this method comes in. It has several functions:

  • It checks if the received data is complete.
  • If data is not complete, decides if the next set of data is to go into the start of the staging buffer or at some offset into it. (This simplifies the case we could have in a TCP receive where the two-byte count field is received in one-byte chunks: we put off interpreting the count until we have all of it. The alternative - copying the data to the output buffer and interpreting the count from there - would require moving the data in the output buffer by two bytes before returning it to the caller.)
  • Copies data from the staging buffer into the output buffer.

This functionality mainly applies to TCP receives. For UDP, all the data is received in one I/O, so this just copies the data into the output buffer.

Parameters
stagingPointer to the start of the staging buffer.
lengthAmount of data in the staging buffer.
cumulativeAmount of data received before the staging buffer is processed (this includes the TCP count field if appropriate). The value should be set to zero before the receive loop is entered, and it will be updated by this method as required.
offsetOffset into the staging buffer where the next read should put the received data. It should be set to zero before the first call and may be updated by this method.
expectedExpected amount of data to be received. This is really the TCP count field and is set to that value when enough of a TCP message is received. It should be initialized to -1 before the first read is executed.
buffOutput buffer. Data in the staging buffer may be copied to this output buffer in the call.
Returns
true if the receive is complete, false if another receive is needed. This is always true for UDP, but for TCP involves checking the amount of data received so far against the amount expected (as indicated by the two-byte count field). If this method returns false, another read should be queued and data should be read into the staging buffer at offset given by the "offset" parameter.

Implemented in isc::asiolink::TCPSocket< C >, isc::asiolink::TCPSocket< SocketCallback >, isc::asiolink::TLSSocket< C >, isc::asiolink::TLSSocket< SocketCallback >, and isc::asiolink::UDPSocket< C >.


The documentation for this class was generated from the following file: