locked
ICMP error processing on UDP socket RRS feed

  • Question

  • I am having a problem doing ICMP error processing on UDP sockets unders Windows Vista and Windows 7, but it works fine under Windows XP.  The problem is that the recvfrom function is documented to return an error if a previously sent UDP datagram gets an ICMP error response.  The WSAGetLastError function returns WSAECONNRESET when this occurs.  That part is working just fine.

    Unders Windows XP and earlier when this occurs, the 'from' parameter (which tells you where an incoming UDP packet originated from) is set to the IP/PORT of the where the errant packet was trying to get to.

    Under Windows Vista, the PORT number is set to the outgoing socket's port number instead of the destination port number that was attempted by the send, but the IP address is correctly set to the destination IP address. 

    Under Windows 7, the PORT number is set incorrectly the same as Vista, but the IP address is set to 0.0.0.0.

    The problem is that I am writing a server that opens a single UDP socket and uses that socket to send data to hundreds of connected users (an MMO game situation), so the socket is not connected to any particular user.  Under Windows XP and earlier, if I receive an ICMP error indicator when trying to receive a packet, I can use the 'from' information to determine which of the hundreds of users is now unreachable and disconnect them.  Under Windows Vista and Windows 7, I have no way of knowing who the ICMP error is coming from, since I am sending data out to all them continuously.

    As best as I can tell, this should be a bug in the Windows Vista and Windows 7 socket implementations.  I have other means (timeouts) for detecting disconnects since ICMP is not always a reliable indicator, but it is far better to realize the disconnection quickly rather than having to timeout.  This is even more of a problem between our back-end services which also communicate via UDP in a similar manner.  I am open to suggestions on how to work around this problem.

    • Edited by Jeff Petersen Wednesday, December 9, 2009 11:40 PM fixed formatting problems.
    Wednesday, December 9, 2009 11:37 PM

All replies

  • Did u check the vista ,w7 windows firewall incoming rule? Type mmc , add Windows firewall & check for rules blocking ICMP
    Monday, December 14, 2009 7:18 AM
  • I have Windows Firewall disabled.  Plus, I am actually getting the indicator that an ICMP error has occurred, it's just the address it came from is not correct.

    Monday, December 14, 2009 5:27 PM
  • Can you get a wireshark trace, and confirm that the ICMP packet has the correct IPaddress/port# in the payload of the error?
    feroze
    --
    My blog (including System.Net topics

     Subscribe in a reader

    Instruction on how to create a tracelog with your System.Net application
    System.Net Links and HOWTOs
    Sunday, January 3, 2010 11:47 PM
  • Did you figure this out Jeff?

    I just hit this same problem too and spent a couple of days banging my head against it on the assumption that it was a new code bug on our side. I've now reluctantly concluded that Windows Server 2008 and Vista just always seem to return 0.0.0.0 for the ICMP packet's source IP and and the port I'm listening on instead instead of the source port. My server is talking to dozens or hundreds of clients and I know one or more of them have gone away but can't tell which ones.

    WSAECONNRESET handling for UDP seems to be relatively poorly understood by developers and I'm guessing that it's just broken and useless in Vista and no-one has noticed.

    Tuesday, January 26, 2010 7:02 PM
  • Hey Jeff, it's been a long time :)

    I've recently run into this myself for a peer-to-peer game that communicates through a single UDP socket with all other peers and TCP isn't an option due to ugly NAT traversal issues. I share your frustration with recent releases of Windows :)

    As far as I can tell, there is no ideal workaround for this problem. If this is a client/server system where the server is reachable by way of TCP, you may want to consider dropping UDP except for completely stateless communication.

    If TCP is not an option, these are some hacks that might work:
    If it is OK to run the server with elevated privileges, you could install a packet cap driver like WinPCAP and inspect ICMP messages in the application itself to emulate the behavior documented for the winsock API.

    If that's not acceptable, you could open one or more new sockets, and send a ping packet (which is ignored by the client) to each connection that's open. As long as there is ever only one datagram in flight per socket, the subsequent recvfrom() that returns WSAECONNRESET is the one that triggered the initial problem. This is an ugly hack that might perform better than waiting for a timeout, but is hardly ideal for emulating what Windows version 6.0 and up are failing to do.

    Lastly, if it's an option, you could move to another operating system that doesn't have this problem :)

    If you run across a better solution, I'd love to hear about it too. I'm setting with the sendto/recvfrom ping hack for now.

    Best of Luck!

    -- Justin
    Tuesday, March 16, 2010 4:04 PM
  • I just got burnt by this too.  It's really crazy.  How did nobody notice this?  I wish there was a better option than to snoop ICMP messages.  I think I might downgrade my OS.  Windows 7 has been pretty disappointing for me personally.
    Tuesday, October 5, 2010 8:32 PM
  • Hi guys!

    Are there any news about this, a hotfix or something ? It's been about a year since the last reply... @Logicle: the workarounds are not acceptable for me, because i have a big application and i don't want to modify it because of a OS implemetation error.

    Is there a more official windows 7 forum on which windows team fix these kind of problems?

     

    Thanks!

    Monday, June 27, 2011 9:56 AM