@@ -2535,6 +2535,10 @@ static int dns_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
|
||||
|
||||
DEFINE_HASH_OPS(dns_packet_hash_ops, DnsPacket, dns_packet_hash_func, dns_packet_compare_func);
|
||||
|
||||
bool dns_packet_equal(const DnsPacket *a, const DnsPacket *b) {
|
||||
return dns_packet_compare_func(a, b) == 0;
|
||||
}
|
||||
|
||||
static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
|
||||
[DNS_RCODE_SUCCESS] = "SUCCESS",
|
||||
[DNS_RCODE_FORMERR] = "FORMERR",
|
||||
|
||||
@@ -227,6 +227,8 @@ void dns_packet_rewind(DnsPacket *p, size_t idx);
|
||||
int dns_packet_skip_question(DnsPacket *p);
|
||||
int dns_packet_extract(DnsPacket *p);
|
||||
|
||||
bool dns_packet_equal(const DnsPacket *a, const DnsPacket *b);
|
||||
|
||||
/* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 */
|
||||
enum {
|
||||
DNS_RCODE_SUCCESS = 0,
|
||||
|
||||
@@ -688,6 +688,11 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager_packet_from_our_transaction(m, p)) {
|
||||
log_debug("Got our own packet looped back, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
r = dns_packet_extract(p);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
|
||||
|
||||
@@ -1264,6 +1264,22 @@ bool manager_packet_from_local_address(Manager *m, DnsPacket *p) {
|
||||
return !!manager_find_link_address(m, p->family, &p->sender);
|
||||
}
|
||||
|
||||
bool manager_packet_from_our_transaction(Manager *m, DnsPacket *p) {
|
||||
DnsTransaction *t;
|
||||
|
||||
assert(m);
|
||||
assert(p);
|
||||
|
||||
/* Let's see if we have a transaction with a query message with the exact same binary contents as the
|
||||
* one we just got. If so, it's almost definitely a packet loop of some kind. */
|
||||
|
||||
t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
|
||||
if (!t)
|
||||
return false;
|
||||
|
||||
return t->sent && dns_packet_equal(t->sent, p);
|
||||
}
|
||||
|
||||
DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
|
||||
Link *l;
|
||||
|
||||
|
||||
@@ -166,6 +166,8 @@ void manager_refresh_rrs(Manager *m);
|
||||
int manager_next_hostname(Manager *m);
|
||||
|
||||
bool manager_packet_from_local_address(Manager *m, DnsPacket *p);
|
||||
bool manager_packet_from_our_transaction(Manager *m, DnsPacket *p);
|
||||
|
||||
DnsScope* manager_find_scope(Manager *m, DnsPacket *p);
|
||||
|
||||
void manager_verify_all(Manager *m);
|
||||
|
||||
Reference in New Issue
Block a user