mirror of https://github.com/dahall/Vanara.git
Fixed and enhanced QoS structures.
parent
9734721440
commit
aba2edf270
|
@ -118,7 +118,7 @@ public static partial class Qwave
|
|||
// QOS_OBJECT_HDR, *LPQOS_OBJECT_HDR;
|
||||
[PInvokeData("qos.h", MSDNShortId = "NS:qos.__unnamed_struct_0")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct QOS_OBJECT_HDR
|
||||
public struct QOS_OBJECT_HDR : IQoSObjectHdr
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Specifies the type of object to which <c>QOS_OBJECT_HDR</c> is attached. The following values are valid for <c>QOS_OBJECT_HDR</c>:</para>
|
||||
|
@ -145,6 +145,9 @@ public static partial class Qwave
|
|||
var ot = CorrespondingTypeAttribute.CanGet<QOS_OBJ_TYPE>(typeof(T), out var e) ? e : throw new ArgumentException();
|
||||
return new() { ObjectType = ot, ObjectLength = (uint)Marshal.SizeOf(typeof(T)) };
|
||||
}
|
||||
|
||||
/// <summary>An instance of <see cref="QOS_OBJECT_HDR"/> used for the end of a list.</summary>
|
||||
public static readonly QOS_OBJECT_HDR EndOfList = Init<QOS_OBJECT_HDR>();
|
||||
}
|
||||
|
||||
/// <summary>The QOS object <c>QOS_SD_MODE</c> defines the behavior of the traffic control-packet shaper component.</summary>
|
||||
|
|
|
@ -228,7 +228,7 @@ public static partial class Qwave
|
|||
}
|
||||
|
||||
ret.Write(native);
|
||||
if (bufLen > 0)
|
||||
if (bufLen > 0 && ParamBuffer.HasValue)
|
||||
{
|
||||
ret.Write(ParamBuffer.Value.Buffer, false, bufOffset);
|
||||
}
|
||||
|
|
|
@ -1973,6 +1973,25 @@ public static partial class Traffic
|
|||
/// criteria). Note that the <c>Mask</c> member must be of the same type as the <c>Pattern</c> member.
|
||||
/// </summary>
|
||||
public IntPtr Mask;
|
||||
|
||||
/// <summary>Creates a <see cref="TC_GEN_FILTER"/> instance.</summary>
|
||||
/// <typeparam name="T">The type of the pattern.</typeparam>
|
||||
/// <param name="AddressType">The filter type to be applied with the filter.</param>
|
||||
/// <param name="Pattern">Indicates the specific format of the pattern to be applied to the filter, such as IP_PATTERN.</param>
|
||||
/// <param name="Mask">A bitmask applied to the bits designated in the <c>Pattern</c> member.</param>
|
||||
/// <param name="memAlloc">The memory allocated too the <paramref name="Pattern"/> and <paramref name="Mask"/> fields.</param>
|
||||
/// <returns>
|
||||
/// A complete <see cref="TC_GEN_FILTER"/> instance. Do not dispose the value returned in <paramref name="memAlloc"/> until this
|
||||
/// structure is no longer needed.
|
||||
/// </returns>
|
||||
public static TC_GEN_FILTER Create<T>(NDIS_PROTOCOL_ID AddressType, in T Pattern, in T Mask, out SafeHandle memAlloc) where T : struct
|
||||
{
|
||||
var sz = Marshal.SizeOf(typeof(T));
|
||||
SafeNativeArray<T> parts = new(new T[] { Pattern, Mask });
|
||||
memAlloc = parts;
|
||||
var ptrs = parts.GetPointers();
|
||||
return new TC_GEN_FILTER { AddressType = AddressType, PatternSize = (uint)sz, Pattern = ptrs[0], Mask = ptrs[1] };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2086,14 +2105,15 @@ public static partial class Traffic
|
|||
if (managedObject is not TC_GEN_FLOW f)
|
||||
throw new ArgumentException("Only objects of type TC_GEN_FLOW can be marshaled.");
|
||||
int objLen = f.TcObjects?.Length ?? 0;
|
||||
SafeCoTaskMemStruct<INT_TC_GEN_FLOW> pFlow = new(new INT_TC_GEN_FLOW() { SendingFlowspec = f.SendingFlowspec, ReceivingFlowspec = f.ReceivingFlowspec, TcObjectsLength = objLen });
|
||||
pFlow.Size += f.TcObjects?.Sum(o => Marshal.SizeOf(o.GetType())) ?? 0;
|
||||
int objByteLen = f.TcObjects?.Sum(o => Marshal.SizeOf(o.GetType())) ?? 0;
|
||||
SafeCoTaskMemStruct<INT_TC_GEN_FLOW> pFlow = new(new INT_TC_GEN_FLOW() { SendingFlowspec = f.SendingFlowspec, ReceivingFlowspec = f.ReceivingFlowspec, TcObjectsLength = objByteLen });
|
||||
pFlow.Size += objByteLen;
|
||||
if (objLen > 0)
|
||||
{
|
||||
var oPtr = pFlow.GetFieldAddress(nameof(TcObjects));
|
||||
for (int i = 0; i < objLen; i++)
|
||||
{
|
||||
oPtr.Write(f.TcObjects[i]);
|
||||
oPtr.Write(f.TcObjects![i]);
|
||||
oPtr = oPtr.Offset(Marshal.SizeOf(f.TcObjects[i].GetType()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,9 +171,30 @@ public static partial class Ws2_32
|
|||
public struct FLOWSPEC
|
||||
{
|
||||
/// <summary>Represents a FLOWSPEC with all unspecified values.</summary>
|
||||
public static readonly FLOWSPEC NotSpecified = new() { DelayVariation = QOS_NOT_SPECIFIED, Latency = QOS_NOT_SPECIFIED, MaxSduSize = QOS_NOT_SPECIFIED,
|
||||
MinimumPolicedSize = QOS_NOT_SPECIFIED, PeakBandwidth = QOS_NOT_SPECIFIED, TokenBucketSize = QOS_NOT_SPECIFIED, TokenRate = QOS_NOT_SPECIFIED,
|
||||
ServiceType = SERVICETYPE.SERVICETYPE_BESTEFFORT };
|
||||
public static readonly FLOWSPEC NotSpecified = new(SERVICETYPE.SERVICETYPE_BESTEFFORT);
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="FLOWSPEC"/> struct.</summary>
|
||||
/// <param name="delayVariation">The delay variation.</param>
|
||||
/// <param name="latency">The latency.</param>
|
||||
/// <param name="maxSduSize">Maximum size of the sdu.</param>
|
||||
/// <param name="minimumPolicedSize">Minimum size of the policed.</param>
|
||||
/// <param name="peakBandwidth">The peak bandwidth.</param>
|
||||
/// <param name="tokenBucketSize">Size of the token bucket.</param>
|
||||
/// <param name="tokenRate">The token rate.</param>
|
||||
/// <param name="serviceType">Type of the service.</param>
|
||||
public FLOWSPEC(SERVICETYPE serviceType, uint tokenRate = QOS_NOT_SPECIFIED, uint delayVariation = QOS_NOT_SPECIFIED,
|
||||
uint latency = QOS_NOT_SPECIFIED, uint maxSduSize = QOS_NOT_SPECIFIED, uint minimumPolicedSize = QOS_NOT_SPECIFIED,
|
||||
uint peakBandwidth = QOS_NOT_SPECIFIED, uint tokenBucketSize = QOS_NOT_SPECIFIED)
|
||||
{
|
||||
DelayVariation = delayVariation;
|
||||
Latency = latency;
|
||||
MaxSduSize = maxSduSize;
|
||||
MinimumPolicedSize = minimumPolicedSize;
|
||||
PeakBandwidth = peakBandwidth;
|
||||
TokenBucketSize = tokenBucketSize;
|
||||
TokenRate = tokenRate;
|
||||
ServiceType = serviceType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
|
|
|
@ -69,14 +69,16 @@ public class QoSTests
|
|||
{
|
||||
TC_GEN_FLOW flow = new()
|
||||
{
|
||||
SendingFlowspec = FLOWSPEC.NotSpecified,
|
||||
ReceivingFlowspec = FLOWSPEC.NotSpecified,
|
||||
TcObjects = new IQoSObjectHdr[] { new QOS_DS_CLASS { ObjectHdr = QOS_OBJECT_HDR.Init<QOS_DS_CLASS>(), DSField = 0x28 } }
|
||||
SendingFlowspec = new FLOWSPEC(SERVICETYPE.SERVICETYPE_GUARANTEED, 10000, maxSduSize: 344, minimumPolicedSize: 12, peakBandwidth: 32000, tokenBucketSize: 680),
|
||||
ReceivingFlowspec = new(SERVICETYPE.SERVICETYPE_GUARANTEED, 10000),
|
||||
TcObjects = new IQoSObjectHdr[] { new QOS_DS_CLASS { ObjectHdr = QOS_OBJECT_HDR.Init<QOS_DS_CLASS>(), DSField = 0x2E }, QOS_OBJECT_HDR.EndOfList }
|
||||
};
|
||||
Assert.That(TcAddFlow(hIfc, default, default, flow, out var hFlow), ResultIs.Successful);
|
||||
try
|
||||
{
|
||||
TC_GEN_FILTER filter = new() { };
|
||||
IP_PATTERN pattern = new() { ProtocolId = (byte)IPPROTO.IPPROTO_UDP, tcDstPort = 5000 };
|
||||
IP_PATTERN mask = new() { ProtocolId = 0xFF, tcDstPort = 0xFFFF };
|
||||
TC_GEN_FILTER filter = TC_GEN_FILTER.Create(NDIS_PROTOCOL_ID.NDIS_PROTOCOL_ID_TCP_IP, pattern, mask, out var mem);
|
||||
Assert.That(TcAddFilter(hFlow, filter, out SafeHFILTER hFilt), ResultIs.Successful);
|
||||
hFilt.Dispose();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue