views:

3031

answers:

3

I need to know what the largest UDP packet I can send to another computer is without fragmentation.

This size is commonly known as the MTU (Maximum Transmission Unit). Supposedly, between 2 computers, will be many routers and modems that may have different MTUs.

I read that the TCP implementation in windows automatically finds the maximum MTU in a path.

I was also experimenting, and I found out that the maximum MTU from my computer to a server was 57712 bytes+header. Anything above that was discarded. My computer is on a LAN, isn't the MTU supposed to be around 1500 bytes?

+1  A: 

Your own MTU is available in the registry, but the MTU in practice is going to the smallest MTU in the path between your machine and the destination. Its both variable and can only be determined empirically. There are a number of RFCs showing how to determine it.

LAN's can internally have very large MTU values, since the network hardware is typically homogeneous or at least centrally administrated.

Jherico
Why do people often say that the MTU for ethernet is 1500?
Unknown
Because that's whats defined in the RFC for Ethernet V2. I'm not savvy enough to know if fragmentation of ethernet packets is typically reversed at an ethernet to ip-only router, so it might or might not be relevant to the question at hand.
Jherico
+4  A: 

The following doesn't answer your question directly but you might find it interesting; it says that IP packets can be disassembled/reassembled, and therefore bigger than limit on the underling media (e.g. 1500-byte Ethernet): Resolve IP Fragmentation, MTU, MSS, and PMTUD Issues with GRE and IPSEC


More on this topic:

I don't know about generating ICMP via an API on Windows: at one time such an API was proposed, and was controversial because people argued that would make it easy to write software that implements denial-of-service functionality by generating a flood of ICMP messages.

No, it looks like it is implemented: see for example Winsock Programmer's FAQ Examples: Ping: Raw Sockets Method.

So, to discover MTU, generate ping packets with the 'do not fragment' flag.

Maybe there's an easier API than this, I don't know; but I hope I've given you to understand the underlying protocol[s].

ChrisW
Thank you this was a bit helpful. I'm just wondering if everyone else that uses UDP just goes with the minimum default of 576, which seems like a horrible idea.
Unknown
When I implemented a protocol using UDP, it used sequence numbers and retransmissions to detect lost packets. Having established a 'connection' using small packets, I tried to 'negotiate' using bigger packet, by sending a bigger packet end-to-end and seeing whether I received a reply (or whether it was lost en route). YMMV. Small packets (e.g. 100-byte) are often used in real world, for an application like VoIP; I dont know what performance characteristics you require, why you're using UDP at all: if you're going for large packets then perhaps you're trying to optimize bandwidth rather than...
ChrisW
... jitter; but I don't know that using as-big-as-possible packets has like a huge effect on bandwidth anyway.
ChrisW
@ChrisW, it does. TCP has an overhead of 160 bytes per packet (not even including handshakes and acks). UDP only has an overhead of 64 bytes.
Unknown
On a 1500-byte packet that's 5% to 10% overhead. <shrug>
ChrisW
How did you come up with 160 and 64 here? AFAIK IP header = 20, UDP header = 8, TCP header = 20.
Nikolai N Fetissov
Could use "do not fragment" flag with UDP packets, and if the ICMP "would fragment" error is received, reduce the size.
David Dolson
+1  A: 

In addition to all the previous answers, quoting the classic:

IPv4 and IPv6 define minimum reassembly buffer size, the minimum datagram size that we are guaranteed any implementation must support. For IPv4, this is 576 bytes. IPv6 raises this to 1,500 bytes. ...


This pretty much means that you want to limit your datagram size to under 576 if you work over public internet and you control only one side of the exchange - that's what most of the standard UDP-based protocols do.

Also note that PMTU is a dynamic property of the path. This is one of the things TCP deals with for you. Unless you are ready to re-implement lots of sequencing, timing, and retransmission logic, use TCP for any critical networking. Benchmark, test, profile, i.e. prove that TCP is your bottleneck, only then consider UDP.

Nikolai N Fetissov
"Unless you are ready to re-implement lots of sequencing, timing, and retransmission logic"... Yes I am already aware of this, and I am ready to implement my own. Also, PMTU is not part of TCP. I don't see any reason why you can't use it for your own protocol.
Unknown
I am just saying that TCP already implements RFC 1191/1981 and much more, and in-kernel too. If you have a reason to work in UDP - fine - go right ahead, just make sure the reason is valid.
Nikolai N Fetissov
Well what if I just use a dummy tcp connection at the beginning? Is it possible to extract the PMTU from that?
Unknown
You can extract _current_ MSS from TCP socket with TCP_MAXSEG option. It makes sense to do so only after the connection has been established - default MSS is returned instead. In theory the PMTU might change since IP routing is dynamic, so YMMV.Just for completeness - IPv6 has an explicit IPV6_PATHMTU socket option one can query.
Nikolai N Fetissov