Coder Social home page Coder Social logo

Received length loss about mdns-sd HOT 21 CLOSED

keepsimple1 avatar keepsimple1 commented on August 16, 2024
Received length loss

from mdns-sd.

Comments (21)

wfeii1980 avatar wfeii1980 commented on August 16, 2024

buf.set_len(sz) is unsafe
buf.truncate(sz) is ok

from mdns-sd.

wfeii1980 avatar wfeii1980 commented on August 16, 2024

Two panic!

        for _ in 0..n {
            let name = self.read_name()?;
            let slice = &self.data[self.offset..];
            // ***************** slice.len() < 10
            let ty = u16_from_be_slice(&slice[..2]);
            let class = u16_from_be_slice(&slice[2..4]);
            let ttl = u32_from_be_slice(&slice[4..8]);
            let length = u16_from_be_slice(&slice[8..10]) as usize;
            self.offset += 10;
            let next_offset = self.offset + length;
            // Check the first 2 bits for possible "Message compression".
            match length & 0xC0 {
                0x00 => {
                    // regular utf8 string with length
                    offset += 1;
                    // **************** (offset + length as usize) > data.len()
                    name += str::from_utf8(&data[offset..(offset + length as usize)])
                        .map_err(|e| Error::Msg(format!("read_name: from_utf8: {}", e)))?;
                    name += ".";
                    offset += length as usize;
                }

from mdns-sd.

wfeii1980 avatar wfeii1980 commented on August 16, 2024

In my environment, MDNS has a relatively large amount of data, and the problem of data loss is often caused by the read cache being full. So it also causes the above problems.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

buf.set_len(sz) is unsafe buf.truncate(sz) is ok

I couldn't remember why we didn't truncate the buffer after the read. One possible reason is DnsIncoming decoding the buffer does not require the truncate (The decoding relies on the message format). But anyhow we can add buf.truncate(sz).

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

// ***************** slice.len() < 10

I think it's a good idea to add a check for the slice length and return Err if fails.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

// **************** (offset + length as usize) > data.len()

Same here, I agree it's good to check the length here.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

In my environment, MDNS has a relatively large amount of data, and the problem of data loss is often caused by the read cache being full. So it also causes the above problems.

What the typical and max size of your mDNS message? Did you mean the mDNS message in your env. is larger than MAX_MSG_ABSOLUTE i.e. 8966 bytes? The RFC says a Multicast DNS packet, including IP and UDP headers, MUST NOT exceed 9000 bytes (here).

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

For the sanity checks, I've opened a PR to add them. Let me know if you have any questions or comments.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

PR merged. Let me know if you have any questions.

from mdns-sd.

wfeii1980 avatar wfeii1980 commented on August 16, 2024

In my environment, MDNS has a relatively large amount of data, and the problem of data loss is often caused by the read cache being full. So it also causes the above problems.

What the typical and max size of your mDNS message? Did you mean the mDNS message in your env. is larger than MAX_MSG_ABSOLUTE i.e. 8966 bytes? The RFC says a Multicast DNS packet, including IP and UDP headers, MUST NOT exceed 9000 bytes (here).

I did receive an oversized package, if it's illegal, then ignore it.

mdns-big.zip

from mdns-sd.

wfeii1980 avatar wfeii1980 commented on August 16, 2024

PR merged. Let me know if you have any questions.

Good!

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

In my environment, MDNS has a relatively large amount of data, and the problem of data loss is often caused by the read cache being full. So it also causes the above problems.

What the typical and max size of your mDNS message? Did you mean the mDNS message in your env. is larger than MAX_MSG_ABSOLUTE i.e. 8966 bytes? The RFC says a Multicast DNS packet, including IP and UDP headers, MUST NOT exceed 9000 bytes (here).

I did receive an oversized package, if it's illegal, then ignore it.

mdns-big.zip

According to WireShark, the packet size is 1030 bytes, far from the max size (8966 bytes). I didn't see obvious problems here. Let me know if you encountered any particular issues.

mdns-sd-wireshark-2024-02-04

from mdns-sd.

wfeii1980 avatar wfeii1980 commented on August 16, 2024

All 11 frames form one package.

wireshark-mdns-big

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

Oh I missed that, sorry. It is a fragmented IP packet. We don't support fragmented IP packets yet. This would be a new feature and it will take some time to implement if I would do it. Would you be interested in creating a PR to add this new feature to support IP fragments?

from mdns-sd.

dalepsmith avatar dalepsmith commented on August 16, 2024

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

Regarding IP fragmentation, it seems that UDP packet received by the socket should already be reassembled, if no dropped packets. From ChatGPT:
In summary, IP handles fragmentation and reassembly, and this applies to both TCP and UDP traffic. UDP itself, being a simple and connectionless protocol, doesn't have built-in mechanisms for handling fragmentation or reassembly.
That means we need not (and should not) have special logic to handle IP fragments.

And as what Dale mentioned :

Basically, an mdns datagram can not be larger than 9000 even when
fragmented into multiple UDP packets. And also can not contain more
than one resource record.

We should be good with the current max size (around 9000). For any large RR (resource record), it should be sent in a separate mDNS datagram.

Looking back at your capture, it seems that all 377 RRs are sent in a single datagram of 15794 bytes, which conflicts the RFC recommendation.

mdns-wireshark-large

from mdns-sd.

dalepsmith avatar dalepsmith commented on August 16, 2024

from mdns-sd.

wfeii1980 avatar wfeii1980 commented on August 16, 2024

I'm curious what is generating that huge datagram! Is that Bonjour or Avahi? Some other library? Something homebrewed? What kind of device is sending that? Thanks! -Dale

I guess it comes from the jmdns package used by my colleague, but I haven't personally verified it yet.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

I don't think we need to support such datagram that is clearly outside of the RFC. On the other hand, I will think of how we can handle such cases more gracefully.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

I had to re-learn some details about UDP socket API. Here is a related info about the recv/recv_from API on Linux:

If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from.

and in the classic book "TCP/IP Illustrated, volume 1", chapter 11, section 11.10 Maximum UDP Datagram Size, it says this about "Datagram Truncation":

What happens if the received datagram exceeds the size the application is prepared to deal with? Unfortunately the answer depends on the programming interface and the implementation.

It then says the sockets API under SVR4 Unix does not truncate the datagram.

Based on the above, I think there is no much more we can do (or should do) besides the sanity checks in the current code.

If a mDNS datagram happens to exceed the max buffer size, it will not be decoded correctly / fully. And if there is no truncation, the follow-up read will have invalid headers, etc, and will fail the decode process with an Err return. As long as there is no crash, I think we are good.

from mdns-sd.

keepsimple1 avatar keepsimple1 commented on August 16, 2024

I've merged in the minor change of MAX_MSG_ABSOLUTE and added comments. Will close this issue. If you have any additional questions, please re-open this issue or open a new issue. Cheers!

from mdns-sd.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.