13 #include <boost/algorithm/string/predicate.hpp>
24 if (boost::iequals(protocol_str,
"UDP")) {
28 if (boost::iequals(protocol_str,
"TCP")) {
33 "Invalid NameChangeRequest protocol: " << protocol_str);
46 std::ostringstream stream;
47 stream <<
"UNKNOWN(" << protocol <<
")";
48 return (stream.str());
56 : listening_(false), io_pending_(false), recv_handler_(recv_handler) {
119 recv_handler_(result, ncr);
120 }
catch (
const std::exception& ex) {
148 recv_handler_(
ERROR, empty);
149 }
catch (
const std::exception& ex) {
161 size_t send_queue_max)
162 : sending_(false), send_handler_(send_handler),
163 send_queue_max_(send_queue_max), io_service_(NULL), mutex_(new mutex) {
179 lock_guard<mutex> lock(*mutex_);
180 startSendingInternal(io_service);
182 startSendingInternal(io_service);
193 ncr_to_send_.reset();
196 io_service_ = &io_service;
214 if (
ioReady() && io_service_ != NULL) {
217 }
catch (
const std::exception& ex) {
249 lock_guard<mutex> lock(*mutex_);
250 sendRequestInternal(ncr);
252 sendRequestInternal(ncr);
258 if (send_queue_.size() >= send_queue_max_) {
260 "send queue has reached maximum capacity: "
265 send_queue_.push_back(ncr);
282 if (!send_queue_.empty()) {
283 ncr_to_send_ = send_queue_.front();
297 lock_guard<mutex> lock(*mutex_);
298 invokeSendHandlerInternal(result);
300 invokeSendHandlerInternal(result);
309 send_queue_.pop_front();
318 send_handler_(result, ncr_to_send_);
319 }
catch (
const std::exception& ex) {
325 ncr_to_send_.reset();
347 send_handler_(
ERROR, ncr_to_send_);
348 }
catch (
const std::exception& ex) {
358 lock_guard<mutex> lock(*mutex_);
366 NameChangeSender::skipNextInternal() {
367 if (!send_queue_.empty()) {
369 send_queue_.pop_front();
380 lock_guard<mutex> lock(*mutex_);
391 " queue size must be greater than zero");
394 send_queue_max_ = new_max;
400 lock_guard<mutex> lock(*mutex_);
401 return (getQueueSizeInternal());
403 return (getQueueSizeInternal());
408 NameChangeSender::getQueueSizeInternal()
const {
409 return (send_queue_.size());
415 lock_guard<mutex> lock(*mutex_);
416 return (peekAtInternal(index));
418 return (peekAtInternal(index));
423 NameChangeSender::peekAtInternal(
const size_t index)
const {
424 auto size = getQueueSizeInternal();
427 "NameChangeSender::peekAt peek beyond end of queue attempted"
428 <<
" index: " << index <<
" queue size: " << size);
431 return (send_queue_.at(index));
437 lock_guard<mutex> lock(*mutex_);
438 return ((ncr_to_send_) ?
true :
false);
440 return ((ncr_to_send_) ?
true :
false);
448 " source sender is actively sending");
453 " target sender is actively sending");
458 " source queue count exceeds target queue max");
462 lock_guard<mutex> lock(*mutex_);
463 assumeQueueInternal(source_sender);
465 assumeQueueInternal(source_sender);
471 if (!send_queue_.empty()) {
473 " target queue is not empty");
488 " sender io service is null");
Exception thrown if an error occurs initiating an IO receive.
A generic exception that is thrown when a function is not implemented.
NameChangeProtocol stringToNcrProtocol(const std::string &protocol_str)
Function which converts text labels to NameChangeProtocol enums.
const isc::log::MessageID DHCP_DDNS_UNCAUGHT_NCR_RECV_HANDLER_ERROR
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
This file defines abstract classes for exchanging NameChangeRequests.
virtual void close()=0
Abstract method which closes the IO source.
virtual bool ioReady()=0
Returns whether or not the sender has IO ready to process.
virtual int getSelectFd()=0
Returns a file descriptor suitable for use with select.
const isc::log::MessageID DHCP_DDNS_NCR_FLUSH_IO_ERROR
void assumeQueue(NameChangeSender &source_sender)
Move all queued requests from a given sender into the send queue.
Result
Defines the outcome of an asynchronous NCR send.
boost::asio::io_service & get_io_service()
Return the native io_service object used in this wrapper.
const isc::log::MessageID DHCP_DDNS_NCR_LISTEN_CLOSE_ERROR
size_t getQueueMaxSize() const
Returns the maximum number of entries allowed in the send queue.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
void skipNext()
Removes the request at the front of the send queue.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
size_t getQueueSize() const
Returns the number of entries currently in the send queue.
The IOService class is a wrapper for the ASIO io_service class.
Thrown when a NameChangeSender encounters an error.
Exception thrown if an NcrListenerError encounters a general error.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
SendQueue & getSendQueue()
Returns a reference to the send queue.
std::string ncrProtocolToString(NameChangeProtocol protocol)
Function which converts NameChangeProtocol enums to text labels.
void clearSendQueue()
Flushes all entries in the send queue.
NameChangeListener(RequestReceiveHandler &recv_handler)
Constructor.
isc::log::Logger dhcp_ddns_logger("libdhcp-ddns")
Defines the logger used within lib dhcp_ddns.
Exception thrown if an error occurs during IO source open.
const isc::log::MessageID DHCP_DDNS_NCR_SEND_NEXT_ERROR
NameChangeSender(RequestSendHandler &send_handler, size_t send_queue_max=MAX_QUEUE_DEFAULT)
Constructor.
Abstract class for defining application layer send callbacks.
void startListening(isc::asiolink::IOService &io_service)
Prepares the IO for reception and initiates the first receive.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
bool isSendInProgress() const
Returns true when a send is in progress.
virtual void open(isc::asiolink::IOService &io_service)=0
Abstract method which opens the IO sink for transmission.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
void receiveNext()
Initiates an asynchronous receive.
const NameChangeRequestPtr & peekAt(const size_t index) const
Returns the entry at a given position in the queue.
const isc::log::MessageID DHCP_DDNS_NCR_RECV_NEXT_ERROR
virtual void doSend(NameChangeRequestPtr &ncr)=0
Initiates an IO layer asynchronous send.
const isc::log::MessageID DHCP_DDNS_NCR_SEND_CLOSE_ERROR
virtual void runReadyIO()
Processes sender IO events.
void stopSending()
Closes the IO sink and stops send logic.
virtual void open(isc::asiolink::IOService &io_service)=0
Abstract method which opens the IO source for reception.
void startSending(isc::asiolink::IOService &io_service)
Prepares the IO for transmission.
Exception thrown if an error occurs initiating an IO send.
void sendNext()
Dequeues and sends the next request on the send queue in a thread safe context.
NameChangeProtocol
Defines the list of socket protocols supported.
const isc::log::MessageID DHCP_DDNS_UNCAUGHT_NCR_SEND_HANDLER_ERROR
void setQueueMaxSize(const size_t new_max)
Sets the maximum queue size to the given value.
bool amListening() const
Returns true if the listener is listening, false otherwise.
Abstract interface for sending NameChangeRequests.
void invokeRecvHandler(const Result result, NameChangeRequestPtr &ncr)
Calls the NCR receive handler registered with the listener.
void sendRequest(NameChangeRequestPtr &ncr)
Queues the given request to be sent.
void stopListening()
Closes the IO source and stops listen logic.
void invokeSendHandler(const NameChangeSender::Result result)
Calls the NCR send completion handler registered with the sender.
virtual void close()=0
Abstract method which closes the IO sink.
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
Abstract class for defining application layer receive callbacks.
virtual void doReceive()=0
Initiates an IO layer asynchronous read.
Result
Defines the outcome of an asynchronous NCR receive.
Exception thrown if an error occurs during IO source open.