diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index ea34dec..3dde11b 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -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) diff --git a/src/router.c b/src/router.c index e5340d0..8fca7a0 100644 --- a/src/router.c +++ b/src/router.c @@ -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); + } +} diff --git a/src/router.h b/src/router.h index 1ee5360..6162221 100644 --- a/src/router.h +++ b/src/router.h @@ -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 */ diff --git a/src/winsock.c b/src/winsock.c index 9e086cd..2807cf0 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -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();