chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
76f468c
)
resolved: properly handle MTU logic
author
Lennart Poettering
<lennart@poettering.net>
Wed, 16 Jul 2014 23:13:22 +0000
(
01:13
+0200)
committer
Lennart Poettering
<lennart@poettering.net>
Wed, 16 Jul 2014 23:41:52 +0000
(
01:41
+0200)
src/resolve/resolved-dns-packet.h
patch
|
blob
|
history
src/resolve/resolved-dns-scope.c
patch
|
blob
|
history
src/resolve/resolved-link.c
patch
|
blob
|
history
src/resolve/resolved-link.h
patch
|
blob
|
history
src/resolve/resolved-manager.c
patch
|
blob
|
history
src/resolve/resolved.h
patch
|
blob
|
history
diff --git
a/src/resolve/resolved-dns-packet.h
b/src/resolve/resolved-dns-packet.h
index 99f60a15569526c2c9024279170c2e516e2b1647..de3a789a783eb8abd483232f7b00e0d209afaebf 100644
(file)
--- a/
src/resolve/resolved-dns-packet.h
+++ b/
src/resolve/resolved-dns-packet.h
@@
-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
/* 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
#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 {
#define DNS_PACKET_SIZE_START 512
struct DnsPacket {
diff --git
a/src/resolve/resolved-dns-scope.c
b/src/resolve/resolved-dns-scope.c
index 0a70cb1f0f6486ff9e79fcc91069d305b09cb0e0..a39e705a3ba60c39df5d30bf13d3beab231fc6f5 100644
(file)
--- a/
src/resolve/resolved-dns-scope.c
+++ b/
src/resolve/resolved-dns-scope.c
@@
-102,8
+102,19
@@
int dns_scope_send(DnsScope *s, DnsPacket *p) {
return -EMSGSIZE;
ifindex = s->link->ifindex;
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 (srv->family == AF_INET)
r = manager_dns_ipv4_send(s->manager, srv, ifindex, p);
else if (srv->family == AF_INET6)
diff --git
a/src/resolve/resolved-link.c
b/src/resolve/resolved-link.c
index 9c886a26b5a4ee480813bb2d19105bcbab2e8b85..61b112cb05091213553cf95919c1f1211e341701 100644
(file)
--- a/
src/resolve/resolved-link.c
+++ b/
src/resolve/resolved-link.c
@@
-91,6
+91,10
@@
int link_update_rtnl(Link *l, sd_rtnl_message *m) {
if (r < 0)
return r;
if (r < 0)
return r;
+ r = sd_rtnl_message_read_u32(m, IFLA_MTU, &l->mtu);
+ if (r < 0)
+ return r;
+
return 0;
}
return 0;
}
diff --git
a/src/resolve/resolved-link.h
b/src/resolve/resolved-link.h
index 07f68ab41ca0c86d3aca0deb7c84d227216b5509..c0ea2362abb39ef01325867b4510375aceee6849 100644
(file)
--- a/
src/resolve/resolved-link.h
+++ b/
src/resolve/resolved-link.h
@@
-58,7
+58,7
@@
struct Link {
DnsScope *mdns_ipv4_scope;
DnsScope *mdns_ipv6_scope;
DnsScope *mdns_ipv4_scope;
DnsScope *mdns_ipv6_scope;
-
size
_t mtu;
+
uint32
_t mtu;
char *operational_state;
char *operational_state;
diff --git
a/src/resolve/resolved-manager.c
b/src/resolve/resolved-manager.c
index 5fbb500fd0530dd57c2ab73a79c9d15b02a0cf0e..fed9a7797359020bb2c30d62289a7a494f257637 100644
(file)
--- a/
src/resolve/resolved-manager.c
+++ b/
src/resolve/resolved-manager.c
@@
-878,3
+878,23
@@
void manager_next_dns_server(Manager *m) {
m->current_dns_server = m->dns_servers;
}
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;
+}
diff --git
a/src/resolve/resolved.h
b/src/resolve/resolved.h
index 438730be6e3c7df6c4e86e715af1baf1b60c824a..c592a7e8335cba2edbccaf9cf1d8a8000bb05b8c 100644
(file)
--- a/
src/resolve/resolved.h
+++ b/
src/resolve/resolved.h
@@
-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);
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);
int manager_dns_ipv4_fd(Manager *m);
int manager_dns_ipv4_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p);