#include "geoip.h"
#include "main.h"
#include "networkstatus.h"
+#include "router.h"
#include "dos.h"
* General interface of the denial of service mitigation subsystem.
*/
+/* Keep stats for the heartbeat. */
+static uint64_t num_single_hop_client_refused;
+
/* Return true iff the circuit creation mitigation is enabled. We look at the
* consensus for this else a default value is returned. */
MOCK_IMPL(STATIC unsigned int,
/* General API */
+/* Note down that we've just refused a single hop client. This increments a
+ * counter later used for the heartbeat. */
+void
+dos_note_refuse_single_hop_client(void)
+{
+ num_single_hop_client_refused++;
+}
+
+/* Return true iff single hop client connection (ESTABLISH_RENDEZVOUS) should
+ * be refused. */
+int
+dos_should_refuse_single_hop_client(void)
+{
+ /* If we aren't a public relay, this shouldn't apply to anything. */
+ if (!public_server_mode(get_options())) {
+ return 0;
+ }
+
+ if (get_options()->DoSRefuseSingleHopClientRendezvous != -1) {
+ return get_options()->DoSRefuseSingleHopClientRendezvous;
+ }
+
+ return (int) networkstatus_get_param(NULL,
+ "DoSRefuseSingleHopClientRendezvous",
+ 0 /* default */, 0, 1);
+}
+
/* Called when a new client connection has been established on the given
* address. */
void
void dos_new_client_conn(or_connection_t *or_conn);
void dos_close_client_conn(const or_connection_t *or_conn);
+int dos_should_refuse_single_hop_client(void);
+void dos_note_refuse_single_hop_client(void);
+
/*
* Circuit creation DoS mitigation subsystemn interface.
*/
**/
#include "or.h"
+#include "channel.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
+#include "dos.h"
#include "relay.h"
#include "rendmid.h"
#include "rephist.h"
goto err;
}
+ /* Check if we are configured to accept established rendezvous cells from
+ * client or in other words tor2web clients. */
+ if (channel_is_client(circ->p_chan) &&
+ dos_should_refuse_single_hop_client()) {
+ /* Note it down for the heartbeat log purposes. */
+ dos_note_refuse_single_hop_client();
+ /* Silent drop so the client has to time out before moving on. */
+ return 0;
+ }
+
if (circ->base_.n_chan) {
log_warn(LD_PROTOCOL,
"Tried to establish rendezvous on non-edge circuit");