Kaleb Blue
Kaleb Blue

Reputation: 507

How to measure packets Maximum transmission unit (MTU) received from server when reading multicast

I am a newbie and tyring my hands on some network programming. I am reading data via multicast(see code below) and want to find the Maximum transmission unit(MTU) or the transmission unit that I can read. Can anyone direct me to a source or a way to do this. Thank you.

  try {
        InetAddress add = InetAddress.getByName("127.0.0.1");

        MulticastSocket socket = new MulticastSocket(1234);
        socket.joinGroup(add);

        byte[] bb = new byte[2500];

        while (true) {

            DatagramPacket data = new DatagramPacket(bb, bb.length);
            datagramSocket.receive(data);
            processDataReceived(bb);
        }

        datagramSocket.leaveGroup(socket);
    }
    catch (IOException e) {
        e.printStackTrace();
    }

Upvotes: 1

Views: 1792

Answers (3)

Falkreon
Falkreon

Reputation: 598

What are MTUs

Maximum Transmission Units are the maximum size of a packet that will definitely not be fragmented across the entire path it travels. Note that as flakes mentions, this fragmentation will generally happen transparently, even over UDP! So your packets will probably arrive safely reassembled, even if you fairly significantly exceed your path MTU.

So MTUs are mostly a tool to lower the overhead of transmitting for intermediate nodes, and possibly lowering the latency incurred from holding packets back for their slowest piece for reassembly.

How to find MTUs, in general

RFC 4821 is a really good synopsis of this process.

In short: Send an ICMP ping with a "do-not-fragment" flag and some junk padding data. Listen for an ICMP "packet too big" message. If you get the ping reply, resend with a larger ping packet. If you get a "packet too big", resend with a smaller ping. In this way you can kind of binary-search towards your actual MTU.

Unfortunately, because this is multicast...

Section 5.4 of RFC 4821 says,

In the case of a multicast destination address, copies of a packet may traverse many different paths to reach many different nodes. The local representation of the "path" to a multicast destination must in fact represent a potentially large set of paths.

Minimally, an implementation MAY maintain a single MTU value to be used for all multicast packets originated from the node. This MTU SHOULD be sufficiently small that it is expected to be less than the Path MTU of all paths comprising the multicast tree. If a Path MTU of less than the configured multicast MTU is learned via unicast means, the multicast MTU MAY be reduced to this value. This approach is likely to result in the use of smaller packets than is necessary for many paths.

If the application using multicast gets complete delivery reports (unlikely since this requirement has poor scaling properties), PLPMTUD MAY be implemented in multicast protocols such that the smallest path MTU learned across a group becomes the effective MTU for that group.

So it's probably not very feasible to find an MTU for multicast users.

Unfortunately, because this is Java...

Java does not support ICMP. At all. And it's not really possible to do this over UDP - due to the transparent reassembly, we never know when fragmentation has happened.

So we have two options

  • Don't worry too much about packet fragmentation, but declare a contract for the receivers' buffer sizes. With RUDP, for instance, each side declares its receive buffer size at the beginning of the connection, and senders MUST NOT exceed that size in any sent packet.
  • Make the most pessimistic, abysmal estimate possible of MTU. ALL IPv4 hardware MUST transmit packets of 68 bytes without fragmentation (per RFC 791), or 576 with reassembly (per RFC 1122). ALL IPv6 hardware MUST transmit packets of 1280 bytes without fragmentation (per RFC 2460), and only source nodes can fragment packets in IPv6(!), so if your own host didn't fragment it, it's good to go.

TL, DR; I'd probably bank on 576 / 1280 for IPv4 / IPv6, respectively.

(note: Minus 68 bytes for an IPv4 UDP packet, or 48 bytes for an IPv6 UDP packet)

Upvotes: 2

user207421
user207421

Reputation: 311018

The maximum datagram you can receive is bounded by 65507 (IPv4) or your socket receive buffer size, whichever is lower.

MTU is the maximum that can be sent, and it is a property of several things at the sender plus the overall limit of 65507 as above. It doesn't have anything to do with receiving. In practice it is as low as 576 or 534 or some such number, because of IP fragementation.

Upvotes: 1

meteor
meteor

Reputation: 51

I'm not sure what are your intentions, but for this answer I will assume you want to get the size for bb to make sure no packet will be truncated.

MulticastSocket class inherits from DatagramSocket. And DatagramSocket has a getReceiveBufferSize() method that returns maximum socket receive buffer in bytes.

Upvotes: 0

Related Questions