Martin.Wilck at fujitsu-siemens.com
Tue Jan 15 09:46:07 CST 2002
I have some concerns wrt your WSAAccept implementation you sent to
wine-patches on Sunday. I have thought a bit about this function
(did you notice my preliminary implementation on Nov. 7 (subject
"[EXPERIMENTAL PATCH]: Winsock2" ?).
The problem I see is related to the treatment of the peer when
the user-supplied condition function returns CF_REJECT or CF_DEFER.
Your implementation calls WS_Accept _before_ calling the condition
function. That is, the peer will think its connection request was
accepted, and possibly start to send or poll for data.
Then if the Condition function returns CF_REJECT, the connection is
Even worse, for CF_DEFER, the peer receives nothing, the
new socket cs returned by WS_Accept remains open but is forgotten after
WSAAccept() returns (correct me if I'm wrong).
So the peer will think it's connected,
but no future WSAAccept or WS_Accept call will ever return a socket
connected to it, and it'll be sending data into the void.
I think you must at least closesocket(cs) for CS_DEFER as well to avoid
this situation. Alternatively (that's the way I did it) the new socket can
be stored in the wineserver to be returned by future WSAAccept calls.
The Winsock2 specs say that "[WSAAccept] extracts the first connection
on the queue of pending connections" (after a CF_DEFER, that should be the
previously deferred connection, until it's either accepted or rejected).
Moreover, it says that "[In the CF_DEFER case] no action about this
connection request should be taken by the service provider".
Taken seriously, this means that it's wrong to call accept() on this
request before a positive decision was made by the Condition function.
Summarizing, the peer should see:
CF_ACCEPT: his request is accepted (this case is OK).
CF_REJECT: his request is rejected (not ok, he receives an accept followed
by a close).
CF_DEFER: nothing (not OK, he receives an accept followed by ???)
I have no idea how this affects behaviour of "real" applications.
The essential problem is that there is no way (well, I have found none)
to obtain the peer's socket address on Linux without accept()ing first.
I guess that is what made you call accept() before the condition routine.
Perhaps someone can come up with a method to read the socket address
of a waiting connection request before it's accepted, but my guess is this
won't work without a kernel hack.
At the very least, though, I consider it necessary to include a FIXME that
tells users that this function may behave different from what the specs
Please don't get me wrong, it's great to see other people work on Winsock,
and your code is clean. I just thought I need to express these concerns.
Martin Wilck Phone: +49 5251 8 15113
Fujitsu Siemens Computers Fax: +49 5251 8 20409
Heinz-Nixdorf-Ring 1 mailto:Martin.Wilck at Fujitsu-Siemens.com
D-33106 Paderborn http://www.fujitsu-siemens.com/primergy
More information about the wine-devel