When there are no packets waiting, ioctlsocket() should return success
and set *argp to zero.
When there are multiple packets waiting, ioctlsocket() should set *argp
to the accumulated size of all received payloads.
As far as I can tell, there's no way to inspect beyond the first packet
queued on a socket, so we must receive and queue all packets from the
socket to be able to know how much is available.
The recv pipeline has been reworked to queue packets in this manner,
and select() will try to emulate the normal behaviour we previously got
for free by passing the socket fd straight through in readfds.
I don't *think* WSAAsyncSelect() needs any changes since the socket
will still raise window messages as appropriate before we have any
opportunity to shunt the packet into the receive queue.
Normally calls like bind() will immediately succeed or fail depending
on what address was requested and what addresses are assigned to the
machine, but when using a DOSBox IPX server we don't know our address
until it gets assigned to us, so block functions impacted by that to
avoid spurious errors when starting up.
If the server is down or slow then the calls will fail after a few
seconds rather than hanging indefinitely.
Various fixups to build under win-builds.org toolchain rather than MinGW. No
longer builds under MinGW as I have removed headers/definitions that it lacks.
Detect multiple sockets bound to the same address within a session by creating
a named mutex. Multiple handles to a mutex may exist and closing the last one
destroys it.
The IPX/SPX protocol versions in 98/2000/XP only require the second socket to
have SO_REUSEADDR when attempting to bind to an already-used address. The state
of the option on the first socket is ignored.
The ADDR_TABLE_ENTRY_REUSE flag is kept and set on all sockets in the address
table to keep compatibility with previous versions.
multiple IPXWrapper processes without needing a shared router thread.
Replaced router/rclient code with a single, per-process router thread.
Add addresses to the cache in the router main loop rather than winsock recv
functions.
Packets are no longer preceeded by an rpacket_header structure when relayed to
the local UDP sockets.
Each IPXWrapper instance creates a "private" UDP socket bound to a random port
on INADDR_ANY which is used for sending all packets and receiving unicast.
Bugfix: Check source socket number before relaying to a connected socket.