Skip to content

Commit

Permalink
Revert to older data structures, but with improved locking
Browse files Browse the repository at this point in the history
  • Loading branch information
bonsaiviking committed Apr 10, 2017
1 parent 8c27249 commit 2518294
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 258 deletions.
34 changes: 10 additions & 24 deletions packetWin7/npf/npf/Loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ NPF_NetworkClassify(
#endif

{
OPEN_ARRAY *TempArray;
POPEN_INSTANCE GroupOpen;
POPEN_INSTANCE TempOpen;
NTSTATUS status = STATUS_SUCCESS;
UINT32 ipHeaderSize = 0;
Expand Down Expand Up @@ -611,31 +611,17 @@ NPF_NetworkClassify(

/* Lock the group */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
/* Grab a local pointer to the copy we're using */
TempArray = g_LoopbackOpenGroupHead->Group;
/* Double-check there is even a group here */
if (TempArray) {
/* Increment the refcount on this so nobody frees it while we're iterating */
TempArray->refcount++;
/* Release the lock, allow others to replace the list if necessary */
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);

for (unsigned int i=0; i < TempArray->length; i++) {
TempOpen = TempArray->array[i];
if (TempOpen->AdapterBindingStatus == ADAPTER_BOUND)
{
NPF_TapExForEachOpen(TempOpen, pClonedNetBufferList);
}
}

/* Reacquire the lock to make sure nobody mucks with refcount after we check it */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
/* Decrement the refcount and check if we were the last ones using this copy */
if (--TempArray->refcount == 0) {
ExFreePool(TempArray);
GroupOpen = g_LoopbackOpenGroupHead->GroupNext;
while (GroupOpen != NULL)
{
TempOpen = GroupOpen;
if (TempOpen->AdapterBindingStatus == ADAPTER_BOUND)
{
//let every group adapter receive the packets
NPF_TapExForEachOpen(TempOpen, pClonedNetBufferList);
}
GroupOpen = TempOpen->GroupNext;
}
/* Release the spin lock no matter what. */
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
}

Expand Down
144 changes: 36 additions & 108 deletions packetWin7/npf/npf/Openclos.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,44 +1036,19 @@ NPF_AddToGroupOpenArray(
POPEN_INSTANCE GroupHead
)
{
OPEN_ARRAY *tempArray = NULL;
unsigned int newLen = 1;
POPEN_INSTANCE GroupRear;

TRACE_ENTER();

NdisAcquireSpinLock(&GroupHead->GroupLock);

if (GroupHead->Group) {
newLen = GroupHead->Group->length + 1;
GroupRear = GroupHead;
while (GroupRear->GroupNext != NULL)
{
GroupRear = GroupRear->GroupNext;
}
GroupRear->GroupNext = Open;
Open->GroupHead = GroupHead;

/* Make a new OPEN_ARRAY with room for all the current Opens plus the new one */
tempArray = ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_ARRAY) + newLen * sizeof(OPEN_INSTANCE *), 'PAOG');
if (tempArray == NULL) {
// no memory
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate memory pool");
NdisReleaseSpinLock(&GroupHead->GroupLock);
TRACE_EXIT();
return;
}

/* Copy over the old array */
if (GroupHead->Group) {
RtlCopyMemory(tempArray->array, GroupHead->Group->array, (GroupHead->Group->length) * sizeof(OPEN_INSTANCE *));
/* If we're the last ones using the old copy, free it */
if (--GroupHead->Group->refcount == 0) {
ExFreePool(GroupHead->Group);
}
}

/* Assign the new Open to the last slot in the array */
tempArray->array[newLen - 1] = Open;
/* Initialize length and refcount and swap in */
tempArray->length = newLen;
tempArray->refcount = 1;
GroupHead->Group = tempArray;

NdisReleaseSpinLock(&GroupHead->GroupLock);

TRACE_EXIT();
Expand Down Expand Up @@ -1125,14 +1100,13 @@ NPF_RemoveFromOpenArray(

// Remove the links between group head and group members.
NdisAcquireSpinLock(&Open->GroupLock);
if (Open->Group) {
for (unsigned int i=0; i < Open->Group->length; i++) {
Open->Group->array[i]->GroupHead = NULL;
}
if(--Open->Group->refcount == 0) {
ExFreePool(Open->Group);
}
GroupOpen = Open->GroupNext;
while (GroupOpen)
{
GroupOpen->GroupHead = NULL;
GroupOpen = GroupOpen->GroupNext;
}
Open->GroupNext = NULL;
NdisReleaseSpinLock(&Open->GroupLock);

NdisReleaseSpinLock(&g_OpenArrayLock);
Expand All @@ -1149,10 +1123,8 @@ NPF_RemoveFromGroupOpenArray(
POPEN_INSTANCE Open
)
{
POPEN_INSTANCE GroupHead = NULL;
OPEN_ARRAY *tempArray = NULL;
unsigned int newLen = 0;
unsigned int curr = 0;
POPEN_INSTANCE GroupOpen;
POPEN_INSTANCE GroupPrev = NULL;

TRACE_ENTER();

Expand All @@ -1162,54 +1134,28 @@ NPF_RemoveFromGroupOpenArray(
TRACE_EXIT();
return;
}
GroupHead = Open->GroupHead;

NdisAcquireSpinLock(&GroupHead->GroupLock);

if (GroupHead->Group) {
newLen = GroupHead->Group->length - 1;
}
NdisAcquireSpinLock(&Open->GroupHead->GroupLock);
GroupPrev = Open->GroupHead;
GroupOpen = GroupPrev->GroupNext;
while (GroupOpen)
{
if (GroupOpen == Open)
{
GroupPrev->GroupNext = GroupOpen->GroupNext;
GroupOpen->GroupHead = NULL;

/* Make a new OPEN_ARRAY with room for all the current Opens minus this one */
/* Because the OPEN_ARRAY contains space for one Open pointer already, this
* space is one too large, but that's ok because it means we don't write off
* the end when copying over in the unexpected case where Open is not
* actually in this group. */
tempArray = ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_ARRAY) + newLen * sizeof(OPEN_INSTANCE *), 'PAOG');
if (tempArray == NULL) {
// no memory
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate memory pool");
NdisReleaseSpinLock(&GroupHead->GroupLock);
TRACE_EXIT();
return;
}
NdisReleaseSpinLock(&Open->GroupHead->GroupLock);
TRACE_EXIT();
return;

/* Copy over the old array */
if (GroupHead->Group) {
for (unsigned int i=0; i < GroupHead->Group->length; i++) {
if (GroupHead->Group->array[i] == Open) {
/* pass */;
}
else {
tempArray->array[curr++] = GroupHead->Group->array[i];
}
}
/* If we're the last ones using the old copy, free it */
if (--GroupHead->Group->refcount == 0) {
ExFreePool(GroupHead->Group);
}
}
GroupPrev = GroupOpen;
GroupOpen = GroupOpen->GroupNext;
}
NdisReleaseSpinLock(&Open->GroupHead->GroupLock);

/* Initialize length and refcount and swap in */
tempArray->length = newLen;
tempArray->refcount = 1;
GroupHead->Group = tempArray;

NdisReleaseSpinLock(&GroupHead->GroupLock);

if (curr > newLen) {
IF_LOUD(DbgPrint("NPF_RemoveFromGroupOpenArray: error, the open isn't in the group open list.\n");)
}
IF_LOUD(DbgPrint("NPF_RemoveFromGroupOpenArray: error, the open isn't in the group open list.\n");)

TRACE_EXIT();
}
Expand Down Expand Up @@ -1920,36 +1866,18 @@ NOTE: Called at PASSIVE_LEVEL and the filter is in paused state
{
POPEN_INSTANCE Open = (POPEN_INSTANCE) FilterModuleContext;
POPEN_INSTANCE GroupOpen;
OPEN_ARRAY *TempArray = NULL;
BOOLEAN bFalse = FALSE;

TRACE_ENTER();

/* Lock the group */
NdisAcquireSpinLock(&Open->GroupLock);
/* Grab a local pointer to the copy we're using */
TempArray = Open->Group;
/* Double-check there is even a group here */
if (TempArray) {
/* Increment the refcount on this so nobody frees it while we're iterating */
TempArray->refcount++;
/* Release the lock, allow others to replace the list if necessary */
NdisReleaseSpinLock(&Open->GroupLock);

for (unsigned int i=0; i < TempArray->length; i++) {
GroupOpen = TempArray->array[i];
NPF_CloseOpenInstance(GroupOpen);

if (GroupOpen->ReadEvent != NULL)
KeSetEvent(GroupOpen->ReadEvent, 0, FALSE);
}
for (GroupOpen = Open->GroupNext; GroupOpen != NULL; GroupOpen = GroupOpen->GroupNext)
{
NPF_CloseOpenInstance(GroupOpen);

/* Reacquire the lock to make sure nobody mucks with refcount after we check it */
NdisAcquireSpinLock(&Open->GroupLock);
/* Decrement the refcount and check if we were the last ones using this copy */
if (--TempArray->refcount == 0) {
ExFreePool(TempArray);
}
if (GroupOpen->ReadEvent != NULL)
KeSetEvent(GroupOpen->ReadEvent, 0, FALSE);
}
/* Release the spin lock no matter what. */
NdisReleaseSpinLock(&Open->GroupLock);
Expand Down
12 changes: 2 additions & 10 deletions packetWin7/npf/npf/Packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,14 +319,6 @@ typedef struct __CPU_Private_Data
} CpuPrivateData;


struct _OPEN_INSTANCE;
typedef struct _OPEN_ARRAY
{
unsigned int refcount;
unsigned int length;
struct _OPEN_INSTANCE *array[1];
} OPEN_ARRAY;

/*!
\brief Contains the state of a running instance of the NPF driver.
Expand All @@ -351,9 +343,9 @@ typedef struct _OPEN_INSTANCE
#endif

struct _OPEN_INSTANCE *Next;
struct _OPEN_INSTANCE *GroupNext;
struct _OPEN_INSTANCE *GroupHead;
NDIS_SPIN_LOCK GroupLock;
OPEN_ARRAY *Group;
NDIS_SPIN_LOCK GroupLock;

ULONG MyPacketFilter;
ULONG HigherPacketFilter;
Expand Down
Loading

0 comments on commit 2518294

Please sign in to comment.