14 namespace ph = std::placeholders;
23 : handler_(handler), data_(new
Data(buffer, buf_size, data_source)) {
35 const size_t bytes_transferred) {
46 handler_(!error_code,
this);
55 if (len > data_->buf_size_) {
59 memcpy (data_->buffer_.get(), src, len);
60 data_->put_len_ = len;
69 const bool reuse_address)
71 port_(port), format_(format), reuse_address_(reuse_address) {
77 recv_callback_.reset(
new UDPCallback(buffer, RECV_BUF_MAX, data_source,
79 this, ph::_1, ph::_2)));
94 asio_socket_.reset(
new boost::asio::ip::udp::
96 (ip_address_.
isV4() ? boost::asio::ip::udp::v4() :
97 boost::asio::ip::udp::v6())));
100 if (reuse_address_) {
101 asio_socket_->set_option(boost::asio::socket_base::reuse_address(
true));
106 }
catch (
const boost::system::system_error& ex) {
107 asio_socket_.reset();
120 socket_->asyncReceive(recv_buffer.get(), recv_callback_->getBufferSize(),
121 0, recv_callback_->getDataSource().get(),
133 if (asio_socket_->is_open()) {
135 asio_socket_->close();
136 }
catch (
const boost::system::system_error& ex) {
145 asio_socket_.reset();
174 boost::system::error_code error_code = callback->
getErrorCode();
175 if (error_code.value() == boost::asio::error::operation_aborted) {
183 .arg(error_code.message());
201 const size_t send_que_max,
const bool reuse_address)
203 ip_address_(ip_address), port_(port), server_address_(server_address),
204 server_port_(server_port), format_(format),
205 reuse_address_(reuse_address) {
211 send_callback_.reset(
new UDPCallback(buffer, SEND_BUF_MAX, data_source,
213 this, ph::_1, ph::_2)));
228 asio_socket_.reset(
new boost::asio::ip::udp::
230 (ip_address_.
isV4() ? boost::asio::ip::udp::v4() :
231 boost::asio::ip::udp::v6())));
234 if (reuse_address_) {
235 asio_socket_->set_option(boost::asio::socket_base::reuse_address(
true));
240 }
catch (
const boost::system::system_error& ex) {
249 UDPEndpoint(server_address_, server_port_));
251 send_callback_->setDataSource(server_endpoint_);
265 if (asio_socket_->is_open()) {
267 asio_socket_->close();
268 }
catch (
const boost::system::system_error& ex) {
277 asio_socket_.reset();
283 watch_socket_.reset();
290 ncr->toFormat(format_, ncr_buffer);
294 send_callback_->putData(static_cast<const uint8_t*>(ncr_buffer.
getData()),
298 socket_->asyncSend(send_callback_->getData(), send_callback_->getPutLen(),
299 send_callback_->getDataSource().get(), *send_callback_);
306 watch_socket_->markReady();
314 watch_socket_->clearReady();
315 }
catch (
const std::exception& ex) {
332 boost::system::error_code error_code = send_callback->
getErrorCode();
333 if (error_code.value() == boost::asio::error::operation_aborted) {
335 .arg(error_code.message());
339 .arg(error_code.message());
352 " not in send mode");
355 return(watch_socket_->getSelectFd());
361 return (watch_socket_->isReady());
368 NameChangeUDPSender::closeWatchSocket() {
370 std::string error_string;
371 watch_socket_->closeSocket(error_string);
372 if (!error_string.empty()) {
virtual ~NameChangeUDPListener()
Destructor.
const isc::log::MessageID DHCP_DDNS_NCR_UDP_SEND_ERROR
A generic exception that is thrown when a function is not implemented.
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
static NameChangeRequestPtr fromFormat(const NameChangeFormat format, isc::util::InputBuffer &buffer)
Static method for creating a NameChangeRequest from a buffer containing a marshalled request in a giv...
const int DBGLVL_TRACE_BASIC
Trace basic operations.
void doReceive()
Initiates an asynchronous read on the socket.
std::function< void(const bool, const UDPCallback *)> UDPCompletionHandler
Defines a function pointer for NameChangeRequest completion handlers.
static const size_t SEND_BUF_MAX
Defines the maximum size packet that can be sent.
virtual ~NameChangeUDPSender()
Destructor.
Result
Defines the outcome of an asynchronous NCR send.
static const size_t RECV_BUF_MAX
Defines the maximum size packet that can be received.
The UDPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a UDP ...
boost::asio::io_service & get_io_service()
Return the native io_service object used in this wrapper.
virtual void open(isc::asiolink::IOService &io_service)
Opens a UDP socket using the given IOService.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Implements the callback class passed into UDPSocket calls.
virtual void close()
Closes the UDPSocket.
NameChangeFormat
Defines the list of data wire formats supported.
This file provides UDP socket based implementation for sending and receiving NameChangeRequests.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
const isc::log::MessageID DHCP_DDNS_INVALID_NCR
bool isV4() const
Convenience function to check for an IPv4 address.
UDPCallback(RawBufferPtr &buffer, const size_t buf_size, UDPEndpointPtr &data_source, const UDPCompletionHandler &handler)
Used as the callback object for UDPSocket services.
void sendCompletionHandler(const bool successful, const UDPCallback *send_callback)
Implements the NameChangeRequest level send completion handler.
The IOService class is a wrapper for the ASIO io_service class.
const boost::asio::ip::udp::endpoint & getASIOEndpoint() const
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Exception thrown when NameChangeRequest marshalling error occurs.
void receiveCompletionHandler(const bool successful, const UDPCallback *recv_callback)
Implements the NameChangeRequest level receive completion handler.
const isc::log::MessageID DHCP_DDNS_NCR_UDP_RECV_ERROR
void operator()(const boost::system::error_code error_code, const size_t bytes_transferred)
Operator that will be invoked by the asiolink layer.
virtual bool ioReady()
Returns whether or not the sender has IO ready to process.
isc::log::Logger dhcp_ddns_logger("libdhcp-ddns")
Defines the logger used within lib dhcp_ddns.
NameChangeUDPSender(const isc::asiolink::IOAddress &ip_address, const uint32_t port, const isc::asiolink::IOAddress &server_address, const uint32_t server_port, const NameChangeFormat format, RequestSendHandler &ncr_send_handler, const size_t send_que_max=NameChangeSender::MAX_QUEUE_DEFAULT, const bool reuse_address=false)
Constructor.
virtual void close()
Closes the UDPSocket.
void setBytesTransferred(const size_t value)
Sets the number of bytes transferred.
const isc::log::MessageID DHCP_DDNS_NCR_UDP_SEND_CANCELED
Provides an IO "ready" semaphore for use with select() or poll() WatchSocket exposes a single open fi...
virtual void open(isc::asiolink::IOService &io_service)
Opens a UDP socket using the given IOService.
NameChangeUDPListener(const isc::asiolink::IOAddress &ip_address, const uint32_t port, const NameChangeFormat format, RequestReceiveHandler &ncr_recv_handler, const bool reuse_address=false)
Constructor.
const isc::log::MessageID DHCP_DDNS_NCR_UDP_CLEAR_READY_ERROR
Abstract class for defining application layer send callbacks.
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.
Thrown when a UDP level exception occurs.
void setErrorCode(const boost::system::error_code value)
Sets the completed IO layer service outcome status.
virtual int getSelectFd()
Returns a file descriptor suitable for use with select.
Defines the logger used by the top-level component of kea-dhcp-ddns.
void receiveNext()
Initiates an asynchronous receive.
Container class which stores service invocation related data.
const isc::log::MessageID DHCP_DDNS_UDP_SENDER_WATCH_SOCKET_CLOSE_ERROR
boost::shared_array< uint8_t > RawBufferPtr
Defines a dynamically allocated shared array.
void stopSending()
Closes the IO sink and stops send logic.
isc::asiolink::UDPSocket< UDPCallback > NameChangeUDPSocket
Convenience type for UDP socket based listener.
void putData(const uint8_t *src, size_t len)
Copies data into the data transfer buffer.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Abstract interface for sending NameChangeRequests.
void invokeRecvHandler(const Result result, NameChangeRequestPtr &ncr)
Calls the NCR receive handler registered with the listener.
virtual void doSend(NameChangeRequestPtr &ncr)
Sends a given request asynchronously over the socket.
boost::system::error_code getErrorCode() const
Returns the completed IO layer service outcome status.
The IOAddress class represents an IP addresses (version agnostic)
void stopListening()
Closes the IO source and stops listen logic.
size_t getLength() const
Return the length of data written in the buffer.
const uint8_t * getData() const
Returns a pointer the data transfer buffer content.
void invokeSendHandler(const NameChangeSender::Result result)
Calls the NCR send completion handler registered with the sender.
boost::shared_ptr< asiolink::UDPEndpoint > UDPEndpointPtr
Abstract interface for receiving NameChangeRequests.
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
Abstract class for defining application layer receive callbacks.
Result
Defines the outcome of an asynchronous NCR receive.
std::string format(const std::string &format, const std::vector< std::string > &args)
Apply Formatting.
const isc::log::MessageID DHCP_DDNS_NCR_UDP_RECV_CANCELED
size_t getBytesTransferred() const
Returns the number of bytes transferred by the completed IO service.