A-A+

suricata 3.1 源码分析15 (流更新)

2018年12月06日 suricata 暂无评论

流更新

通过FlowWorker线程函数中调用FlowUpdate,FlowUpdate中又调用了FlowHandlePacketUpdate来更新流。
在获取到包所属的流后,接下来将根据这个包对流进行更新。

/** \brief Update Packet and Flow
 *
 *  Updates packet and flow based on the new packet.
 *
 *  \param f locked flow
 *  \param p packet
 *
 *  \note overwrites p::flowflags
 */
void FlowHandlePacketUpdate(Flow *f, Packet *p)
{
    SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f);

    /* update flags and counters */
    if (FlowGetPacketDirection(f, p) == TOSERVER) {
//调用FlowGetPacketDirection获取数据包的方向。注意,这里的方向是相对于流来说的,而流的初始方向由该流的第一个包决定,若当前包与流的第一个包的方向一致(源端口相同或源地址相同),则方向为TOSERVER(可以认为是正向),否则为TOCLIENT(反向)。

        f->todstpktcnt++;
        f->todstbytecnt += GET_PKT_LEN(p);
        p->flowflags = FLOW_PKT_TOSERVER;
        if (!(f->flags & FLOW_TO_DST_SEEN)) {
            if (FlowUpdateSeenFlag(p)) {
                f->flags |= FLOW_TO_DST_SEEN;
                p->flowflags |= FLOW_PKT_TOSERVER_FIRST;
            }
        }
//若数据包方向为TOSERVER,则增加对应的引用计数,添加流状态标志FLOW_TO_DST_SEEN,并且为数据包的flowflags添加FLOW_PKT_TOSERVER。
    } else {
        f->tosrcpktcnt++;
        f->tosrcbytecnt += GET_PKT_LEN(p);
        p->flowflags = FLOW_PKT_TOCLIENT;
        if (!(f->flags & FLOW_TO_SRC_SEEN)) {
            if (FlowUpdateSeenFlag(p)) {
                f->flags |= FLOW_TO_SRC_SEEN;
                p->flowflags |= FLOW_PKT_TOCLIENT_FIRST;
            }
        }
    }
//若数据包方向为TOCLIENT,则增加对应的引用计数,添加流状态标志FLOW_TO_SRC_SEEN,并且为数据包的flowflags添加FLOW_PKT_TOSERVER。

    if ((f->flags & (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) == (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) {
        SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p);
        p->flowflags |= FLOW_PKT_ESTABLISHED;

        if (f->proto != IPPROTO_TCP) {
            SC_ATOMIC_SET(f->flow_state, FLOW_STATE_ESTABLISHED);
        }
    }
//若流的FLOW_TO_DST_SEEN和FLOW_TO_SRC_SEEN都设置了,说明流已经建立,给包添加FLOW_PKT_ESTABLISHED标志。后面检测时会用到这个标志。

    /*set the detection bypass flags*/
    if (f->flags & FLOW_NOPACKET_INSPECTION) {
        SCLogDebug("setting FLOW_NOPACKET_INSPECTION flag on flow %p", f);
        DecodeSetNoPacketInspectionFlag(p);
    }
    if (f->flags & FLOW_NOPAYLOAD_INSPECTION) {
        SCLogDebug("setting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f);
        DecodeSetNoPayloadInspectionFlag(p);
    }
}
//若流的FLOW_NOPACKET_INSPECTION(绕过包检测)或FLOW_NOPAYLOAD_INSPECTION(绕过负载检测)设置了,则给包也添加相应标志。
标签:

给我留言

Copyright © 九毛的官方博客 保留所有权利.   Theme  Ality

用户登录