ws: add workaround for Komodia based LSPs that break SIO_BASE_HANDLE
This commit is contained in:
parent
8223744d7b
commit
8dc6115127
57
src/ws.c
57
src/ws.c
@ -1,9 +1,14 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "util.h"
|
||||
#include "win.h"
|
||||
#include "ws.h"
|
||||
|
||||
#ifndef SIO_BSP_HANDLE_POLL
|
||||
#define SIO_BSP_HANDLE_POLL 0x4800001D
|
||||
#endif
|
||||
|
||||
#ifndef SIO_BASE_HANDLE
|
||||
#define SIO_BASE_HANDLE 0x48000022
|
||||
#endif
|
||||
@ -19,20 +24,54 @@ int ws_global_init(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SOCKET ws_get_base_socket(SOCKET socket) {
|
||||
SOCKET base_socket;
|
||||
static inline SOCKET ws__ioctl_get_bsp_socket(SOCKET socket, DWORD ioctl) {
|
||||
SOCKET bsp_socket;
|
||||
DWORD bytes;
|
||||
|
||||
if (WSAIoctl(socket,
|
||||
SIO_BASE_HANDLE,
|
||||
ioctl,
|
||||
NULL,
|
||||
0,
|
||||
&base_socket,
|
||||
sizeof base_socket,
|
||||
&bsp_socket,
|
||||
sizeof bsp_socket,
|
||||
&bytes,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
return_map_error(INVALID_SOCKET);
|
||||
|
||||
return base_socket;
|
||||
NULL) != SOCKET_ERROR)
|
||||
return bsp_socket;
|
||||
else
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
SOCKET ws_get_base_socket(SOCKET socket) {
|
||||
SOCKET base_socket;
|
||||
DWORD error;
|
||||
|
||||
for (;;) {
|
||||
base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BASE_HANDLE);
|
||||
if (base_socket != INVALID_SOCKET)
|
||||
return base_socket;
|
||||
|
||||
error = GetLastError();
|
||||
if (error == WSAENOTSOCK)
|
||||
return_set_error(INVALID_SOCKET, error);
|
||||
|
||||
/* clang-format off */
|
||||
/* Even though Microsoft documentation clearly states that LSPs should
|
||||
* never intercept the `SIO_BASE_HANDLE` ioctl [1], Komodia based LSPs do
|
||||
* so anyway, breaking it, with the apparent intention of preventing LSP
|
||||
* bypass [2]. Fortunately they don't handle `SIO_BSP_HANDLE_POLL`, which
|
||||
* we can use to obtain the socket associated with the next protocol chain
|
||||
* entry. If this succeeds, loop around and call `SIO_BASE_HANDLE` again
|
||||
* with the retrieved BSP socket to be sure that we actually got all the
|
||||
* way to the base.
|
||||
* [1] https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls
|
||||
* [2] https://www.komodia.com/newwiki/index.php?title=Komodia%27s_Redirector_bug_fixes#Version_2.2.2.6
|
||||
*/
|
||||
/* clang-format on */
|
||||
base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BSP_HANDLE_POLL);
|
||||
if (base_socket != INVALID_SOCKET && base_socket != socket)
|
||||
socket = base_socket;
|
||||
else
|
||||
return_set_error(INVALID_SOCKET, error);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user