mirror of
https://github.com/tnodir/fort
synced 2024-11-15 07:06:08 +00:00
Driver: Shaper: Rework packets processing
This commit is contained in:
parent
6cec5d5029
commit
e880ea9ae5
@ -19,6 +19,7 @@ SOURCES += \
|
|||||||
fortscb.c \
|
fortscb.c \
|
||||||
fortstat.c \
|
fortstat.c \
|
||||||
forttds.c \
|
forttds.c \
|
||||||
|
fortthr.c \
|
||||||
forttlsf.c \
|
forttlsf.c \
|
||||||
forttmr.c \
|
forttmr.c \
|
||||||
forttrace.c \
|
forttrace.c \
|
||||||
@ -57,6 +58,7 @@ HEADERS += \
|
|||||||
fortscb.h \
|
fortscb.h \
|
||||||
fortstat.h \
|
fortstat.h \
|
||||||
forttds.h \
|
forttds.h \
|
||||||
|
fortthr.h \
|
||||||
forttlsf.h \
|
forttlsf.h \
|
||||||
forttmr.h \
|
forttmr.h \
|
||||||
forttrace.h \
|
forttrace.h \
|
||||||
|
@ -26,7 +26,6 @@ typedef enum FORT_FUNC_ID {
|
|||||||
FORT_DEVICE_LOAD,
|
FORT_DEVICE_LOAD,
|
||||||
FORT_DEVICE_UNLOAD,
|
FORT_DEVICE_UNLOAD,
|
||||||
FORT_PACKET_INJECT_COMPLETE,
|
FORT_PACKET_INJECT_COMPLETE,
|
||||||
FORT_SHAPER_TIMER_PROCESS,
|
|
||||||
FORT_SYSCB_POWER,
|
FORT_SYSCB_POWER,
|
||||||
FORT_SYSCB_TIME,
|
FORT_SYSCB_TIME,
|
||||||
FORT_TIMER_CALLBACK,
|
FORT_TIMER_CALLBACK,
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "fortps.c"
|
#include "fortps.c"
|
||||||
#include "fortstat.c"
|
#include "fortstat.c"
|
||||||
#include "fortscb.c"
|
#include "fortscb.c"
|
||||||
|
#include "fortthr.c"
|
||||||
#include "forttmr.c"
|
#include "forttmr.c"
|
||||||
#include "forttrace.c"
|
#include "forttrace.c"
|
||||||
#include "fortutl.c"
|
#include "fortutl.c"
|
||||||
|
@ -17,6 +17,16 @@
|
|||||||
|
|
||||||
typedef void FORT_SHAPER_PACKET_FOREACH_FUNC(PFORT_SHAPER, PFORT_FLOW_PACKET);
|
typedef void FORT_SHAPER_PACKET_FOREACH_FUNC(PFORT_SHAPER, PFORT_FLOW_PACKET);
|
||||||
|
|
||||||
|
static UCHAR fort_shaper_flags_set(PFORT_SHAPER shaper, UCHAR flags, BOOL on)
|
||||||
|
{
|
||||||
|
return on ? InterlockedOr8(&shaper->flags, flags) : InterlockedAnd8(&shaper->flags, ~flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UCHAR fort_shaper_flags(PFORT_SHAPER shaper)
|
||||||
|
{
|
||||||
|
return fort_shaper_flags_set(shaper, 0, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static LONG fort_shaper_io_bits_exchange(volatile LONG *io_bits, LONG v)
|
static LONG fort_shaper_io_bits_exchange(volatile LONG *io_bits, LONG v)
|
||||||
{
|
{
|
||||||
return InterlockedExchange(io_bits, v);
|
return InterlockedExchange(io_bits, v);
|
||||||
@ -83,15 +93,10 @@ inline static BOOL fort_packet_is_ipsec_tunneled(PCFORT_CALLOUT_ARG ca)
|
|||||||
return info.isTunnelMode && !info.isDeTunneled;
|
return info.isTunnelMode && !info.isDeTunneled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG fort_packet_data_length(const PNET_BUFFER_LIST netBufList)
|
inline static ULONG fort_packet_data_length(PCFORT_CALLOUT_ARG ca)
|
||||||
{
|
{
|
||||||
ULONG data_length = 0;
|
PNET_BUFFER netBuf = NET_BUFFER_LIST_FIRST_NB(ca->netBufList);
|
||||||
|
const ULONG data_length = NET_BUFFER_DATA_LENGTH(netBuf);
|
||||||
PNET_BUFFER netBuf = NET_BUFFER_LIST_FIRST_NB(netBufList);
|
|
||||||
while (netBuf != NULL) {
|
|
||||||
data_length += NET_BUFFER_DATA_LENGTH(netBuf);
|
|
||||||
netBuf = NET_BUFFER_NEXT_NB(netBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data_length;
|
return data_length;
|
||||||
}
|
}
|
||||||
@ -578,14 +583,15 @@ static void fort_shaper_queue_process_bandwidth(
|
|||||||
{
|
{
|
||||||
const UINT64 bps = queue->limit.bps;
|
const UINT64 bps = queue->limit.bps;
|
||||||
|
|
||||||
/* Advance the available bytes */
|
|
||||||
const UINT64 accumulated =
|
|
||||||
((now.QuadPart - queue->last_tick.QuadPart) * bps) / shaper->qpcFrequency.QuadPart;
|
|
||||||
queue->available_bytes += accumulated;
|
|
||||||
|
|
||||||
if (fort_shaper_packet_list_is_empty(&queue->bandwidth_list)
|
if (fort_shaper_packet_list_is_empty(&queue->bandwidth_list)
|
||||||
&& queue->available_bytes > FORT_QUEUE_INITIAL_TOKEN_COUNT) {
|
&& queue->available_bytes > FORT_QUEUE_INITIAL_TOKEN_COUNT) {
|
||||||
queue->available_bytes = FORT_QUEUE_INITIAL_TOKEN_COUNT;
|
queue->available_bytes = FORT_QUEUE_INITIAL_TOKEN_COUNT;
|
||||||
|
} else {
|
||||||
|
/* Advance the available bytes */
|
||||||
|
const UINT64 accumulated =
|
||||||
|
((now.QuadPart - queue->last_tick.QuadPart) * bps) / shaper->qpcFrequency.QuadPart;
|
||||||
|
|
||||||
|
queue->available_bytes += accumulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue->last_tick = now;
|
queue->last_tick = now;
|
||||||
@ -598,11 +604,13 @@ static void fort_shaper_queue_process_bandwidth(
|
|||||||
PFORT_FLOW_PACKET pkt_tail = NULL;
|
PFORT_FLOW_PACKET pkt_tail = NULL;
|
||||||
PFORT_FLOW_PACKET pkt = pkt_chain;
|
PFORT_FLOW_PACKET pkt = pkt_chain;
|
||||||
do {
|
do {
|
||||||
if (bps != 0LL && queue->available_bytes < pkt->data_length)
|
const UINT64 pkt_length = pkt->data_length;
|
||||||
|
|
||||||
|
if (bps != 0LL && queue->available_bytes < pkt_length)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
queue->available_bytes -= pkt->data_length;
|
queue->available_bytes -= pkt_length;
|
||||||
queue->queued_bytes -= pkt->data_length;
|
queue->queued_bytes -= pkt_length;
|
||||||
|
|
||||||
pkt->latency_start = now;
|
pkt->latency_start = now;
|
||||||
|
|
||||||
@ -626,6 +634,12 @@ static PFORT_FLOW_PACKET fort_shaper_queue_process_latency(
|
|||||||
|
|
||||||
const UINT32 latency_ms = queue->limit.latency_ms;
|
const UINT32 latency_ms = queue->limit.latency_ms;
|
||||||
|
|
||||||
|
if (latency_ms == 0) {
|
||||||
|
fort_shaper_packet_list_cut_chain(&queue->latency_list, queue->latency_list.packet_tail);
|
||||||
|
|
||||||
|
return pkt_chain;
|
||||||
|
}
|
||||||
|
|
||||||
const UINT64 qpcFrequency = shaper->qpcFrequency.QuadPart;
|
const UINT64 qpcFrequency = shaper->qpcFrequency.QuadPart;
|
||||||
const UINT64 qpcFrequencyHalfMs = qpcFrequency / 2000LL;
|
const UINT64 qpcFrequencyHalfMs = qpcFrequency / 2000LL;
|
||||||
|
|
||||||
@ -786,17 +800,12 @@ static void fort_shaper_free_queues(PFORT_SHAPER shaper)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fort_shaper_timer_start(PFORT_SHAPER shaper)
|
inline static void fort_shaper_thread_set_event(PFORT_SHAPER shaper)
|
||||||
{
|
{
|
||||||
const ULONG active_io_bits = fort_shaper_io_bits(&shaper->active_io_bits);
|
KeSetEvent(&shaper->thread_event, IO_NO_INCREMENT, FALSE);
|
||||||
|
|
||||||
if (active_io_bits == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fort_timer_set_running(&shaper->timer, /*run=*/TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static ULONG fort_shaper_timer_process_queues(PFORT_SHAPER shaper, ULONG active_io_bits)
|
inline static ULONG fort_shaper_thread_process_queues(PFORT_SHAPER shaper, ULONG active_io_bits)
|
||||||
{
|
{
|
||||||
ULONG new_active_io_bits = 0;
|
ULONG new_active_io_bits = 0;
|
||||||
|
|
||||||
@ -821,25 +830,50 @@ inline static ULONG fort_shaper_timer_process_queues(PFORT_SHAPER shaper, ULONG
|
|||||||
return new_active_io_bits;
|
return new_active_io_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fort_shaper_timer_process(void)
|
inline static BOOL fort_shaper_thread_process(PFORT_SHAPER shaper)
|
||||||
{
|
{
|
||||||
FORT_CHECK_STACK(FORT_SHAPER_TIMER_PROCESS);
|
|
||||||
|
|
||||||
PFORT_SHAPER shaper = &fort_device()->shaper;
|
|
||||||
|
|
||||||
ULONG active_io_bits =
|
ULONG active_io_bits =
|
||||||
fort_shaper_io_bits_set(&shaper->active_io_bits, FORT_PACKET_FLUSH_ALL, FALSE);
|
fort_shaper_io_bits_set(&shaper->active_io_bits, FORT_PACKET_FLUSH_ALL, FALSE);
|
||||||
|
|
||||||
if (active_io_bits == 0)
|
if (active_io_bits == 0)
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
active_io_bits = fort_shaper_timer_process_queues(shaper, active_io_bits);
|
active_io_bits = fort_shaper_thread_process_queues(shaper, active_io_bits);
|
||||||
|
|
||||||
if (active_io_bits != 0) {
|
if (active_io_bits != 0) {
|
||||||
fort_shaper_io_bits_set(&shaper->active_io_bits, active_io_bits, TRUE);
|
fort_shaper_io_bits_set(&shaper->active_io_bits, active_io_bits, TRUE);
|
||||||
|
|
||||||
fort_shaper_timer_start(shaper);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fort_shaper_thread_loop(PVOID context)
|
||||||
|
{
|
||||||
|
PFORT_SHAPER shaper = context;
|
||||||
|
PKEVENT thread_event = &shaper->thread_event;
|
||||||
|
|
||||||
|
LARGE_INTEGER due;
|
||||||
|
due.QuadPart = 1LL * -10000LL /* ms -> us */;
|
||||||
|
|
||||||
|
PLARGE_INTEGER timeout = NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
KeWaitForSingleObject(thread_event, Executive, KernelMode, FALSE, timeout);
|
||||||
|
|
||||||
|
const BOOL is_active = fort_shaper_thread_process(shaper);
|
||||||
|
|
||||||
|
timeout = is_active ? &due : NULL;
|
||||||
|
|
||||||
|
} while ((fort_shaper_flags(shaper) & FORT_SHAPER_CLOSED) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fort_shaper_thread_close(PFORT_SHAPER shaper)
|
||||||
|
{
|
||||||
|
fort_shaper_thread_set_event(shaper);
|
||||||
|
|
||||||
|
fort_thread_wait(&shaper->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static PFORT_FLOW_PACKET fort_shaper_flush_queues(PFORT_SHAPER shaper, UINT32 group_io_bits)
|
inline static PFORT_FLOW_PACKET fort_shaper_flush_queues(PFORT_SHAPER shaper, UINT32 group_io_bits)
|
||||||
@ -889,13 +923,16 @@ FORT_API void fort_shaper_open(PFORT_SHAPER shaper)
|
|||||||
|
|
||||||
KeInitializeSpinLock(&shaper->lock);
|
KeInitializeSpinLock(&shaper->lock);
|
||||||
|
|
||||||
fort_timer_open(
|
KeInitializeEvent(&shaper->thread_event, SynchronizationEvent, FALSE);
|
||||||
&shaper->timer, /*period(ms)=*/1, FORT_TIMER_ONESHOT, &fort_shaper_timer_process);
|
|
||||||
|
fort_thread_run(&shaper->thread, &fort_shaper_thread_loop, shaper);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORT_API void fort_shaper_close(PFORT_SHAPER shaper)
|
FORT_API void fort_shaper_close(PFORT_SHAPER shaper)
|
||||||
{
|
{
|
||||||
fort_timer_close(&shaper->timer);
|
fort_shaper_flags_set(shaper, FORT_SHAPER_CLOSED, TRUE);
|
||||||
|
|
||||||
|
fort_shaper_thread_close(shaper);
|
||||||
|
|
||||||
fort_shaper_drop_packets(shaper);
|
fort_shaper_drop_packets(shaper);
|
||||||
fort_shaper_free_queues(shaper);
|
fort_shaper_free_queues(shaper);
|
||||||
@ -1020,11 +1057,12 @@ inline static NTSTATUS fort_shaper_packet_queue(
|
|||||||
return STATUS_NO_SUCH_GROUP;
|
return STATUS_NO_SUCH_GROUP;
|
||||||
|
|
||||||
/* Calculate the Packets' Data Length */
|
/* Calculate the Packets' Data Length */
|
||||||
const ULONG data_length = fort_packet_data_length(ca->netBufList);
|
const ULONG data_length = fort_packet_data_length(ca);
|
||||||
|
|
||||||
/* Check the Queue for new Packet */
|
/* Check the Queue for new Packet */
|
||||||
if (!fort_shaper_packet_queue_check_packet(queue, data_length))
|
if (!fort_shaper_packet_queue_check_packet(queue, data_length)) {
|
||||||
return STATUS_SUCCESS; /* drop the packet */
|
return STATUS_SUCCESS; /* drop the packet */
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the Packet */
|
/* Create the Packet */
|
||||||
PFORT_FLOW_PACKET pkt = fort_shaper_packet_get(shaper);
|
PFORT_FLOW_PACKET pkt = fort_shaper_packet_get(shaper);
|
||||||
@ -1048,8 +1086,8 @@ inline static NTSTATUS fort_shaper_packet_queue(
|
|||||||
/* Packets in transport layer must be re-injected in DCP due to locking */
|
/* Packets in transport layer must be re-injected in DCP due to locking */
|
||||||
fort_shaper_io_bits_set(&shaper->active_io_bits, queue_bit, TRUE);
|
fort_shaper_io_bits_set(&shaper->active_io_bits, queue_bit, TRUE);
|
||||||
|
|
||||||
/* Start the Timer */
|
/* Process the queued packets in thread */
|
||||||
fort_shaper_timer_start(shaper);
|
fort_shaper_thread_set_event(shaper);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "common/fortconf.h"
|
#include "common/fortconf.h"
|
||||||
#include "fortcoutarg.h"
|
#include "fortcoutarg.h"
|
||||||
#include "forttds.h"
|
#include "forttds.h"
|
||||||
#include "forttmr.h"
|
#include "fortthr.h"
|
||||||
|
|
||||||
#define FORT_PACKET_QUEUE_BAD_INDEX ((UINT16) -1)
|
#define FORT_PACKET_QUEUE_BAD_INDEX ((UINT16) -1)
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ typedef struct fort_pending_packet
|
|||||||
HANDLE completion_context;
|
HANDLE completion_context;
|
||||||
} FORT_PENDING_PACKET, *PFORT_PENDING_PACKET;
|
} FORT_PENDING_PACKET, *PFORT_PENDING_PACKET;
|
||||||
|
|
||||||
#define FORT_PENDING_PROC_COUNT_MAX 1024
|
#define FORT_PENDING_PROC_COUNT_MAX 1024
|
||||||
#define FORT_PENDING_PROC_PACKET_COUNT_MAX 3
|
#define FORT_PENDING_PROC_PACKET_COUNT_MAX 3
|
||||||
|
|
||||||
typedef struct fort_pending_proc
|
typedef struct fort_pending_proc
|
||||||
@ -129,8 +129,12 @@ typedef struct fort_pending
|
|||||||
KSPIN_LOCK lock;
|
KSPIN_LOCK lock;
|
||||||
} FORT_PENDING, *PFORT_PENDING;
|
} FORT_PENDING, *PFORT_PENDING;
|
||||||
|
|
||||||
|
#define FORT_SHAPER_CLOSED 0x01
|
||||||
|
|
||||||
typedef struct fort_shaper
|
typedef struct fort_shaper
|
||||||
{
|
{
|
||||||
|
UCHAR volatile flags;
|
||||||
|
|
||||||
UINT32 limit_io_bits;
|
UINT32 limit_io_bits;
|
||||||
|
|
||||||
LONG volatile group_io_bits;
|
LONG volatile group_io_bits;
|
||||||
@ -139,7 +143,8 @@ typedef struct fort_shaper
|
|||||||
ULONG randomSeed;
|
ULONG randomSeed;
|
||||||
LARGE_INTEGER qpcFrequency;
|
LARGE_INTEGER qpcFrequency;
|
||||||
|
|
||||||
FORT_TIMER timer;
|
KEVENT thread_event;
|
||||||
|
FORT_THREAD thread;
|
||||||
|
|
||||||
PFORT_FLOW_PACKET packet_free;
|
PFORT_FLOW_PACKET packet_free;
|
||||||
tommy_arrayof packets;
|
tommy_arrayof packets;
|
||||||
|
36
src/driver/fortthr.c
Normal file
36
src/driver/fortthr.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/* Fort Firewall Thread */
|
||||||
|
|
||||||
|
#include "fortthr.h"
|
||||||
|
|
||||||
|
#include "fortcb.h"
|
||||||
|
#include "fortdbg.h"
|
||||||
|
|
||||||
|
FORT_API NTSTATUS fort_thread_run(PFORT_THREAD thread, PKSTART_ROUTINE routine, PVOID context)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
thread->thread_obj = NULL;
|
||||||
|
|
||||||
|
HANDLE hThread;
|
||||||
|
status = PsCreateSystemThread(&hThread, 0, NULL, NULL, NULL, routine, context);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
hThread, THREAD_ALL_ACCESS, NULL, KernelMode, &thread->thread_obj, NULL);
|
||||||
|
|
||||||
|
ZwClose(hThread);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORT_API void fort_thread_wait(PFORT_THREAD thread)
|
||||||
|
{
|
||||||
|
if (thread->thread_obj == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
KeWaitForSingleObject(thread->thread_obj, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
|
ObDereferenceObject(thread->thread_obj);
|
||||||
|
thread->thread_obj = NULL;
|
||||||
|
}
|
23
src/driver/fortthr.h
Normal file
23
src/driver/fortthr.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef FORTTHR_H
|
||||||
|
#define FORTTHR_H
|
||||||
|
|
||||||
|
#include "fortdrv.h"
|
||||||
|
|
||||||
|
typedef struct fort_thread
|
||||||
|
{
|
||||||
|
PVOID thread_obj;
|
||||||
|
} FORT_THREAD, *PFORT_THREAD;
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FORT_API NTSTATUS fort_thread_run(PFORT_THREAD thread, PKSTART_ROUTINE routine, PVOID context);
|
||||||
|
|
||||||
|
FORT_API void fort_thread_wait(PFORT_THREAD thread);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // FORTTHR_H
|
@ -315,6 +315,20 @@ void IoQueueWorkItemEx(
|
|||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS PsCreateSystemThread(PHANDLE threadHandle, ULONG desiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES objectAttributes, HANDLE processHandle, PVOID clientId,
|
||||||
|
PKSTART_ROUTINE startRoutine, PVOID startContext)
|
||||||
|
{
|
||||||
|
UNUSED(threadHandle);
|
||||||
|
UNUSED(desiredAccess);
|
||||||
|
UNUSED(objectAttributes);
|
||||||
|
UNUSED(processHandle);
|
||||||
|
UNUSED(clientId);
|
||||||
|
UNUSED(startRoutine);
|
||||||
|
UNUSED(startContext);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER performanceFrequency)
|
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER performanceFrequency)
|
||||||
{
|
{
|
||||||
UNUSED(performanceFrequency);
|
UNUSED(performanceFrequency);
|
||||||
|
@ -246,6 +246,9 @@ typedef IO_WORKITEM_ROUTINE *PIO_WORKITEM_ROUTINE;
|
|||||||
typedef VOID IO_WORKITEM_ROUTINE_EX(PVOID IoObject, PVOID Context, PIO_WORKITEM IoWorkItem);
|
typedef VOID IO_WORKITEM_ROUTINE_EX(PVOID IoObject, PVOID Context, PIO_WORKITEM IoWorkItem);
|
||||||
typedef IO_WORKITEM_ROUTINE_EX *PIO_WORKITEM_ROUTINE_EX;
|
typedef IO_WORKITEM_ROUTINE_EX *PIO_WORKITEM_ROUTINE_EX;
|
||||||
|
|
||||||
|
typedef VOID KSTART_ROUTINE(PVOID startContext);
|
||||||
|
typedef KSTART_ROUTINE *PKSTART_ROUTINE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
short Year; // range [1601...]
|
short Year; // range [1601...]
|
||||||
@ -393,6 +396,10 @@ FORT_API void IoQueueWorkItem(
|
|||||||
FORT_API void IoQueueWorkItemEx(
|
FORT_API void IoQueueWorkItemEx(
|
||||||
PIO_WORKITEM workItem, PIO_WORKITEM_ROUTINE_EX routine, int queueType, PVOID context);
|
PIO_WORKITEM workItem, PIO_WORKITEM_ROUTINE_EX routine, int queueType, PVOID context);
|
||||||
|
|
||||||
|
FORT_API NTSTATUS PsCreateSystemThread(PHANDLE threadHandle, ULONG desiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES objectAttributes, HANDLE processHandle, PVOID clientId,
|
||||||
|
PKSTART_ROUTINE startRoutine, PVOID startContext);
|
||||||
|
|
||||||
FORT_API LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER performanceFrequency);
|
FORT_API LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER performanceFrequency);
|
||||||
|
|
||||||
FORT_API void KeQuerySystemTime(PLARGE_INTEGER time);
|
FORT_API void KeQuerySystemTime(PLARGE_INTEGER time);
|
||||||
|
@ -664,7 +664,7 @@ void ConfUtil::writeLimit(fort_speed_limit *limit, quint32 kBits, quint32 buffer
|
|||||||
limit->plr = packetLoss;
|
limit->plr = packetLoss;
|
||||||
limit->latency_ms = latencyMsec;
|
limit->latency_ms = latencyMsec;
|
||||||
limit->buffer_bytes = bufferSize;
|
limit->buffer_bytes = bufferSize;
|
||||||
limit->bps = quint64(kBits) * (1024 / 8);
|
limit->bps = quint64(kBits) * (1024LL / 8); /* to bytes per second */
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfUtil::writeAddressRanges(char **data, const addrranges_arr_t &addressRanges)
|
void ConfUtil::writeAddressRanges(char **data, const addrranges_arr_t &addressRanges)
|
||||||
|
Loading…
Reference in New Issue
Block a user