views:

55

answers:

3

I'm having a little test program that sends a lot of udp packets between client->server->client (ping/pong test). The packets are fixed size on each run(last run is max allowable size of udp packet) I'm filling the packets with random data except for the beginning of each packet that contains the packet number. So I'm only interested to see if I receive all the packets back at the client.

I'm using sendto() and recvfrom() and I only read the sizeof(packet_number) (which in this case is an int). What happens to the rest of the data? Does it end up in fairyland (gets discarded)? or does the new packet that arrives gets appended to this "old" data?

(using linux)

+1  A: 

I haven't tested this, but from my interpretation of the man page, it will always be discarded. This seems reasonable since otherwise there would be no way to detect the beginning of the next package.

There are two ways to detect truncation:

Use the MSG_TRUNC flag. recvfrom will then return the true size of the package even if it didn't fit the provided buffer. So you can simply check if the return value is larger then the len you gave as an argument.

Use recvmsg and check the returned structure for the MSG_TRUNC flag.

To avoid trunaction, use a 64k buffer. UDP packages can't be bigger than that (16 bit length field in the protocol).

Lawnmower
+2  A: 

Each read from UDP socket de-queues one whole datagram off kernel socket receive buffer no matter what's your userland buffer size. That is:

  • If your buffer is bigger then the next pending datagram, you'll read less then your buffer size.
  • If your buffer is smaller, you'll read your buffer size worth and the rest of the data is discarded.
  • You can set MSG_TRUNC option in the flags, so recv(2) will return the whole datagram length, not just the part you read into your userland buffer.

Hope this helps.

Nikolai N Fetissov
A: 

To answer your first question, does the data get discarded? Yes it does. The IP & ARP protocols come into play when your packet is larger than the Path MTU. The Path MTU is the maximum transmission unit of the path between your client and server. Assuming that your NIC card is a standard ethernet card, then your maximum MTU is 1500. Now, lets assume that the whole Path MTU between your client and server is 1500. In this scenario, if you send any packet that is greater than 1472 bytes (1500 - (20 byte ip header) - (8 byte UDP header)) then IP fragmentation will occur. What will then happen is that the IP layer will chop the packet into fragments to meet the MTU of the ethernet link. Now, before any data can be sent, the MAC address of the destination needs to be resolved. So all of a sudden, the ARP protocol will receive multiple IP fragments requesting the same IP to MAC address resolution. What will then happen is that ARP will initiate an ARP request for the first received packet and wait for the ARP response. While waiting, ARP will discard all of the fragments making the same ARP request and queue only the latest arrived fragment. Therefore, if you send a packet greater than 1472 bytes, don't expect to receive the whole packet on the other end if your ARP cache is empty.

Does the newly arrived packet get appended to No, it doesn't get appended. UDP is a datagram protocol with strict message boundaries. Therefore, each arriving packet is considered as a complete self-contained datagram; the data will not get appended.

WindsurferOak
The question has nothing to do with MTU - it's entirely about the sockets API (and the effect of doing a short read).
caf
@caf - If you reread the question, it states that: (last run is max allowable size of udp packet) meaning that the length is set to UDP's "theoretical" maximum packet size. Please read Richard Stevens book, TCP/IP illustrated: The protocols. Section 11.9 - The interaction between UDP and ARP. You would understand why I mentioned MTU and ARP.
WindsurferOak