+
+ /* Known Answer Suppresion */
+ for (n = flx_dns_packet_get_field(p, FLX_DNS_FIELD_ANCOUNT); n > 0; n --) {
+ flxRecord *record;
+ gboolean unique = FALSE;
+
+ if (!(record = flx_dns_packet_consume_record(p, &unique))) {
+ g_warning("Packet too short (2)");
+ return;
+ }
+
+ flx_packet_scheduler_incoming_known_answer(i->scheduler, record, a);
+ flx_record_unref(record);
+ }
+
+ /* Probe record */
+ for (n = flx_dns_packet_get_field(p, FLX_DNS_FIELD_NSCOUNT); n > 0; n --) {
+ flxRecord *record;
+ gboolean unique = FALSE;
+
+ if (!(record = flx_dns_packet_consume_record(p, &unique))) {
+ g_warning("Packet too short (3)");
+ return;
+ }
+
+ if (record->key->type != FLX_DNS_TYPE_ANY)
+ incoming_probe(s, record, i);
+
+ flx_record_unref(record);
+ }
+}
+
+static gboolean handle_conflict(flxServer *s, flxInterface *i, flxRecord *record, const flxAddress *a) {
+ gboolean valid = TRUE;
+ flxEntry *e, *n;
+ gchar *t;
+
+ g_assert(s);
+ g_assert(i);
+ g_assert(record);
+
+ t = flx_record_to_string(record);
+
+ for (e = g_hash_table_lookup(s->entries_by_key, record->key); e; e = n) {
+ n = e->by_key_next;
+
+ if (e->dead)
+ continue;
+
+ if (flx_entry_registered(s, e, i)) {
+
+ gboolean equal = flx_record_equal_no_ttl(record, e->record);
+
+ /* Check whether there is a unique record conflict */
+ if (!equal && (e->flags & FLX_ENTRY_UNIQUE)) {
+
+ /* The lexicographically later data wins. */
+ if (flx_record_lexicographical_compare(record, e->record) > 0) {
+ withdraw_entry(s, e);
+ g_message("Recieved conflicting record [%s]. Local host lost. Withdrawing.", t);
+ } else {
+ /* Tell the other host that our entry is lexicographically later */
+ valid = FALSE;
+ flx_interface_post_response(i, a, e->record, e->flags & FLX_ENTRY_UNIQUE, TRUE);
+ g_message("Recieved conflicting record [%s]. Local host won. Refreshing.", t);
+ }
+
+ /* Check wheter there is a TTL conflict */
+ } else if (equal && record->ttl <= e->record->ttl/2) {
+ /* Correct the TTL */
+ valid = FALSE;
+ flx_interface_post_response(i, a, e->record, e->flags & FLX_ENTRY_UNIQUE, TRUE);
+ g_message("Recieved record with bad TTL [%s]. Refreshing.", t);
+ }
+ }
+ }
+
+ g_free(t);
+
+ return valid;