resolved: collect incoming fragment size when receiving UDP datagrams

We can later use this to adapt our announced EDNS buffer size in order
to avoid fragmentation to make the best of large datagrams while still
avoiding he security weaknesses of it.
This commit is contained in:
Lennart Poettering
2021-02-18 15:42:18 +01:00
parent eb170e75ab
commit 20a001bdd7
4 changed files with 18 additions and 1 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ struct DnsPacketHeader {
struct DnsPacket {
unsigned n_ref;
DnsProtocol protocol;
size_t size, allocated, rindex, max_size;
size_t size, allocated, rindex, max_size, fragsize;
void *_data; /* don't access directly, use DNS_PACKET_DATA()! */
Hashmap *names; /* For name compression */
size_t opt_start, opt_size;
+5
View File
@@ -415,6 +415,11 @@ static int dns_scope_socket(
r = socket_disable_pmtud(fd, sa.sa.sa_family);
if (r < 0)
log_debug_errno(r, "Failed to disable UDP PMTUD, ignoring: %m");
/* Learn about fragmentation taking place */
r = socket_set_recvfragsize(fd, sa.sa.sa_family, true);
if (r < 0)
log_debug_errno(r, "Failed to enable fragment size reception, ignoring: %m");
}
if (ret_socket_address)
+4
View File
@@ -1121,6 +1121,10 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
r = socket_disable_pmtud(fd, l->family);
if (r < 0)
log_debug_errno(r, "Failed to disable UDP PMTUD, ignoring: %m");
r = socket_set_recvfragsize(fd, l->family, true);
if (r < 0)
log_debug_errno(r, "Failed to enable fragment size reception, ignoring: %m");
}
if (bind(fd, &sa.sa, SOCKADDR_LEN(sa)) < 0) {
+8
View File
@@ -19,6 +19,7 @@
#include "idn-util.h"
#include "io-util.h"
#include "missing_network.h"
#include "missing_socket.h"
#include "netlink-util.h"
#include "ordered-set.h"
#include "parse-util.h"
@@ -881,6 +882,9 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
p->ttl = *(int *) CMSG_DATA(cmsg);
break;
case IPV6_RECVFRAGSIZE:
p->fragsize = *(int *) CMSG_DATA(cmsg);
break;
}
} else if (cmsg->cmsg_level == IPPROTO_IP) {
assert(p->family == AF_INET);
@@ -900,6 +904,10 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
case IP_TTL:
p->ttl = *(int *) CMSG_DATA(cmsg);
break;
case IP_RECVFRAGSIZE:
p->fragsize = *(int *) CMSG_DATA(cmsg);
break;
}
}
}