/* The various DNS protocols deviate in how large a packet can grow,
but the TCP transport has a 16bit size field, hence that appears to
- be the maximum. */
+ be the absolute maximum. */
#define DNS_PACKET_SIZE_MAX 0xFFFF
+
+/* RFC 1035 say 512 is the maximum, for classic unicast DNS */
+#define DNS_PACKET_UNICAST_SIZE_MAX 512
+
#define DNS_PACKET_SIZE_START 512
struct DnsPacket {
return -EMSGSIZE;
ifindex = s->link->ifindex;
+ } else {
+ uint32_t mtu;
+
+ mtu = manager_find_mtu(s->manager);
+ if (mtu > 0) {
+ if (p->size > mtu)
+ return -EMSGSIZE;
+ }
}
+ if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
+ return -EMSGSIZE;
+
if (srv->family == AF_INET)
r = manager_dns_ipv4_send(s->manager, srv, ifindex, p);
else if (srv->family == AF_INET6)
if (r < 0)
return r;
+ r = sd_rtnl_message_read_u32(m, IFLA_MTU, &l->mtu);
+ if (r < 0)
+ return r;
+
return 0;
}
DnsScope *mdns_ipv4_scope;
DnsScope *mdns_ipv6_scope;
- size_t mtu;
+ uint32_t mtu;
char *operational_state;
m->current_dns_server = m->dns_servers;
}
+
+uint32_t manager_find_mtu(Manager *m) {
+ uint32_t mtu = 0;
+ Link *l;
+ Iterator i;
+
+ /* If we don't know on which link a DNS packet would be
+ * delivered, let's find the largest MTU that works on all
+ * interfaces we know of */
+
+ HASHMAP_FOREACH(l, m->links, i) {
+ if (l->mtu <= 0)
+ continue;
+
+ if (mtu <= 0 || l->mtu < mtu)
+ mtu = l->mtu;
+ }
+
+ return mtu;
+}
DnsServer* manager_find_dns_server(Manager *m, unsigned char family, union in_addr_union *in_addr);
DnsServer *manager_get_dns_server(Manager *m);
void manager_next_dns_server(Manager *m);
+uint32_t manager_find_mtu(Manager *m);
int manager_dns_ipv4_fd(Manager *m);
int manager_dns_ipv4_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p);