# 代码实现 1、修改配置文件读取流程,使之支持灰白名单配置。 2、增加灰白名单功能函数。 3、修改原有用户面代码,使之支持灰白名单配置。 ## 1 修改配置文件读取流程,使之支持灰名单配置: 1)、增加灰名单配置文件,内容如下: JSON EXAMPLE: ```JSON { "is_global": true, "dnn_binding_list": [ "default", "internet" ], "domain_name_list": [ "www.99cloud.net", "www.google.com" ] } ``` XML EXAMPLE: ```xml true default internet www.99cloud.net www.google.com ``` 2)、增加解析白名单配置的函数,该函数将解析配置并将内容存放到 `upf_main_t um` 全局变量中的 `grey_list_feature_type *grey_list` 成员中。 修改 upf_conf.h 文件: ```C // 解析灰名单配置的函数 ``` 修改 upf_conf.c 文件: ```C // 解析灰名单配置的函数 ``` ## 2 在用户面增加灰名单过滤处理: 1、增加灰名单配置存放变量: 1)、修改 upf.h 文件中的 `upf_main_t` 结构体: ```C typedef struct { /*……*/ grey_list_feature_type *grey_list; } upf_main_t; ``` 2)、在 picohttpparser.h 文件中增加 `grey_list_feature` 结构体: ```C #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; }grey_list_feature_type; ``` 3)、增加 `check_grey_grey_list` 函数,封装灰名单检查步骤: ```c /******************************************* * 函数功能 : 检查访问对象是否在灰/白名单中 * 函数参数 : 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` 函数,增加灰名单功能实现流程: ![image1](../../../_static/white_grey_list_1_modify_upf_process.png) 上图中红框部分修改为如下代码: ```C // 灰名单过滤 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; } } } ```