]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: packet - ensure there is space for IP+UDP headers
authorTom Gundersen <teg@jklm.no>
Wed, 24 Jun 2015 19:22:46 +0000 (21:22 +0200)
committerTom Gundersen <teg@jklm.no>
Tue, 14 Jul 2015 10:03:04 +0000 (12:03 +0200)
Currently we only make sure our links can handle the size of the payload witohut
taking the headers into account.

src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-scope.c

index fa0516f8a0c3235f84322c98dc49825003ae6f98..a9cc5ca6aa5113e8a286257f8290af8af50b55d2 100644 (file)
@@ -32,10 +32,10 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
 
         assert(ret);
 
-        if (mtu <= 0)
+        if (mtu <= UDP_PACKET_HEADER_SIZE)
                 a = DNS_PACKET_SIZE_START;
         else
-                a = mtu;
+                a = mtu - UDP_PACKET_HEADER_SIZE;
 
         if (a < DNS_PACKET_HEADER_SIZE)
                 a = DNS_PACKET_HEADER_SIZE;
index bf998aa84ea9b764d682878e1ab112c3b408bb29..6588ed9df52b9d4c051a1437cbaa9f31a6e091a6 100644 (file)
@@ -21,6 +21,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
  ***/
 
+#include <netinet/udp.h>
+#include <netinet/ip.h>
 
 #include "macro.h"
 #include "sparse-endian.h"
@@ -53,6 +55,7 @@ struct DnsPacketHeader {
 };
 
 #define DNS_PACKET_HEADER_SIZE sizeof(DnsPacketHeader)
+#define UDP_PACKET_HEADER_SIZE (sizeof(struct iphdr) + sizeof(struct udphdr))
 
 /* 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
index 25392d21d71600e4bdfc1ed69c7ed7382b6406c7..e01e97be354518b1faa7d519fc754cfc5181394b 100644 (file)
@@ -160,7 +160,7 @@ int dns_scope_emit(DnsScope *s, DnsPacket *p) {
                 if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
                         return -EMSGSIZE;
 
-                if (p->size > mtu)
+                if (p->size + UDP_PACKET_HEADER_SIZE > mtu)
                         return -EMSGSIZE;
 
                 if (family == AF_INET)