From dde08ae3a9d285514e5d0ff4b4b00c328a02f76f Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Mon, 4 Sep 2023 20:24:22 +0100 Subject: [PATCH] Fix local packet delivery when using DOSBox encapsulation. --- src/router.c | 23 +++++++++++++---------- src/router.h | 2 ++ src/winsock.c | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/router.c b/src/router.c index cb0e090..e5340d0 100644 --- a/src/router.c +++ b/src/router.c @@ -49,8 +49,9 @@ static HANDLE router_thread = NULL; * will be bound to loopback rather than INADDR_ANY since it is only used for * forwarding IPX packets on to local sockets. * - * When running in DOSBox mode, only the private socket will be opened and it - * will be "connected" to the DOSBox server address. + * When running in DOSBox mode, only the private socket will be opened and + * bound to a random port on INADDR_ANY to communicate with the DOSBox server + * and also relay packets to local sockets. */ SOCKET shared_socket = -1; @@ -58,7 +59,7 @@ SOCKET private_socket = -1; #define DOSBOX_CONNECT_TIMEOUT_SECS 10 -static struct sockaddr_in dosbox_server_addr; +struct sockaddr_in dosbox_server_addr; static time_t dosbox_connect_begin; static void _send_dosbox_registration_request(void); @@ -148,12 +149,6 @@ void router_init(void) dosbox_server_addr.sin_addr.s_addr = inet_addr(main_config.dosbox_server_addr); dosbox_server_addr.sin_port = htons(main_config.dosbox_server_port); - if(connect(private_socket, (struct sockaddr*)(&dosbox_server_addr), sizeof(dosbox_server_addr)) != 0) - { - log_printf(LOG_ERROR, "Error connecting private socket: %s", w32_error(WSAGetLastError())); - abort(); - } - _send_dosbox_registration_request(); dosbox_state = DOSBOX_REGISTERING; @@ -582,6 +577,14 @@ static bool _do_udp_recv(int fd) if(ipx_encap_type == ENCAP_TYPE_DOSBOX) { + if(addr.sin_family != dosbox_server_addr.sin_family + || memcmp(&(addr.sin_addr), &(dosbox_server_addr.sin_addr), sizeof(struct in_addr)) != 0 + || addr.sin_port != dosbox_server_addr.sin_port) + { + /* Ignore packet from wrong address. */ + return true; + } + if(dosbox_state == DOSBOX_REGISTERING) { _handle_dosbox_registration_response((novell_ipx_packet*)(buf), len); @@ -691,7 +694,7 @@ static void _send_dosbox_registration_request(void) memset(reg_pkt.src_node, 0, sizeof(reg_pkt.src_node)); reg_pkt.src_socket = htons(IPX_SOCK_ECHO); - if(send(private_socket, (const void*)(®_pkt), sizeof(reg_pkt), 0) < 0) + if(sendto(private_socket, (const void*)(®_pkt), sizeof(reg_pkt), 0, (struct sockaddr*)(&dosbox_server_addr), sizeof(dosbox_server_addr)) < 0) { log_printf(LOG_ERROR, "Error sending DOSBox IPX registration request: %s", w32_error(WSAGetLastError())); } diff --git a/src/router.h b/src/router.h index eeedd68..1ee5360 100644 --- a/src/router.h +++ b/src/router.h @@ -26,6 +26,8 @@ extern SOCKET shared_socket; extern SOCKET private_socket; +extern struct sockaddr_in dosbox_server_addr; + void router_init(void); void router_cleanup(void); diff --git a/src/winsock.c b/src/winsock.c index b39e9bb..9116034 100644 --- a/src/winsock.c +++ b/src/winsock.c @@ -1351,7 +1351,7 @@ static DWORD ipx_send_packet( DWORD error = ERROR_SUCCESS; - if(r_send(private_socket, (const void*)(packet), packet_size, 0) < 0) + if(r_sendto(private_socket, (const void*)(packet), packet_size, 0, (struct sockaddr*)(&dosbox_server_addr), sizeof(dosbox_server_addr)) < 0) { error = WSAGetLastError(); log_printf(LOG_ERROR, "Error sending DOSBox IPX packet: %s", w32_error(error));