mirror of
https://github.com/systemd/systemd.git
synced 2024-10-31 16:21:26 +03:00
resolved: properly handle MTU logic
This commit is contained in:
parent
76f468c8ea
commit
e1c959948c
@ -44,8 +44,12 @@ struct DnsPacketHeader {
|
||||
|
||||
/* 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 {
|
||||
|
@ -102,8 +102,19 @@ int dns_scope_send(DnsScope *s, DnsPacket *p) {
|
||||
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)
|
||||
|
@ -91,6 +91,10 @@ int link_update_rtnl(Link *l, sd_rtnl_message *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_rtnl_message_read_u32(m, IFLA_MTU, &l->mtu);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ struct Link {
|
||||
DnsScope *mdns_ipv4_scope;
|
||||
DnsScope *mdns_ipv6_scope;
|
||||
|
||||
size_t mtu;
|
||||
uint32_t mtu;
|
||||
|
||||
char *operational_state;
|
||||
|
||||
|
@ -878,3 +878,23 @@ void manager_next_dns_server(Manager *m) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ int manager_write_resolv_conf(Manager *m);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user