summaryrefslogtreecommitdiffstats
path: root/avahi-core
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-06-29 02:24:02 +0200
committerLennart Poettering <lennart@poettering.net>2010-06-29 02:24:02 +0200
commitd7b03753f10d93d278091d39b95adf3b18a2770c (patch)
tree49e7a335eac64aa01a84c3c1cd0003e83f02c8eb /avahi-core
parent17cb9485bbf194aadf94642eafe261303fe8a867 (diff)
core: implement packet rate limiting and enable it by default
Diffstat (limited to 'avahi-core')
-rw-r--r--avahi-core/core.h3
-rw-r--r--avahi-core/iface.c24
-rw-r--r--avahi-core/iface.h4
-rw-r--r--avahi-core/internal.h1
-rw-r--r--avahi-core/server.c2
5 files changed, 34 insertions, 0 deletions
diff --git a/avahi-core/core.h b/avahi-core/core.h
index 1f50126..f50c612 100644
--- a/avahi-core/core.h
+++ b/avahi-core/core.h
@@ -29,6 +29,7 @@ typedef struct AvahiServer AvahiServer;
#include <avahi-common/address.h>
#include <avahi-common/defs.h>
#include <avahi-common/watch.h>
+#include <avahi-common/timeval.h>
#include <avahi-core/rr.h>
AVAHI_C_DECL_BEGIN
@@ -66,6 +67,8 @@ typedef struct AvahiServerConfig {
int publish_a_on_ipv6; /**< Publish an IPv4 A RR on IPv6 sockets */
int publish_aaaa_on_ipv4; /**< Publish an IPv4 A RR on IPv6 sockets */
unsigned n_cache_entries_max; /**< Maximum number of cache entries per interface */
+ AvahiUsec ratelimit_interval; /**< If non-zero, rate-limiting interval parameter. */
+ unsigned ratelimit_burst; /**< If ratelimit_interval is non-zero, rate-limiting burst parameter. */
} AvahiServerConfig;
/** Allocate a new mDNS responder object. */
diff --git a/avahi-core/iface.c b/avahi-core/iface.c
index ad83fe4..39a860a 100644
--- a/avahi-core/iface.c
+++ b/avahi-core/iface.c
@@ -390,6 +390,9 @@ AvahiHwInterface *avahi_hw_interface_new(AvahiInterfaceMonitor *m, AvahiIfIndex
hw->index = idx;
hw->mac_address_size = 0;
hw->entry_group = NULL;
+ hw->ratelimit_begin.tv_sec = 0;
+ hw->ratelimit_begin.tv_usec = 0;
+ hw->ratelimit_counter = 0;
AVAHI_LLIST_HEAD_INIT(AvahiInterface, hw->interfaces);
AVAHI_LLIST_PREPEND(AvahiHwInterface, hardware, m->hw_interfaces, hw);
@@ -571,6 +574,27 @@ void avahi_interface_send_packet_unicast(AvahiInterface *i, AvahiDnsPacket *p, c
assert(!a || a->proto == i->protocol);
+ if (i->monitor->server->config.ratelimit_interval > 0) {
+ struct timeval now, end;
+
+ gettimeofday(&now, NULL);
+
+ end = i->hardware->ratelimit_begin;
+ avahi_timeval_add(&end, i->monitor->server->config.ratelimit_interval);
+
+ if (i->hardware->ratelimit_begin.tv_sec <= 0 ||
+ avahi_timeval_compare(&end, &now) < 0) {
+
+ i->hardware->ratelimit_begin = now;
+ i->hardware->ratelimit_counter = 0;
+ }
+
+ if (i->hardware->ratelimit_counter > i->monitor->server->config.ratelimit_burst)
+ return;
+
+ i->hardware->ratelimit_counter++;
+ }
+
if (i->protocol == AVAHI_PROTO_INET && i->monitor->server->fd_ipv4 >= 0)
avahi_send_dns_packet_ipv4(i->monitor->server->fd_ipv4, i->hardware->index, p, i->mcast_joined ? &i->local_mcast_address.data.ipv4 : NULL, a ? &a->data.ipv4 : NULL, port);
else if (i->protocol == AVAHI_PROTO_INET6 && i->monitor->server->fd_ipv6 >= 0)
diff --git a/avahi-core/iface.h b/avahi-core/iface.h
index b38578c..c3f24af 100644
--- a/avahi-core/iface.h
+++ b/avahi-core/iface.h
@@ -85,6 +85,10 @@ struct AvahiHwInterface {
AvahiSEntryGroup *entry_group;
+ /* Packet rate limiting */
+ struct timeval ratelimit_begin;
+ unsigned ratelimit_counter;
+
AVAHI_LLIST_HEAD(AvahiInterface, interfaces);
};
diff --git a/avahi-core/internal.h b/avahi-core/internal.h
index eb7f146..b8f9302 100644
--- a/avahi-core/internal.h
+++ b/avahi-core/internal.h
@@ -25,6 +25,7 @@ typedef struct AvahiEntry AvahiEntry;
#include <avahi-common/llist.h>
#include <avahi-common/watch.h>
+#include <avahi-common/timeval.h>
#include "core.h"
#include "iface.h"
diff --git a/avahi-core/server.c b/avahi-core/server.c
index d7fd71b..2b8f95f 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -1591,6 +1591,8 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) {
c->publish_aaaa_on_ipv4 = 1;
c->publish_a_on_ipv6 = 0;
c->n_cache_entries_max = AVAHI_DEFAULT_CACHE_ENTRIES_MAX;
+ c->ratelimit_interval = 0;
+ c->ratelimit_burst = 0;
return c;
}