-/* $Id$ */
-
/***
This file is part of avahi.
#include "domain-util.h"
#include "rr-util.h"
+#define AVAHI_DEFAULT_CACHE_ENTRIES_MAX 4096
+
static void enum_aux_records(AvahiServer *s, AvahiInterface *i, const char *name, uint16_t type, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata) {
assert(s);
assert(i);
avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ARCOUNT); n > 0; n--) {
AvahiRecord *record;
int cache_flush = 0;
-/* char *txt; */
if (!(record = avahi_dns_packet_consume_record(p, &cache_flush))) {
avahi_log_warn(__FILE__": Packet too short or invalid while reading response record. (Maybe a UTF-8 problem?)");
if (!avahi_key_is_pattern(record->key)) {
if (handle_conflict(s, i, record, cache_flush)) {
- if (!from_local_iface)
+ if (!from_local_iface && !avahi_record_is_link_local_address(record))
reflect_response(s, i, record, cache_flush);
avahi_cache_update(i->cache, record, cache_flush, a);
avahi_response_scheduler_incoming(i->response_scheduler, record, cache_flush);
}
/* If the incoming response contained a conflicting record, some
- records have been scheduling for sending. We need to flush them
+ records have been scheduled for sending. We need to flush them
here. */
if (!avahi_record_list_is_empty(s->record_list))
avahi_server_generate_response(s, i, NULL, NULL, 0, 0, 1);
if (getsockname(s->fd_legacy_unicast_ipv4, (struct sockaddr*) &lsa, &l) != 0)
avahi_log_warn("getsockname(): %s", strerror(errno));
else
- return lsa.sin_port == port;
+ return avahi_port_from_sockaddr((struct sockaddr*) &lsa) == port;
}
if (getsockname(s->fd_legacy_unicast_ipv6, (struct sockaddr*) &lsa, &l) != 0)
avahi_log_warn("getsockname(): %s", strerror(errno));
else
- return lsa.sin6_port == port;
+ return avahi_port_from_sockaddr((struct sockaddr*) &lsa) == port;
}
return 0;
return;
}
+ if (port <= 0) {
+ /* This fixes RHBZ #475394 */
+ avahi_log_warn("Received packet from invalid source port %u.", (unsigned) port);
+ return;
+ }
+
if (avahi_address_is_ipv4_in_ipv6(src_address))
/* This is an IPv4 address encapsulated in IPv6, so let's ignore it. */
return;
if (avahi_dns_packet_is_query(p)) {
int legacy_unicast = 0;
- if (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ARCOUNT) != 0) {
- avahi_log_warn("Invalid query packet.");
- return;
- }
+ /* For queries EDNS0 might allow ARCOUNT != 0. We ignore the
+ * AR section completely here, so far. Until the day we add
+ * EDNS0 support. */
if (port != AVAHI_MDNS_PORT) {
/* Legacy Unicast */
avahi_dns_packet_set_field(p, AVAHI_DNS_FIELD_ID, slot->id);
}
-static void cleanup_dead(AvahiServer *s) {
- assert(s);
-
- avahi_cleanup_dead_entries(s);
- avahi_browser_cleanup(s);
-}
-
static void mcast_socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events, void *userdata) {
AvahiServer *s = userdata;
AvahiAddress dest, src;
if (iface != AVAHI_IF_UNSPEC)
dispatch_packet(s, p, &src, port, &dest, iface, ttl);
else
- avahi_log_error("Incoming packet recieved on address that isn't local.");
+ avahi_log_error("Incoming packet received on address that isn't local.");
avahi_dns_packet_free(p);
- cleanup_dead(s);
+ avahi_cleanup_dead_entries(s);
}
}
dispatch_legacy_unicast_packet(s, p);
avahi_dns_packet_free(p);
- cleanup_dead(s);
+ avahi_cleanup_dead_entries(s);
}
}
register_browse_domain(s);
avahi_interface_monitor_update_rrs(s->monitor, 0);
+ assert(s->n_host_rr_pending > 0);
s->n_host_rr_pending --;
if (s->n_host_rr_pending == 0)
AVAHI_CHECK_VALIDITY(s, !host_name || avahi_is_valid_host_name(host_name), AVAHI_ERR_INVALID_HOST_NAME);
- if (!host_name) {
+ if (!host_name)
hn = avahi_get_host_name_strdup();
- hn[strcspn(hn, ".")] = 0;
- host_name = hn;
- }
+ else
+ hn = avahi_normalize_name_strdup(host_name);
- if (avahi_domain_equal(s->host_name, host_name) && s->state != AVAHI_SERVER_COLLISION) {
+ hn[strcspn(hn, ".")] = 0;
+
+ if (avahi_domain_equal(s->host_name, hn) && s->state != AVAHI_SERVER_COLLISION) {
avahi_free(hn);
return avahi_server_set_errno(s, AVAHI_ERR_NO_CHANGE);
}
withdraw_host_rrs(s);
avahi_free(s->host_name);
- s->host_name = hn ? hn : avahi_strdup(host_name);
+ s->host_name = hn;
update_fqdn(s);
AVAHI_CHECK_VALIDITY(s, !domain_name || avahi_is_valid_domain_name(domain_name), AVAHI_ERR_INVALID_DOMAIN_NAME);
- if (!domain_name) {
+ if (!domain_name)
dn = avahi_strdup("local");
- domain_name = dn;
- }
+ else
+ dn = avahi_normalize_name_strdup(domain_name);
if (avahi_domain_equal(s->domain_name, domain_name)) {
avahi_free(dn);
withdraw_host_rrs(s);
avahi_free(s->domain_name);
- s->domain_name = avahi_normalize_name_strdup(domain_name);
+ s->domain_name = dn;
update_fqdn(s);
register_stuff(s);
s->need_entry_cleanup = 0;
s->need_group_cleanup = 0;
s->need_browser_cleanup = 0;
+ s->cleanup_time_event = NULL;
s->hinfo_entry_group = NULL;
s->browse_domain_entry_group = NULL;
s->error = AVAHI_OK;
avahi_wide_area_engine_free(s->wide_area_lookup_engine);
avahi_multicast_lookup_engine_free(s->multicast_lookup_engine);
+ if (s->cleanup_time_event)
+ avahi_time_event_free(s->cleanup_time_event);
+
avahi_time_event_queue_free(s->time_event_queue);
/* Free watches */
memset(c, 0, sizeof(AvahiServerConfig));
c->use_ipv6 = 1;
c->use_ipv4 = 1;
+ c->allow_interfaces = NULL;
+ c->deny_interfaces = NULL;
c->host_name = NULL;
c->domain_name = NULL;
c->check_response_ttl = 0;
c->allow_point_to_point = 0;
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;
}
avahi_free(c->host_name);
avahi_free(c->domain_name);
avahi_string_list_free(c->browse_domains);
+ avahi_string_list_free(c->allow_interfaces);
+ avahi_string_list_free(c->deny_interfaces);
}
AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c) {
char *d = NULL, *h = NULL;
- AvahiStringList *l = NULL;
+ AvahiStringList *browse = NULL, *allow = NULL, *deny = NULL;
assert(ret);
assert(c);
return NULL;
}
- if (!(l = avahi_string_list_copy(c->browse_domains)) && c->browse_domains) {
+ if (!(browse = avahi_string_list_copy(c->browse_domains)) && c->browse_domains) {
+ avahi_free(h);
+ avahi_free(d);
+ return NULL;
+ }
+
+ if (!(allow = avahi_string_list_copy(c->allow_interfaces)) && c->allow_interfaces) {
+ avahi_string_list_free(browse);
+ avahi_free(h);
+ avahi_free(d);
+ return NULL;
+ }
+
+ if (!(deny = avahi_string_list_copy(c->deny_interfaces)) && c->deny_interfaces) {
+ avahi_string_list_free(allow);
+ avahi_string_list_free(browse);
avahi_free(h);
avahi_free(d);
return NULL;
*ret = *c;
ret->host_name = h;
ret->domain_name = d;
- ret->browse_domains = l;
+ ret->browse_domains = browse;
+ ret->allow_interfaces = allow;
+ ret->deny_interfaces = deny;
return ret;
}