基于TCAM的确定性有穷状态自动机DFA的匹配方法和装置与流程

文档序号:11772780阅读:144来源:国知局
基于TCAM的确定性有穷状态自动机DFA的匹配方法和装置与流程
本发明涉及计算机应用技术领域,尤其涉及一种基于TCAM(ternarycontentaddressablememory,三态内容寻址存储器)的DFA的匹配方法和装置。

背景技术:
正则表达式技术是计算机网络系统的一项核心基础技术,被广泛应用于入侵检测和防护、签名匹配、蠕虫检测、包内容过滤、流量分析、协议识别等领域。正则表达式具有灵活、强大的描述字符串模式的能力,正则表达式的匹配通过有限自动机实现,该有限自动机包括NFA(non-deterministicfiniteautomaton,非确定性有限自动机)和DFA(deterministicfiniteautomaton,确定性有限自动机)。即可将正则表达式编译为一个NFA,然后可以进一步将此NFA编译为一个与之等价的DFA,通过NFA或者DFA的状态转换检查输入字符串中是否存在给定的正则表达式模式。NFA和DFA在存储空间和匹配速度两个方面拥有各自的优点和缺点。有限自动机存储的是一个状态转换表,给定一个当前活跃状态和一个输入字符,通过在状态转换表中查询,可得到下一时刻活跃的状态。自动机的存储空间取决于这个状态转换表的大小,由于字符表的大小通常是确定的(如ASCII表),所以自动机的存储空间主要取决于状态的个数。NFA所需存储空间小,其状态数与正则表达式的规则集大小(即规则集中字符数)成线性增长关系。但NFA的匹配速度很慢。由于NFA的不确定性,对于每个字符,NFA中的状态都有可能同时转移到多个目的状态,导致一次状态转换需要多次内存访问。对于这些同时激活的目的状态,在处理下一个输入字符时,它们又会同时激活更多的目的状态。因此,NFA的匹配速度是不可预测的,实际应用中,通常需要几十次内存访问才能完成一次NFA状态转换,远不能满足网络线速(linerate)。DFA具有确定性的匹配速度,由于对于每个输入字符,每个DFA状态有且仅有唯一的目的状态,因此每次DFA状态转换仅需一次内存访问。但DFA的状态数可能与正则表达式的规则集大小成指数增长关系,导致正则表达式规则通常无法用DFA存储。目前的基于DFA的方法都无法突破一个存储体积的瓶颈,即所存储的DFA转移边的数目总是大于DFA状态数,因此也就无法存储状态数成指数膨胀的DFA。目前,由于上述有限状态自动机的体量非常大,导致上述基于DFA的正则表达式匹配方法亟待改进。

技术实现要素:
本发明的实施例提供了一种基于TCAM的DFA的匹配方法和装置,以实现解决同时兼顾存储空间和匹配速度的难题。为实现上述的发明目的,本发明采用下述的技术方案:一种基于TCAM的确定性有穷状态自动机DFA的匹配方法,包括:将确定性有穷状态自动机DFA的每个状态用若干三态内容寻址存储器TCAM条目表示,每个TCAM条目由源状态域、输入字符域和目的状态域三个域组成,所述源状态域由模板ID域和私有ID域两个子域组成,分别用于存储源状态的模板ID编码和私有ID编码,所述目的状态域由模板ID域和私有ID域两个子域组成,所述模板ID域用于存储目的状态的模板ID编码和源状态的模板ID编码的异或结果,所述私有ID域用于存储目的状态的私有ID编码;以具体的所述源状态域和输入字符域的拼接作为搜索关键词,按照所述搜索关键字在所述DFA的所有TCAM条目中进行搜索,获取搜索得到的目的状态域,将所述目的状态域中的模板ID域的值与所述搜索关键字搜索关键词中的模板ID域的值进行异或,将所述异或结果作为所述目的状态域中的最终的模板ID域的值。一种基于TCAM的确定性有穷状态自动机的匹配装置,包括:TCAM条目构造模块,用于将确定性有穷状态自动机DFA的每个状态用若干三态内容寻址存储器TCAM条目表示,每个TCAM条目由源状态域、输入字符域和目的状态域三个域组成,所述源状态域由模板ID域和私有ID域两个子域组成,分别用于存储源状态的模板ID编码和私有ID编码,所述目的状态域由模板ID域和私有ID域两个子域组成,所述模板ID域用于存储目的状态的模板ID编码和源状态的模板ID编码的异或结果,所述私有ID域用于存储目的状态的私有ID编码;搜索匹配模块,用于以具体的所述源状态域和输入字符域的拼接作为搜索关键词,按照所述搜索关键字在所述DFA的所有TCAM条目中进行搜索,获取搜索得到的目的状态域,将所述目的状态域中的模板ID域的值与所述搜索关键词中的模板ID域的值进行异或,将所述异或结果作为所述目的状态域中的最终的模板ID域的值。本发明实施例通过基于TCAM实现DFA,TCAM条目的源状态域由模板ID域和私有ID域两个子域组成,目的状态域由模板ID域和私有ID域两个子域组成,可以在不牺牲匹配速度的前提下突破DFA状态数指数膨胀的问题,大大减少了DFA所需的存储空间。【附图说明】图1为本发明实施例一提供的一种基于TCAM(ternarycontentaddressablememory,三态内容寻址存储器)的DFA的匹配方法的具体处理流程图;图2为本发明实施例二所提供的用于匹配正则表达式ab.*cd的和ef.*gh的DFA;图3为本发明实施例四所提供的图2中的状态00生成的TCAM条目;图4为本发明实施例五所提供的用于匹配正则表达式ab.*cd的和ef.*gh的NFA;图5为本发明实施例五所提供的图2中的各个DFA状态所对应的NFA子集;图6为本发明实施例五所提供的模板ID的编码;图7为本发明实施例五所提供的基于私有ID相同的状态集合和模板关系构造的树;图8为本发明实施例五所提供的私有ID的编码;图9为本发明实施例六所提供的图2的整个DFA进行编码后的TCAM;图10为本发明实施例七所提供的对图9中的TCAM进行压缩后的TCAM;图11为本发明实施例八提供的一种基于TCAM的DFA的匹配装置的具体结构图。【具体实施方式】为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合附图,以对本发明实施例进行清楚、完整地描述人员。本发明实施例的目的在于突破当前DFA实现技术难以同时兼顾存储空间和匹配速度的难题,尤其是在不牺牲匹配速度的前提下突破DFA状态数指数膨胀的问题,提供一种基于TCAM实现DFA的方法。实施例一该实施例提供的一种基于TCAM的DFA的匹配方法的具体处理流程如图1所示,包括如下的处理步骤:步骤S101、将DFA的每个状态用若干TCAM条目表示,每个TCAM条目由源状态域、输入字符域和目的状态域三个域组成,所述源状态域由模板ID域和私有ID域两个子域组成。DFA可采用TCAM实现。TCAM作为一种高速并行查找引擎,已广泛部署于各种高速网络设备中,用于IP地址查找和基于包头的包分类等网络应用。TCAM存储单元可存储“0”、“1”、“*”三种状态的比特值,其中,比特值“*”表示“不关心状态”,即既可以是“0”也可以是“1”。TCAM芯片由一定数目的TCAM条目(entry)组成。每个时钟周期内,TCAM并行地将所有条目与搜索关键词(searchkey)进行比较,在所有满足匹配条件的条目中,TCAM返回第一个条目作为输出。TCAM的输出将作为新的搜索关键词的一部分,继续参与下一次匹配。由于TCAM能存储“*”的模糊匹配能力,使得TCAM能有效存储和压缩DFA的存储空间;由于TCAM的并行查找能力,使得TCAM每执行一次DFA状态转换,只需要一次TCAM时钟周期,从而保证了不牺牲DFA的匹配速度。基于TCAM实现DFA,有望同时兼顾存储空间和匹配速度两大难题。当上述输入字符采用ASCII字符时,因为ASCII字符有256个,所以每个状态对应256个TCAM条目。在实际应用中,上述“出发状态”域和“输入字符”域可以是由“0”、“1”和“*”组成的字符串,“到达状态”域可以是“0”和“1”组成的字符串。上述DFA可能是由正则表达式规则编译得到,也可能是由字符串规则编译得到,甚至别的任何方式得到。本发明实施例将DFA的每个状态用若干TCAM条目表示,每个TCAM条目由源状态域、输入字符域和目的状态域三个域组成。表示同一状态的TCAM条目的出发状态相同。源状态域、输入字符域存储在TCAM中,目的状态域存储在附属的SRAM中。步骤S102、基于DFA内在的结构特征,对DFA状态进行编号的方法。定义DFA状态i和的DFA状态j之间的“共享边”和“非共享边”,若对于某个输入字符,状态i和状态j各有一条出边经过该输入字符转移到某个相同的目的状态,则这两条出边是状态i和状态j之间的“共享边”;若对于某个输入字符,状态i和状态j各有一条出边经过该输入字符转移到不同的目的状态,则状态i的这条出边是关于状态j的“非共享边”,且状态j的这条出边是关于状态i的“非共享边”。定义两个DFA状态的“相似度”,它的取值是这两个DFA状态之间的共享边的数目。每个DFA状态均用一对状态ID进行编号,这个状态ID对命名为(“模板ID”,“私有ID”),每个DFA状态有且仅有唯一的(模板ID,私有ID)对。定义“自循环状态”,它是转移到自身的出边的数目超过了一定的阈值的状态,阈值大小为10。为每个自循环状态分配一个唯一的模板ID,为所有的自循环状态分配一个相同的私有ID。每个自循环状态的模板ID的编码过程如下:根据DFA与生成它的NFA之间的关系:每个DFA状态代表一组NFA状态的集合;对DFA中所有的自循环状态所代表的NFA状态的集合取并集,模板ID编码的长度即为该并集的大小,在模板ID编码中为并集中的每个NFA状态分配一位比特,对每一个自循环状态,若其子集中的NFA状态出现在此并集中,其比特位置“1”,否则置“0”。对于每个非自循环状态,其模板ID的取值为与其相似度最大的自循环状态的模板ID;其私有ID的取值按如下宽度遍历过程迭代进行,即维护一个状态集合的队列Q,尝试为所有在同一个状态集合中的状态分配相同的私有ID,初始将由所有自循环状态组成的状态集合入队,并将该状态集合标记为“已访问”,每次取出队首的状态集合S直至队列为空:依次迭代检查S经每一个字符所达到的目的状态集合D。从D中删去所有自循环状态;若D中存在多个状态共享相同的模板ID,则只留下其中一个状态(优先留下尚未被分配私有ID的状态),其余的状态从D中删去。若存在一个已访问过的状态集合S’,使得则跳出本次迭代;若存在一个已访问过的状态集合S’(S’中所有的状态已被分配相同的“私有ID”),使得则将S’中状态所分配的“私有ID”分配给D中所有状态;否则,D中所有状态分配一个尚未被分配过的“私有ID”;将D中所有状态从所有已访问的状态集合中删除;标记集合D为已访问;D入队。步骤S103、基于上述DFA的状态编号方法,确定DFA状态间“模板”关系的方法。定义DFA状态间的“模板”关系,模板关系是一种单向的关系,每个DFA状态至多只有一个模板状态,若状态i以状态j为模板,则状态i在TCAM中只需要存储其关于状态j的非共享边。全部的DFA状态被划分成多个状态集合,每个状态集合包含的是全部拥有相同私有ID的状态,且该状态集合以这个私有ID命名。定义“亲属状态”,如果两个状态分属于两个状态集合,且它们共享相同的模板ID,则它们互为彼此的亲属状态。每个状态至多只有一个模板状态。对于私有ID为K的状态集合,若私有ID为J的状态集合同时满足下述条件,则状态集合K的所有状态都各自选择它们在状态集合J中的亲属状态作为模板状态:J<K;对于集合K中的每一个状态,其在集合J中都存在一个亲属状态;在所有满足上述两个条件的候选状态集合中,集合J与集合K的相似度(它的值为集合K与集合J之间所有的的亲属状态对的相似度之和)最大;私有ID为0的状态,即自循环状态,不为之分配模板。步骤S104、基于上述DFA的状态编号方法和模板关系,在TCAM中对DFA状态进行编码的方法。定义字符串之间的“匹配”关系,给定两个由比特“0”、“1”或“*”组成的字符串,分别记为T和P,如果字符串T和P的长度一样,且对于每一位比特,T在该位上的比特值等于P在该位上的比特值或者P在该位上的比特值为“*”,则称字符串T“匹配”字符串P。每一个在DFA中出现的模板ID,其在TCAM中均有唯一的模板ID编码;每一个在DFA中出现的私有ID,其在TCAM中均有唯一的私有ID编码;每一个DFA状态,其在TCAM中均有有唯一的(模板ID编码,私有ID编码)对;对于存在模板关系的两个DFA状态i和j,若状态i以状态j为模板,则状态i的私有ID编码覆盖状态j的私有ID编码。基于上述DFA状态间的模板关系,在TCAM中对私有ID进行编码的方法包括:DFA状态间的模板关系将所有的DFA状态组织成多个树,每个树均以一个自循环状态作为根,每个状态均以它的模板状态为父结点;在所述树中为每个状态分配一个“子编码”,如果一个状态有N个子结点,则这N个子结点所需的子编码比特数为每个子结点分配一个长度为n的互不相同的子编码;全“0”的编码保留不分配,叶子结点的子编码为空;私有ID相同的状态分配的子编码必须相同;每个状态的私有ID的编码即为它所有祖先结点的子编码与自身子编码的拼接,即从树根开始到每个状态,该状态的初始私有ID编码为空,沿途依次在后面拼接上所访问的父结点的子编码,最后拼接上该状态的子编码,作为该状态的私有ID编码;为使私有ID编码的长度一致,取最长的私有ID编码的长度,在所有的私有ID编码后面拼接上全“*”以扩展到统一的最长的长度。步骤S104、基于上述TCAM中的状态编码方法,在TCAM中对DFA的状态转移边进行编码的方法。TCAM条目的源状态域由“模板ID域”和“私有ID域”两个子域组成,分别用于存储源状态的模板ID编码和私有ID编码;TCAM条目的目的状态域由“模板ID域”和“私有ID域”两个子域组成,“模板ID域”用于存储目的状态的模板ID编码和源状态的模板ID编码的异或结果,“私有ID域”用于存储目的状态的私有ID编码;TCAM的搜索关键词由源状态域和输入字符域拼接而成,其中源状态域由模板ID域和私有ID域组成,TCAM的搜索关键词仅包含比特“0”或“1”;给定搜索关键词,TCAM返回对应的目的状态域,其中,对于返回结果中的“模板ID域”的值,需计算它与搜索关键词中的模板ID域的值的异或结果,作为真实的“模板ID域”的值输出;每个DFA状态只需存储它关于其模板状态的非共享边,若一个状态没有模板状态,则它需要存储其全部的状态转移边;存在模板关系的两个DFA状态生成的TCAM条目之间的顺序如下:若状态i以状态j为模板,则状态i的状态转移边都必须存储在状态j的状态转移边之前;不存在模板关系的两个DFA状态生成的TCAM条目之间的顺序是任意的。步骤S105、对TCAM条目进行压缩的方法。状态内的TCAM条目压缩:根据不同的TCAM条目共享相同的目的状态域、源状态域,对输入字符域进行合并,从而减少单个状态所占用的TCAM条目;其过程如下:若存在共享相同的目的状态域、源状态域的两个条目i和j且i和j的输入字符域只相差一个比特,则在条目i的输入字符域中,将与条目j相差的比特位的值置为“*”,删除条目j,如此反复直到不存在这样的两个条目为止;状态间的TCAM条目压缩:根据不同的TCAM条目共享相同的目的状态域、输入字符域、源状态域的私有ID域,对源状态域的模板ID域进行合并,从而减少不同状态所占用的TCAM条目;其过程如下:若存在共享相同的目的状态域、输入字符域、源状态域的私有ID域的两个条目i和j且i和j的源状态域的模板ID域只相差一个比特,则在条目i的模板ID域中,将与条目j相差的比特位的值置为“*”,删除条目j,如此反复直到不存在这样的两个条目为止。步骤S106、将源状态域和输入字符域的拼接构成TCAM的搜索关键词,按照所述搜索关键字在所述DFA的所有TCAM条目中进行搜索,获取搜索得到的目的状态域。TCAM的搜索关键词由源状态域和输入字符域拼接而成,其中源状态域由模板ID域和私有ID域组成,TCAM的搜索关键词仅包含比特“0”或“1”。按照所述搜索关键字在所述DFA的所有TCAM条目中进行搜索,获取搜索得到的目的状态域,一次DFA状态转换只需要一次TCAM并行查找即可完成。将所述返回的目的状态域中的模板ID域的值与所述搜索关键词中的模板ID域的值进行异或,将所述异或结果作为所述目的状态域中的最终的模板ID域的值。以下实施例均采用两个正则表达式ab.*cd的和ef.*gh进行说明,正则表达式ab.*cd用于识别如下特征的字符串:首先匹配ab,接下来是任意字符出现任意多次,接下来是cd;正则表达式ef.*gh用于识别如下特征的字符串:首先匹配ef,接下来是任意字符出现任意多次,接下来是gh。这两个正则表达式匹配的字符串可以出现在输入文本中的任意位置。实施例二该实施例提供的一种对DFA中的状态进行编码的方法包括:一个状态数为n的DFA,它的状态通常用整数ID表示,即从表示,本发明对状态号重新编码以反映DFA的内在结构特征。图2所示是用于匹配正则表达式ab.*cd的和ef.*gh的DFA,圆圈为DFA状态,实线箭头为DFA的状态转移边。状态00是起始状态,接收状态用双圈表示,状态15和状态35是接收规则ab.*cd的接收状态,状态26和状态36是接收规则ef.*gh的接收状态。先定义一些相关的概念:定义DFA状态i和的DFA状态j之间的“共享边”和“非共享边”,若对于某个输入字符,状态i和状态j各有一条出边经过该字符转移到某个相同的目的状态,则这两条出边是状态i和状态j之间的“共享边”;若对于某个输入字符,状态i和状态j各有一条出边经过该字符转移到不同的目的状态,则状态i的这条出边是关于状态j的“非共享边”,且状态j的这条出边是关于状态i的“非共享边”;如图2中状态00和状态01,对于字符b,状态00到达状态00,而状态01到达状态10,故关于字符b的出边即为状态00和状态01的非共享边;对于字符a,状态00和状态01都转移到状态01,对于字符e,状态00和状态01都转移到状态03,而对于除a、b和e以外的字符,状态00和状态01都转移到状态00,故除字符b以外的255条边都是状态00和状态01的共享边;定义两个DFA状态的“相似度”,它的取值是这两个DFA状态之间的共享边的数目;如图2中状态00和状态11的相似度为255,因为它们除了对于字符b的目的状态不相同以外,对于其他255个字符均转移到相同的目的状态;定义DFA状态间的“模板”关系,模板关系是一种单向的关系,每个DFA状态至多只有一个模板状态,若状态i以状态j为模板,则状态i在TCAM中只需要存储其关于状态j的非共享边;图2中的状态间的模板关系用虚线箭头表示,箭头末端的状态即为箭头起始端的状态的“模板”;在图2中,每个状态只画出了它关于它的模板状态的非共享边,任何一个状态的非共享边都可以通过它的模板状态(通过虚线箭头)得到;定义“自循环状态”,它是转移到自身的出边的数目超过了一定的阈值的状态,阈值大小为10;图2中对四个代表自循环状态的圆圈加粗表示,即状态00、10、20、30,。图2中,DFA内部存在特征相似的子结构,如和都是识别字符串ab的子结构,和都是识别字符串cd的子结构,和都是识别字符串ef的子结构,和都是识别字符串gh的子结构。本发明对DFA状态进行合适的重编号,即用一对状态ID进行编号,其中一个ID用于表示具有相似结构特征的状态(称之为“模板ID”),另一个ID则用于区分在同一个相似子结构中不同的状态(称之为“私有ID”)。以下是状态ID重编号的方法:每个DFA状态均用一对状态ID进行编号,这个状态ID对命名为(模板ID,私有ID),每个DFA状态有且仅有唯一的(模板ID,私有ID)对;这也就保证了ID的唯一性,但同一个模板ID或者私有ID可以被不同的DFA状态所共享,只需保证对于每个状态,由模板ID和私有ID组合起来的ID对是唯一的即可;为每个自循环状态各自分配一个唯一的模板ID,为所有的自循环状态分配一个相同的私有ID;图2中为四个自循环状态00、10、20、30各自分配一个模板ID为0、1、2、3;同时分配一个相同的私有ID为0;对于每个非自循环状态,其模板ID的取值为与其相似度最大的自循环状态的模板ID;图2中的状态01、03与自循环状态00相似度最大,故它们的“模板ID”为0;状态12、13、15与自循环状态10相似度最大,故它们的“模板ID”为1;状态21、24、26与自循环状态20相似度最大,故它们的“模板ID”为2;状态32、34、35、36与自循环状态30相似度最大,故它们的“模板ID”为3;非自循环状态的“私有ID”的取值按如下宽度遍历过程迭代进行,即维护一个状态集合的队列Q,尝试为所有在同一个状态集合中的状态分配相同的私有ID,初始将由所有自循环状态组成的状态集合入队,即Q={00,10,20,30},并将该状态集合标记为已访问,每次取出队首的状态集合S直至队列为空:依次迭代检查S经每一个字符所达到的目的状态集合D,以字符a为例说明,状态集合S={00,10,20,30},S经过字符a所到达的目的状态集合D={01,10,21,30}:从D中删去所有自循环状态,因为自循环状态已经分配过了私有ID;若D中存在多个状态共享相同的模板ID,则只留下其中一个(优先留下尚未被分配私有ID的状态),其余的从D中删去,这样保证了模板ID相同的状态不会被分配相同的私有ID,也就保证了每个状态分配了唯一的ID对;经过此步骤后,D={01,21};若存在一个已访问过的状态集合S’,使得则跳出本次迭代;若存在一个已访问过的状态集合S’(S’中所有的状态已被分配相同的“私有ID”),使得则将S’中状态所分配的“私有ID”分配给D中所有状态;否则,D中所有状态分配一个尚未被分配过的“私有ID”,因此D中的所有状态01和21被分配了一个相同的新的“私有ID”为1;将D中所有状态从所有已访问的状态集合中删除;标记集合D为已访问;D加入队列Q。图2中整个“私有ID”的分配过程如下:从自循环状态组成的集合{00,10,20,30}出发,经过字符a找到集合{01,21}并为状态01、21分配“私有ID”1,经过字符c找到集合{12,32}并为状态12、32分配“私有ID”2,经过字符e找到集合{03,13}并为状态03、13分配“私有ID”3,经过字符g找到集合{24,34}并为状态24、34分配“私有ID”4;从状态集合{12,32}出发,经过字符d找到集合{15,35}并为状态15、35分配“私有ID”5;从状态集合{24,34}出发,经过字符h找到集合{26,36}并为状态26、36分配“私有ID”6;图2中的每个状态的ID都用两位数字表示,左边的数字表示模板ID,右边的数字表示私有ID,如状态01,其模板ID为0,且其私有ID为1。实施例三该实施例提供的一种确定DFA状态间“模板”关系的方法包括:图2中状态间的模板状态已用虚线箭头表示,本实施例说明如何建立状态间的模板关系。每个状态至多只有一个模板状态,其中自循环状态都没有模板状态,非自循环状态都有一个模板状态。首先,全部的DFA状态被划分成多个状态集合,每个集合包含的是全部拥有相同私有ID的状态,且该集合以这个私有ID命名;这样,图2中的状态可划分为7个状态集合,分别是私有ID为0~7的状态集合;定义“亲属状态”,如果两个状态分属于两个状态集合,且它们共享相同的模板ID,则它们互为彼此的亲属状态。如状态01和状态00就是一对亲属状态,因为状态01属于私有ID为1的状态集合,状态00属于私有ID为0的状态集合,且状态01和状态00共享相同的模板ID0。对于私有ID为K的状态集合,若私有ID为J的状态集合同时满足下述条件,则状态集合K的所有状态都各自选择它们在状态集合J中的亲属状态作为模板状态:J<K;对于集合K中的每一个状态,其在集合J中都存在一个亲属状态;在所有满足上述两个条件的候选状态集合中,集合J与集合K的相似度(即所有的集合K中的状态与其在集合J中的亲属状态的相似度之和)最大;也就是说,每个状态都选择一个和它共享模板ID的状态作为模板状态,同时,对于私有ID相同的状态,它们的模板状态的私有ID也是相同的。对于任意一个状态集合K,总是可以找到一个满足条件的状态集合J,因为由所有自循环状态组成的状态集合总是满足前两个条件。由于具有模板关系的所有状态都共享相同的模板ID,假设DFA中存在m个自循环状态(即m个模板ID),那么整个DFA就被分成了m棵树,树中状态通过模板关系联通,树根为一个自循环状态。依次按私有ID从小到大为每个状态集合中的状态分配模板关系,图2中的模板分配过程如下:私有ID为0的状态集合不分配模板;私有ID为1~6的所有状态集合都和私有ID为0的状态集合相似度最大,故均以私有ID为0的亲属状态为模板状态。最终得到的状态间的模板关系如图2的虚线箭头所示。实施例四该实施例提供的一种在TCAM中存储图2中的状态00的转移边的方法包括:如图3所示,DFA的状态转移边存储在一个TCAM和一个与之附属的SRAM中,一个“TCAM条目”由存储在TCAM中的“源状态域”、“输入字符域”和存储在附属的SRAM中的“目的状态域”所组成;“源状态域”和“读入字符域”是由“0”、“1”和“*”组成的字符串,“目的状态域”是“0”和“1”组成的字符串。用TCAM存储该DFA,在不经过任何压缩的情况下,每个状态需要256个TCAM条目(因为ASCII字符有256个),由于TCAM可以存储“*”,使得TCAM可以用较少的条目数表示一个状态的转移边。图2中的状态00经字符a到达目的状态01,经字符e到达目的状态03,经其它字符均返回自身。为清晰表示,下文中,状态在TCAM中的编码均以下划线标注。虽然TCAM存储的是比特“0”、“1”、“*”,附属的SRAM中存储的是比特“0”和“1”,但为方便表示,下文中的文字说明以及附图中,状态ID的编码有时会简写为状态的ID值,输入字符的编码简写为输入字符的值,为作分辨,在文字说明中用下划线标记编码形式的值。TCAM条目用“(源状态ID或其编码)(读入字符值或其ASCII编码)→(目的状态ID或其编码)”,其中编码形式用下划线表示,如图3中的第一个TCAM条目,记为“100000a→100001”。假定已知状态00的编码为“100000”,状态01的编码为“100001”,状态03的编码为“100100”,则如图3所示,只需要3个TCAM条目即可表示状态00的转移边。将DFA的源状态编码和输入字符编码拼接作为TCAM的搜索关键词,在所有匹配的条目中,TCAM返回最高(即最前)的结果(存储在附属的SRAM中的对应的目的状态编码),一次DFA状态转换只需要一次TCAM并行查找;如图3所示,假定在DFA的匹配过程中,当前状态为00,根据输入字符分三种情况:若输入字符为a,则搜索关键词为“100001a”,在TCAM中并行查找,搜索关键词会同时匹配第一个条目和第三个条目,TCAM返回第一个条目,输出存储在SRAM中的结果“100001”,即状态01;若输入字符为e,则搜索关键词为“100001e”,在TCAM中并行查找,搜索关键词会同时匹配第二个条目和第三个条目,TCAM返回第二个条目,输出存储在SRAM中的结果“100011”,即状态03;若输入字符为a和e以外的任意字符,则在TCAM中并行查找,搜索关键词仅匹配第三个条目,TCAM返回存储在SRAM中的结果“100000”,即状态00。用TCAM存储DFA,使得状态转换可以通过TCAM的并行查找来完成,而且一次状态转换仅需要一次并行查找。图3只是一个引子,用于说明TCAM如何存储单个DFA状态的转移边,TCAM更具体的结构将在后面的实施例中说明。实施例五该实施例提供的一种在TCAM中对DFA状态进行编码的方法包括:即对DFA状态的模板ID和私有ID进行编码,每一个在DFA中出现的模板ID,其在TCAM中均有唯一的模板ID编码;每一个在DFA中出现的私有ID,其在TCAM中均有唯一的私有ID编码。这样,每个DFA状态也将拥有一个由模板ID编码和私有ID编码组成的唯一的状态编码。实施例2中已说明,在分配模板状态的过程中,若DFA中存在m个自循环状态,则所有的状态被分成了m棵树,每棵树都以一个自循环状态为根状态。这样,每棵树中的状态都共享相同的模板ID,也就是作为树根的自循环状态的模板ID,因此,只需要对所有自循环状态的模板ID进行编码即可;同时,具有模板关系的状态因为彼此都共享相同的模板ID,故只需在私有ID编码中正确地反映状态间的模板关系即可。对模板ID和私有ID编码是独立进行的。对模板ID进行编码的原理:根据DFA与NFA之间的内在关系,在NFA转化为一个等价的DFA的过程中,每个DFA状态实际上模拟的是一组NFA状态的集合,或者说一个DFA状态本质上就是一个NFA状态子集。图4所示是用于匹配正则表达式ab.*cd的和ef.*gh的NFA,圆圈为NFA状态,箭头为NFA的状态转移边。状态0是起始状态,接收状态用双圈表示,状态7是接收规则ab.*cd的接收状态,状态8是接收规则ef.*gh的接收状态。图2所示的DFA是通过图4的NFA通过标准的算法(子集构造法)构造得到的。图5所示的是每个DFA状态所对应的NFA状态子集。对模板ID进行编码的步骤如下:对DFA中所有的自循环状态所代表的NFA状态的集合取并集,模板ID编码的长度即为该并集的大小,在模板ID编码中为并集中的每个NFA状态分配一位比特;对每一个自循环状态,若其子集中的NFA状态出现在此并集中,其比特位置“1”,否则置“0”。如图5,四个自循环状态的NFA子集分别为{0}、{0,3}、{0,4}、{0,3,4},取并集得到{0,3,4},为并集中的每一个NFA状态依次分配一位比特,于是自循环状态的NFA子集分别编码为“100”、“110”、“101”、“111”,也就是这些自循环状态的模板ID的编码。对于非自循环状态,其模板ID总是和某个自循环状态的模板ID相同,故它的模板ID编码也和那个自循环状态的模板ID编码相同。图6所示的是模板ID的编码。对私有ID进行编码的原理是:DFA状态间的模板关系将所有的DFA状态组织成多个树,每个树均以一个自循环状态作为根,每个状态均以它的模板状态为父结点。每个状态只需在TCAM中保存它关于它的模板状态的非共享边,它和模板状态的共享边只需存放在模板状态处。定义字符串之间的“匹配”关系,给定两个由比特“0”、“1”或“*”组成的字符串,分别记为T和P,如果字符串T和P的长度一样,且对于每一位比特,T在该位上的比特值等于P在该位上的比特值或者P在该位上的比特值为“*”,则称字符串T“匹配”字符串P;要在TCAM中实现状态间模板关系,当且仅当:对于存在模板关系的两个DFA状态i和j,若状态i以状态j为模板,则状态i的私有ID匹配状态j的私有ID编码。对私有ID进行编码的步骤如下:为每个私有ID分配一个“子编码”,如果一个状态有N个子结点,为了区分这N个子结点以及它们的父结点,所需的子编码比特数为每个子结点分配一个长度为n的互不相同的子编码;全“0”的编码保留不分配,叶子结点的子编码为空;私有ID相同的状态分配的子编码必须相同;为保证私有ID相同的状态分配相同的子编码,可采用实例2的基于状态集合的方法,即只构建一颗树,将私有ID相同的状态放到树中同一个节点中,在这棵树上,原来m棵树的模板关系仍然得到保持。如图7所示,每个结点代表一个私有ID相同的状态集合,图7中共7个结点,一个根结点和6个叶子结点,故需要个比特,私有ID为1~6的状态分别被分配子编码001~111;每个状态的私有ID的编码即为它所有祖先结点的子编码与自身子编码的拼接,即从树根开始到每个状态,该状态的初始私有ID编码为空,沿途依次在后面拼接上所访问的父结点的子编码,最后拼接上该状态的子编码,作为该状态的私有ID编码;为使私有ID编码的长度一致,取最长的私有ID编码的长度,在所有的私有ID编码后面拼接上全“*”以扩展到统一的最长的长度。如图8所示,每个私有ID均分配了三位比特的编码,其中私有ID0补齐“*”得到一个全“*”的编码。实施例六该实施例提供的一种在TCAM中对DFA状态转移边进行编码的方法包括:图9所示为对图2的整个DFA进行编码后的TCAM。TCAM条目的源状态域存储在TCAM部分,由“模板ID域”和“私有ID域”两个子域组成,分别用于存储源状态的模板ID编码和私有ID编码,源状态域允许存储比特“*”,能够被搜索关键词中的比特“0”或“1”匹配,因此在不改变TCAM的语义的前提下,源状态域可以将其存储的状态编码的部分比特位置“*”。TCAM条目的目的状态域存储在附属的SRAM中,仅存储比特“0”或“1”,由“模板ID域”和“私有ID域”两个子域组成,“模板ID域”用于存储目的状态的模板ID编码和源状态的模板ID编码的异或结果,“私有ID域”用于存储目的状态的私有ID编码。这里的“异或”是指对于源状态的私有ID编码和目的状态的私有ID编码,如果对应位置上的比特相同,则异或的结果为“0”,否则异或的结果为“1”,如“110”和“101”异或的结果为“011”,因为“110”和“101”的第一个比特相同,故异或的结果为“0”,后两位比特都不相同,故异或的结果为“1”。如果源状态的私有ID编码中出现“*”,在参与异或的时候,将其当做“0”处理即可。每一个DFA状态转移边都可以表示为一个TCAM条目,DFA状态转移边由三部分组成,即源状态,输入字符和目的状态;源状态在TCAM中编码成该状态的模板ID的编码和私有ID的编码的连接,输入字符在TCAM中编码成该字符的ASCII二进制码,计算源状态的模板ID编码(若该编码中包含比特*,则将比特*替换成比特0)和目的状态的模板ID编码(若该编码中包含比特*,则将比特*替换成比特0)的异或结果,目的状态域存储的是该异或结果和私有ID的编码的连接。如图9中的第一个条目“100001b→010000”表示图2中的状态01经过字符b转移到了一个目的状态10,对源状态的的模板ID编码(“100”)与目的状态的模板ID编码(“110”)做异或,异或的结果(“010”)存储在目的状态域的模板ID域。如图9中的第五个条目“100****→000000”表示图2中的状态00经过除字符a和e以外的任意字符转移到了自身(状态00),目的状态域的模板ID域存储的是源状态的模板ID编码(“100”)与目的状态的模板ID编码(“100”)的异或结果,状态00的私有ID编码是“***”,但目的状态域只能存储比特“0”和“1”,故在目的状态域将私有ID编码中的“*”全部替换成“0”,由于在分配私有ID编码的过程中为所有的父结点预留了全“0”的“子编码”,故将私有ID编码中的“*”全部替换成“0”不会导致和其他状态的私有ID编码产生歧义;TCAM的搜索关键词由源状态域和输入字符域拼接而成,其中源状态域由模板ID域和私有ID域组成,TCAM的搜索关键词仅包含比特“0”或“1”;如图9中的第一个条目“100001b→010000”表示图2中的状态01经过字符b转移到了一个目的状态,若搜索关键词匹配并输出第一个条目,因为目的状态域的模板ID域存储的是源状态的模板ID编码与目的状态的模板ID编码的异或结果,为获得真实的目的状态的模板ID编码,只需将搜索关键词中的模板ID域(“100”)与目的状态的模板ID域(“010”)做异或,异或的结果(“110”)即为真实的目的状态的模板ID编码,因此可知目的状态为图2中的状态10;每个DFA状态只需存储它关于其模板状态的非共享边,若一个状态没有模板状态,则它需要存储其全部的状态转移边;图2中的状态01以状态00为模板,故状态01只需存储其关于状态00的非共享边,图9的第一个条目即用于存储状态01的非共享边;状态00没有模板状态,故它需存储所有的256条边,由于空间所限,无法在图9中列出状态00的所有的256个TCAM条目,故利用TCAM可以存储“*”的能力,在图9中仅用三个条目存储状态00的所有的256条边,即图9所示的第3~5个TCAM条目,对状态00的条目的压缩方法将在后面的实施例中予以说明。存在模板关系的两个DFA状态生成的TCAM条目之间的顺序如下:若状态i以状态j为模板,则状态i的状态转移边都必须存储在状态j的状态转移边之前,反之若状态j以状态i为模板,则状态j的状态转移边都必须存储在状态i的状态转移边之前;若状态i和状态j之间不存在模板关系,则状态i的状态转移边和状态j的状态转移边之间的顺序是任意的;如图9所示,图2中的状态01以状态00为模板,故状态01的TCAM条目必须放置于状态00的条目之前,其余具有模板状态的状态也遵循同样的顺序放置它们的条目;不存在模板关系的两个DFA状态生成的TCAM条目之间的顺序是任意的。在对状态的私有ID进行编码时,根据DFA状态间的模板关系将所有的DFA状态组织成多个树,每个树均以一个自循环状态作为根,每个状态均以它的模板状态为父结点。通过把私有ID相同的状态合并到一个集合,可以将这些树表示为一棵树,如图7所示。因此,只需自顶向下层序遍历这颗树,对于依次遍历到的状态集合,将集合中的状态关于各自的模板状态的非共享边编码后自上往下地放置于TCAM中即可。如图9中,首先处理图7中的叶子结点,依次将私有ID为1~6的状态的非共享边编码到TCAM中,即第1~8个条目,最后处理私有ID为0的所有状态(即自循环状态),如图9中的第9~20个条目所示。实施例七该实施例提供的一种对TCAM条目进行压缩的方法包括:状态内的TCAM条目压缩:根据不同的TCAM条目共享相同的目的状态域、源状态域,对输入字符域进行合并,从而减少单个状态所占用的TCAM条目。如图9所示,原本状态00需要存储为所有的256个字符存储所有的256个条目,但采用状态内压缩以后,仅需第3~5个条目即可存储状态00的所有条目,即在状态00的压缩前的256个条目中,找到出现次数最多的目的状态域的值,即“000000”,生成一个新的条目作为“默认条目”,默认条目的输入字符域为全“*”,默认条目的目的状态域为这个出现次数最多的值(状态00的默认条目即为“100****→000000”),默认条目存储为最后一个条目;在原256个条目中,删去所有目的状态域为默认条目的目的状态域的值的条目;若剩下的条目中存在如下两个条目i和j:i和j的目的状态域相同且输入字符域只相差一个比特,则在条目i的输入字符域,将与条目j相差的比特位的值置为“*”,删除条目j,如此反复直到不存在这样的两个条目为止。经过上述步骤,状态00最终只需要三个条目。状态间的TCAM条目压缩:根据不同的TCAM条目共享相同的目的状态域、输入字符域、源状态域的私有ID域,对源状态域的模板ID域进行合并,从而减少不同状态所占用的TCAM条目;状态间压缩过程如下:若存在共享相同的目的状态域、输入字符域、源状态域的私有ID域的两个条目i和j:i和j的源状态域的模板ID域只相差一个比特,则在条目i的模板ID域中,将与条目j相差的比特位的值置为“*”,删除条目j,如此反复直到不存在这样的两个条目为止。图9的TCAM经过状态间压缩和状态内压缩后最终的结果如图10所示。对于一个状态数为16的DFA,本发明只需要9个TCAM条目即可存储,条目数少于DFA状态数,等于NFA状态数。本实施例说明,本发明突破了DFA状态空间的指数膨胀,所需的TCAM条目数能够少于DFA的状态数。本发明的积极效果不限于本实施例。实施例八该实施例提供了一种基于TCAM的NFA的匹配装置,其具体结构如图11所示,包括如下的模块:TCAM条目构造模块111,用于将确定性有穷状态自动机DFA的每个状态用若干三态内容寻址存储器TCAM条目表示,每个TCAM条目由源状态域、输入字符域和目的状态域三个域组成,所述源状态域由模板ID域和私有ID域两个子域组成,分别用于存储源状态的模板ID编码和私有ID编码,所述目的状态域由模板ID域和私有ID域两个子域组成,所述模板ID域用于存储目的状态的模板ID编码和源状态的模板ID编码的异或结果,所述私有ID域用于存储目的状态的私有ID编码;搜索匹配模块112,用于以具体的所述源状态域和输入字符域的拼接作为搜索关键词,按照所述搜索关键字在所述DFA的所有TCAM条目中进行搜索,获取搜索得到的目的状态域,将所述目的状态域中的模板ID域的值与所述搜索关键词中的模板ID域的值进行异或,将所述异或结果作为所述目的状态域中的最终的模板ID域的值。具体的,TCAM条目构造模块111,还用于当若对于某个输入字符,状态i和状态j各有一条出边经过该输入字符转移到某个相同的目的状态,则这两条出边是状态i和状态j之间的“共享边”;若对于某个输入字符,状态i和状态j各有一条出边经过该输入字符转移到不同的目的状态,则状态i的这条出边是关于状态j的“非共享边”,且状态j的这条出边是关于状态i的“非共享边”;每个DFA状态均用一对状态ID进行编号,所述状态ID对为模板ID和私有ID,全部的DFA状态被划分成多个状态集合,每个状态集合包含的是全部拥有相同私有ID的状态,且该状态集合以这个私有ID命名;如果两个状态分属于两个状态集合,且所述两个状态集合共享相同的模板ID,则所述两个状态集合互为彼此的亲属状态;对于私有ID为K的状态集合,若私有ID为J的状态集合同时满足下述条件,则状态集合K的所有状态都各自选择它们在状态集合J中的亲属状态作为模板状态:J<K;对于集合K中的每一个状态,其在集合J中都存在一个亲属状态;在所有满足上述两个条件的候选状态集合中,集合J中集合K的相似度最大;每个DFA状态最多只有一个模板状态,对于自循环状态不为之分配模板;若一个DFA状态有模板状态时,则该DFA状态的状态转移边只需存储该DFA状态关于其模板状态的非共享边;若一个DFA状态没有模板状态,则该DFA状态需要存储其全部的状态转移边;存在模板关系的两个DFA状态生成的TCAM条目之间的存储顺序如下:若状态i以状态j为模板,则状态i的状态转移边都必须存储在状态j的状态转移边之前;不存在模板关系的两个DFA状态生成的TCAM条目之间的存储顺序是任意的。具体的,TCAM条目构造模块111,还用于将转移到自身的出边的数目超过了一定的阈值的状态定义为自循环状态,每个DFA状态有且仅有唯一的(模板ID,私有ID)对;为每个自循环状态分配一个唯一的模板ID,为所有的自循环状态分配一个相同的私有ID;对于每个非自循环状态,其模板ID的取值为与其相似度最大的自循环状态的模板ID;其私有ID的取值按如下宽度遍历过程迭代进行:维护一个状态集合的队列,尝试为所有在同一个状态集合中的状态分配相同的私有ID,初始将由所有自循环状态组成的状态集合入队,并将该状态集合标记为已访问,每次取出队首的状态集合S直至队列为空:依次迭代检查S经每一个字符所达到的目的状态集合D:从D中删去所有自循环状态;若D中存在多个状态共享相同的模板ID,则只留下其中一个状态,其余的状态从D中删去;若存在一个已访问过的状态集合S’,使得则跳出本次迭代;若存在一个已访问过的状态集合S’,S’中所有的状态已被分配相同的“私有ID”,使得则将S’中状态所分配的私有ID分配给D中所有状态;否则,D中所有状态分配一个尚未被分配过的私有ID;将D中所有状态从所有已访问的状态集合中删除;标记集合D为已访问;D入队。具体的,TCAM条目构造模块111,还用于对于存在模板关系的两个DFA状态i和j,若状态i以状态j为模板,则状态i的私有ID编码匹配状态j的私有ID编码;DFA状态间的模板关系将所有的DFA状态组织成多个树,每个树均以一个自循环状态作为根,每个DFA状态均以它的模板状态为父结点;在所述树中为每一个状态分配一个“子编码”,如果一个状态有N个子结点,则这N个子结点所需的子编码比特数为每个子结点分配一个长度为n的互不相同的子编码;全“0”的编码保留不分配,叶子结点的子编码为空;私有ID相同的状态分配的子编码必须相同;每个状态的私有ID的编码即为该状态所有祖先结点的子编码与自身子编码的拼接,即从树根开始到每个状态,该状态的初始私有ID编码为空,沿途依次在后面拼接上所访问的父结点的子编码,最后拼接上该状态的子编码,作为该状态的私有ID编码;将所有状态的私有ID编码的长度设置为一致。进一步地,所述的装置还可以包括:TCAM条目删除模块113,用于若存在共享相同的目的状态域、源状态域的两个TCAM条目i和j且i和j的输入字符域只相差一个比特,则在TCAM条目i的输入字符域中,将与TCAM条目j相差的比特位的值置为“*”,删除TCAM条目j;若存在共享相同的目的状态域、输入字符域、源状态域的私有ID域的两个TCAM条目i和j且i和j的源状态域的模板ID域只相差一个比特,则在TCAM条目i的模板ID域中,将与TCAM条目j相差的比特位的值置为“*”,删除TCAM条目j。应用本发明实施例的装置进行DFA匹配的具体处理过程与前述方法实施例类似,此处不再赘述。本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于一计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。其中,所述的存储介质可为磁碟、光盘、只读存储记忆体(Read-OnlyMemory,ROM)或随机存储记忆体(RandomAccessMemory,RAM)等。综上所述,本发明实施例通过基于TCAM实现DFA,TCAM条目的源状态域由模板ID域和私有ID域两个子域组成,目的状态域由模板ID域和私有ID域两个子域组成,可以在不牺牲匹配速度的前提下突破DFA状态数指数膨胀的问题,所需的TCAM条目数能够少于DFA的状态数,从而大大减少了DFA所需的存储空间。基于DFA的正则表达式匹配技术是当代网络系统的一项基础核心技术,各种网络应用,如深度包检测、签名匹配、蠕虫检测、入侵检测和防护、流量分析等等,一旦解决了DFA的匹配速度和存储空间的两难境地,将对这些网络应用产生直接的经济效益。以上所述,仅为本发明较佳的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应该以权利要求的保护范围为准。
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1