diff options
Diffstat (limited to 'src/resolve/resolved-dns-scope.c')
-rw-r--r-- | src/resolve/resolved-dns-scope.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index a8c0ae1569..42478e41e2 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -158,12 +158,13 @@ void dns_scope_packet_lost(DnsScope *s, usec_t usec) { s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC); } -int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) { +int dns_scope_emit(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) { union in_addr_union addr; int ifindex = 0, r; int family; uint16_t port; uint32_t mtu; + size_t saved_size = 0; assert(s); assert(p); @@ -178,9 +179,19 @@ int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) { switch (s->protocol) { case DNS_PROTOCOL_DNS: + assert(server); + if (DNS_PACKET_QDCOUNT(p) > 1) return -EOPNOTSUPP; + if (server->possible_features >= DNS_SERVER_FEATURE_LEVEL_EDNS0) { + r = dns_packet_append_opt_rr(p, DNS_PACKET_UNICAST_SIZE_MAX, &saved_size); + if (r < 0) + return r; + + DNS_PACKET_HEADER(p)->arcount = htobe16(be16toh(DNS_PACKET_HEADER(p)->arcount) + 1); + } + if (p->size > DNS_PACKET_UNICAST_SIZE_MAX) return -EMSGSIZE; @@ -191,6 +202,12 @@ int dns_scope_emit(DnsScope *s, int fd, DnsPacket *p) { if (r < 0) return r; + if (saved_size > 0) { + dns_packet_truncate(p, saved_size); + + DNS_PACKET_HEADER(p)->arcount = htobe16(be16toh(DNS_PACKET_HEADER(p)->arcount) - 1); + } + break; case DNS_PROTOCOL_LLMNR: @@ -739,7 +756,7 @@ static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata return 0; } - r = dns_scope_emit(scope, -1, p); + r = dns_scope_emit(scope, -1, NULL, p); if (r < 0) log_debug_errno(r, "Failed to send conflict packet: %m"); } |