代码实现
1、修改配置文件读取流程,使之支持灰白名单配置。
2、增加灰白名单功能函数。
3、修改原有用户面代码,使之支持灰白名单配置。
1 修改配置文件读取流程,使之支持白名单配置:
1)、增加白名单配置文件,内容如下:
JSON EXAMPLE:
{
"is_global": true,
"dnn_binding_list": [
"default",
"internet"
],
"domain_name_list": [
"www.99cloud.net",
"www.google.com"
],
"enhanced_feature_list": [
"header_enrichment"
]
}
XML EXAMPLE:
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<white_list_feature>
<is_global>true</is_global>
<dnn_binding_list>default</dnn_binding_list>
<dnn_binding_list>internet</dnn_binding_list>
<domain_name_list>www.99cloud.net</domain_name_list>
<domain_name_list>www.google.com</domain_name_list>
<enhanced_feature_list>header_enrichment</enhanced_feature_list>
</white_list_feature>
</root>
2)、增加解析白名单配置的函数,该函数将解析配置并将内容存放到 upf_main_t um
全局变量中的 white_list_feature_type *white_list
成员中。
修改 upf_conf.h 文件:
// 解析白名单配置的函数
修改 upf_conf.c 文件:
//解析白名单配置的函数
2 在用户面增加白名单过滤处理:
1、增加白名单配置存放变量:
1)、修改 upf.h 文件中的 upf_main_t
结构体:
typedef struct
{
/*……*/
white_list_feature_type *white_list;
} upf_main_t;
2)、在 picohttpparser.h 文件中增加 white_list_feature
结构体:
#define WGLIST_HEADER_ENRICHMENT_FEATURE_STR "header_enrichment"
#define WGLIST_ANTI_CHEAT_FEATURE_STR "anti_cheat"
#define WGLIST_HEADER_ENRICHMENT_FEATURE_TYPE 1
#define WGLIST_ANTI_CHEAT_FEATURE_TYPE 2
typedef struct{
u8 is_global;
char * dnn_binding_list;
char * domain_name_list;
u8 * enhanced_feature_list;
}white_list_feature_type;
3)、增加 white_grey_list_features
函数,封装白名单检查步骤:
/*******************************************
* 函数功能 : 检查访问对象是否在灰/白名单中
* 函数参数 : dnn - 访问目标网络
* domain - 访问目标域名
* list_type - 灰名单/白名单
* 函数返回值 : 0 - 不在名单中
* 1 - 在名单中
*******************************************/
u8 check_white_grey_list (const char *dnn, const char *domain, const u8 list_type) {
upf_main_t *um = &upf_main;
u8 is_global = NULL;
char * dnn_binding_list = NULL;
char * domain_name_list = NULL;
char * dnn_binding_str = NULL;
char * domain_name_str = NULL;
int hit = 0;
switch (list_type) {
case 1:
is_global = um->grey_list_feature.is_global;
dnn_binding_list = um->grey_list_feature.dnn_binding_list;
domain_name_list = um->grey_list_feature.domain_name_list;
enhanced_feature_list = um->grey_list_feature.enhanced_feature_list;
break;
case 2:
is_global = um->white_list_feature.is_global;
dnn_binding_list = um->white_list_feature.dnn_binding_list;
domain_name_list = um->white_list_feature.domain_name_list;
*enhanced_feature_list = 0x02;
break;
default:
return 0;
}
if ( !is_global && dnn ){ // 有配置指定 DNN
vec_foreach(dnn_binding_str, dnn_binding_list){ // 遍历配置中的 DNN list
if (strcmp(dnn, dnn_binding_str)){ // 有命中
hit = 1;
break;
}
}
}
if ( hit && domain ){ // DNN 命中,继续检查 domain 是否在名单中
vec_foreach(domain_name_str, domain_name_list){ // domain list
if (strcmp(domain, domain_name_str)){ // 有命中
hit = 2;
break;
}
}
if (hit > 1){
return 1;
}
}
return 0;
}
2、修改 upf_process.c 文件中的 upf_process
函数,增加白名单功能实现流程:
上图中红框部分修改为如下代码:
// 灰名单过滤
if ( um->grey_list ) {
if ( upf_buffer_opaque (b)->upf.http ) {
phr_parse_request (http, http_length, &method, &method_len, &path,&path_len, &minor_version, headers, &num_headers, 0);
// 检查是否在灰名单中
if ( check_grey_grey_list(dnn, domain, 1) ) {
// 是否是欺诈包
if ( upf_cheat_defense != -1) {
next = DROP;
goto trace;
}
}
}else if ( upf_buffer_opaque (b)->upf.https_client_hello ) {
// 检查是否在灰名单中
if ( check_grey_grey_list(dnn, domain, 1) ) {
// 是否是欺诈包
if ( upf_cheat_defense != -1 ) {
next = DROP;
goto trace;
}
}
}
}
// 白名单过滤
if ( um->white_list ) {
if ( upf_buffer_opaque (b)->upf.http ) {
// 检查是否在白名单中
if ( check_grey_grey_list(dnn, domain, 2) ) {
// 调用头增强功能
upf_https_header_enrichment;
}
}else if ( upf_buffer_opaque (b)->upf.https_client_hello ) {
// 检查是否在白名单中
if ( check_grey_grey_list(dnn, domain, 2) ) {
// 调用头增强功能
upf_http_header_enrichment_pro;
}
}
}