From b6820898d317c29a31f97018ede6da5195d16bfb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Jun 2005 20:27:00 +0000 Subject: [PATCH] * use FIONREAD to minimize allocated buffer size when reading incoming packets * enforce a cache size limit git-svn-id: file:///home/lennart/svn/public/avahi/trunk@96 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-core/cache.c | 11 +++++++++++ avahi-core/cache.h | 2 ++ avahi-core/dns.c | 4 ++-- avahi-core/dns.h | 1 + avahi-core/netlink.c | 13 ++++++++----- avahi-core/server.c | 2 +- avahi-core/socket.c | 23 +++++++++++++++++++---- 7 files changed, 44 insertions(+), 12 deletions(-) diff --git a/avahi-core/cache.c b/avahi-core/cache.c index 433f5a8..8f9ffaf 100644 --- a/avahi-core/cache.c +++ b/avahi-core/cache.c @@ -28,6 +28,8 @@ #include "util.h" #include "cache.h" +#define AVAHI_MAX_CACHE_ENTRIES 200 + static void remove_entry(AvahiCache *c, AvahiCacheEntry *e) { AvahiCacheEntry *t; @@ -55,6 +57,8 @@ static void remove_entry(AvahiCache *c, AvahiCacheEntry *e) { avahi_record_unref(e->record); g_free(e); + + g_assert(c->n_entries-- >= 1); } AvahiCache *avahi_cache_new(AvahiServer *server, AvahiInterface *iface) { @@ -67,6 +71,7 @@ AvahiCache *avahi_cache_new(AvahiServer *server, AvahiInterface *iface) { c->hash_table = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal); AVAHI_LLIST_HEAD_INIT(AvahiCacheEntry, c->entries); + c->n_entries = 0; return c; } @@ -76,6 +81,7 @@ void avahi_cache_free(AvahiCache *c) { while (c->entries) remove_entry(c, c->entries); + g_assert(c->n_entries == 0); g_hash_table_destroy(c->hash_table); @@ -293,6 +299,11 @@ void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean cache_flush, con /* No entry found, therefore we create a new one */ /* g_message("couldn't find matching cache entry"); */ + + if (c->n_entries >= AVAHI_MAX_CACHE_ENTRIES) + return; + + c->n_entries++; e = g_new(AvahiCacheEntry, 1); e->cache = c; diff --git a/avahi-core/cache.h b/avahi-core/cache.h index 7496568..e4bdbc4 100644 --- a/avahi-core/cache.h +++ b/avahi-core/cache.h @@ -65,6 +65,8 @@ struct AvahiCache { GHashTable *hash_table; AVAHI_LLIST_HEAD(AvahiCacheEntry, entries); + + guint n_entries; }; AvahiCache *avahi_cache_new(AvahiServer *server, AvahiInterface *interface); diff --git a/avahi-core/dns.c b/avahi-core/dns.c index 4294c1e..9e19c9e 100644 --- a/avahi-core/dns.c +++ b/avahi-core/dns.c @@ -38,8 +38,8 @@ AvahiDnsPacket* avahi_dns_packet_new(guint mtu) { if (mtu <= 0) max_size = AVAHI_DNS_PACKET_MAX_SIZE; - else if (mtu >= 48) - max_size = mtu - 48; + else if (mtu >= AVAHI_DNS_PACKET_EXTRA_SIZE) + max_size = mtu - AVAHI_DNS_PACKET_EXTRA_SIZE; else max_size = 0; diff --git a/avahi-core/dns.h b/avahi-core/dns.h index a6d7895..03d9798 100644 --- a/avahi-core/dns.h +++ b/avahi-core/dns.h @@ -28,6 +28,7 @@ #define AVAHI_DNS_PACKET_MAX_SIZE 9000 #define AVAHI_DNS_PACKET_HEADER_SIZE 12 +#define AVAHI_DNS_PACKET_EXTRA_SIZE 48 typedef struct AvahiDnsPacket { guint size, rindex, max_size; diff --git a/avahi-core/netlink.c b/avahi-core/netlink.c index e3cc3fa..88979e1 100644 --- a/avahi-core/netlink.c +++ b/avahi-core/netlink.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "netlink.h" @@ -43,16 +44,18 @@ gboolean avahi_netlink_work(AvahiNetlink *nl, gboolean block) { g_assert(nl); for (;;) { - guint8 replybuf[64*1024]; ssize_t bytes; - struct nlmsghdr *p = (struct nlmsghdr *) replybuf; + struct nlmsghdr *p; + guint8 buffer[64*1024]; - if ((bytes = recv(nl->fd, replybuf, sizeof(replybuf), block ? 0 : MSG_DONTWAIT)) < 0) { + p = (struct nlmsghdr *) buffer; + + if ((bytes = recv(nl->fd, buffer, sizeof(buffer), block ? 0 : MSG_DONTWAIT)) < 0) { if (errno == EAGAIN || errno == EINTR) break; - g_warning("NETLINK: recv() failed"); + g_warning("NETLINK: recv() failed: %s", strerror(errno)); return FALSE; } @@ -160,7 +163,7 @@ AvahiNetlink *avahi_netlink_new(GMainContext *context, gint priority, guint32 gr void avahi_netlink_free(AvahiNetlink *nl) { g_assert(nl); - + g_source_destroy(nl->source); g_source_unref(nl->source); g_main_context_unref(nl->context); diff --git a/avahi-core/server.c b/avahi-core/server.c index 9356fec..da946e5 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -36,7 +36,7 @@ #include "socket.h" #include "browse.h" -#define AVAHI_HOST_RR_HOLDOFF_MSEC 1000 +#define AVAHI_HOST_RR_HOLDOFF_MSEC 2000 static void free_entry(AvahiServer*s, AvahiEntry *e) { AvahiEntry *t; diff --git a/avahi-core/socket.c b/avahi-core/socket.c index a2264ce..7007452 100644 --- a/avahi-core/socket.c +++ b/avahi-core/socket.c @@ -424,13 +424,19 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, ssize_t l; struct cmsghdr *cmsg; gboolean found_ttl = FALSE, found_iface = FALSE; + guint ms; g_assert(fd >= 0); g_assert(ret_sa); g_assert(ret_iface); g_assert(ret_ttl); - p = avahi_dns_packet_new(0); + if (ioctl(fd, FIONREAD, &ms) < 0) { + g_warning("ioctl(): %s", strerror(errno)); + goto fail; + } + + p = avahi_dns_packet_new(ms + AVAHI_DNS_PACKET_EXTRA_SIZE); io.iov_base = AVAHI_DNS_PACKET_DATA(p); io.iov_len = p->max_size; @@ -445,7 +451,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, msg.msg_flags = 0; if ((l = recvmsg(fd, &msg, 0)) < 0) { - g_warning("recvmsg(): %s\n", strerror(errno)); + g_warning("recvmsg(): %s", strerror(errno)); goto fail; } @@ -502,6 +508,8 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, struct iovec io; uint8_t aux[64]; ssize_t l; + guint ms; + struct cmsghdr *cmsg; gboolean found_ttl = FALSE, found_iface = FALSE; @@ -510,7 +518,12 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, g_assert(ret_iface); g_assert(ret_ttl); - p = avahi_dns_packet_new(0); + if (ioctl(fd, FIONREAD, &ms) < 0) { + g_warning("ioctl(): %s", strerror(errno)); + goto fail; + } + + p = avahi_dns_packet_new(ms + AVAHI_DNS_PACKET_EXTRA_SIZE); io.iov_base = AVAHI_DNS_PACKET_DATA(p); io.iov_len = p->max_size; @@ -524,8 +537,10 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, msg.msg_controllen = sizeof(aux); msg.msg_flags = 0; - if ((l = recvmsg(fd, &msg, 0)) < 0) + if ((l = recvmsg(fd, &msg, 0)) < 0) { + g_warning("recvmsg(): %s", strerror(errno)); goto fail; + } p->size = (size_t) l; -- 2.39.5