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:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user