Skip to content

Commit

Permalink
added ability to pass callbacks instead of a handler to the context
Browse files Browse the repository at this point in the history
  • Loading branch information
EmielBruijntjes committed Oct 11, 2020
1 parent bf72dcb commit 8907057
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/dnscpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@
#include <dnscpp/operation.h>
#include <dnscpp/request.h>
#include <dnscpp/question.h>
#include <dnscpp/reverse.h>
114 changes: 114 additions & 0 deletions include/dnscpp/callbacks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* Callbacks.h
*
* Type definition of the callbacks
*
* @author Emiel Bruijntjes <[email protected]>
* @copyright 2020 Copernica BV
*/

/**
* Include guard
*/
#pragma once

/**
* Dependencies
*/
#include <functional>
#include "handler.h"

/**
* Begin of namespace
*/
namespace DNS {

/**
* Forward declarations
*/
class Response;
class Operation;

/**
* The callback-type used for the callback-based query() methods
* @type function
*/
using SuccessCallback = std::function<void(const Operation *, const Response &response)>;
using FailureCallback = std::function<void(const Operation *, int rcode)>;

/**
* Utility class to turn callbacks into a handler
*/
class Callbacks : public Handler
{
private:
/**
* The success callback
* @var SuccessCallback
*/
SuccessCallback _success;

/**
* The failure callback
* @var FailureCallback
*/
FailureCallback _failure;


/**
* Method that is called when a valid, successful, response was received.
* @param operation the operation that finished
* @param response the received response
*/
virtual void onResolved(const Operation *operation, const Response &response) override
{
// call to user-space
_success(operation, response);

// self-destruct
delete this;
}

/**
* Method that is called when a query could not be processed or answered.
* @param operation the operation that finished
* @param rcode the received rcode
*/
virtual void onFailure(const Operation *operation, int rcode) override
{
// call to user-space
_failure(operation, rcode);

// self-destruct
delete this;
}

/**
* Method that is called when the operation is cancelled
* @param operation the operation that was cancelled
*/
virtual void onCancelled(const Operation *operation) override
{
// self-destruct
delete this;
}

/**
* Private destructor (object is self-destructing)
*/
virtual ~Callbacks() = default;

public:
/**
* Constructor
* @param success the success-callback
* @param failure the failure-callback
*/
Callbacks(const SuccessCallback &success, const FailureCallback &failure) :
_success(success), _failure(failure) {}
};

/**
* End of namespace
*/
}
24 changes: 22 additions & 2 deletions include/dnscpp/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <vector>
#include "type.h"
#include "core.h"
#include "reverse.h"
#include "callbacks.h"

/**
* Begin of namespace
Expand Down Expand Up @@ -98,7 +98,7 @@ class Context : private Core
}

/**
* Do a dns lookup
* Do a dns lookup and pass the result to a user-space handler object
* When you supply invalid parameters (for example a syntactivally invalid
* domain or an unsupported type) this method returns null.
* @param name the record name to look for
Expand All @@ -115,6 +115,26 @@ class Context : private Core
* @return operation object to interact with the operation while it is in progress
*/
Operation *query(const Ip &ip, Handler *handler);

/**
* Do a dns lookup and pass the result to callbacks
* @param name the record name to look for
* @param type type of record (normally you ask for an 'a' record)
* @param success function that will be called on success
* @param failure function that will be called on failure
* @return operation object to interact with the operation while it is in progress
*/
Operation *query(const char *domain, ns_type type, const SuccessCallback &success, const FailureCallback &failure);

/**
* Do a reverse dns lookup and pass the result to callbacks
* @param ip the ip address to lookup
* @param success function that will be called on success
* @param failure function that will be called on failure
* @return operation object to interact with the operation while it is in progress
*/
Operation *query(const DNS::Ip &ip, const SuccessCallback &success, const FailureCallback &failure);

};

/**
Expand Down
10 changes: 9 additions & 1 deletion include/dnscpp/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Handler
* @param operation the operation that finished
* @param rcode the received rcode
*/
virtual void onFailure(const Operation *operation, int rrcode) {}
virtual void onFailure(const Operation *operation, int rcode) {}

/**
* Method that is called when an operation times out.
Expand All @@ -80,6 +80,14 @@ class Handler
* @param response the received response
*/
virtual void onReceived(const Operation *operation, const Response &response);

/**
* Method that is called when the operation is cancelled
* This method is immediately triggered when operation->cancel() is called.
*
* @param operation the operation that was cancelled
*/
virtual void onCancelled(const Operation *operation) {}
};

/**
Expand Down
26 changes: 26 additions & 0 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ Operation *Context::query(const Ip &ip, Handler *handler)
return query(Reverse(ip), TYPE_PTR, handler);
}

/**
* Do a dns lookup and pass the result to callbacks
* @param name the record name to look for
* @param type type of record (normally you ask for an 'a' record)
* @param success function that will be called on success
* @param failure function that will be called on failure
* @return operation object to interact with the operation while it is in progress
*/
Operation *Context::query(const char *domain, ns_type type, const SuccessCallback &success, const FailureCallback &failure)
{
// use a self-destructing wrapper for the handler
return query(domain, type, new Callbacks(success, failure));
}

/**
* Do a reverse dns lookup and pass the result to callbacks
* @param ip the ip address to lookup
* @param success function that will be called on success
* @param failure function that will be called on failure
* @return operation object to interact with the operation while it is in progress
*/
Operation *Context::query(const DNS::Ip &ip, const SuccessCallback &success, const FailureCallback &failure)
{
// use a self-destructing wrapper for the handler
return query(ip, new Callbacks(success, failure));
}

/**
* End of namespace
Expand Down
5 changes: 5 additions & 0 deletions src/locallookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
#include "../include/dnscpp/request.h"
#include "../include/dnscpp/question.h"
#include "../include/dnscpp/reverse.h"

/**
* Begin of namespace
Expand Down Expand Up @@ -74,6 +75,10 @@ class LocalLookup : public Operation, private Timer

// stop the timer
_loop->cancel(_timer, this);

// if the operation is destructed while the timer was still running, it means that the
// operation was prematurely cancelled from user-space, let the handler know
_handler->onCancelled(this);
}

public:
Expand Down
4 changes: 4 additions & 0 deletions src/remotelookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ RemoteLookup::~RemoteLookup()
// but if userspace decided to kill the job (by calling job->cancel()) we still
// have to do some cleaning ourselves
cleanup();

// if the operation is destructed while the timer was still running, it means that the
// operation was prematurely cancelled from user-space, let the handler know
_handler->onCancelled(this);
}

/**
Expand Down

0 comments on commit 8907057

Please sign in to comment.