resolved: split out check whether reply matches our question

It's complicated enough, it deserves its own call.

(Also contains some unrelated whitespace, comment and assertion changes)
This commit is contained in:
Lennart Poettering 2015-12-09 17:49:05 +01:00
parent 8b5b564947
commit 8af5b88322
3 changed files with 40 additions and 7 deletions

View File

@ -2021,6 +2021,30 @@ finish:
return r;
}
int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
int r;
assert(p);
assert(key);
/* Checks if the specified packet is a reply for the specified
* key and the specified key is the only one in the question
* section. */
if (DNS_PACKET_QR(p) != 1)
return 0;
/* Let's unpack the packet, if that hasn't happened yet. */
r = dns_packet_extract(p);
if (r < 0)
return r;
if (p->question->n_keys != 1)
return 0;
return dns_resource_key_equal(p->question->keys[0], key);
}
static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
[DNS_RCODE_SUCCESS] = "SUCCESS",
[DNS_RCODE_FORMERR] = "FORMERR",

View File

@ -161,6 +161,8 @@ int dns_packet_validate(DnsPacket *p);
int dns_packet_validate_reply(DnsPacket *p);
int dns_packet_validate_query(DnsPacket *p);
int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key);
int dns_packet_append_blob(DnsPacket *p, const void *d, size_t sz, size_t *start);
int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start);
int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start);

View File

@ -428,12 +428,13 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
switch (t->scope->protocol) {
case DNS_PROTOCOL_DNS:
assert(t->server);
if (IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
/* request failed, immediately try again with reduced features */
/* Request failed, immediately try again with reduced features */
log_debug("Server returned error: %s", dns_rcode_to_string(DNS_PACKET_RCODE(p)));
dns_server_packet_failed(t->server, t->current_features);
@ -449,13 +450,14 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
dns_server_packet_received(t->server, t->current_features, ts - t->start_usec, p->size);
break;
case DNS_PROTOCOL_LLMNR:
case DNS_PROTOCOL_MDNS:
dns_scope_packet_received(t->scope, ts - t->start_usec);
break;
break;
default:
break;
assert_not_reached("Invalid DNS protocol.");
}
if (DNS_PACKET_TC(p)) {
@ -474,7 +476,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
return;
}
if (r < 0) {
/* On LLMNR and mDNS, if we cannot connect to the host,
/* On LLMNR, if we cannot connect to the host,
* we immediately give up */
if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
@ -494,7 +496,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
}
}
/* Parse and update the cache */
/* Parse message, if it isn't parsed yet. */
r = dns_packet_extract(p);
if (r < 0) {
dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
@ -503,7 +505,12 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
if (t->scope->protocol == DNS_PROTOCOL_DNS) {
/* Only consider responses with equivalent query section to the request */
if (p->question->n_keys != 1 || dns_resource_key_equal(p->question->keys[0], t->key) <= 0) {
r = dns_packet_is_reply_for(p, t->key);
if (r < 0) {
dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
return;
}
if (r == 0) {
dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
return;
}
@ -549,7 +556,7 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use
DNS_PACKET_ID(p) == t->id)
dns_transaction_process_reply(t, p);
else
log_debug("Invalid DNS packet.");
log_debug("Invalid DNS packet, ignoring.");
return 0;
}