1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

Block certain calls momentarily when connecting to a DOSBox server.

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.
This commit is contained in:
Daniel Collins 2023-09-05 18:19:30 +01:00
parent 61cfcf7730
commit 36693ee9e0
4 changed files with 33 additions and 0 deletions

View File

@ -36,6 +36,13 @@
#define IPX_CONNECT_TIMEOUT 6
#define IPX_CONNECT_TRIES 3
/* Maximum number of milliseconds to block waiting for IPX networking to be ready.
*
* This blocks functions which usually don't block (e.g. bind()) so that they don't fail right as
* the process is starting up because we are still connecting to a DOSBox IPX server.
*/
#define IPX_READY_TIMEOUT 3000
#define IPX_FILTER (int)(1<<0)
#define IPX_BOUND (int)(1<<1)
#define IPX_BROADCAST (int)(1<<2)

View File

@ -61,6 +61,7 @@ SOCKET private_socket = -1;
struct sockaddr_in dosbox_server_addr;
static time_t dosbox_connect_begin;
static HANDLE dosbox_ready_event = NULL;
static void _send_dosbox_registration_request(void);
static DWORD router_main(void *arg);
@ -141,6 +142,13 @@ void router_init(void)
}
else if(ipx_encap_type == ENCAP_TYPE_DOSBOX)
{
dosbox_ready_event = CreateEvent(NULL, TRUE, FALSE, NULL);
if(dosbox_ready_event == NULL)
{
log_printf(LOG_ERROR, "Error creating event object: %s", w32_error(GetLastError()));
abort();
}
/* TODO: Support DNS. Do this async somewhere within router_main. */
_init_socket(&private_socket, 0, FALSE, FALSE);
@ -522,6 +530,8 @@ static void _handle_dosbox_registration_response(novell_ipx_packet *packet, size
addr48_string(local_nodenum_s, dosbox_local_nodenum);
log_printf(LOG_INFO, "Connected to DOSBox server, local address: %s/%s", local_netnum_s, local_nodenum_s);
SetEvent(dosbox_ready_event);
}
static void _handle_dosbox_recv(novell_ipx_packet *packet, size_t packet_size)
@ -787,3 +797,11 @@ static DWORD router_main(void *arg)
return exit_status;
}
void wait_for_ready(DWORD timeout)
{
if(dosbox_ready_event != NULL)
{
WaitForSingleObject(dosbox_ready_event, timeout);
}
}

View File

@ -31,4 +31,6 @@ extern struct sockaddr_in dosbox_server_addr;
void router_init(void);
void router_cleanup(void);
void wait_for_ready(DWORD timeout);
#endif /* !IPXWRAPPER_ROUTER_H */

View File

@ -542,6 +542,8 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen)
if(sock)
{
wait_for_ready(IPX_READY_TIMEOUT);
struct sockaddr_ipx ipxaddr;
if(addrlen < sizeof(ipxaddr) || addr->sa_family != AF_IPX)
@ -940,6 +942,8 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F
if(sock)
{
wait_for_ready(IPX_READY_TIMEOUT);
if(level == NSPROTO_IPX)
{
if(optname == IPX_PTYPE)
@ -1477,6 +1481,8 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
if(sock)
{
wait_for_ready(IPX_READY_TIMEOUT);
if(sock->flags & IPX_IS_SPX)
{
unlock_sockets();