]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-scope.c
resolved: rework OPT RR generation logic
[thirdparty/systemd.git] / src / resolve / resolved-dns-scope.c
index b29f15d2c0982b1a66564c6ad497bad34dfb9c03..13be2a3792e37dc4ae98c3d666ad714286bf149f 100644 (file)
@@ -162,17 +162,15 @@ void dns_scope_packet_lost(DnsScope *s, usec_t usec) {
                 s->resend_timeout = MIN(s->resend_timeout * 2, MULTICAST_RESEND_TIMEOUT_MAX_USEC);
 }
 
-static int dns_scope_emit_one(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
+static int dns_scope_emit_one(DnsScope *s, int fd, DnsPacket *p) {
         union in_addr_union addr;
         int ifindex = 0, r;
         int family;
         uint32_t mtu;
-        size_t saved_size = 0;
 
         assert(s);
         assert(p);
         assert(p->protocol == s->protocol);
-        assert((s->protocol == DNS_PROTOCOL_DNS) != (fd < 0));
 
         if (s->link) {
                 mtu = s->link->mtu;
@@ -181,30 +179,13 @@ static int dns_scope_emit_one(DnsScope *s, int fd, DnsServer *server, DnsPacket
                 mtu = manager_find_mtu(s->manager);
 
         switch (s->protocol) {
+
         case DNS_PROTOCOL_DNS:
-                assert(server);
+                assert(fd >= 0);
 
                 if (DNS_PACKET_QDCOUNT(p) > 1)
                         return -EOPNOTSUPP;
 
-                if (server->possible_features >= DNS_SERVER_FEATURE_LEVEL_EDNS0) {
-                        bool edns_do;
-                        size_t packet_size;
-
-                        edns_do = server->possible_features >= DNS_SERVER_FEATURE_LEVEL_DO;
-
-                        if (server->possible_features >= DNS_SERVER_FEATURE_LEVEL_LARGE)
-                                packet_size = DNS_PACKET_UNICAST_SIZE_LARGE_MAX;
-                        else
-                                packet_size = server->received_udp_packet_max;
-
-                        r = dns_packet_append_opt_rr(p, packet_size, edns_do, &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;
 
@@ -215,15 +196,11 @@ static int dns_scope_emit_one(DnsScope *s, int fd, DnsServer *server, DnsPacket
                 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:
+                assert(fd < 0);
+
                 if (DNS_PACKET_QDCOUNT(p) > 1)
                         return -EOPNOTSUPP;
 
@@ -250,6 +227,8 @@ static int dns_scope_emit_one(DnsScope *s, int fd, DnsServer *server, DnsPacket
                 break;
 
         case DNS_PROTOCOL_MDNS:
+                assert(fd < 0);
+
                 if (!ratelimit_test(&s->ratelimit))
                         return -EBUSY;
 
@@ -279,13 +258,13 @@ static int dns_scope_emit_one(DnsScope *s, int fd, DnsServer *server, DnsPacket
         return 1;
 }
 
-int dns_scope_emit_udp(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
+int dns_scope_emit_udp(DnsScope *s, int fd, DnsPacket *p) {
         int r;
 
         assert(s);
         assert(p);
         assert(p->protocol == s->protocol);
-        assert((s->protocol == DNS_PROTOCOL_DNS) != (fd < 0));
+        assert((s->protocol == DNS_PROTOCOL_DNS) == (fd >= 0));
 
         do {
                 /* If there are multiple linked packets, set the TC bit in all but the last of them */
@@ -294,18 +273,24 @@ int dns_scope_emit_udp(DnsScope *s, int fd, DnsServer *server, DnsPacket *p) {
                         dns_packet_set_flags(p, true, true);
                 }
 
-                r = dns_scope_emit_one(s, fd, server, p);
+                r = dns_scope_emit_one(s, fd, p);
                 if (r < 0)
                         return r;
 
                 p = p->more;
-        } while(p);
+        } while (p);
 
         return 0;
 }
 
-static int dns_scope_socket(DnsScope *s, int type, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
-        DnsServer *srv = NULL;
+static int dns_scope_socket(
+                DnsScope *s,
+                int type,
+                int family,
+                const union in_addr_union *address,
+                DnsServer *server,
+                uint16_t port) {
+
         _cleanup_close_ int fd = -1;
         union sockaddr_union sa = {};
         socklen_t salen;
@@ -313,32 +298,27 @@ static int dns_scope_socket(DnsScope *s, int type, int family, const union in_ad
         int ret, r;
 
         assert(s);
-        assert((family == AF_UNSPEC) == !address);
-
-        if (family == AF_UNSPEC) {
-                srv = dns_scope_get_dns_server(s);
-                if (!srv)
-                        return -ESRCH;
-
-                /* Determine current feature level to use */
-                (void) dns_server_possible_features(srv);
 
-                if (type == SOCK_DGRAM && srv->possible_features < DNS_SERVER_FEATURE_LEVEL_UDP)
-                        return -EAGAIN;
+        if (server) {
+                assert(family == AF_UNSPEC);
+                assert(!address);
 
-                sa.sa.sa_family = srv->family;
-                if (srv->family == AF_INET) {
+                sa.sa.sa_family = server->family;
+                if (server->family == AF_INET) {
                         sa.in.sin_port = htobe16(port);
-                        sa.in.sin_addr = srv->address.in;
+                        sa.in.sin_addr = server->address.in;
                         salen = sizeof(sa.in);
-                } else if (srv->family == AF_INET6) {
+                } else if (server->family == AF_INET6) {
                         sa.in6.sin6_port = htobe16(port);
-                        sa.in6.sin6_addr = srv->address.in6;
+                        sa.in6.sin6_addr = server->address.in6;
                         sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
                         salen = sizeof(sa.in6);
                 } else
                         return -EAFNOSUPPORT;
         } else {
+                assert(family != AF_UNSPEC);
+                assert(address);
+
                 sa.sa.sa_family = family;
 
                 if (family == AF_INET) {
@@ -396,21 +376,18 @@ static int dns_scope_socket(DnsScope *s, int type, int family, const union in_ad
         if (r < 0 && errno != EINPROGRESS)
                 return -errno;
 
-        if (server)
-                *server = srv;
-
         ret = fd;
         fd = -1;
 
         return ret;
 }
 
-int dns_scope_socket_udp(DnsScope *s, DnsServer **server) {
-        return dns_scope_socket(s, SOCK_DGRAM, AF_UNSPEC, NULL, 53, server);
+int dns_scope_socket_udp(DnsScope *s, DnsServer *server, uint16_t port) {
+        return dns_scope_socket(s, SOCK_DGRAM, AF_UNSPEC, NULL, server, port);
 }
 
-int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *address, uint16_t port, DnsServer **server) {
-        return dns_scope_socket(s, SOCK_STREAM, family, address, port, server);
+int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *address, DnsServer *server, uint16_t port) {
+        return dns_scope_socket(s, SOCK_STREAM, family, address, server, port);
 }
 
 DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
@@ -869,7 +846,7 @@ static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata
                         return 0;
                 }
 
-                r = dns_scope_emit_udp(scope, -1, NULL, p);
+                r = dns_scope_emit_udp(scope, -1, p);
                 if (r < 0)
                         log_debug_errno(r, "Failed to send conflict packet: %m");
         }