How can I pass through the bandwidth at the domain level of the application in Windows (in user mode)?

I would like to do the following:

  • My application runs on a Windows machine (name this application A).
  • I can modify the application source code to enter bandwidth throttling.
  • I would like to be able to reuse my bandwidth limitation code and transfer it to any other applications that I have (in other words, I would like to try to reduce bandwidth at the application domain level so that there is no refactoring of existing applications to regulate bandwidth )
  • I want to throttle cumulative download and download speed separately. For example, if A has a maximum of 5 Kbit / s allocated for download, then all A download flows will be limited to 5 Kbit / s.

My requirements:

  • I can not use the kernel mode driver.
  • I need to add throttling at the application domain level.

I tried to learn this, especially in Stack Overflow, but could not find anything useful for my case:

  • I saw this example of using the wrapper of the ThrottledStream class around the Stream object, which will introduce throttling when it is used, but I need it to be at the domain level; this approach is problematic because it will require me to reorganize a lot of existing code in other applications.
  • I saw this question that answers when talking about using the Windows Filtering API. Unfortunately, the requirement that I have is that I absolutely cannot use the kernel mode driver for this, and I understand that this requires the WFP API.

Does anyone know a way to implement my specific bandwidth requirements to throttle applications at the application domain level?

+6
source share
1 answer

I think I found a solution. Using the QOS API, you need to get the descriptor of the target interface using TcOpenInterface (you can find out which interface you want to target by calling TcEnumerateInterfaces ). Using the interface handle, you need to call TcAddFlow along with a pointer to TC_GEN_FLOW , which allows you to specify the SendingFlowspec ( FLOWSPEC ) and ReceivingFlowspec ( FLOWSPEC ) structures that contain the PeakBandwidth element. Then, in order for your interface to use this stream that you just added to it, you need to add a filter to your interface using the TcAddFilter call, since MSDN says that the TcAddFilter function associates a new filter with an existing stream that allows you to transfer packets matching the filter , in the corresponding stream. I think that in order to make it application-specific, calling TcRegisterClient can do a trick that you will need to call anyway to get the client handle to use with TcEnumerateInterfaces and TcAddFlow from the look (but this remains to be verified). I found this useful example (not tested it).

Taken from MSDN, the PeakBandwidth member is the upper limit on the time resolution for a given stream in bytes per second. The PeakBandwidth element limits the flows that can charge a significant amount of credits for transfer, or tokens from redundant network resources with one-time or cyclic data packets, by providing a data transfer ceiling per second. Some intermediate systems may take advantage of this information, resulting in a more efficient allocation of resources.

+1
source

Source: https://habr.com/ru/post/979738/


All Articles