Since v.0.5.1 RESTinio supports ability to check remote address of a new incoming connection and deny or allow this connection for further processing.

By default, RESTinio accepts all incoming connections and tries to read incoming requests from them. But since v.0.5.1 a user can specify an IP-blocker objects and RESTinio will call this object when a new incoming connection accepted. If IP-blocker denies that new connection it will be imediatelly closed. But if IP-blocker allows that connection it will be processed the usual way.

How to specify IP-blocker?

There are three steps those needs to be done to specify own IP-blocker to RESTinio server.

The first step is the creation of class with non-static inspect method. This class can look like:

class my_ip_blocker {
   inspect(const restinio::ip_blocker::incoming_info_t & info) noexcept {
         return restinio::ip_blocker::deny();
         return restinio::ip_blocker::allow();

Please notice that inspect gets a single argument of type restinio::ip_blocker::incoming_info_t by const reference and returns restinio::ip_blocker::inspection_result_t. It is also important to mention that inspect is noexcept-method.

The second step is the definition of my_ip_blocker as a type of IP-blocker for RESTinio. A typedef with name ip_blocker_t should be defined inside the server’s traits:

struct my_traits : public restinio::default_traits_t {
   using ip_blocker_t = my_ip_blocker;

The third step is the creation an instance of IP-blocker and passing it to the server’s settings:

restinio::run( restinio::on_this_thread<my_traits>()
      ... );

The restinio::ip_blocker::incoming_info_t class

An instance of restinio::ip_blocker::incoming_info_t class passed to inspect method contains all available information about the new connection. This class has the following interface:

class incoming_info_t
public :

   //! Get the remote endpoint for the connection.
   endpoint_t remote_endpoint() const noexcept;

NOTE. Amount of available information can be extended in future versions of RESTinio.

When and where IP-blocker is called?

If a user specifies an IP-blocker object this object will be called by RESTinio’s acceptor. If RESTinio is run on thread pool then calls to IP-blocker object can be performed from different worker thread. It means that IP-blocker should be a thread-safe object if RESTinio is run on thread pool.

It is very important to mention that a call to IP-blocker blocks further work on the accepted connection. It means that IP-blocker should work as fast as possible.

If the default value for ip_blocker_t is used (e.g. ip_blocker_t in server traits has the default value of restinio::ip_blocker::noop_ip_blocker_t) then there won’t be any performance impact because all IP-blocker code will be eliminated by C++ compiler (it’s a consequence of specializations inside RESTinio’s code for noop_ip_blocker_t case).

Thread safety of IP-blocker

If RESTinio is run on a thread pool then calls of inspect can be made from several threads. Moreover, several calls to inspect can be performed at the same time.

It’s a user’s task to make an IP-blocker thread-safe.

Integration of IP-blocker and connection-state-listener

It is possible it integrate functionality of IP-blocker and connection state listener (see Connection state listener) in one object. There is an example that shows how it can be done: ip_blocker).