Skip to content

Commit

Permalink
[libfscp] Adds a limitation for PRESENTATION messages processing.
Browse files Browse the repository at this point in the history
We adds a limit of 512 PRESENTATION packets per 10 seconds. This is not a
perfect solution but at least it will not bother too much existing
communications between peers.
  • Loading branch information
s-vincent committed Dec 17, 2018
1 parent 780d8ef commit 9c217b4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
21 changes: 21 additions & 0 deletions libs/fscp/include/fscp/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1426,6 +1426,12 @@ namespace fscp
void handle_presentation_message_from(const identity_store&, const presentation_message&, const ep_type&);
void do_handle_presentation(const identity_store& identity, const ep_type&, bool, cert_type);

/**
* \brief Reset presentation limit.
* \param ec error code.
*/
void do_presentation_reset_limit(const boost::system::error_code& ec);

void do_set_presentation_message_received_callback(presentation_message_received_handler_type, void_handler_type);

// This strand is also used by session requests and session messages during the cipherment/decipherment phase.
Expand All @@ -1437,6 +1443,21 @@ namespace fscp
presentation_store_map m_presentation_store_map;
presentation_message_received_handler_type m_presentation_message_received_handler;

/**
* \brief Current number of session request sent.
*/
size_t m_presentation_requests;

/**
* \brief Timer for reesting presentation requests limit.
*/
boost::asio::deadline_timer m_presentation_limit_timer;

/**
* \brief maximum number of session request.
*/
static const size_t MAX_PRESENTATION_REQUESTS;

private: // SESSION_REQUEST messages

typedef std::map<ep_type, peer_session> peer_session_map_type;
Expand Down
34 changes: 34 additions & 0 deletions libs/fscp/src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ namespace fscp
}
}

const size_t server::MAX_PRESENTATION_REQUESTS = 512;

// Public methods

server::server(boost::asio::io_service& io_service, fscp::logger& _logger, const identity_store& identity) :
Expand All @@ -227,6 +229,8 @@ namespace fscp
m_hello_message_received_handler(),
m_presentation_strand(io_service),
m_presentation_message_received_handler(),
m_presentation_requests(0),
m_presentation_limit_timer(io_service, boost::posix_time::seconds(10)),
m_session_strand(io_service),
m_accept_session_request_messages_default(true),
m_cipher_suites(get_default_cipher_suites()),
Expand Down Expand Up @@ -307,6 +311,9 @@ namespace fscp
async_receive_from();

m_keep_alive_timer.async_wait(m_session_strand.wrap(boost::bind(&server::do_check_keep_alive, this, boost::asio::placeholders::error)));
m_presentation_limit_timer.async_wait(m_presentation_strand.wrap(
boost::bind(&server::do_presentation_reset_limit, this,
boost::asio::placeholders::error)));
}

void server::close()
Expand All @@ -315,6 +322,8 @@ namespace fscp

m_keep_alive_timer.cancel();

m_presentation_limit_timer.cancel();

m_socket.close();
}

Expand Down Expand Up @@ -1415,6 +1424,16 @@ namespace fscp
void server::do_handle_presentation(const identity_store& identity, const ep_type& sender, bool has_session, cert_type signature_certificate)
{
// All do_handle_presentation() calls are done in the same strand so the following is thread-safe.
if(m_presentation_requests <= MAX_PRESENTATION_REQUESTS)
{
m_presentation_requests++;
}
else
{
// presentation flood?
return;
}

presentation_status_type presentation_status = PS_FIRST;

const presentation_store_map::iterator entry = m_presentation_store_map.find(sender);
Expand Down Expand Up @@ -1442,6 +1461,21 @@ namespace fscp
m_presentation_store_map[sender] = presentation_store(signature_certificate, identity.pre_shared_key());
}

void server::do_presentation_reset_limit(const boost::system::error_code& ec)
{
// All do_presentation_reset_limit calls are done in the same strand so the following is thread-safe.
if (ec != boost::asio::error::operation_aborted)
{
m_presentation_requests = 0;

// rearm timer again
m_presentation_limit_timer.expires_from_now(boost::posix_time::seconds(10));
m_presentation_limit_timer.async_wait(m_presentation_strand.wrap(
boost::bind(&server::do_presentation_reset_limit, this,
boost::asio::placeholders::error)));
}
}

void server::do_set_presentation_message_received_callback(presentation_message_received_handler_type callback, void_handler_type handler)
{
// All do_set_presentation_message_received_callback() calls are done in the same strand so the following is thread-safe.
Expand Down

0 comments on commit 9c217b4

Please sign in to comment.