[Bug 5774] udp traffic stop working after a time for dht/utorrent and kademlia/emule

Wine Bugs wine-bugs at winehq.org
Sat May 12 04:39:57 CDT 2007


http://bugs.winehq.org/show_bug.cgi?id=5774





------- Additional Comments From damjan.jov at gmail.com  2007-12-05 04:39 -------
Created an attachment (id=6242)
 --> (http://bugs.winehq.org/attachment.cgi?id=6242&action=view)
patch select to ensure readability

So looking over an enormous emule log that someone sent me, I see that emule
only ever creates 3 UDP sockets, all of them early on.

In order of creation:
* fd 38,  handle 0xa8, bound to 0.0.0.0:0, closed very close to the end, works
perfectly sending and receiving
* fd 43,  handle 0x3fc, emule tries to bind it to 0.0.0.0:11291 and fails
because it's already in use, then closes it immediately
* fd 144, handle 0x404, bound to 0.0.0.0:47772, closed very close to the end,
works perfectly sending, but receiving, after some time it hits EWOULDBLOCK,
and never tries to receive again!

Elaborating on that very suspicious last socket just before it breaks:

0009: get_message( flags=00000001, get_win=(nil), get_first=00000000, 
    get_last=ffffffff, hw_id=00000000 )
0009: get_message() = 0 { win=0x1002e, type=6, msg=00000373, wparam=404, 
    lparam=1, info=0, x=0, y=0, time=00a8e216, hw_id=00000000, 
    active_hooks=80000041, total=0, data={} }
0009:trace:winsock:WS_select read 0x34d078, write (nil), excp (nil) 
    timeout 0x34d17c
0009:trace:winsock:WSARecvFrom socket 0404, wsabuf 0x34bc14, nbufs 1, 
    flags 0, from 0x34d030, fromlen 16, ovl (nil), func (nil)
0009:trace:winsock:WSARecvFrom fd=158, options=0
0009: get_socket_event( handle=0x404, service=0, c_event=(nil) )
0009: get_socket_event() = 0 { mask=00000003, pmask=00000000, state=20000003,
    errors={} }
0009:trace:winsock:WS2_recv fd 158, iovec 0x171c348, count 1 addr { 
    family 0, address 0.0.0.0, port 0 }, len 0x34d020, flags 0
0009:trace:winsock:WS2_recv recvmsg error 11
0009:trace:winsock:WS2_recv -> -1
0009:warn:winsock:wsaErrno errno 11, (Resource temporarily unavailable).
0009:warn:winsock:WSARecvFrom  -> ERROR 10035

For some reason, emule tries a WSARecvFrom() on socket 404, which immediately
fails with EWOULDBLOCK (10035), normally an innocent error that means 
"try again". It's the first and only time that emule ever gets 
EWOULDBLOCK on any socket, but emule never tries again to receive from 
that socket.

If emule was a UNIX app this would be an application bug. But this 
behaviour clearly never happens on Windows, so it's a wine bug.

Why does it try a WSARecvFrom() on a socket that has no data?
* The call to WSARecvFrom is preceded by a call to select(), which asks 
  for readability (but we don't know for which sockets). So select() 
  could be reporting readability for sockets that aren't readable (this 
  is a possibility, it's a known fact that for eg. TCP sockets you 
  cannot use a blocking listening socket and poll for readability and then
  call accept(), because readability is signalled before a successful
  connection is established, so your accept() could block until the next 
  connection comes in. Maybe in the case of UDP sockets, readability is
  signalled before the UDP packet is verified/checksummed, and then when
  you try read, the packet is discarded, and if the socket is non-blocking,
  there is now no data and it fails with EWOULDBLOCK. This theory is 
  very difficult to prove, it would require crafting a corrupt UDP 
  packet and seeing what happens to a select() on the socket that 
  receives it (any volunteers?)).
* Socket 404 is also WSAAsyncSelect()-ed just after creation to deliver
  event mask 3 (FD_READ | FD_WRITE) to a window. Just before the call to
  select(), the FD_READ event is delivered for socket 404, which, combined
  with select(), could be causing emule to try WSARecvFrom, which fails 
  for the same reasons as above.

Either way, it looks like non-blocking I/O availability must only be 
signalled when we are absolutely certain it can be performed.

This patch modifies select() to ensure there is data to read before it 
returns readability. It could well be this is not enough, reading over 
the source code for emule 0.47a I see that it didn't even use select(),
but just try to do I/O straight away when the FD_READ notification 
arrived, so event notifications might need to be patched as well.

So please try this patch, and report whether emule/uTorrent work any 
better.


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the wine-bugs mailing list