suricata 3.1 源码分析33 (FlowWorker处理流程2 - FlowHandlePacket)

来源:互联网 发布:图的深度优先遍历算法 编辑:程序博客网 时间:2024/06/05 23:55
void FlowHandlePacket(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p){    /* Get this packet's flow from the hash. FlowHandlePacket() will setup     * a new flow if nescesary. If we get NULL, we're out of flow memory.     * The returned flow is locked. *///获取包对应的流,找不到就新建流,返回流指针,返回空说明内存不足    Flow *f = FlowGetFlowFromHash(tv, dtv, p, &p->flow);    if (f == NULL)        return;    /* set the flow in the packet *///设置包的标记为属于某条流    p->flags |= PKT_HAS_FLOW;    return;}
Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p, Flow **dest){    Flow *f = NULL;    /* get our hash bucket and lock it */    const uint32_t hash = p->flow_hash;//获取对应的bucket    FlowBucket *fb = &flow_hash[hash % flow_config.hash_size];    FBLOCK_LOCK(fb);    SCLogDebug("fb %p fb->head %p", fb, fb->head);    /* see if the bucket already has a flow *//*如果p->flow_hash找不到对应的FlowBucket,则新建flow挂到对应的bucket上,并通过参数dest返回*/    if (fb->head == NULL) {        f = FlowGetNew(tv, dtv, p);        if (f == NULL) {            FBLOCK_UNLOCK(fb);            return NULL;        }        /* flow is locked */        fb->head = f;        fb->tail = f;        /* got one, now lock, initialize and return */        FlowInit(f, p);        f->flow_hash = hash;        f->fb = fb;        /* update the last seen timestamp of this flow */        COPY_TIMESTAMP(&p->ts,&f->lastts);        FlowReference(dest, f);        FBLOCK_UNLOCK(fb);        return f;    }    /* ok, we have a flow in the bucket. Let's find out if it is our flow */    f = fb->head;    /* see if this is the flow we are looking for *///如果packet和bucket的第一个flow不匹配(五元组+vlan不完全相同)    if (FlowCompare(f, p) == 0) {        Flow *pf = NULL; /* previous flow */        while (f) {            pf = f;            f = f->hnext;/*若遍历整个bucket链表找不到对应的flow,则新建flow挂到对应的bucket上,并通过参数dest返回*/            if (f == NULL) {                f = pf->hnext = FlowGetNew(tv, dtv, p);                if (f == NULL) {                    FBLOCK_UNLOCK(fb);                    return NULL;                }                fb->tail = f;                /* flow is locked */                f->hprev = pf;                /* initialize and return */                FlowInit(f, p);                f->flow_hash = hash;                f->fb = fb;                /* update the last seen timestamp of this flow */                COPY_TIMESTAMP(&p->ts,&f->lastts);                FlowReference(dest, f);                FBLOCK_UNLOCK(fb);                return f;            }/*若遍历bucket链表找到对应的flow,将当前flow放到bucket的flow->head,判断流重用,并通过参数dest返回*/            if (FlowCompare(f, p) != 0) {                /* we found our flow, lets put it on top of the                 * hash list -- this rewards active flows */                if (f->hnext) {                    f->hnext->hprev = f->hprev;                }                if (f->hprev) {                    f->hprev->hnext = f->hnext;                }                if (f == fb->tail) {                    fb->tail = f->hprev;                }                f->hnext = fb->head;                f->hprev = NULL;                fb->head->hprev = f;                fb->head = f;                /* found our flow, lock & return */                FLOWLOCK_WRLOCK(f);                if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) {                    f = TcpReuseReplace(tv, dtv, fb, f, hash, p);                    if (f == NULL) {                        FBLOCK_UNLOCK(fb);                        return NULL;                    }                }                /* update the last seen timestamp of this flow */                COPY_TIMESTAMP(&p->ts,&f->lastts);                FlowReference(dest, f);                FBLOCK_UNLOCK(fb);                return f;            }        }    }    /* lock & return *//*如果packet和bucket的第一个flow匹配(五元组+vlan相同),判断流重用,并通过参数dest返回*/    FLOWLOCK_WRLOCK(f);    if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) {        f = TcpReuseReplace(tv, dtv, fb, f, hash, p);        if (f == NULL) {            FBLOCK_UNLOCK(fb);            return NULL;        }    }    /* update the last seen timestamp of this flow */    COPY_TIMESTAMP(&p->ts,&f->lastts);    FlowReference(dest, f);    FBLOCK_UNLOCK(fb);    return f;}
0 0
原创粉丝点击