Skip to content

Sending dynamic updates that would result in the message being bigger than 65535 silently truncates records #356

@MMauro94

Description

@MMauro94

Hello.

Sorry for opening another issue. This ties up with #355 but it's a separate issue so I opened a new one to make tracking easier and to avoid mixing up the two.

The problem here is that trying to send a dynamic update where the wire message would be bigger than the maximum DNS message length of 65535 results in DNSJava silently truncating the records and sending a partial update.

This is because the toWire(Message.MAXLENGTH) call here will just truncate the recrods and set the truncated flag. I believe that's implemented for UDP splitting, but when the overall message is bigger than the maxiumum allowed by a DNS message the library should fail instead of proceeding with a partial update without any warning.

A small repro, again in Kotlin, that shows that only part of the records get sent and no exception is thrown:

import org.xbill.DNS.DClass
import org.xbill.DNS.Message
import org.xbill.DNS.Name
import org.xbill.DNS.SimpleResolver
import org.xbill.DNS.TXTRecord
import org.xbill.DNS.Update
import org.xbill.DNS.io.IoClientFactory
import org.xbill.DNS.io.TcpIoClient
import org.xbill.DNS.io.UdpIoClient
import java.util.UUID
import java.util.concurrent.CompletableFuture


fun main() {
    val update = Update(Name.fromConstantString("zone.example.com."))

    repeat(2000) { i ->
        val record = TXTRecord(
            Name.fromConstantString("name-$i.zone.example.com."),
            DClass.IN,
            900,
            UUID.randomUUID().toString(),
        )
        update.add(record)
    }

    val resolver = SimpleResolver().apply {
        ioClientFactory = object : IoClientFactory {
            override fun createOrGetTcpClient(): TcpIoClient {
                return TcpIoClient { local, remote, query, data, timeout ->
                    println("Message that is being sent: ")
                    println(Message(data).toString())
                    CompletableFuture.failedFuture(Exception())
                }
            }

            override fun createOrGetUdpClient(): UdpIoClient {
                TODO("Not yet implemented")
            }
        }
    }

    resolver.send(update)
}

This outputs:

Message that is being sent: 
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 36069
;; flags: tc ; qd: 1 an: 0 au: 1128 ad: 1 

;; OPT PSEUDOSECTION: 
; EDNS: version: 0; flags: ; udp: 1280
;; ZONE:
;;	zone.example.com., type = SOA, class = IN

;; PREREQUISITES:

;; UPDATE RECORDS:
name-0.zone.example.com.	900	IN	TXT	"2a1892e9-95fd-4789-899d-ea5a052fb1eb"
name-1.zone.example.com.	900	IN	TXT	"7161836a-cf67-422f-bd2e-546cd8a1b378"
name-2.zone.example.com.	900	IN	TXT	"79cacbf4-bcff-42d2-9ec4-86d2698e4988"
name-3.zone.example.com.	900	IN	TXT	"e07ce27b-acf6-4ff6-948b-cd58dc824f56"
name-4.zone.example.com.	900	IN	TXT	"adf275c8-df1b-4eaa-8199-c3f15726d860"
name-5.zone.example.com.	900	IN	TXT	"54ae5c0f-17ab-4bce-b523-362edf567b52"
name-6.zone.example.com.	900	IN	TXT	"f9285803-e636-401d-a6ec-40c8250b47e1"
name-7.zone.example.com.	900	IN	TXT	"13aac9c1-79ca-42cd-ba83-77b914567670"
name-8.zone.example.com.	900	IN	TXT	"e8691f96-b67d-4fbb-99ed-51e9338f0408"
name-9.zone.example.com.	900	IN	TXT	"4abed64a-5fbc-40d5-a1dc-e89668ea351f"
name-10.zone.example.com.	900	IN	TXT	"34c527da-5a9a-4f95-a0a3-47a7930dad7e"
name-11.zone.example.com.	900	IN	TXT	"1c109b42-5c42-47cd-bee9-76e43a37b070"
name-12.zone.example.com.	900	IN	TXT	"a5a8a812-2cc6-4db6-8575-fac0c8f8b855"
name-13.zone.example.com.	900	IN	TXT	"3c72bcd0-27de-4382-aafb-38e109c0a67e"
name-14.zone.example.com.	900	IN	TXT	"0949a8c0-65bf-492d-8a58-ea78aa5f91ed"
...
...
name-1117.zone.example.com.	900	IN	TXT	"cc7ae8ff-452c-467e-98cc-be8bc837a0bf"
name-1118.zone.example.com.	900	IN	TXT	"e75ab8c1-7587-4abb-a4c3-65b793c07bbf"
name-1119.zone.example.com.	900	IN	TXT	"a7a5d528-90ea-4289-bcb8-8f4e115ad8ff"
name-1120.zone.example.com.	900	IN	TXT	"e4401d39-fafc-45c0-ab09-f24bcd4ad7ef"
name-1121.zone.example.com.	900	IN	TXT	"516b0a76-91f8-46d6-b8f2-6c8b36fd43a8"
name-1122.zone.example.com.	900	IN	TXT	"f335078c-9854-4189-8676-5cb3f3401cfa"
name-1123.zone.example.com.	900	IN	TXT	"13ef419f-1d67-4e74-bf35-9e5af49b81ef"
name-1124.zone.example.com.	900	IN	TXT	"3840537f-3392-4d33-8205-0422efe7a07e"
name-1125.zone.example.com.	900	IN	TXT	"827a28a8-1868-4df2-8e34-423305c08229"
name-1126.zone.example.com.	900	IN	TXT	"2236796c-6eae-4c30-9295-f89fa02d65f9"
name-1127.zone.example.com.	900	IN	TXT	"ac49da35-d9c9-4b7c-b16e-059c23493306"

;; ADDITIONAL RECORDS:


;; Message size: 65487 bytes

As you can see all records from 1128 to 1999 are silently missing from the update.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions