-
Notifications
You must be signed in to change notification settings - Fork 389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Winsock Kernel (WSK) Interface for the VIOSOCK Driver #835
Winsock Kernel (WSK) Interface for the VIOSOCK Driver #835
Conversation
@MartinDrab Thanks a lot for sending the PR. I am going to review it. Quick comment - please add "Signed off by" to commit message (you can do it automatically to using "-s" command line option for git commit command). Please use your real name. |
Can you also please add a page for virtio-vsock in the wiki: https://github.com/virtio-win/kvm-guest-drivers-windows/wiki If possible add following:
Thanks a lot! |
Yes, I will add some documentation related to the WSK interface nad its current limitations. I will work on it tomorrow. |
If trying to compile from the solution that is found in the driver directory, compilation fails (tried to compile with Win8 and Win10 Release | x64" configurations. 4>Generating Code... |
What about ARM64 support? |
|
||
#if defined(DBG) || defined(_DEBUG) | ||
|
||
#define DEBUG_ENTER_FUNCTION(Format, ...) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use existing debug printing infrastructure that depending one configuration will use different debug print methods?
Checkout: InitializeDebugPrints and VirtioDebugPrintProc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LICENSE file should be present in the directories of the new binaries, similar to "sys" and "lib" directories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several ways to build the drives.
For developers: you can use solution in each of the drivers directories (btw: doesn't work for me)
For release and CI: build every binary from the solution in the root directory. Currently wsk project is missing from this solution.
+1 for additional commits |
Yes, I am still working on it. I hope to finish the PR on this week's end. |
1f941c1
to
ca908ea
Compare
7aea4dc
to
6694b94
Compare
Hi @MartinDrab, If you are going to make additional changes to viosock driver, can you please take a look also on:
Thanks, |
@MartinDrab Are you planning to submit additional changes to PR? Currently, it needs rebase. Best regards, |
Yes, I will rebase and finish this PR soon (I hope). As far as I remember, the only thing that is missing is adopting WPP tracing for debug prints (in the past I was always using I suppose I will finish this PR once we release and WHQL-sign new driver versions. |
Thanks for the update! |
6694b94
to
ed7e49c
Compare
Hi @MartinDrab The compilation fails for viosock-wsk-test. Please add "sha256" in "File Digest Algorithm" under "Driver Signing"->"General". Thanks, |
dc6f109
to
6044592
Compare
034396d
to
07de476
Compare
These macros will be used mostly when entering into or exiting from a function, sending routine name nad values of its arguments to a potential kernel debugger. These macros are NOPs on Release build, however, their usage can be invaluable when debugging driver crashes. Signed-off-by: Martin Drab <[email protected]>
…iderNPI Unlike the Windows WSK implementation, this library needs to be initialized through VioWskModuleInit before calling its WsRegister equivalent. This approach allows the client driver to provide the library with an optional device object that is then used to prevent IRP completion routines and workitems used by the library to execute after the device deletion. If the client application decides not to provide such a device object, the library can live with it but no unload protection is then enforced. Also, the client driver must provide pointer to its DRIVER_OBJECT which is used during WskCaptureProviderNPI to connect to the VIOSOCK driver. Instead of having the VIOSOCK device name hard-coded, the library takes advantage of IoRegisterPlugPlayNotification to search for the GUID_DEVINTERFACE_VIOSOCK device interface (which is enabled by the VIOSOCK driver) dynamically. Signed-off-by: Martin Drab <[email protected]>
Implements WskGetAddressInfo, WskFreeAddressInfo and WskGetNameInfo which can be used to translate AF_VSOCK addresses between their string and binary forms. Also, some necessary logic for IRP processing is being added as well. This is necessary because the WSK interface uses IRPs to signal the client driver that certain WSK operation was completed. Apart from that (and from providing operation results in their `IoStatus` field), IRPs are not used by the interface (they carry neither operation information, nor data associated with it). It is worth to note that the whole concept of address translation is not that useful for AF_VSOCK since there are no such things as DNS servers and domain names. ref: [WskGetAddressInfo](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_get_address_info) ref: [WskFreeAddressInfo](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_free_address_info) ref: [WskGetNameInfo](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_get_name_info) Signed-off-by: Martin Drab <[email protected]>
Signed-off-by: Martin Drab <[email protected]>
Most of the work done by this WSK implementation consists of packing client driver's calls into IOCTL and read/write request and passing them to the VIOSOCK driver. This commit introduces routines for creating IOCTL requests and sending them to VIOSOCK. Also, a concept of WSK Completion Contexts is introduces. The purpose of these contexts is to transfer information between code sending IRPs and their completion routines. Also, these contexts can be used to implement one WSK interface call as a sequence of requests to the VIOSOCK driver. Signed-off-by: Martin Drab <[email protected]>
The library implements this call by forwarding it to the VIOSOCK driver as an IOCTL_SOCKET_GET_SOCK_NAME request. ref: [WskGetLocalAddress](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_get_local_address) Signed-off-by: Martin Drab <[email protected]>
The library implements this call by forwarding it to the VIOSOCK driver as an IOCTL_SOCKET_GET_PEER_NAME request. ref: [WskGetRemoteAddress](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_get_remote_address) Signed-off-by: Martin Drab <[email protected]>
Unlike the standard WSK interface (TCP/IP etc.), AF_VSOCK does not require to call WskBind before WskConnect. This also holds for the connect() call in usermode. The client driver can use VMADDR_CID_ANY to connect to loopback. ref: https://www.bing.com/search?q=wskconnect&cvid=6a21f40a81d8444a886dbae1cbb54e09&aqs=edge..69i57j0l8.1546j0j1&pglt=2083&FORM=ANSPA1&PC=U531 Signed-off-by: Martin Drab <[email protected]>
The implementation supports both synchronous (Irp == NULL) and asynchronous (Irp != NULL) modes of operation and can be used to get/set socket options and send IOCTLs. ref: [WskControlSocket](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_control_socket) Signed-off-by: Martin Drab <[email protected]>
Routines for building IRP_MJ_WRITE and IRP_MJ_WRITE IRPs are also par of this commit since the VIOSOCK driver implements send/recv operations through these requests. It is also necessary to deal with the fact that the WSK interface transfers send/recv buffers through WSK_BUF structures, very similar to WSABUF in usermode, that support MDL chaining. Since the VIOSOCK driver does not support MDL chaining, the WskSend initiates a sequence of IRP_MJ_WRITE requests, one for each MDL in the chain. ref: [WskSend](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_send_to) Signed-off-by: Martin Drab <[email protected]>
Since the VIOSOCK driver does not support MDL chaining, one call to WskReceive fills at most one MDL of the WSK_BUF structure. ref: [WskReceive](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_receive) Signed-off-by: Martin Drab <[email protected]>
Only the zero value for the Flags argument is supported. The client driver may use the Buffer argument to send data before disconnecting from the remote end. ref: [WskDisconnect](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_disconnect) Signed-off-by: Martin Drab <[email protected]>
If called at IRQL = PASSIVE_LEVEL, this call blocks until a connection is accepted. This is due to the fact that the VIOSOCK driver implements the accept() operation through an IRP_MJ_CREATE (ZwCreateFile) which is usually synchronous. To make WskAccept non-blocking, the client driver can call it at higher IRQL, the accept() call into the VIOSOCK driver is then deferred to a workitem. ref: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_accept Signed-off-by: Martin Drab <[email protected]>
This call translates to an IOCTL_SOCKET_BIND request to the VIOSOCK driver, followed with IOCTL_SOCKET_LISTEN one if the socket in question is a listening one. This needs to be done because the WskListen function was not part of the WSK interface until Windows 10 version 1703. Contrary to the TCP/IP WSK implementation in Windows, it is not necessary to call WskBind for non-listening sockets. ref: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_bind Signed-off-by: Martin Drab <[email protected]>
The following routines are not implemented: - WskControlClient - WskInspectComplete - WskConnectEx - WskSendEd - WskReceiveEx ref: [WskInspectComplete](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_inspect_complete) ref: [WskConnectEx](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wsk/nc-wsk-pfn_wsk_connect_ex) Signed-off-by: Martin Drab <[email protected]>
2e8dca1
to
819dc29
Compare
@MartinDrab - I suggest breaking this PR to start merging. First PR - add new project skeleton and binary build. Second PR - add to the main solution; third - functional changes (this one can remain open or also be broken into pieces that we can merge). What do you say? |
819dc29
to
881446c
Compare
Hello, I consider this PR ready for merge. Of course, I can divide it into more PRs in order to make the whole thing easier to read. For example, I can create these PRs:
Since the main load of commits belongs to the "Add the main functionality" bullet, the separation will not help that much but I see the point and it is fine for me to make the separate PRs. |
The leverages WSK to create a set of client and server threads. The server thread listen for connection and exchange a message with connecting clients. Cryptographic hash function (SHA256) is used to verify that message data are not damaged during their transmission. Server threads are working in non-blocking mode. Such behavior is necessary in order to be able to cancel pending WskAccept calls since the viosock.sys driver does not permit their cancellation (unlike send/recv requests which ARE cancellable by design). Signed-off-by: Martin Drab <[email protected]>
The WPP Event Tracing can be disabled which means return to the good old DbgPrintEx routine. To disable WPP, the following steps need to be done: - commenting the line `#define EVENT_TRACING` in project's trace.h file, - setting the "Run Wpp Tracing" option in project settings to No. Signed-off-by: Martin Drab <[email protected]>
881446c
to
a831488
Compare
|
re-run tests |
I am merging. There is still a problem with the build all script inside of viosock folder.
|
This pull request introduces WSK interface for the Socket driver. That allows to take advantage of the driver (and communicate with other virtual machines and the hypervisor through
AF_VSOCK
) also directly in the kernel.Starting Windows Vista, Microsoft implements WSK interface for
AF_INET
andAF_INET6
address families. The interface provides similar functions to WinSock2 known from the usermode (well, the word similar needs to be relaxed a bit). Support forAF_VM
allows the user, in theory, to easily reuse kernel code communicating over a network.Limitations
Aim of this PR is to provide sort of a basic implementation of the WSK interface for
AF_VSOCK
, without any changes to the Socket driver code. This means that some WSK calls and features are NOT implemented yet.The following WSK calls are not implemented
WskListen
, (WskBind
on a listening socket does the trick),WskConnectEx
(the same asWskConnect
+WskSend
),WskSendEx
,WskReceiveEx
,WskSocketConnect
(same asWskSocket
+WskBind
+WskConnect
),WskControlClient
.Also, socket event callbacks are not working yet. Their implementation possibly requires some changes to the Socket driver code, thus, I decided to possibly do that in a later PR. These callbacks can be used to notify the user about an incomming connection or of newly arrived data.
This is still a WORK IN PROGRESS, some formatting needs to be altered and some descriptions added. It will be finished this Monday or Tuesday.