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 <stdlib.h>
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "util.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "ws.h"
|
#include "ws.h"
|
||||||
|
|
||||||
|
#ifndef SIO_BSP_HANDLE_POLL
|
||||||
|
#define SIO_BSP_HANDLE_POLL 0x4800001D
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SIO_BASE_HANDLE
|
#ifndef SIO_BASE_HANDLE
|
||||||
#define SIO_BASE_HANDLE 0x48000022
|
#define SIO_BASE_HANDLE 0x48000022
|
||||||
#endif
|
#endif
|
||||||
@ -19,20 +24,54 @@ int ws_global_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET ws_get_base_socket(SOCKET socket) {
|
static inline SOCKET ws__ioctl_get_bsp_socket(SOCKET socket, DWORD ioctl) {
|
||||||
SOCKET base_socket;
|
SOCKET bsp_socket;
|
||||||
DWORD bytes;
|
DWORD bytes;
|
||||||
|
|
||||||
if (WSAIoctl(socket,
|
if (WSAIoctl(socket,
|
||||||
SIO_BASE_HANDLE,
|
ioctl,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&base_socket,
|
&bsp_socket,
|
||||||
sizeof base_socket,
|
sizeof bsp_socket,
|
||||||
&bytes,
|
&bytes,
|
||||||
NULL,
|
NULL,
|
||||||
NULL) == SOCKET_ERROR)
|
NULL) != SOCKET_ERROR)
|
||||||
return_map_error(INVALID_SOCKET);
|
return bsp_socket;
|
||||||
|
else
|
||||||
return base_socket;
|
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