I have a problem which is identical to the one described here:
http://www.experts-exchange.com/Networking/Protocols/Transport/UDP/Q_25146550.html
Essentially, while using sendto to send a UDP packet from host
192.168.1.20 to host 192.168.1.101, both on same Ethernet segment, the
stack on source node issues ARP request to determine Ethernet address
for 192.168.1.101. Meanwhile, it silently discards the sendto UDP
packet that triggered the ARP request.
I am hoping for a hack that will cause protocol stack to buffer as
much as possible before discard, as this loss of packet is causing me
grief system I am designing.
Also, if you would be so kind to spare me the lecture on reliable vs
unreliable transmission - I do research in network protocols. :D Just
hoping for dirty fix (on Windows only) to get past this problem.
TIA,
-Le Chaud Lapin-
I took a quick look at Windows ARP cache behavior.
No solution to my problem, but here is what I have found so far. My OS
is Vista.
1. My lost packet is, indeed, being caused by ARP cache trying to
augment during call to sendto().
2. If user sends 20 UDP packets in rapid succession under this
scenario, Windows will discard the first 19 and hold the 20th until
ARP cache is augmented.
3. If user sends one packet that must be broken into 15 fragments such
that none of the fragments exceeds link-layer MTU (roughly speaking),
Windows will discard the first 14, but keep the 15th until the ARP
cache is agumented. Naturally, after it finally sends the 15th runt
fragment, the target node will discard the runt, so effectively, the
entire packet is lost.
4. Statements #2 and #3 above imply that the programmer of tcpip.sys
simply overwrites the 1-packet-only buffer for outgoing UDP packets,
as the packets are received, until the ARP cache is augmented.
5. The SendARP function was supposed to help with this situation by
allowing us to prime the ARP cache before wasting any of our packets
to effectively do the same. Ideally, the programmer would call SendARP
before sending any packets, using the (known) destination addresses of
the packets in call to SendARP, forcing the cache to prime itself so
as not to lose any packets sent immediately after call to SendARP().
Unfortunately, it appears that SendARP is not behaving as specified.
MSDN says that SendARP will consider whether cache is already primed
before actually placing an ARP request on the wire. In my test code,
it seems that this is not true - ARP requests are being placed on wire
on every single call to SendARP, regardless of state of ARP Cache
[Maybe I'm doing something wrong here].
6. If you have any compilation errors duing compilation after #include
<iphlpapi.h>, check if you are defining _WIN32_WINNT.
7. If you have linker errors such as warning LNK4006:
__NULL_IMPORT_DESCRIPTOR already defined in blah...try removing .lib
for Winsock from problem, keeping Iphlpapi.lib.
-Le Chaud Lapin-
References:
// INFO: UDP Datagram Can Be Silently Discarded if Larger than MTU
// http://support.microsoft.com/kb/233401
// SendARP Function:
// http://msdn.microsoft.com/en-us/library/aa366358(VS.85).aspx
// Description of Address Resolution Protocol (ARP) caching behavior
in Windows Vista TCP/IP implementations
// http://support.microsoft.com/kb/949589
// Microsoft Windows Server 2003 TCP/IP Implementation Details
// http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=06c60bfe-4d37-4f50-8587-8b68d32fa6ee
// UDP and ARP cache timeout
// http://www.eggheadcafe.com/software/aspnet/33535631/udp-and-arp-cache-timeout.aspx
// ARP request drops UDP packets Windows XP
// http://www.experts-exchange.com/Networking/Protocols/Transport/UDP/Q_25146550.htm
-Le Chaud Lapin-