+/* avahi_log_debug("ours=%i conflict=%i", ours, conflict); */
+
+ if (!ours && conflict) {
+ gchar *t;
+
+ valid = FALSE;
+
+ t = avahi_record_to_string(record);
+
+ if (withdraw_immediately) {
+ avahi_log_debug("Recieved conflicting record [%s] with local record to be. Withdrawing.", t);
+ withdraw_rrset(s, record->key);
+ } else {
+ g_assert(conflicting_entry);
+ avahi_log_debug("Recieved conflicting record [%s]. Resetting our record.", t);
+ avahi_entry_return_to_initial_state(s, conflicting_entry, i);
+
+ /* Local unique records are returned to probin
+ * state. Local shared records are reannounced. */
+ }
+
+ g_free(t);
+ }
+
+ return valid;
+}
+
+static void append_aux_callback(AvahiServer *s, AvahiRecord *r, gboolean flush_cache, gpointer userdata) {
+ gboolean *unicast_response = userdata;
+
+ g_assert(s);
+ g_assert(r);
+ g_assert(unicast_response);
+
+ avahi_record_list_push(s->record_list, r, flush_cache, *unicast_response, TRUE);
+}
+
+static void append_aux_records_to_list(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, gboolean unicast_response) {
+ g_assert(s);
+ g_assert(r);
+
+ avahi_server_enumerate_aux_records(s, i, r, append_aux_callback, &unicast_response);
+}
+
+void avahi_server_generate_response(AvahiServer *s, AvahiInterface *i, AvahiDnsPacket *p, const AvahiAddress *a, guint16 port, gboolean legacy_unicast) {
+
+ g_assert(s);
+ g_assert(i);
+ g_assert(!legacy_unicast || (a && port > 0 && p));
+
+ if (legacy_unicast) {
+ AvahiDnsPacket *reply;
+ AvahiRecord *r;
+
+ reply = avahi_dns_packet_new_reply(p, 512 /* unicast DNS maximum packet size is 512 */ , TRUE, TRUE);
+
+ while ((r = avahi_record_list_next(s->record_list, NULL, NULL, NULL))) {
+
+ append_aux_records_to_list(s, i, r, FALSE);
+
+ if (avahi_dns_packet_append_record(reply, r, FALSE, 10))
+ avahi_dns_packet_inc_field(reply, AVAHI_DNS_FIELD_ANCOUNT);
+ else {
+ gchar *t = avahi_record_to_string(r);
+ avahi_log_warn("Record [%s] not fitting in legacy unicast packet, dropping.", t);
+ g_free(t);
+ }
+
+ avahi_record_unref(r);
+ }
+
+ if (avahi_dns_packet_get_field(reply, AVAHI_DNS_FIELD_ANCOUNT) != 0)
+ avahi_interface_send_packet_unicast(i, reply, a, port);
+
+ avahi_dns_packet_free(reply);
+
+ } else {
+ gboolean unicast_response, flush_cache, auxiliary;
+ AvahiDnsPacket *reply = NULL;
+ AvahiRecord *r;
+
+ /* In case the query packet was truncated never respond
+ immediately, because known answer suppression records might be
+ contained in later packets */
+ gboolean tc = p && !!(avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_FLAGS) & AVAHI_DNS_FLAG_TC);
+
+ while ((r = avahi_record_list_next(s->record_list, &flush_cache, &unicast_response, &auxiliary))) {
+
+ if (!avahi_interface_post_response(i, r, flush_cache, a, !tc && flush_cache && !auxiliary) && unicast_response) {
+
+ append_aux_records_to_list(s, i, r, unicast_response);
+
+ /* Due to some reasons the record has not been scheduled.
+ * The client requested an unicast response in that
+ * case. Therefore we prepare such a response */
+
+ for (;;) {
+
+ if (!reply) {
+ g_assert(p);
+ reply = avahi_dns_packet_new_reply(p, i->hardware->mtu, FALSE, FALSE);
+ }
+
+ if (avahi_dns_packet_append_record(reply, r, flush_cache, 0)) {
+
+ /* Appending this record succeeded, so incremeant
+ * the specific header field, and return to the caller */
+
+ avahi_dns_packet_inc_field(reply, AVAHI_DNS_FIELD_ANCOUNT);
+
+ break;
+ }
+
+ if (avahi_dns_packet_get_field(reply, AVAHI_DNS_FIELD_ANCOUNT) == 0) {
+ guint size;
+
+ /* The record is too large for one packet, so create a larger packet */
+
+ avahi_dns_packet_free(reply);
+ size = avahi_record_get_estimate_size(r) + AVAHI_DNS_PACKET_HEADER_SIZE;
+ if (size > AVAHI_DNS_PACKET_MAX_SIZE)
+ size = AVAHI_DNS_PACKET_MAX_SIZE;
+ reply = avahi_dns_packet_new_reply(p, size, FALSE, TRUE);
+
+ if (!avahi_dns_packet_append_record(reply, r, flush_cache, 0)) {
+ avahi_dns_packet_free(reply);
+
+ gchar *t = avahi_record_to_string(r);
+ avahi_log_warn("Record [%s] too large, doesn't fit in any packet!", t);
+ g_free(t);
+ break;
+ } else
+ avahi_dns_packet_inc_field(reply, AVAHI_DNS_FIELD_ANCOUNT);
+ }
+
+ /* Appending the record didn't succeeed, so let's send this packet, and create a new one */
+ avahi_interface_send_packet_unicast(i, reply, a, port);
+ avahi_dns_packet_free(reply);
+ reply = NULL;
+ }
+ }
+
+ avahi_record_unref(r);
+ }
+
+ if (reply) {
+ if (avahi_dns_packet_get_field(reply, AVAHI_DNS_FIELD_ANCOUNT) != 0)
+ avahi_interface_send_packet_unicast(i, reply, a, port);
+ avahi_dns_packet_free(reply);
+ }
+ }
+
+ avahi_record_list_flush(s->record_list);
+}
+
+
+static void reflect_response(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, gboolean flush_cache) {
+ AvahiInterface *j;
+
+ g_assert(s);
+ g_assert(i);
+ g_assert(r);
+
+ if (!s->config.enable_reflector)
+ return;
+
+ for (j = s->monitor->interfaces; j; j = j->interface_next)
+ if (j != i && (s->config.reflect_ipv || j->protocol == i->protocol))
+ avahi_interface_post_response(j, r, flush_cache, NULL, TRUE);