Skip to content

Commit

Permalink
detect/port: merge port ranges for same signatures
Browse files Browse the repository at this point in the history
To avoid getting multiple entries in the final port list and to also
make the next step more efficient by reducing the size of the items to
traverse over.

Ticket 6792
Bug 6414
  • Loading branch information
inashivb authored and victorjulien committed Mar 4, 2024
1 parent 83aba93 commit 643ae85
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/detect-engine-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -1163,9 +1163,7 @@ static inline uint32_t SetUniquePortPoints(
}

/* Treat right boundary as single point to avoid creating unneeded
* ranges later on
* TODO merge the extra entry created in the rulegroup
* for such points in *CreateGroupedPortList* fn */
* ranges later on */
if (unique_list[p->port2] == 0) {
size_list++;
}
Expand Down
25 changes: 25 additions & 0 deletions src/detect-engine-siggroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,31 @@ void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx)
return;
}

/**
* \brief Finds if two Signature Group Heads are the same.
*
* \param sgha First SGH to be compared
* \param sghb Secornd SGH to be compared
*
* \return true if they're a match, false otherwise
*/
bool SigGroupHeadEqual(const SigGroupHead *sgha, const SigGroupHead *sghb)
{
if (sgha == NULL || sghb == NULL)
return false;

if (sgha->init->sig_size != sghb->init->sig_size)
return false;

if (sgha->init->max_sig_id != sghb->init->max_sig_id)
return false;

if (SCMemcmp(sgha->init->sig_array, sghb->init->sig_array, sgha->init->sig_size) != 0)
return false;

return true;
}

void SigGroupHeadSetProtoAndDirection(SigGroupHead *sgh,
uint8_t ipproto, int dir)
{
Expand Down
1 change: 1 addition & 0 deletions src/detect-engine-siggroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ int SigGroupHeadHashRemove(DetectEngineCtx *, SigGroupHead *);

void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid);
void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx);
bool SigGroupHeadEqual(const SigGroupHead *, const SigGroupHead *);
void SigGroupHeadSetProtoAndDirection(SigGroupHead *sgh,
uint8_t ipproto, int dir);
int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint32_t max_idx);
Expand Down
32 changes: 32 additions & 0 deletions src/util-port-interval-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,35 @@ int SCPortIntervalInsert(DetectEngineCtx *de_ctx, SCPortIntervalTree *it, const
return SC_OK;
}

/**
* \brief Function to remove multiple sig entries corresponding to the same
* signature group and merge them into one.
*
* \param de_ctx Detection Engine Context
* \param list Pointer to the list to be modified
*/
static void SCPortIntervalSanitizeList(DetectEngineCtx *de_ctx, DetectPort **list)
{
DetectPort *cur = (*list)->last;
if (cur == NULL)
return;

DetectPort *prev = (*list)->last->prev;
if (prev == NULL)
return;

/* rulegroup IDs are assigned much later so, compare SGHs */
if (SigGroupHeadEqual(prev->sh, cur->sh)) {
if (prev->port2 == (cur->port - 1)) {
/* Merge the port objects */
prev->port2 = cur->port2;
(*list)->last = prev;
(*list)->last->next = NULL;
DetectPortFree(de_ctx, cur);
}
}
}

/**
* \brief Function to check if a port range overlaps with a given set of ports
*
Expand Down Expand Up @@ -226,6 +255,7 @@ static void SCPortIntervalFindOverlaps(DetectEngineCtx *de_ctx, const uint16_t p
((*list)->last->port2 != new_port->port)) {
DEBUG_VALIDATE_BUG_ON(new_port->port < (*list)->last->port);
(*list)->last->next = new_port;
new_port->prev = (*list)->last;
(*list)->last = new_port;
} else {
SCLogDebug("Port already exists in the list");
Expand Down Expand Up @@ -260,6 +290,8 @@ static void SCPortIntervalFindOverlaps(DetectEngineCtx *de_ctx, const uint16_t p
BUG_ON(popped == NULL);
current = IRB_RIGHT(popped, irb);
}
if (new_port != NULL)
SCPortIntervalSanitizeList(de_ctx, list);
if (stack != NULL)
SCFree(stack);
return;
Expand Down

0 comments on commit 643ae85

Please sign in to comment.